summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_handle.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2024-04-22 19:47:55 +0300
committerDarrick J. Wong <djwong@kernel.org>2024-04-23 17:47:00 +0300
commitb8c9d4253da43c02b287831f7e576568f24fbe58 (patch)
tree1a3c365c142d82c95f46f8e58bfb0e7cc74b1e01 /fs/xfs/xfs_handle.c
parentaf69d852dfe62b925d0df401eafad40698c889c6 (diff)
downloadlinux-b8c9d4253da43c02b287831f7e576568f24fbe58.tar.xz
xfs: split out handle management helpers a bit
Split out the functions that generate file/fs handles and map them back into dentries in preparation for the GETPARENTS ioctl next. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/xfs_handle.c')
-rw-r--r--fs/xfs/xfs_handle.c98
1 files changed, 67 insertions, 31 deletions
diff --git a/fs/xfs/xfs_handle.c b/fs/xfs/xfs_handle.c
index 13c2479a3053..b9f4d9860682 100644
--- a/fs/xfs/xfs_handle.c
+++ b/fs/xfs/xfs_handle.c
@@ -30,6 +30,42 @@
#include <linux/namei.h>
+static inline size_t
+xfs_filehandle_fid_len(void)
+{
+ struct xfs_handle *handle = NULL;
+
+ return sizeof(struct xfs_fid) - sizeof(handle->ha_fid.fid_len);
+}
+
+static inline size_t
+xfs_filehandle_init(
+ struct xfs_mount *mp,
+ xfs_ino_t ino,
+ uint32_t gen,
+ struct xfs_handle *handle)
+{
+ memcpy(&handle->ha_fsid, mp->m_fixedfsid, sizeof(struct xfs_fsid));
+
+ handle->ha_fid.fid_len = xfs_filehandle_fid_len();
+ handle->ha_fid.fid_pad = 0;
+ handle->ha_fid.fid_gen = gen;
+ handle->ha_fid.fid_ino = ino;
+
+ return sizeof(struct xfs_handle);
+}
+
+static inline size_t
+xfs_fshandle_init(
+ struct xfs_mount *mp,
+ struct xfs_handle *handle)
+{
+ memcpy(&handle->ha_fsid, mp->m_fixedfsid, sizeof(struct xfs_fsid));
+ memset(&handle->ha_fid, 0, sizeof(handle->ha_fid));
+
+ return sizeof(struct xfs_fsid);
+}
+
/*
* xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
* a file or fs handle.
@@ -84,20 +120,11 @@ xfs_find_handle(
memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
- if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
- /*
- * This handle only contains an fsid, zero the rest.
- */
- memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
- hsize = sizeof(xfs_fsid_t);
- } else {
- handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
- sizeof(handle.ha_fid.fid_len);
- handle.ha_fid.fid_pad = 0;
- handle.ha_fid.fid_gen = inode->i_generation;
- handle.ha_fid.fid_ino = ip->i_ino;
- hsize = sizeof(xfs_handle_t);
- }
+ if (cmd == XFS_IOC_PATH_TO_FSHANDLE)
+ hsize = xfs_fshandle_init(ip->i_mount, &handle);
+ else
+ hsize = xfs_filehandle_init(ip->i_mount, ip->i_ino,
+ inode->i_generation, &handle);
error = -EFAULT;
if (copy_to_user(hreq->ohandle, &handle, hsize) ||
@@ -126,6 +153,31 @@ xfs_handle_acceptable(
return 1;
}
+/* Convert handle already copied to kernel space into a dentry. */
+static struct dentry *
+xfs_khandle_to_dentry(
+ struct file *file,
+ struct xfs_handle *handle)
+{
+ struct xfs_fid64 fid = {
+ .ino = handle->ha_fid.fid_ino,
+ .gen = handle->ha_fid.fid_gen,
+ };
+
+ /*
+ * Only allow handle opens under a directory.
+ */
+ if (!S_ISDIR(file_inode(file)->i_mode))
+ return ERR_PTR(-ENOTDIR);
+
+ if (handle->ha_fid.fid_len != xfs_filehandle_fid_len())
+ return ERR_PTR(-EINVAL);
+
+ return exportfs_decode_fh(file->f_path.mnt, (struct fid *)&fid, 3,
+ FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG,
+ xfs_handle_acceptable, NULL);
+}
+
/*
* Convert userspace handle data into a dentry.
*/
@@ -136,29 +188,13 @@ xfs_handle_to_dentry(
u32 hlen)
{
xfs_handle_t handle;
- struct xfs_fid64 fid;
-
- /*
- * Only allow handle opens under a directory.
- */
- if (!S_ISDIR(file_inode(parfilp)->i_mode))
- return ERR_PTR(-ENOTDIR);
if (hlen != sizeof(xfs_handle_t))
return ERR_PTR(-EINVAL);
if (copy_from_user(&handle, uhandle, hlen))
return ERR_PTR(-EFAULT);
- if (handle.ha_fid.fid_len !=
- sizeof(handle.ha_fid) - sizeof(handle.ha_fid.fid_len))
- return ERR_PTR(-EINVAL);
-
- memset(&fid, 0, sizeof(struct fid));
- fid.ino = handle.ha_fid.fid_ino;
- fid.gen = handle.ha_fid.fid_gen;
- return exportfs_decode_fh(parfilp->f_path.mnt, (struct fid *)&fid, 3,
- FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG,
- xfs_handle_acceptable, NULL);
+ return xfs_khandle_to_dentry(parfilp, &handle);
}
STATIC struct dentry *