Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs fixes from Al Viro:
"A bunch of fixes; the last one is this cycle regression, the rest are
-stable fodder."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
fix off-by-one in argument passed by iterate_fd() to callbacks
lookup_one_len: don't accept . and ..
cifs: get rid of blind d_drop() in readdir
nfs_lookup_revalidate(): fix a leak
don't do blind d_drop() in nfs_prime_dcache()

+21 -10
+4 -1
fs/cifs/readdir.c
··· 86 86 87 87 dentry = d_lookup(parent, name); 88 88 if (dentry) { 89 + int err; 89 90 inode = dentry->d_inode; 90 91 /* update inode in place if i_ino didn't change */ 91 92 if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { 92 93 cifs_fattr_to_inode(inode, fattr); 93 94 return dentry; 94 95 } 95 - d_drop(dentry); 96 + err = d_invalidate(dentry); 96 97 dput(dentry); 98 + if (err) 99 + return NULL; 97 100 } 98 101 99 102 dentry = d_alloc(parent, name);
+8 -6
fs/file.c
··· 994 994 const void *p) 995 995 { 996 996 struct fdtable *fdt; 997 - struct file *file; 998 997 int res = 0; 999 998 if (!files) 1000 999 return 0; 1001 1000 spin_lock(&files->file_lock); 1002 - fdt = files_fdtable(files); 1003 - while (!res && n < fdt->max_fds) { 1004 - file = rcu_dereference_check_fdtable(files, fdt->fd[n++]); 1005 - if (file) 1006 - res = f(p, file, n); 1001 + for (fdt = files_fdtable(files); n < fdt->max_fds; n++) { 1002 + struct file *file; 1003 + file = rcu_dereference_check_fdtable(files, fdt->fd[n]); 1004 + if (!file) 1005 + continue; 1006 + res = f(p, file, n); 1007 + if (res) 1008 + break; 1007 1009 } 1008 1010 spin_unlock(&files->file_lock); 1009 1011 return res;
+5
fs/namei.c
··· 2131 2131 if (!len) 2132 2132 return ERR_PTR(-EACCES); 2133 2133 2134 + if (unlikely(name[0] == '.')) { 2135 + if (len < 2 || (len == 2 && name[1] == '.')) 2136 + return ERR_PTR(-EACCES); 2137 + } 2138 + 2134 2139 while (len--) { 2135 2140 c = *(const unsigned char *)name++; 2136 2141 if (c == '/' || c == '\0')
+4 -3
fs/nfs/dir.c
··· 450 450 nfs_refresh_inode(dentry->d_inode, entry->fattr); 451 451 goto out; 452 452 } else { 453 - d_drop(dentry); 453 + if (d_invalidate(dentry) != 0) 454 + goto out; 454 455 dput(dentry); 455 456 } 456 457 } ··· 1101 1100 out_zap_parent: 1102 1101 nfs_zap_caches(dir); 1103 1102 out_bad: 1103 + nfs_free_fattr(fattr); 1104 + nfs_free_fhandle(fhandle); 1104 1105 nfs_mark_for_revalidate(dir); 1105 1106 if (inode && S_ISDIR(inode->i_mode)) { 1106 1107 /* Purge readdir caches. */ ··· 1115 1112 shrink_dcache_parent(dentry); 1116 1113 } 1117 1114 d_drop(dentry); 1118 - nfs_free_fattr(fattr); 1119 - nfs_free_fhandle(fhandle); 1120 1115 dput(parent); 1121 1116 dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", 1122 1117 __func__, dentry->d_parent->d_name.name,