ANDROID: sdcardfs: use d_splice_alias
adapted from wrapfs commit 9671770ff8b9 ("Wrapfs: use d_splice_alias") Refactor interpose code to allow lookup to use d_splice_alias. Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu> Signed-off-by: Daniel Rosenberg <drosen@google.com> Bug: 35766959 Change-Id: Icf51db8658202c48456724275b03dc77f73f585b
This commit is contained in:
parent
63cd557652
commit
2e5e3fd117
1 changed files with 39 additions and 16 deletions
|
@ -164,27 +164,25 @@ struct inode *sdcardfs_iget(struct super_block *sb, struct inode *lower_inode, u
|
|||
}
|
||||
|
||||
/*
|
||||
* Connect a sdcardfs inode dentry/inode with several lower ones. This is
|
||||
* the classic stackable file system "vnode interposition" action.
|
||||
*
|
||||
* @dentry: sdcardfs's dentry which interposes on lower one
|
||||
* @sb: sdcardfs's super_block
|
||||
* @lower_path: the lower path (caller does path_get/put)
|
||||
* Helper interpose routine, called directly by ->lookup to handle
|
||||
* spliced dentries.
|
||||
*/
|
||||
int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb,
|
||||
struct path *lower_path, userid_t id)
|
||||
static struct dentry *__sdcardfs_interpose(struct dentry *dentry,
|
||||
struct super_block *sb,
|
||||
struct path *lower_path,
|
||||
userid_t id)
|
||||
{
|
||||
int err = 0;
|
||||
struct inode *inode;
|
||||
struct inode *lower_inode;
|
||||
struct super_block *lower_sb;
|
||||
struct dentry *ret_dentry;
|
||||
|
||||
lower_inode = d_inode(lower_path->dentry);
|
||||
lower_sb = sdcardfs_lower_super(sb);
|
||||
|
||||
/* check that the lower file system didn't cross a mount point */
|
||||
if (lower_inode->i_sb != lower_sb) {
|
||||
err = -EXDEV;
|
||||
ret_dentry = ERR_PTR(-EXDEV);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -196,14 +194,32 @@ int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb,
|
|||
/* inherit lower inode number for sdcardfs's inode */
|
||||
inode = sdcardfs_iget(sb, lower_inode, id);
|
||||
if (IS_ERR(inode)) {
|
||||
err = PTR_ERR(inode);
|
||||
ret_dentry = ERR_CAST(inode);
|
||||
goto out;
|
||||
}
|
||||
|
||||
d_add(dentry, inode);
|
||||
ret_dentry = d_splice_alias(inode, dentry);
|
||||
dentry = ret_dentry ?: dentry;
|
||||
update_derived_permission_lock(dentry);
|
||||
out:
|
||||
return err;
|
||||
return ret_dentry;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect an sdcardfs inode dentry/inode with several lower ones. This is
|
||||
* the classic stackable file system "vnode interposition" action.
|
||||
*
|
||||
* @dentry: sdcardfs's dentry which interposes on lower one
|
||||
* @sb: sdcardfs's super_block
|
||||
* @lower_path: the lower path (caller does path_get/put)
|
||||
*/
|
||||
int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb,
|
||||
struct path *lower_path, userid_t id)
|
||||
{
|
||||
struct dentry *ret_dentry;
|
||||
|
||||
ret_dentry = __sdcardfs_interpose(dentry, sb, lower_path, id);
|
||||
return PTR_ERR(ret_dentry);
|
||||
}
|
||||
|
||||
struct sdcardfs_name_data {
|
||||
|
@ -244,6 +260,7 @@ static struct dentry *__sdcardfs_lookup(struct dentry *dentry,
|
|||
const struct qstr *name;
|
||||
struct path lower_path;
|
||||
struct qstr dname;
|
||||
struct dentry *ret_dentry = NULL;
|
||||
struct sdcardfs_sb_info *sbi;
|
||||
|
||||
sbi = SDCARDFS_SB(dentry->d_sb);
|
||||
|
@ -330,9 +347,13 @@ static struct dentry *__sdcardfs_lookup(struct dentry *dentry,
|
|||
}
|
||||
|
||||
sdcardfs_set_lower_path(dentry, &lower_path);
|
||||
err = sdcardfs_interpose(dentry, dentry->d_sb, &lower_path, id);
|
||||
if (err) /* path_put underlying path on error */
|
||||
ret_dentry =
|
||||
__sdcardfs_interpose(dentry, dentry->d_sb, &lower_path, id);
|
||||
if (IS_ERR(ret_dentry)) {
|
||||
err = PTR_ERR(ret_dentry);
|
||||
/* path_put underlying path on error */
|
||||
sdcardfs_put_reset_lower_path(dentry);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -372,7 +393,9 @@ static struct dentry *__sdcardfs_lookup(struct dentry *dentry,
|
|||
err = 0;
|
||||
|
||||
out:
|
||||
return ERR_PTR(err);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
return ret_dentry;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue