aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/refcounttree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/refcounttree.c')
-rw-r--r--fs/ocfs2/refcounttree.c49
1 files changed, 11 insertions, 38 deletions
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index ebfd3825f12a..cf7823382664 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -4368,25 +4368,6 @@ static inline int ocfs2_may_create(struct inode *dir, struct dentry *child)
4368 return inode_permission(dir, MAY_WRITE | MAY_EXEC); 4368 return inode_permission(dir, MAY_WRITE | MAY_EXEC);
4369} 4369}
4370 4370
4371/* copied from user_path_parent. */
4372static int ocfs2_user_path_parent(const char __user *path,
4373 struct nameidata *nd, char **name)
4374{
4375 char *s = getname(path);
4376 int error;
4377
4378 if (IS_ERR(s))
4379 return PTR_ERR(s);
4380
4381 error = kern_path_parent(s, nd);
4382 if (error)
4383 putname(s);
4384 else
4385 *name = s;
4386
4387 return error;
4388}
4389
4390/** 4371/**
4391 * ocfs2_vfs_reflink - Create a reference-counted link 4372 * ocfs2_vfs_reflink - Create a reference-counted link
4392 * 4373 *
@@ -4460,10 +4441,8 @@ int ocfs2_reflink_ioctl(struct inode *inode,
4460 bool preserve) 4441 bool preserve)
4461{ 4442{
4462 struct dentry *new_dentry; 4443 struct dentry *new_dentry;
4463 struct nameidata nd; 4444 struct path old_path, new_path;
4464 struct path old_path;
4465 int error; 4445 int error;
4466 char *to = NULL;
4467 4446
4468 if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb))) 4447 if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb)))
4469 return -EOPNOTSUPP; 4448 return -EOPNOTSUPP;
@@ -4474,39 +4453,33 @@ int ocfs2_reflink_ioctl(struct inode *inode,
4474 return error; 4453 return error;
4475 } 4454 }
4476 4455
4477 error = ocfs2_user_path_parent(newname, &nd, &to); 4456 new_dentry = user_path_create(AT_FDCWD, newname, &new_path, 0);
4478 if (error) { 4457 error = PTR_ERR(new_dentry);
4458 if (IS_ERR(new_dentry)) {
4479 mlog_errno(error); 4459 mlog_errno(error);
4480 goto out; 4460 goto out;
4481 } 4461 }
4482 4462
4483 error = -EXDEV; 4463 error = -EXDEV;
4484 if (old_path.mnt != nd.path.mnt) 4464 if (old_path.mnt != new_path.mnt) {
4485 goto out_release;
4486 new_dentry = lookup_create(&nd, 0);
4487 error = PTR_ERR(new_dentry);
4488 if (IS_ERR(new_dentry)) {
4489 mlog_errno(error); 4465 mlog_errno(error);
4490 goto out_unlock; 4466 goto out_dput;
4491 } 4467 }
4492 4468
4493 error = mnt_want_write(nd.path.mnt); 4469 error = mnt_want_write(new_path.mnt);
4494 if (error) { 4470 if (error) {
4495 mlog_errno(error); 4471 mlog_errno(error);
4496 goto out_dput; 4472 goto out_dput;
4497 } 4473 }
4498 4474
4499 error = ocfs2_vfs_reflink(old_path.dentry, 4475 error = ocfs2_vfs_reflink(old_path.dentry,
4500 nd.path.dentry->d_inode, 4476 new_path.dentry->d_inode,
4501 new_dentry, preserve); 4477 new_dentry, preserve);
4502 mnt_drop_write(nd.path.mnt); 4478 mnt_drop_write(new_path.mnt);
4503out_dput: 4479out_dput:
4504 dput(new_dentry); 4480 dput(new_dentry);
4505out_unlock: 4481 mutex_unlock(&new_path.dentry->d_inode->i_mutex);
4506 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 4482 path_put(&new_path);
4507out_release:
4508 path_put(&nd.path);
4509 putname(to);
4510out: 4483out:
4511 path_put(&old_path); 4484 path_put(&old_path);
4512 4485