Commit 4346cdd4 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Christoph Hellwig

xfs: cleanup xfs_find_handle

Remove the superflous igrab by keeping a reference on the path/file all the
time and clean up various bits of surrounding code.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarFelix Blyakher <felixb@sgi.com>
parent ef8f7fc5
...@@ -78,92 +78,74 @@ xfs_find_handle( ...@@ -78,92 +78,74 @@ xfs_find_handle(
int hsize; int hsize;
xfs_handle_t handle; xfs_handle_t handle;
struct inode *inode; struct inode *inode;
struct file *file = NULL;
memset((char *)&handle, 0, sizeof(handle));
switch (cmd) {
case XFS_IOC_PATH_TO_FSHANDLE:
case XFS_IOC_PATH_TO_HANDLE: {
struct path path; struct path path;
int error = user_lpath((const char __user *)hreq->path, &path); int error;
if (error) struct xfs_inode *ip;
return error;
ASSERT(path.dentry);
ASSERT(path.dentry->d_inode);
inode = igrab(path.dentry->d_inode);
path_put(&path);
break;
}
case XFS_IOC_FD_TO_HANDLE: {
struct file *file;
if (cmd == XFS_IOC_FD_TO_HANDLE) {
file = fget(hreq->fd); file = fget(hreq->fd);
if (!file) if (!file)
return -EBADF; return -EBADF;
inode = file->f_path.dentry->d_inode;
ASSERT(file->f_path.dentry); } else {
ASSERT(file->f_path.dentry->d_inode); error = user_lpath((const char __user *)hreq->path, &path);
inode = igrab(file->f_path.dentry->d_inode); if (error)
fput(file); return error;
break; inode = path.dentry->d_inode;
} }
ip = XFS_I(inode);
default: /*
ASSERT(0); * We can only generate handles for inodes residing on a XFS filesystem,
return -XFS_ERROR(EINVAL); * and only for regular files, directories or symbolic links.
} */
error = -EINVAL;
if (inode->i_sb->s_magic != XFS_SB_MAGIC)
goto out_put;
if (inode->i_sb->s_magic != XFS_SB_MAGIC) { error = -EBADF;
/* we're not in XFS anymore, Toto */ if (!S_ISREG(inode->i_mode) &&
iput(inode); !S_ISDIR(inode->i_mode) &&
return -XFS_ERROR(EINVAL); !S_ISLNK(inode->i_mode))
} goto out_put;
switch (inode->i_mode & S_IFMT) {
case S_IFREG:
case S_IFDIR:
case S_IFLNK:
break;
default:
iput(inode);
return -XFS_ERROR(EBADF);
}
/* now we can grab the fsid */ memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid,
sizeof(xfs_fsid_t));
hsize = sizeof(xfs_fsid_t);
if (cmd != XFS_IOC_PATH_TO_FSHANDLE) { if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
xfs_inode_t *ip = XFS_I(inode); /*
* This handle only contains an fsid, zero the rest.
*/
memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
hsize = sizeof(xfs_fsid_t);
} else {
int lock_mode; int lock_mode;
/* need to get access to the xfs_inode to read the generation */
lock_mode = xfs_ilock_map_shared(ip); lock_mode = xfs_ilock_map_shared(ip);
/* fill in fid section of handle from inode */
handle.ha_fid.fid_len = sizeof(xfs_fid_t) - handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
sizeof(handle.ha_fid.fid_len); sizeof(handle.ha_fid.fid_len);
handle.ha_fid.fid_pad = 0; handle.ha_fid.fid_pad = 0;
handle.ha_fid.fid_gen = ip->i_d.di_gen; handle.ha_fid.fid_gen = ip->i_d.di_gen;
handle.ha_fid.fid_ino = ip->i_ino; handle.ha_fid.fid_ino = ip->i_ino;
xfs_iunlock_map_shared(ip, lock_mode); xfs_iunlock_map_shared(ip, lock_mode);
hsize = XFS_HSIZE(handle); hsize = XFS_HSIZE(handle);
} }
/* now copy our handle into the user buffer & write out the size */ error = -EFAULT;
if (copy_to_user(hreq->ohandle, &handle, hsize) || if (copy_to_user(hreq->ohandle, &handle, hsize) ||
copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) { copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
iput(inode); goto out_put;
return -XFS_ERROR(EFAULT);
}
iput(inode); error = 0;
return 0;
out_put:
if (cmd == XFS_IOC_FD_TO_HANDLE)
fput(file);
else
path_put(&path);
return error;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment