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: Christoph Hellwig <hch@lst.de> Reviewed-by: Felix Blyakher <felixb@sgi.com>
This commit is contained in:
parent
ef8f7fc549
commit
4346cdd464
|
@ -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;
|
||||||
|
struct path path;
|
||||||
|
int error;
|
||||||
|
struct xfs_inode *ip;
|
||||||
|
|
||||||
memset((char *)&handle, 0, sizeof(handle));
|
if (cmd == XFS_IOC_FD_TO_HANDLE) {
|
||||||
|
|
||||||
switch (cmd) {
|
|
||||||
case XFS_IOC_PATH_TO_FSHANDLE:
|
|
||||||
case XFS_IOC_PATH_TO_HANDLE: {
|
|
||||||
struct path path;
|
|
||||||
int error = user_lpath((const char __user *)hreq->path, &path);
|
|
||||||
if (error)
|
|
||||||
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;
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue