From: Steve French <smfrench@xxxxxxxxx> Signed-off-by: Pavel Shilovsky <piastryyy@xxxxxxxxx> Signed-off-by: Steve French <smfrench@xxxxxxxxx> --- 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 5bc1f78..811cf97 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 60e8b1e..30c7c89 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); + struct smb2_file_all_info *smb2_data; + + smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + 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 c64362e..5d1ac2b 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -75,6 +75,7 @@ extern void smb2_echo_request(struct work_struct *work); extern void move_smb2_info_to_cifs(FILE_ALL_INFO *dst, struct smb2_file_all_info *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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html