Skip to content

Commit

Permalink
Merge branch 'work.lookup' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/viro/vfs

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()
  ...
  • Loading branch information
torvalds committed Jun 4, 2018
2 parents 9214407 + 888e2b0 commit b058efc
Show file tree
Hide file tree
Showing 26 changed files with 293 additions and 451 deletions.
42 changes: 15 additions & 27 deletions drivers/staging/ncpfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -823,12 +823,11 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, unsig
struct ncp_server *server = NCP_SERVER(dir);
struct inode *inode = NULL;
struct ncp_entry_info finfo;
int error, res, len;
int res, len;
__u8 __name[NCP_MAXPATHLEN + 1];

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

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

Expand All @@ -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));
}
ncp_vdbg("looked for %pd2, res=%d\n", dentry, res);
/*
* If we didn't find an entry, make a negative dentry.
*/
if (res)
goto add_entry;

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

if (inode) {
ncp_new_dentry(dentry);
add_entry:
d_add(dentry, inode);
error = 0;
if (!res) {
/*
* Entry found; create an inode for it.
*/
finfo.opened = 0;
finfo.ino = iunique(dir->i_sb, 2);
finfo.volume = finfo.i.volNumber;
inode = ncp_iget(dir->i_sb, &finfo);
if (unlikely(!inode))
inode = ERR_PTR(-EACCES);
else
ncp_new_dentry(dentry);
}

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

/*
Expand Down
35 changes: 15 additions & 20 deletions fs/9p/vfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -823,28 +823,21 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
if (IS_ERR(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
* unlink. For cached mode create calls request for new
* 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);
else
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
* for the new name, then make sure we instantiate with
Expand All @@ -853,12 +846,14 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
* k/b.
*/
res = d_splice_alias(inode, dentry);
if (!res)
v9fs_fid_add(dentry, fid);
else if (!IS_ERR(res))
v9fs_fid_add(res, fid);
else
p9_client_clunk(fid);
if (!IS_ERR(fid)) {
if (!res)
v9fs_fid_add(dentry, fid);
else if (!IS_ERR(res))
v9fs_fid_add(res, fid);
else
p9_client_clunk(fid);
}
return res;
}

Expand Down
24 changes: 5 additions & 19 deletions fs/adfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,20 +146,6 @@ adfs_dir_lookup_byname(struct inode *inode, const struct qstr *name, struct obje

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);

ret = ops->setpos(&dir, 0);
Expand Down Expand Up @@ -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);
if (error == 0) {
error = -EACCES;
/*
* This only returns NULL if get_empty_inode
* fails.
*/
inode = adfs_iget(dir->i_sb, &obj);
if (inode)
error = 0;
if (!inode)
inode = ERR_PTR(-EACCES);
} else if (error != -ENOENT) {
inode = ERR_PTR(error);
}
d_add(dentry, inode);
return ERR_PTR(error);
return d_splice_alias(inode, dentry);
}

/*
Expand Down
43 changes: 16 additions & 27 deletions fs/bfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@
#define dprintf(x...)
#endif

static int bfs_add_entry(struct inode *dir, const unsigned char *name,
int namelen, int ino);
static int bfs_add_entry(struct inode *dir, const struct qstr *child, int ino);
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);

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

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

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) {
unsigned long ino = (unsigned long)le16_to_cpu(de->ino);
brelse(bh);
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);
d_add(dentry, inode);
return NULL;
return d_splice_alias(inode, dentry);
}

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

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

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))
goto out_brelse;

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

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

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

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

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

static int bfs_add_entry(struct inode *dir, const unsigned char *name,
int namelen, int ino)
static int bfs_add_entry(struct inode *dir, const struct qstr *child, int ino)
{
const unsigned char *name = child->name;
int namelen = child->len;
struct buffer_head *bh;
struct bfs_dirent *de;
int block, sblock, eblock, off, pos;
Expand Down Expand Up @@ -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,
const unsigned char *name, int namelen,
const struct qstr *child,
struct bfs_dirent **res_dir)
{
unsigned long block = 0, offset = 0;
struct buffer_head *bh = NULL;
struct bfs_dirent *de;
const unsigned char *name = child->name;
int namelen = child->len;

*res_dir = NULL;
if (namelen > BFS_NAMELEN)
Expand Down
38 changes: 19 additions & 19 deletions fs/cifs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,21 +780,25 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink)) {
free_xid(xid);
return (struct dentry *)tlink;
return ERR_CAST(tlink);
}
pTcon = tlink_tcon(tlink);

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

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

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

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

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

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

static int
Expand Down
5 changes: 1 addition & 4 deletions fs/cramfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -808,10 +808,7 @@ static struct dentry *cramfs_lookup(struct inode *dir, struct dentry *dentry, un
}
out:
mutex_unlock(&read_mutex);
if (IS_ERR(inode))
return ERR_CAST(inode);
d_add(dentry, inode);
return NULL;
return d_splice_alias(inode, dentry);
}

static int cramfs_readpage(struct file *file, struct page *page)
Expand Down
8 changes: 2 additions & 6 deletions fs/freevxfs/vxfs_lookup.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,9 @@ vxfs_lookup(struct inode *dip, struct dentry *dp, unsigned int flags)
return ERR_PTR(-ENAMETOOLONG);

ino = vxfs_inode_by_name(dip, dp);
if (ino) {
if (ino)
ip = vxfs_iget(dip->i_sb, ino);
if (IS_ERR(ip))
return ERR_CAST(ip);
}
d_add(dp, ip);
return NULL;
return d_splice_alias(ip, dp);
}

/**
Expand Down
Loading

0 comments on commit b058efc

Please sign in to comment.