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

Commit b058efc1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull dcache lookup cleanups from Al Viro:
 "Cleaning ->lookup() instances up - mostly d_splice_alias() conversions"

* 'work.lookup' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (29 commits)
  switch the rest of procfs lookups to d_splice_alias()
  procfs: switch instantiate_t to d_splice_alias()
  don't bother with tid_fd_revalidate() in lookups
  proc_lookupfd_common(): don't bother with instantiate unless the file is open
  procfs: get rid of ancient BS in pid_revalidate() uses
  cifs_lookup(): switch to d_splice_alias()
  cifs_lookup(): cifs_get_inode_...() never returns 0 with *inode left NULL
  9p: unify paths in v9fs_vfs_lookup()
  ncp_lookup(): use d_splice_alias()
  hfsplus: switch to d_splice_alias()
  hfs: don't allow mounting over .../rsrc
  hfs: use d_splice_alias()
  omfs_lookup(): report IO errors, use d_splice_alias()
  orangefs_lookup: simplify
  openpromfs: switch to d_splice_alias()
  xfs_vn_lookup: simplify a bit
  adfs_lookup: do not fail with ENOENT on negatives, use d_splice_alias()
  adfs_lookup_byname: .. *is* taken care of in fs/namei.c
  romfs_lookup: switch to d_splice_alias()
  qnx6_lookup: switch to d_splice_alias()
  ...
parents 9214407d 888e2b03
Loading
Loading
Loading
Loading
+15 −27
Original line number Original line Diff line number Diff line
@@ -823,12 +823,11 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, unsig
	struct ncp_server *server = NCP_SERVER(dir);
	struct ncp_server *server = NCP_SERVER(dir);
	struct inode *inode = NULL;
	struct inode *inode = NULL;
	struct ncp_entry_info finfo;
	struct ncp_entry_info finfo;
	int error, res, len;
	int res, len;
	__u8 __name[NCP_MAXPATHLEN + 1];
	__u8 __name[NCP_MAXPATHLEN + 1];


	error = -EIO;
	if (!ncp_conn_valid(server))
	if (!ncp_conn_valid(server))
		goto finished;
		return ERR_PTR(-EIO);


	ncp_vdbg("server lookup for %pd2\n", dentry);
	ncp_vdbg("server lookup for %pd2\n", dentry);


@@ -847,31 +846,20 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, unsig
			res = ncp_obtain_info(server, dir, __name, &(finfo.i));
			res = ncp_obtain_info(server, dir, __name, &(finfo.i));
	}
	}
	ncp_vdbg("looked for %pd2, res=%d\n", dentry, res);
	ncp_vdbg("looked for %pd2, res=%d\n", dentry, res);
	if (!res) {
		/*
		/*
	 * If we didn't find an entry, make a negative dentry.
		 * Entry found; create an inode for it.
	 */
	if (res)
		goto add_entry;

	/*
	 * Create an inode for the entry.
		 */
		 */
		finfo.opened = 0;
		finfo.opened = 0;
		finfo.ino = iunique(dir->i_sb, 2);
		finfo.ino = iunique(dir->i_sb, 2);
		finfo.volume = finfo.i.volNumber;
		finfo.volume = finfo.i.volNumber;
	error = -EACCES;
		inode = ncp_iget(dir->i_sb, &finfo);
		inode = ncp_iget(dir->i_sb, &finfo);

		if (unlikely(!inode))
	if (inode) {
			inode = ERR_PTR(-EACCES);
		else
			ncp_new_dentry(dentry);
			ncp_new_dentry(dentry);
add_entry:
		d_add(dentry, inode);
		error = 0;
	}
	}

	return d_splice_alias(inode, dentry);
finished:
	ncp_vdbg("result=%d\n", error);
	return ERR_PTR(error);
}
}


