diff options
author | Nakajima Akira <nakajima.akira@nttcom.co.jp> | 2015-04-22 15:24:44 +0900 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2015-05-20 13:05:25 -0500 |
commit | 7196ac113a4f38b7ca1a3282fd9edf328bd22287 (patch) | |
tree | 178e1b3431d73f91c704e093955da6632919a8d3 /fs/cifs | |
parent | 65c3b205ebe06a389a29544e71a8071da0ce4155 (diff) | |
download | linux-7196ac113a4f38b7ca1a3282fd9edf328bd22287.tar.gz linux-7196ac113a4f38b7ca1a3282fd9edf328bd22287.tar.bz2 linux-7196ac113a4f38b7ca1a3282fd9edf328bd22287.zip |
Fix to check Unique id and FileType when client refer file directly.
When you refer file directly on cifs client,
(e.g. ls -li <filename>, cd <dir>, stat <filename>)
the function return old inode number and filetype from old inode cache,
though server has different inode number or filetype.
When server is Windows, cifs client has same problem.
When Server is Windows
, This patch fixes bug in different filetype,
but does not fix bug in different inode number.
Because QUERY_PATH_INFO response by Windows does not include inode number(Index Number) .
BUG INFO
https://bugzilla.kernel.org/show_bug.cgi?id=90021
https://bugzilla.kernel.org/show_bug.cgi?id=90031
Reported-by: Nakajima Akira <nakajima.akira@nttcom.co.jp>
Signed-off-by: Nakajima Akira <nakajima.akira@nttcom.co.jp>
Reviewed-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/inode.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index ef71aa1515f6..f621b44cb800 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -401,9 +401,25 @@ int cifs_get_inode_info_unix(struct inode **pinode, rc = -ENOMEM; } 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(*pinode)->uniqueid != fattr.cf_uniqueid)) { + rc = -ESTALE; + goto cgiiu_exit; + } + + /* if filetype is different, return error */ + if (unlikely(((*pinode)->i_mode & S_IFMT) != + (fattr.cf_mode & S_IFMT))) { + rc = -ESTALE; + goto cgiiu_exit; + } + cifs_fattr_to_inode(*pinode, &fattr); } +cgiiu_exit: return rc; } @@ -838,6 +854,15 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, if (!*inode) rc = -ENOMEM; } else { + /* we already have inode, update it */ + + /* if filetype is different, return error */ + if (unlikely(((*inode)->i_mode & S_IFMT) != + (fattr.cf_mode & S_IFMT))) { + rc = -ESTALE; + goto cgii_exit; + } + cifs_fattr_to_inode(*inode, &fattr); } |