diff -rub linux-2.6.33/fs/cifs/cifssmb.c linux-2.6.33.crtime/fs/cifs/cifssmb.c --- linux-2.6.33/fs/cifs/cifssmb.c 2010-03-05 16:20:12.000000000 -0800 +++ linux-2.6.33.crtime/fs/cifs/cifssmb.c 2010-03-08 07:52:06.000000000 -0800 @@ -5417,6 +5417,22 @@ if (rc == -EAGAIN) goto QAllEAsRetry; + /* Pseudo-xattr returns file creation time. + * Samba bug 7175, CGN bug 5131 -GAP 3/3/10 + */ + { + static const char *crtime_name = "user.crtime"; + int crtime_len = strlen(crtime_name) + 1; + if (EAData != NULL && buf_size > crtime_len && rc >= 0) { + memcpy(EAData, crtime_name, crtime_len); + EAData += crtime_len; + rc += crtime_len; + buf_size -= crtime_len; + } + else if (buf_size == 0 && rc >= 0) { + rc += crtime_len; + } + } return (ssize_t)rc; } diff -rub linux-2.6.33/fs/cifs/xattr.c linux-2.6.33.crtime/fs/cifs/xattr.c --- linux-2.6.33/fs/cifs/xattr.c 2010-03-05 16:20:12.000000000 -0800 +++ linux-2.6.33.crtime/fs/cifs/xattr.c 2010-03-08 07:52:06.000000000 -0800 @@ -38,6 +38,10 @@ #define XATTR_SECURITY_PREFIX_LEN 9 /* BB need to add server (Samba e.g) support for security and trusted prefix */ +/* Pseudo-xattr returns file creation time. + * Samba bug 7175, CGN bug 5131 -GAP 3/3/10 + */ +#define CIFS_XATTR_CRTIME "user.crtime" int cifs_removexattr(struct dentry *direntry, const char *ea_name) @@ -201,6 +205,45 @@ return rc; } + +/* Pseudo-xattr returns file creation time. + * Samba bug 7175, CGN bug 5131 -GAP 3/3/10 + */ +static int cifs_get_crtime(const unsigned char *full_path, struct super_block *sb, + int xid, void *ea_value, size_t buf_size) +{ + int rc = 0; + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); + struct cifsTconInfo *pTcon = cifs_sb->tcon; + FILE_ALL_INFO *pfindData = NULL; + struct timespec creation_time = {0}; + u64 crtime = 0; + + if (buf_size == 0) + return sizeof crtime; + if (buf_size < sizeof crtime) + return -ERANGE; + if (ea_value == NULL) + return -EINVAL; + pfindData = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); + if (pfindData == NULL) + return -ENOMEM; + + rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData, + 0 /* not legacy */, + cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); + + if (rc == 0) { + creation_time = cifs_NTtimeToUnix(le64_to_cpu(pfindData->CreationTime)); + crtime = creation_time.tv_sec; // discard the nanosecs + memcpy(ea_value, &crtime, sizeof crtime); + rc = sizeof crtime; + } + kfree(pfindData); + return rc; +} + ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, void *ea_value, size_t buf_size) { @@ -235,6 +278,14 @@ /* return alt name if available as pseudo attr */ if (ea_name == NULL) { cFYI(1, ("Null xattr names not supported")); + } else if (strncmp(ea_name, CIFS_XATTR_CRTIME, strlen(CIFS_XATTR_CRTIME)) == 0) { + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) + goto get_ea_exit; + /* Pseudo-xattr returns file creation time. + * Samba bug 7175, CGN bug 5131 -GAP 3/3/10 + */ + rc = cifs_get_crtime(full_path, sb, xid, ea_value, buf_size); + cFYI(1, ("%s(%s), rc=%d", __FUNCTION__, full_path, rc)); } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) goto get_ea_exit;