/*
/*
+15 −20
Original line number Original line Diff line number Diff line
@@ -823,28 +823,21 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
	if (IS_ERR(dfid))
	if (IS_ERR(dfid))
		return ERR_CAST(dfid);
		return ERR_CAST(dfid);


	name = dentry->d_name.name;
	fid = p9_client_walk(dfid, 1, &name, 1);
	if (IS_ERR(fid)) {
		if (fid == ERR_PTR(-ENOENT)) {
			d_add(dentry, NULL);
			return NULL;
		}
		return ERR_CAST(fid);
	}
	/*
	/*
	 * Make sure we don't use a wrong inode due to parallel
	 * Make sure we don't use a wrong inode due to parallel
	 * unlink. For cached mode create calls request for new
	 * unlink. For cached mode create calls request for new
	 * inode. But with cache disabled, lookup should do this.
	 * inode. But with cache disabled, lookup should do this.
	 */
	 */
	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
	name = dentry->d_name.name;
	fid = p9_client_walk(dfid, 1, &name, 1);
	if (fid == ERR_PTR(-ENOENT))
		inode = NULL;
	else if (IS_ERR(fid))
		inode = ERR_CAST(fid);
	else if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
	else
	else
		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
	if (IS_ERR(inode)) {
		p9_client_clunk(fid);
		return ERR_CAST(inode);
	}
	/*
	/*
	 * If we had a rename on the server and a parallel lookup
	 * If we had a rename on the server and a parallel lookup
	 * for the new name, then make sure we instantiate with
	 * for the new name, then make sure we instantiate with
@@ -853,12 +846,14 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
	 * k/b.
	 * k/b.
	 */
	 */
	res = d_splice_alias(inode, dentry);
	res = d_splice_alias(inode, dentry);
	if (!IS_ERR(fid)) {
		if (!res)
		if (!res)
			v9fs_fid_add(dentry, fid);
			v9fs_fid_add(dentry, fid);
		else if (!IS_ERR(res))
		else if (!IS_ERR(res))
			v9fs_fid_add(res, fid);
			v9fs_fid_add(res, fid);
		else
		else
			p9_client_clunk(fid);
			p9_client_clunk(fid);
	}
	return res;
	return res;
}
}


+5 −19
Original line number Original line Diff line number Diff line
@@ -146,20 +146,6 @@ adfs_dir_lookup_byname(struct inode *inode, const struct qstr *name, struct obje


	obj->parent_id = inode->i_ino;
	obj->parent_id = inode->i_ino;


	/*
	 * '.' is handled by reserved_lookup() in fs/namei.c
	 */
	if (name->len == 2 && name->name[0] == '.' && name->name[1] == '.') {
		/*
		 * Currently unable to fill in the rest of 'obj',
		 * but this is better than nothing.  We need to
		 * ascend one level to find it's parent.
		 */
		obj->name_len = 0;
		obj->file_id  = obj->parent_id;
		goto free_out;
	}

	read_lock(&adfs_dir_lock);
	read_lock(&adfs_dir_lock);


	ret = ops->setpos(&dir, 0);
	ret = ops->setpos(&dir, 0);
@@ -266,17 +252,17 @@ adfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)


	error = adfs_dir_lookup_byname(dir, &dentry->d_name, &obj);
	error = adfs_dir_lookup_byname(dir, &dentry->d_name, &obj);
	if (error == 0) {
	if (error == 0) {
		error = -EACCES;
		/*
		/*
		 * This only returns NULL if get_empty_inode
		 * This only returns NULL if get_empty_inode
		 * fails.
		 * fails.
		 */
		 */
		inode = adfs_iget(dir->i_sb, &obj);
		inode = adfs_iget(dir->i_sb, &obj);
		if (inode)
		if (!inode)
			error = 0;
			inode = ERR_PTR(-EACCES);
	} else if (error != -ENOENT) {
		inode = ERR_PTR(error);
	}
	}
	d_add(dentry, inode);
	return d_splice_alias(inode, dentry);
	return ERR_PTR(error);
}
}


