diff options
author | Steve French <smfrench@gmail.com> | 2016-09-20 04:05:57 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2016-10-12 13:08:31 -0400 |
commit | 6609804413ae5b84830e35fdd3a7b7fe4149cf71 (patch) | |
tree | f9f591330c0109acfaeae2b819f418afd0d294c9 | |
parent | a958fff2429525692c571bb6421b606fb0fef50a (diff) |
Add way to query creation time of file via cifs xattr
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>
-rw-r--r-- | fs/cifs/xattr.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index c4237b8ad9c6..20af5187ba63 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #define MAX_EA_VALUE_SIZE 65535 | 34 | #define MAX_EA_VALUE_SIZE 65535 |
35 | #define CIFS_XATTR_CIFS_ACL "system.cifs_acl" | 35 | #define CIFS_XATTR_CIFS_ACL "system.cifs_acl" |
36 | #define CIFS_XATTR_ATTRIB "cifs.dosattrib" /* full name: user.cifs.dosattrib */ | 36 | #define CIFS_XATTR_ATTRIB "cifs.dosattrib" /* full name: user.cifs.dosattrib */ |
37 | 37 | #define CIFS_XATTR_CREATETIME "cifs.creationtime" /* user.cifs.creationtime */ | |
38 | /* BB need to add server (Samba e.g) support for security and trusted prefix */ | 38 | /* BB need to add server (Samba e.g) support for security and trusted prefix */ |
39 | 39 | ||
40 | enum { XATTR_USER, XATTR_CIFS_ACL, XATTR_ACL_ACCESS, XATTR_ACL_DEFAULT }; | 40 | enum { XATTR_USER, XATTR_CIFS_ACL, XATTR_ACL_ACCESS, XATTR_ACL_DEFAULT }; |
@@ -169,6 +169,29 @@ static int cifs_attrib_get(struct dentry *dentry, | |||
169 | return sizeof(__u32); | 169 | return sizeof(__u32); |
170 | } | 170 | } |
171 | 171 | ||
172 | static int cifs_creation_time_get(struct dentry *dentry, struct inode *inode, | ||
173 | void *value, size_t size) | ||
174 | { | ||
175 | ssize_t rc; | ||
176 | __u64 * pcreatetime; | ||
177 | |||
178 | rc = cifs_revalidate_dentry_attr(dentry); | ||
179 | if (rc) | ||
180 | return rc; | ||
181 | |||
182 | if ((value == NULL) || (size == 0)) | ||
183 | return sizeof(__u64); | ||
184 | else if (size < sizeof(__u64)) | ||
185 | return -ERANGE; | ||
186 | |||
187 | /* return dos attributes as pseudo xattr */ | ||
188 | pcreatetime = (__u64 *)value; | ||
189 | *pcreatetime = CIFS_I(inode)->createtime; | ||
190 | return sizeof(__u64); | ||
191 | |||
192 | return rc; | ||
193 | } | ||
194 | |||
172 | 195 | ||
173 | static int cifs_xattr_get(const struct xattr_handler *handler, | 196 | static int cifs_xattr_get(const struct xattr_handler *handler, |
174 | struct dentry *dentry, struct inode *inode, | 197 | struct dentry *dentry, struct inode *inode, |
@@ -202,6 +225,9 @@ static int cifs_xattr_get(const struct xattr_handler *handler, | |||
202 | if (strcmp(name, CIFS_XATTR_ATTRIB) == 0) { | 225 | if (strcmp(name, CIFS_XATTR_ATTRIB) == 0) { |
203 | rc = cifs_attrib_get(dentry, inode, value, size); | 226 | rc = cifs_attrib_get(dentry, inode, value, size); |
204 | break; | 227 | break; |
228 | } else if (strcmp(name, CIFS_XATTR_CREATETIME) == 0) { | ||
229 | rc = cifs_creation_time_get(dentry, inode, value, size); | ||
230 | break; | ||
205 | } | 231 | } |
206 | 232 | ||
207 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) | 233 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) |