| From 66612b92c09bf9ba59366473f8a76cacb173de26 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 2 Dec 2015 14:46:08 +0000 |
| Subject: cifs: Check uniqueid for SMB2+ and return -ESTALE if necessary |
| |
| From: Ross Lagerwall <ross.lagerwall@citrix.com> |
| |
| [ Upstream commit a108471b5730b52017e73b58c9f486319d2ac308 ] |
| |
| Commit 7196ac113a4f ("Fix to check Unique id and FileType when client |
| refer file directly.") checks whether the uniqueid of an inode has |
| changed when getting the inode info, but only when using the UNIX |
| extensions. Add a similar check for SMB2+, since this can be done |
| without an extra network roundtrip. |
| |
| Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> |
| Signed-off-by: Steve French <smfrench@gmail.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/cifs/inode.c | 24 ++++++++++++++++++++++-- |
| 1 file changed, 22 insertions(+), 2 deletions(-) |
| |
| diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c |
| index 0f210cb5038a4..3d3c66fcb5ee6 100644 |
| --- a/fs/cifs/inode.c |
| +++ b/fs/cifs/inode.c |
| @@ -829,8 +829,21 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, |
| } |
| } else |
| fattr.cf_uniqueid = iunique(sb, ROOT_I); |
| - } else |
| - fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; |
| + } else { |
| + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && |
| + validinum == false && server->ops->get_srv_inum) { |
| + /* |
| + * Pass a NULL tcon to ensure we don't make a round |
| + * trip to the server. This only works for SMB2+. |
| + */ |
| + tmprc = server->ops->get_srv_inum(xid, |
| + NULL, cifs_sb, full_path, |
| + &fattr.cf_uniqueid, data); |
| + if (tmprc) |
| + fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; |
| + } else |
| + fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; |
| + } |
| |
| /* query for SFU type info if supported and needed */ |
| if (fattr.cf_cifsattrs & ATTR_SYSTEM && |
| @@ -871,6 +884,13 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, |
| } else { |
| /* we already have inode, update it */ |
| |
| + /* if uniqueid is different, return error */ |
| + if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && |
| + CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) { |
| + rc = -ESTALE; |
| + goto cgii_exit; |
| + } |
| + |
| /* if filetype is different, return error */ |
| if (unlikely(((*inode)->i_mode & S_IFMT) != |
| (fattr.cf_mode & S_IFMT))) { |
| -- |
| 2.20.1 |
| |