diff --git a/fs/sharefs/dentry.c b/fs/sharefs/dentry.c index 29d0f2e685db87eb91ec82c3a49dbf3002f25912..dee29cace6b751a5cd29b648bb5024bc53e96714 100644 --- a/fs/sharefs/dentry.c +++ b/fs/sharefs/dentry.c @@ -29,6 +29,7 @@ static void sharefs_d_release(struct dentry *dentry) */ if (SHAREFS_D(dentry)) { /* release and reset the lower paths */ + sharefs_put_reset_lower_path(dentry); free_dentry_private_data(dentry); } return; diff --git a/fs/sharefs/file.c b/fs/sharefs/file.c index 21f240303e3beb1bc51734fe4cd6c1cc38bfd55c..f04963d57a4a6b8896393ade9d80d59cae885ff9 100644 --- a/fs/sharefs/file.c +++ b/fs/sharefs/file.c @@ -31,7 +31,6 @@ static int sharefs_open(struct inode *inode, struct file *file) int err = 0; struct file *lower_file = NULL; struct path lower_path; - struct inode *lower_inode = NULL; /* don't open unhashed/deleted files */ if (d_unhashed(file->f_path.dentry)) { @@ -67,13 +66,7 @@ static int sharefs_open(struct inode *inode, struct file *file) kuid_t uid = inode->i_uid; kgid_t gid = inode->i_gid; mode_t mode = inode->i_mode; - lower_inode = sharefs_get_lower_inode(file->f_path.dentry); - if (IS_ERR(lower_inode)) { - err = PTR_ERR(lower_inode); - goto out_err; - } - fsstack_copy_attr_all(inode, lower_inode); - iput(lower_inode); + fsstack_copy_attr_all(inode, sharefs_lower_inode(inode)); inode->i_uid = uid; inode->i_gid = gid; inode->i_mode = mode; diff --git a/fs/sharefs/inode.c b/fs/sharefs/inode.c index e56a90f847b23d807eb0795f7c8fb50d617709c2..d0964f74433839e937128f7349951111633faa73 100644 --- a/fs/sharefs/inode.c +++ b/fs/sharefs/inode.c @@ -14,39 +14,6 @@ #include "authentication.h" #endif -struct inode *sharefs_get_lower_inode(struct dentry *d) -{ - int err = 0; - struct path lower_path; - struct path lower_parent_dentry; - struct inode *lower_inode; - struct dentry *parent; - - parent = dget_parent(d); - sharefs_get_lower_path(parent, &lower_parent_dentry); - err = vfs_path_lookup(lower_parent_dentry.dentry, lower_parent_dentry.mnt, - d->d_name.name, 0, &lower_path); - if (err) - goto out; - - lower_inode = d_inode(lower_path.dentry); - if (!lower_inode) { - err = -ENOENT; - } else if (lower_inode->i_flags & S_DEAD) { - err = -ENOENT; - } else if (!igrab(lower_inode)) { - err = -ESTALE; - } - - sharefs_put_lower_path(d, &lower_path); -out: - sharefs_put_lower_path(parent, &lower_parent_dentry); - dput(parent); - if (err) - return ERR_PTR(err); - return lower_inode; -} - static const char *sharefs_get_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done) { @@ -118,10 +85,6 @@ static ssize_t sharefs_listxattr(struct dentry *dentry, char *buffer, size_t buf sharefs_get_lower_path(dentry, &lower_path); lower_dentry = lower_path.dentry; - if (d_inode(lower_dentry)->i_flags & S_DEAD) { - err = -ENOENT; - goto out; - } if (!(d_inode(lower_dentry)->i_opflags & IOP_XATTR)) { err = -EOPNOTSUPP; goto out; @@ -166,7 +129,6 @@ static int sharefs_create(struct inode *dir, struct dentry *dentry, struct dentry *lower_parent_dentry = NULL; struct path lower_path; const struct cred *saved_cred = NULL; - struct inode *lower_inode = NULL; __u16 child_perm; saved_cred = sharefs_override_file_fsids(dir, &child_perm); @@ -185,14 +147,8 @@ static int sharefs_create(struct inode *dir, struct dentry *dentry, err = sharefs_interpose(dentry, dir->i_sb, &lower_path); if (err) goto out; - lower_inode = sharefs_get_lower_inode(dentry); - if (IS_ERR(lower_inode)) { - err = PTR_ERR(lower_inode); - goto out; - } - fsstack_copy_attr_times(dir, lower_inode); + fsstack_copy_attr_times(dir, sharefs_lower_inode(dir)); fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry)); - iput(lower_inode); out: unlock_dir(lower_parent_dentry); @@ -208,7 +164,6 @@ static int sharefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) struct dentry *lower_parent_dentry = NULL; struct path lower_path; const struct cred *saved_cred = NULL; - struct inode *lower_inode = NULL; __u16 child_perm; saved_cred = sharefs_override_file_fsids(dir, &child_perm); @@ -227,16 +182,11 @@ static int sharefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) err = sharefs_interpose(dentry, dir->i_sb, &lower_path); if (err) goto out; - lower_inode = sharefs_get_lower_inode(dentry); - if (IS_ERR(lower_inode)) { - err = PTR_ERR(lower_inode); - goto out; - } - fsstack_copy_attr_times(dir, lower_inode); + + fsstack_copy_attr_times(dir, sharefs_lower_inode(dir)); fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry)); /* update number of links on parent directory */ - set_nlink(dir, lower_inode->i_nlink); - iput(lower_inode); + set_nlink(dir, sharefs_lower_inode(dir)->i_nlink); out: unlock_dir(lower_parent_dentry); @@ -249,38 +199,24 @@ static int sharefs_unlink(struct inode *dir, struct dentry *dentry) { int err; struct dentry *lower_dentry = NULL; - struct inode *lower_dir_inode = NULL; - struct inode *lower_inode = NULL; + struct inode *lower_dir_inode = sharefs_lower_inode(dir); struct dentry *lower_dir_dentry = NULL; struct path lower_path; - lower_dir_inode = sharefs_get_lower_inode(dentry->d_parent); - if (IS_ERR(lower_dir_inode)) { - err = PTR_ERR(lower_dir_inode); - goto out; - } - lower_inode = sharefs_get_lower_inode(dentry); - if (IS_ERR(lower_inode)) { - err = PTR_ERR(lower_inode); - goto put_dir; - } sharefs_get_lower_path(dentry, &lower_path); lower_dentry = lower_path.dentry; dget(lower_dentry); lower_dir_dentry = lock_parent(lower_dentry); err = vfs_unlink(lower_dir_inode, lower_dentry, NULL); if (err) - goto put; + goto out; fsstack_copy_attr_times(dir, lower_dir_inode); fsstack_copy_inode_size(dir, lower_dir_inode); - set_nlink(dentry->d_inode, lower_inode->i_nlink); + set_nlink(dentry->d_inode, + sharefs_lower_inode(dentry->d_inode)->i_nlink); dentry->d_inode->i_ctime = dir->i_ctime; d_drop(dentry); -put: - iput(lower_dir_inode); -put_dir: - iput(lower_inode); out: unlock_dir(lower_dir_dentry); dput(lower_dentry); @@ -377,7 +313,7 @@ static int sharefs_setattr(struct dentry *dentry, struct iattr *ia) int err; struct dentry *lower_dentry; struct inode *inode; - struct inode *lower_inode = NULL; + struct inode *lower_inode; struct path lower_path; struct iattr lower_ia; @@ -394,11 +330,7 @@ static int sharefs_setattr(struct dentry *dentry, struct iattr *ia) sharefs_get_lower_path(dentry, &lower_path); lower_dentry = lower_path.dentry; - lower_dentry = sharefs_get_lower_inode(dentry); - if (IS_ERR(lower_dentry)) { - err = PTR_ERR(lower_dentry); - goto out_err; - } + lower_inode = sharefs_lower_inode(inode); /* prepare our own lower struct iattr (with the lower file) */ memcpy(&lower_ia, ia, sizeof(lower_ia)); @@ -451,7 +383,6 @@ static int sharefs_setattr(struct dentry *dentry, struct iattr *ia) */ out: - iput(lower_inode); sharefs_put_lower_path(dentry, &lower_path); out_err: return err; diff --git a/fs/sharefs/lookup.c b/fs/sharefs/lookup.c index 72e2c9768fc5d7f0555f906a21c37376a373029e..0b0c30ef46f12aa9e22c49ebe7cee8ca5efd9875 100644 --- a/fs/sharefs/lookup.c +++ b/fs/sharefs/lookup.c @@ -141,7 +141,6 @@ struct inode *sharefs_iget(struct super_block *sb, struct inode *lower_inode) fsstack_copy_inode_size(inode, lower_inode); unlock_new_inode(inode); - iput(lower_inode); return inode; } @@ -215,7 +214,7 @@ static struct dentry *__sharefs_lookup(struct dentry *dentry, d_set_d_op(dentry, &sharefs_dops); if (IS_ROOT(dentry)) - return NULL; + goto out; name = dentry->d_name.name; @@ -283,7 +282,6 @@ static struct dentry *__sharefs_lookup(struct dentry *dentry, out: if (err) return ERR_PTR(err); - sharefs_put_lower_path(dentry, &lower_path); return ret_dentry; } diff --git a/fs/sharefs/sharefs.h b/fs/sharefs/sharefs.h index 114c40cdb875dff28f7cf652df2dcd23d3f4985d..143f047b235f340d0d8122e34ec3b15b9d5ddf6f 100644 --- a/fs/sharefs/sharefs.h +++ b/fs/sharefs/sharefs.h @@ -91,7 +91,6 @@ extern int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, struct path *path); extern int sharefs_parse_options(struct sharefs_sb_info *sbi, const char *data); -extern struct inode *sharefs_get_lower_inode(struct dentry *d); /* * inode to private data diff --git a/fs/sharefs/super.c b/fs/sharefs/super.c index ef6437c9e455b9726b2a29375897a2ea79f6aa5c..bbe65944647fd611c2aea433b7228f03eeab8e89 100644 --- a/fs/sharefs/super.c +++ b/fs/sharefs/super.c @@ -117,13 +117,17 @@ static int sharefs_statfs(struct dentry *dentry, struct kstatfs *buf) */ static void sharefs_evict_inode(struct inode *inode) { + struct inode *lower_inode; + truncate_inode_pages(&inode->i_data, 0); clear_inode(inode); /* * Decrement a reference to a lower_inode, which was incremented * by our read_inode when it was created initially. */ + lower_inode = sharefs_lower_inode(inode); sharefs_set_lower_inode(inode, NULL); + iput(lower_inode); } void __sharefs_log(const char *level, const bool ratelimited,