/*
/*
+16 −27
Original line number Original line Diff line number Diff line
@@ -21,10 +21,9 @@
#define dprintf(x...)
#define dprintf(x...)
#endif
#endif


static int bfs_add_entry(struct inode *dir, const unsigned char *name,
static int bfs_add_entry(struct inode *dir, const struct qstr *child, int ino);
						int namelen, int ino);
static struct buffer_head *bfs_find_entry(struct inode *dir,
static struct buffer_head *bfs_find_entry(struct inode *dir,
				const unsigned char *name, int namelen,
				const struct qstr *child,
				struct bfs_dirent **res_dir);
				struct bfs_dirent **res_dir);


static int bfs_readdir(struct file *f, struct dir_context *ctx)
static int bfs_readdir(struct file *f, struct dir_context *ctx)
@@ -111,8 +110,7 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
        mark_inode_dirty(inode);
        mark_inode_dirty(inode);
	bfs_dump_imap("create", s);
	bfs_dump_imap("create", s);


	err = bfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len,
	err = bfs_add_entry(dir, &dentry->d_name, inode->i_ino);
							inode->i_ino);
	if (err) {
	if (err) {
		inode_dec_link_count(inode);
		inode_dec_link_count(inode);
		mutex_unlock(&info->bfs_lock);
		mutex_unlock(&info->bfs_lock);
@@ -136,19 +134,14 @@ static struct dentry *bfs_lookup(struct inode *dir, struct dentry *dentry,
		return ERR_PTR(-ENAMETOOLONG);
		return ERR_PTR(-ENAMETOOLONG);


	mutex_lock(&info->bfs_lock);
	mutex_lock(&info->bfs_lock);
	bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
	bh = bfs_find_entry(dir, &dentry->d_name, &de);
	if (bh) {
	if (bh) {
		unsigned long ino = (unsigned long)le16_to_cpu(de->ino);
		unsigned long ino = (unsigned long)le16_to_cpu(de->ino);
		brelse(bh);
		brelse(bh);
		inode = bfs_iget(dir->i_sb, ino);
		inode = bfs_iget(dir->i_sb, ino);
		if (IS_ERR(inode)) {
			mutex_unlock(&info->bfs_lock);
			return ERR_CAST(inode);
		}
	}
	}
	mutex_unlock(&info->bfs_lock);
	mutex_unlock(&info->bfs_lock);
	d_add(dentry, inode);
	return d_splice_alias(inode, dentry);
	return NULL;
}
}


static int bfs_link(struct dentry *old, struct inode *dir,
static int bfs_link(struct dentry *old, struct inode *dir,
@@ -159,8 +152,7 @@ static int bfs_link(struct dentry *old, struct inode *dir,
	int err;
	int err;


	mutex_lock(&info->bfs_lock);
	mutex_lock(&info->bfs_lock);
	err = bfs_add_entry(dir, new->d_name.name, new->d_name.len,
	err = bfs_add_entry(dir, &new->d_name, inode->i_ino);
							inode->i_ino);
	if (err) {
	if (err) {
		mutex_unlock(&info->bfs_lock);
		mutex_unlock(&info->bfs_lock);
		return err;
		return err;
@@ -183,7 +175,7 @@ static int bfs_unlink(struct inode *dir, struct dentry *dentry)
	struct bfs_sb_info *info = BFS_SB(inode->i_sb);
	struct bfs_sb_info *info = BFS_SB(inode->i_sb);


	mutex_lock(&info->bfs_lock);
	mutex_lock(&info->bfs_lock);
	bh = bfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
	bh = bfs_find_entry(dir, &dentry->d_name, &de);
	if (!bh || (le16_to_cpu(de->ino) != inode->i_ino))
	if (!bh || (le16_to_cpu(de->ino) != inode->i_ino))
		goto out_brelse;
		goto out_brelse;


@@ -228,27 +220,21 @@ static int bfs_rename(struct inode *old_dir, struct dentry *old_dentry,
	info = BFS_SB(old_inode->i_sb);
	info = BFS_SB(old_inode->i_sb);


	mutex_lock(&info->bfs_lock);
	mutex_lock(&info->bfs_lock);
	old_bh = bfs_find_entry(old_dir, 
	old_bh = bfs_find_entry(old_dir, &old_dentry->d_name, &old_de);
				old_dentry->d_name.name, 
				old_dentry->d_name.len, &old_de);


	if (!old_bh || (le16_to_cpu(old_de->ino) != old_inode->i_ino))
	if (!old_bh || (le16_to_cpu(old_de->ino) != old_inode->i_ino))
		goto end_rename;
		goto end_rename;


	error = -EPERM;
	error = -EPERM;
	new_inode = d_inode(new_dentry);
	new_inode = d_inode(new_dentry);
	new_bh = bfs_find_entry(new_dir, 
	new_bh = bfs_find_entry(new_dir, &new_dentry->d_name, &new_de);
				new_dentry->d_name.name, 
				new_dentry->d_name.len, &new_de);


	if (new_bh && !new_inode) {
	if (new_bh && !new_inode) {
		brelse(new_bh);
		brelse(new_bh);
		new_bh = NULL;
		new_bh = NULL;
	}
	}
	if (!new_bh) {
	if (!new_bh) {
		error = bfs_add_entry(new_dir, 
		error = bfs_add_entry(new_dir, &new_dentry->d_name,
					new_dentry->d_name.name,
					new_dentry->d_name.len,
					old_inode->i_ino);
					old_inode->i_ino);
		if (error)
		if (error)
			goto end_rename;
			goto end_rename;
@@ -278,9 +264,10 @@ const struct inode_operations bfs_dir_inops = {
	.rename			= bfs_rename,
	.rename			= bfs_rename,
};
};


static int bfs_add_entry(struct inode *dir, const unsigned char *name,
static int bfs_add_entry(struct inode *dir, const struct qstr *child, int ino)
							int namelen, int ino)
{
{
	const unsigned char *name = child->name;
	int namelen = child->len;
	struct buffer_head *bh;
	struct buffer_head *bh;
	struct bfs_dirent *de;
	struct bfs_dirent *de;
	int block, sblock, eblock, off, pos;
	int block, sblock, eblock, off, pos;
@@ -332,12 +319,14 @@ static inline int bfs_namecmp(int len, const unsigned char *name,
}
}


static struct buffer_head *bfs_find_entry(struct inode *dir,
static struct buffer_head *bfs_find_entry(struct inode *dir,
			const unsigned char *name, int namelen,
			const struct qstr *child,
			struct bfs_dirent **res_dir)
			struct bfs_dirent **res_dir)
{
{
	unsigned long block = 0, offset = 0;
	unsigned long block = 0, offset = 0;
	struct buffer_head *bh = NULL;
	struct buffer_head *bh = NULL;
	struct bfs_dirent *de;
	struct bfs_dirent *de;
	const unsigned char *name = child->name;
	int namelen = child->len;


	*res_dir = NULL;
	*res_dir = NULL;
	if (namelen > BFS_NAMELEN)
	if (namelen > BFS_NAMELEN)
+19 −19
Original line number Original line Diff line number Diff line
@@ -780,21 +780,25 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
	tlink = cifs_sb_tlink(cifs_sb);
	tlink = cifs_sb_tlink(cifs_sb);
	if (IS_ERR(tlink)) {
	if (IS_ERR(tlink)) {
		free_xid(xid);
		free_xid(xid);
		return (struct dentry *)tlink;
		return ERR_CAST(tlink);
	}
	}
	pTcon = tlink_tcon(tlink);
	pTcon = tlink_tcon(tlink);


	rc = check_name(direntry, pTcon);
	rc = check_name(direntry, pTcon);
	if (rc)
	if (unlikely(rc)) {
		goto lookup_out;
		cifs_put_tlink(tlink);
		free_xid(xid);
		return ERR_PTR(rc);
	}


	/* can not grab the rename sem here since it would
	/* can not grab the rename sem here since it would
	deadlock in the cases (beginning of sys_rename itself)
	deadlock in the cases (beginning of sys_rename itself)
	in which we already have the sb rename sem */
	in which we already have the sb rename sem */
	full_path = build_path_from_dentry(direntry);
	full_path = build_path_from_dentry(direntry);
	if (full_path == NULL) {
	if (full_path == NULL) {
		rc = -ENOMEM;
		cifs_put_tlink(tlink);
		goto lookup_out;
		free_xid(xid);
		return ERR_PTR(-ENOMEM);
	}
	}


	if (d_really_is_positive(direntry)) {
	if (d_really_is_positive(direntry)) {
@@ -813,29 +817,25 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
				parent_dir_inode->i_sb, xid, NULL);
				parent_dir_inode->i_sb, xid, NULL);
	}
	}


	if ((rc == 0) && (newInode != NULL)) {
	if (rc == 0) {
		d_add(direntry, newInode);
		/* since paths are not looked up by component - the parent
		/* since paths are not looked up by component - the parent
		   directories are presumed to be good here */
		   directories are presumed to be good here */
		renew_parental_timestamps(direntry);
		renew_parental_timestamps(direntry);

	} else if (rc == -ENOENT) {
	} else if (rc == -ENOENT) {
		rc = 0;
		cifs_set_time(direntry, jiffies);
		cifs_set_time(direntry, jiffies);
		d_add(direntry, NULL);
		newInode = NULL;
	/*	if it was once a directory (but how can we tell?) we could do
	} else {
		shrink_dcache_parent(direntry); */
		if (rc != -EACCES) {
	} else if (rc != -EACCES) {
			cifs_dbg(FYI, "Unexpected lookup error %d\n", rc);
			cifs_dbg(FYI, "Unexpected lookup error %d\n", rc);
			/* We special case check for Access Denied - since that
			/* We special case check for Access Denied - since that
			is a common return code */
			is a common return code */
		}
		}

		newInode = ERR_PTR(rc);
lookup_out:
	}
	kfree(full_path);
	kfree(full_path);
	cifs_put_tlink(tlink);
	cifs_put_tlink(tlink);
	free_xid(xid);
	free_xid(xid);
	return ERR_PTR(rc);
	return d_splice_alias(newInode, direntry);
}
}


static int
static int
Loading