Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 331fee3c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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()
parents b3c3a9cf a77cfcb4
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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);
+8 −6
Original line number Diff line number Diff line
@@ -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)
	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;
+5 −0
Original line number Diff line number Diff line
@@ -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')
+4 −3
Original line number Diff line number Diff line
@@ -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 @@ out_set_verifier:
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 @@ out_zap_parent:
		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,