Add way to query creation time of file via cifs xattr
authorSteve French <smfrench@gmail.com>
Tue, 20 Sep 2016 08:05:57 +0000 (03:05 -0500)
committerSteve French <smfrench@gmail.com>
Wed, 12 Oct 2016 17:08:31 +0000 (12:08 -0500)
Add parsing for new pseudo-xattr user.cifs.creationtime file
attribute to allow backup and test applications to view
birth time of file on cifs/smb3 mounts.

Signed-off-by: Steve French <steve.french@primarydata.com>
fs/cifs/xattr.c

index c4237b8..20af518 100644 (file)
@@ -34,7 +34,7 @@
 #define MAX_EA_VALUE_SIZE 65535
 #define CIFS_XATTR_CIFS_ACL "system.cifs_acl"
 #define CIFS_XATTR_ATTRIB "cifs.dosattrib"  /* full name: user.cifs.dosattrib */
-
+#define CIFS_XATTR_CREATETIME "cifs.creationtime"  /* user.cifs.creationtime */
 /* BB need to add server (Samba e.g) support for security and trusted prefix */
 
 enum { XATTR_USER, XATTR_CIFS_ACL, XATTR_ACL_ACCESS, XATTR_ACL_DEFAULT };
@@ -169,6 +169,29 @@ static int cifs_attrib_get(struct dentry *dentry,
        return sizeof(__u32);
 }
 
+static int cifs_creation_time_get(struct dentry *dentry, struct inode *inode,
+                                 void *value, size_t size)
+{
+       ssize_t rc;
+       __u64 * pcreatetime;
+
+       rc = cifs_revalidate_dentry_attr(dentry);
+       if (rc)
+               return rc;
+
+       if ((value == NULL) || (size == 0))
+               return sizeof(__u64);
+       else if (size < sizeof(__u64))
+               return -ERANGE;
+
+       /* return dos attributes as pseudo xattr */
+       pcreatetime = (__u64 *)value;
+       *pcreatetime = CIFS_I(inode)->createtime;
+       return sizeof(__u64);
+
+       return rc;
+}
+
 
 static int cifs_xattr_get(const struct xattr_handler *handler,
                          struct dentry *dentry, struct inode *inode,
@@ -202,6 +225,9 @@ static int cifs_xattr_get(const struct xattr_handler *handler,
                if (strcmp(name, CIFS_XATTR_ATTRIB) == 0) {
                        rc = cifs_attrib_get(dentry, inode, value, size);
                        break;
+               } else if (strcmp(name, CIFS_XATTR_CREATETIME) == 0) {
+                       rc = cifs_creation_time_get(dentry, inode, value, size);
+                       break;
                }
 
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)