From 789d216176ee76c1d43e06b3438a5b043236192d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 1 Dec 2012 17:55:13 -0800 Subject: [PATCH] --- yaml --- r: 336181 b: refs/heads/master c: 3c46f3d6406b1d0c53575774b2d1fd013cd7f76f h: refs/heads/master i: 336179: 5f2703caa725d186f4bd31612a9a0e80d8f3ddaf v: v3 --- [refs] | 2 +- trunk/fs/cifs/readdir.c | 5 ++++- trunk/fs/file.c | 14 ++++++++------ trunk/fs/namei.c | 5 +++++ trunk/fs/nfs/dir.c | 7 ++++--- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/[refs] b/[refs] index 8126dce3918a..b69b8ea48ab2 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8852aac25e79e38cc6529f20298eed154f60b574 +refs/heads/master: 3c46f3d6406b1d0c53575774b2d1fd013cd7f76f diff --git a/trunk/fs/cifs/readdir.c b/trunk/fs/cifs/readdir.c index f9b5d3d6cf33..1c576e871366 100644 --- a/trunk/fs/cifs/readdir.c +++ b/trunk/fs/cifs/readdir.c @@ -86,14 +86,17 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, dentry = d_lookup(parent, name); if (dentry) { + int err; inode = dentry->d_inode; /* update inode in place if i_ino didn't change */ if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { cifs_fattr_to_inode(inode, fattr); return dentry; } - d_drop(dentry); + err = d_invalidate(dentry); dput(dentry); + if (err) + return NULL; } dentry = d_alloc(parent, name); diff --git a/trunk/fs/file.c b/trunk/fs/file.c index 7cb71b992603..eff23162485f 100644 --- a/trunk/fs/file.c +++ b/trunk/fs/file.c @@ -994,16 +994,18 @@ int iterate_fd(struct files_struct *files, unsigned n, const void *p) { struct fdtable *fdt; - struct file *file; int res = 0; if (!files) return 0; spin_lock(&files->file_lock); - fdt = files_fdtable(files); - while (!res && n < fdt->max_fds) { - file = rcu_dereference_check_fdtable(files, fdt->fd[n++]); - if (file) - res = f(p, file, n); + for (fdt = files_fdtable(files); n < fdt->max_fds; n++) { + struct file *file; + file = rcu_dereference_check_fdtable(files, fdt->fd[n]); + if (!file) + continue; + res = f(p, file, n); + if (res) + break; } spin_unlock(&files->file_lock); return res; diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 937f9d50c84b..5f4cdf3ad913 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -2131,6 +2131,11 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) if (!len) return ERR_PTR(-EACCES); + if (unlikely(name[0] == '.')) { + if (len < 2 || (len == 2 && name[1] == '.')) + return ERR_PTR(-EACCES); + } + while (len--) { c = *(const unsigned char *)name++; if (c == '/' || c == '\0') diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c index ce8cb926526b..b9e66b7e0c14 100644 --- a/trunk/fs/nfs/dir.c +++ b/trunk/fs/nfs/dir.c @@ -450,7 +450,8 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) nfs_refresh_inode(dentry->d_inode, entry->fattr); goto out; } else { - d_drop(dentry); + if (d_invalidate(dentry) != 0) + goto out; dput(dentry); } } @@ -1100,6 +1101,8 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags) out_zap_parent: nfs_zap_caches(dir); out_bad: + nfs_free_fattr(fattr); + nfs_free_fhandle(fhandle); nfs_mark_for_revalidate(dir); if (inode && S_ISDIR(inode->i_mode)) { /* Purge readdir caches. */ @@ -1112,8 +1115,6 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags) shrink_dcache_parent(dentry); } d_drop(dentry); - nfs_free_fattr(fattr); - nfs_free_fhandle(fhandle); dput(parent); dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", __func__, dentry->d_parent->d_name.name,