Skip to content

Commit

Permalink
[PATCH] switch all filesystems over to d_obtain_alias
Browse files Browse the repository at this point in the history
Switch all users of d_alloc_anon to d_obtain_alias.

Signed-off-by: Christoph Hellwig <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Christoph Hellwig authored and Al Viro committed Oct 23, 2008
1 parent 4ea3ada commit 4400372
Show file tree
Hide file tree
Showing 19 changed files with 78 additions and 305 deletions.
10 changes: 5 additions & 5 deletions fs/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1187,17 +1187,17 @@ struct dentry * d_alloc_anon(struct inode *inode)
* allocating a new one.
*
* On successful return, the reference to the inode has been transferred
* to the dentry. If %NULL is returned (indicating kmalloc failure),
* the reference on the inode has been released. To make it easier
* to use in export operations a NULL or IS_ERR inode may be passed in
* and will be casted to the corresponding NULL or IS_ERR dentry.
* to the dentry. In case of an error the reference on the inode is released.
* To make it easier to use in export operations a %NULL or IS_ERR inode may
* be passed in and will be the error will be propagate to the return value,
* with a %NULL @inode replaced by ERR_PTR(-ESTALE).
*/
struct dentry *d_obtain_alias(struct inode *inode)
{
struct dentry *dentry;

if (!inode)
return NULL;
return ERR_PTR(-ESTALE);
if (IS_ERR(inode))
return ERR_CAST(inode);

Expand Down
29 changes: 4 additions & 25 deletions fs/efs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,35 +112,14 @@ struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,

struct dentry *efs_get_parent(struct dentry *child)
{
struct dentry *parent;
struct inode *inode;
struct dentry *parent = ERR_PTR(-ENOENT);
efs_ino_t ino;
long error;

lock_kernel();

error = -ENOENT;
ino = efs_find_entry(child->d_inode, "..", 2);
if (!ino)
goto fail;

inode = efs_iget(child->d_inode->i_sb, ino);
if (IS_ERR(inode)) {
error = PTR_ERR(inode);
goto fail;
}

error = -ENOMEM;
parent = d_alloc_anon(inode);
if (!parent)
goto fail_iput;

if (ino)
parent = d_obtain_alias(efs_iget(child->d_inode->i_sb, ino));
unlock_kernel();
return parent;

fail_iput:
iput(inode);
fail:
unlock_kernel();
return ERR_PTR(error);
return parent;
}
4 changes: 0 additions & 4 deletions fs/exportfs/expfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,8 +366,6 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
* Try to get any dentry for the given file handle from the filesystem.
*/
result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
if (!result)
result = ERR_PTR(-ESTALE);
if (IS_ERR(result))
return result;

Expand Down Expand Up @@ -422,8 +420,6 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,

target_dir = nop->fh_to_parent(mnt->mnt_sb, fid,
fh_len, fileid_type);
if (!target_dir)
goto err_result;
err = PTR_ERR(target_dir);
if (IS_ERR(target_dir))
goto err_result;
Expand Down
13 changes: 1 addition & 12 deletions fs/ext2/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, str
struct dentry *ext2_get_parent(struct dentry *child)
{
unsigned long ino;
struct dentry *parent;
struct inode *inode;
struct dentry dotdot;

dotdot.d_name.name = "..";
Expand All @@ -83,16 +81,7 @@ struct dentry *ext2_get_parent(struct dentry *child)
ino = ext2_inode_by_name(child->d_inode, &dotdot);
if (!ino)
return ERR_PTR(-ENOENT);
inode = ext2_iget(child->d_inode->i_sb, ino);

if (IS_ERR(inode))
return ERR_CAST(inode);
parent = d_alloc_anon(inode);
if (!parent) {
iput(inode);
parent = ERR_PTR(-ENOMEM);
}
return parent;
return d_obtain_alias(ext2_iget(child->d_inode->i_sb, ino));
}

/*
Expand Down
14 changes: 1 addition & 13 deletions fs/ext3/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -1057,8 +1057,6 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, str
struct dentry *ext3_get_parent(struct dentry *child)
{
unsigned long ino;
struct dentry *parent;
struct inode *inode;
struct dentry dotdot;
struct ext3_dir_entry_2 * de;
struct buffer_head *bh;
Expand All @@ -1068,7 +1066,6 @@ struct dentry *ext3_get_parent(struct dentry *child)
dotdot.d_parent = child; /* confusing, isn't it! */

bh = ext3_find_entry(&dotdot, &de);
inode = NULL;
if (!bh)
return ERR_PTR(-ENOENT);
ino = le32_to_cpu(de->inode);
Expand All @@ -1080,16 +1077,7 @@ struct dentry *ext3_get_parent(struct dentry *child)
return ERR_PTR(-EIO);
}

