From: Steve French <[email protected]>
Signed-off-by: Pavel Shilovsky <[email protected]>
Signed-off-by: Steve French <[email protected]>
---
fs/cifs/inode.c | 18 +++++++++++++++---
fs/cifs/smb2inode.c | 42 ++++++++++++++++++++++++++++++++++++++++++
fs/cifs/smb2proto.h | 1 +
3 files changed, 58 insertions(+), 3 deletions(-)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index a465d04..9db398e 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -568,7 +568,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr,
FILE_ALL_INFO *info,
fattr->cf_gid = cifs_sb->mnt_gid;
}
-int cifs_get_file_info(struct file *filp)
+static int
+cifs_query_file_info(struct file *filp)
{
int rc;
int xid;
@@ -599,7 +600,7 @@ int cifs_get_file_info(struct file *filp)
rc = 0;
CIFS_I(inode)->time = 0;
default:
- goto cgfi_exit;
+ goto cqfi_exit;
}
/*
@@ -609,11 +610,22 @@ int cifs_get_file_info(struct file *filp)
fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
cifs_fattr_to_inode(inode, &fattr);
-cgfi_exit:
+cqfi_exit:
FreeXid(xid);
return rc;
}
+int cifs_get_file_info(struct file *filp)
+{
+#ifdef CONFIG_CIFS_SMB2
+ struct cifsFileInfo *cfile = filp->private_data;
+
+ if (tlink_tcon(cfile->tlink)->ses->server->is_smb2)
+ return smb2_query_file_info(filp);
+#endif
+ return cifs_query_file_info(filp);
+}
+
static int
cifs_query_inode_info(struct inode **pinode, const char *full_path,
FILE_ALL_INFO *data, struct super_block *sb, int xid,
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
index 1d21185..17297e4 100644
--- a/fs/cifs/smb2inode.c
+++ b/fs/cifs/smb2inode.c
@@ -284,6 +284,48 @@ sqii_exit:
return rc;
}
+int smb2_query_file_info(struct file *filp)
+{
+ int rc;
+ int xid;
+ FILE_ALL_INFO find_data;
+ struct cifs_fattr fattr;
+ struct inode *inode = filp->f_path.dentry->d_inode;
+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+ struct cifsFileInfo *cfile = filp->private_data;
+ struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
+ FILE_ALL_INFO_SMB2 *smb2_data;
+
+ smb2_data = kzalloc(sizeof(FILE_ALL_INFO_SMB2) + MAX_NAME*2,
+ GFP_KERNEL);
+ if (smb2_data == NULL)
+ return -ENOMEM;
+
+ xid = GetXid();
+ rc = SMB2_query_info(xid, tcon, cfile->persist_fid,
+ cfile->volatile_fid, smb2_data);
+ if (!rc) {
+ move_smb2_info_to_cifs(&find_data, smb2_data);
+ cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false);
+ } else if (rc == -EREMOTE) {
+ cifs_create_dfs_fattr(&fattr, inode->i_sb);
+ rc = 0;
+ } else
+ goto sqfi_exit;
+
+ /*
+ * don't bother with SFU junk here -- just mark inode as needing
+ * revalidation.
+ */
+ fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
+ fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
+ cifs_fattr_to_inode(inode, &fattr);
+sqfi_exit:
+ FreeXid(xid);
+ kfree(smb2_data);
+ return rc;
+}
+
int smb2_mkdir(struct inode *inode, struct dentry *direntry, int mode)
{
int rc = 0, tmprc;
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
index 45ce215..73bc050 100644
--- a/fs/cifs/smb2proto.h
+++ b/fs/cifs/smb2proto.h
@@ -105,6 +105,7 @@ extern int smb2_setup_session(unsigned int xid, struct
cifs_ses *pses_info,
extern int smb2_umount(struct super_block *, struct cifs_sb_info *);
extern void move_smb2_info_to_cifs(FILE_ALL_INFO *dst, FILE_ALL_INFO_SMB2
*src);
+extern int smb2_query_file_info(struct file *filp);
extern int smb2_query_inode_info(struct inode **pinode, const char *full_path,
FILE_ALL_INFO *data, struct super_block *sb,
int xid);
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html