aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSuresh Jayaraman <sjayaraman@suse.de>2010-10-01 11:53:33 -0400
committerSteve French <sfrench@us.ibm.com>2010-10-15 11:19:55 -0400
commit6221ddd0f5e2ddc1d5d928119a2cde033d16f96d (patch)
treeded17afe18712966dcc26560d9036145a3f1f98c /fs
parent5d0d28824c76409f0d1a645bf0ae81318c8ffa42 (diff)
cifs: handle FindFirst failure gracefully
FindFirst failure due to permission errors or any other errors are silently ignored by cifs_readdir(). This could cause problem to applications that depend on the error to do further processing. Reproducer: - mount a cifs share - mkdir tdir;touch tdir/1 tdir/2 tdir/3 - chmod -x tdir - ls tdir Currently, we start calling filldir() for '.' and '..' before we know we whether FindFirst could succeed or not. If FindFirst fails later, there is no way to notify VFS by setting buf.error and so VFS won't be able to catch this. Fix this by moving the call to initiate_cifs_search() before we start doing filldir(). This fixes https://bugzilla.samba.org/show_bug.cgi?id=7535 Reported-by: Tom Dexter <digitalaudiorock@gmail.com> Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/readdir.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 1f0bd0f972d4..6f3d13ff9470 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -790,6 +790,17 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
790 790
791 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 791 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
792 792
793 /*
794 * Ensure FindFirst doesn't fail before doing filldir() for '.' and
795 * '..'. Otherwise we won't be able to notify VFS in case of failure.
796 */
797 if (file->private_data == NULL) {
798 rc = initiate_cifs_search(xid, file);
799 cFYI(1, "initiate cifs search rc %d", rc);
800 if (rc)
801 goto rddir2_exit;
802 }
803
793 switch ((int) file->f_pos) { 804 switch ((int) file->f_pos) {
794 case 0: 805 case 0:
795 if (filldir(direntry, ".", 1, file->f_pos, 806 if (filldir(direntry, ".", 1, file->f_pos,
@@ -814,14 +825,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
814 if after then keep searching till find it */ 825 if after then keep searching till find it */
815 826
816 if (file->private_data == NULL) { 827 if (file->private_data == NULL) {
817 rc = initiate_cifs_search(xid, file);
818 cFYI(1, "initiate cifs search rc %d", rc);
819 if (rc) {
820 FreeXid(xid);
821 return rc;
822 }
823 }
824 if (file->private_data == NULL) {
825 rc = -EINVAL; 828 rc = -EINVAL;
826 FreeXid(xid); 829 FreeXid(xid);
827 return rc; 830 return rc;