inode = ext3_iget(child->d_inode->i_sb, ino);
if (IS_ERR(inode))
return ERR_CAST(inode);

parent = d_alloc_anon(inode);
if (!parent) {
iput(inode);
parent = ERR_PTR(-ENOMEM);
}
return parent;
return d_obtain_alias(ext3_iget(child->d_inode->i_sb, ino));
}

#define S_SHIFT 12
Expand Down
11 changes: 1 addition & 10 deletions fs/ext4/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -1083,16 +1083,7 @@ struct dentry *ext4_get_parent(struct dentry *child)
return ERR_PTR(-EIO);
}

inode = ext4_iget(child->d_inode->i_sb, ino);
if (IS_ERR(inode))
return ERR_CAST(inode);

parent = d_alloc_anon(inode);
if (!parent) {
iput(inode);
parent = ERR_PTR(-ENOMEM);
}
return parent;
return d_obtain_alias(ext4_iget(child->d_inode->i_sb, ino));
}

#define S_SHIFT 12
Expand Down
52 changes: 18 additions & 34 deletions fs/fat/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,33 +681,24 @@ static struct dentry *fat_fh_to_dentry(struct super_block *sb,
inode = NULL;
}
}
if (!inode) {
/* For now, do nothing
* What we could do is:
* follow the file starting at fh[4], and record
* the ".." entry, and the name of the fh[2] entry.
* The follow the ".." file finding the next step up.
* This way we build a path to the root of
* the tree. If this works, we lookup the path and so
* get this inode into the cache.
* Finally try the fat_iget lookup again
* If that fails, then weare totally out of luck
* But all that is for another day
*/
}
if (!inode)
return ERR_PTR(-ESTALE);


/* now to find a dentry.
* If possible, get a well-connected one
/*
* For now, do nothing if the inode is not found.
*
* What we could do is:
*
* - follow the file starting at fh[4], and record the ".." entry,
* and the name of the fh[2] entry.
* - then follow the ".." file finding the next step up.
*
* This way we build a path to the root of the tree. If this works, we
* lookup the path and so get this inode into the cache. Finally try
* the fat_iget lookup again. If that fails, then we are totally out
* of luck. But all that is for another day
*/
result = d_alloc_anon(inode);
if (result == NULL) {
iput(inode);
return ERR_PTR(-ENOMEM);
}
result->d_op = sb->s_root->d_op;
result = d_obtain_alias(inode);
if (!IS_ERR(result))
result->d_op = sb->s_root->d_op;
return result;
}

Expand Down Expand Up @@ -754,15 +745,8 @@ static struct dentry *fat_get_parent(struct dentry *child)
}
inode = fat_build_inode(sb, de, i_pos);
brelse(bh);
if (IS_ERR(inode)) {
parent = ERR_CAST(inode);
goto out;
}
parent = d_alloc_anon(inode);
if (!parent) {
iput(inode);
parent = ERR_PTR(-ENOMEM);
}

parent = d_obtain_alias(inode);
out:
unlock_super(sb);

Expand Down
23 changes: 8 additions & 15 deletions fs/fuse/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,12 +596,8 @@ static struct dentry *fuse_get_dentry(struct super_block *sb,
if (inode->i_generation != handle->generation)
goto out_iput;

entry = d_alloc_anon(inode);
err = -ENOMEM;
if (!entry)
goto out_iput;

if (get_node_id(inode) != FUSE_ROOT_ID) {
entry = d_obtain_alias(inode);
if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) {
entry->d_op = &fuse_dentry_operations;
fuse_invalidate_entry_cache(entry);
}
Expand Down Expand Up @@ -696,17 +692,14 @@ static struct dentry *fuse_get_parent(struct dentry *child)
name.name = "..";
err = fuse_lookup_name(child_inode->i_sb, get_node_id(child_inode),
&name, &outarg, &inode);
if (err && err != -ENOENT)
if (err) {
if (err == -ENOENT)
return ERR_PTR(-ESTALE);
return ERR_PTR(err);
if (err || !inode)
return ERR_PTR(-ESTALE);

parent = d_alloc_anon(inode);
if (!parent) {
iput(inode);
return ERR_PTR(-ENOMEM);
}
if (get_node_id(inode) != FUSE_ROOT_ID) {

parent = d_obtain_alias(inode);
if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) {
parent->d_op = &fuse_dentry_operations;
fuse_invalidate_entry_cache(parent);
}
Expand Down
33 changes: 9 additions & 24 deletions fs/gfs2/ops_export.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,28 +130,17 @@ static int gfs2_get_name(struct dentry *parent, char *name,
static struct dentry *gfs2_get_parent(struct dentry *child)
{
struct qstr dotdot;
struct inode *inode;
struct dentry *dentry;

gfs2_str2qstr(&dotdot, "..");
inode = gfs2_lookupi(child->d_inode, &dotdot, 1);

if (!inode)
return ERR_PTR(-ENOENT);
/*
* In case of an error, @inode carries the error value, and we
* have to return that as a(n invalid) pointer to dentry.
* XXX(hch): it would be a good idea to keep this around as a
* static variable.
*/
if (IS_ERR(inode))
return ERR_CAST(inode);

dentry = d_alloc_anon(inode);
if (!dentry) {
iput(inode);
return ERR_PTR(-ENOMEM);
}
gfs2_str2qstr(&dotdot, "..");

dentry->d_op = &gfs2_dops;
dentry = d_obtain_alias(gfs2_lookupi(child->d_inode, &dotdot, 1));
if (!IS_ERR(dentry))
dentry->d_op = &gfs2_dops;
return dentry;
}

Expand Down Expand Up @@ -233,13 +222,9 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb,
gfs2_glock_dq_uninit(&i_gh);

out_inode:
dentry = d_alloc_anon(inode);
if (!dentry) {
iput(inode);
return ERR_PTR(-ENOMEM);
}

dentry->d_op = &gfs2_dops;
dentry = d_obtain_alias(inode);
if (!IS_ERR(dentry))
dentry->d_op = &gfs2_dops;
return dentry;

fail_rgd:
Expand Down
33 changes: 5 additions & 28 deletions fs/isofs/export.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ isofs_export_iget(struct super_block *sb,
__u32 generation)
{
struct inode *inode;
struct dentry *result;

if (block == 0)
return ERR_PTR(-ESTALE);
inode = isofs_iget(sb, block, offset);
Expand All @@ -32,12 +32,7 @@ isofs_export_iget(struct super_block *sb,
iput(inode);
return ERR_PTR(-ESTALE);
}
result = d_alloc_anon(inode);
if (!result) {
iput(inode);
return ERR_PTR(-ENOMEM);
}
return result;
return d_obtain_alias(inode);
}

/* This function is surprisingly simple. The trick is understanding
Expand All @@ -51,7 +46,6 @@ static struct dentry *isofs_export_get_parent(struct dentry *child)
unsigned long parent_offset = 0;
struct inode *child_inode = child->d_inode;
struct iso_inode_info *e_child_inode = ISOFS_I(child_inode);
struct inode *parent_inode = NULL;
struct iso_directory_record *de = NULL;
struct buffer_head * bh = NULL;
struct dentry *rv = NULL;
Expand Down Expand Up @@ -104,28 +98,11 @@ static struct dentry *isofs_export_get_parent(struct dentry *child)
/* Normalize */
isofs_normalize_block_and_offset(de, &parent_block, &parent_offset);

/* Get the inode. */
parent_inode = isofs_iget(child_inode->i_sb,
parent_block,
parent_offset);
if (IS_ERR(parent_inode)) {
rv = ERR_CAST(parent_inode);
if (rv != ERR_PTR(-ENOMEM))
rv = ERR_PTR(-EACCES);
goto out;
}

/* Allocate the dentry. */
rv = d_alloc_anon(parent_inode);
if (rv == NULL) {
rv = ERR_PTR(-ENOMEM);
goto out;
}

rv = d_obtain_alias(isofs_iget(child_inode->i_sb, parent_block,
parent_offset));
out:
if (bh) {
if (bh)
brelse(bh);
}
return rv;
}

Expand Down
Loading

0 comments on commit 4400372

Please sign in to comment.