From: Andrey Albershteyn <aalbersh@redhat.com>
To: linux-fsdevel@vgre.kernel.org, linux-xfs@vger.kernel.org
Cc: Andrey Albershteyn <aalbersh@redhat.com>
Subject: [PATCH 4/4] xfs: add XFS_IOC_SETFSXATTRAT and XFS_IOC_GETFSXATTRAT
Date: Thu, 9 May 2024 17:15:00 +0200 [thread overview]
Message-ID: <20240509151459.3622910-6-aalbersh@redhat.com> (raw)
In-Reply-To: <20240509151459.3622910-2-aalbersh@redhat.com>
XFS has project quotas which could be attached to a directory. All
new inodes in these directories inherit project ID.
The project is created from userspace by opening and calling
FS_IOC_FSSETXATTR on each inode. This is not possible for special
files such as FIFO, SOCK, BLK etc. as opening them return special
inode from VFS. Therefore, some inodes are left with empty project
ID.
This patch adds new XFS ioctl which allows userspace, such as
xfs_quota, to set project ID on special files. This will let
xfs_quota set ID on all inodes and also reset it when project is
removed.
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
---
fs/xfs/libxfs/xfs_fs.h | 11 +++++
fs/xfs/xfs_ioctl.c | 86 ++++++++++++++++++++++++++++++++++++++++
include/linux/fileattr.h | 2 +-
3 files changed, 98 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index 97996cb79aaa..f68e98005d4b 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -670,6 +670,15 @@ typedef struct xfs_swapext
struct xfs_bstat sx_stat; /* stat of target b4 copy */
} xfs_swapext_t;
+/*
+ * Structure passed to XFS_IOC_GETFSXATTRAT/XFS_IOC_GETFSXATTRAT
+ */
+struct xfs_xattrat_req {
+ struct fsxattr __user *fsx; /* XATTR to get/set */
+ __u32 dfd; /* parent dir */
+ const char __user *path;
+};
+
/*
* Flags for going down operation
*/
@@ -997,6 +1006,8 @@ struct xfs_getparents_by_handle {
#define XFS_IOC_BULKSTAT _IOR ('X', 127, struct xfs_bulkstat_req)
#define XFS_IOC_INUMBERS _IOR ('X', 128, struct xfs_inumbers_req)
#define XFS_IOC_EXCHANGE_RANGE _IOWR('X', 129, struct xfs_exchange_range)
+#define XFS_IOC_GETFSXATTRAT _IOR ('X', 130, struct xfs_xattrat_req)
+#define XFS_IOC_SETFSXATTRAT _IOW ('X', 131, struct xfs_xattrat_req)
/* XFS_IOC_GETFSUUID ---------- deprecated 140 */
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 515c9b4b862d..d54dba9128a0 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -1408,6 +1408,74 @@ xfs_ioctl_fs_counts(
return 0;
}
+static int
+xfs_xattrat_get(
+ struct file *dir,
+ const char __user *pathname,
+ struct xfs_xattrat_req *xreq)
+{
+ struct path filepath;
+ struct xfs_inode *ip;
+ struct fileattr fa;
+ int error = -EBADF;
+
+ memset(&fa, 0, sizeof(struct fileattr));
+
+ if (!S_ISDIR(file_inode(dir)->i_mode))
+ return error;
+
+ error = user_path_at(xreq->dfd, pathname, 0, &filepath);
+ if (error)
+ return error;
+
+ ip = XFS_I(filepath.dentry->d_inode);
+
+ xfs_ilock(ip, XFS_ILOCK_SHARED);
+ xfs_fill_fsxattr(ip, XFS_DATA_FORK, &fa);
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+
+ error = copy_fsxattr_to_user(&fa, xreq->fsx);
+
+ path_put(&filepath);
+ return error;
+}
+
+static int
+xfs_xattrat_set(
+ struct file *dir,
+ const char __user *pathname,
+ struct xfs_xattrat_req *xreq)
+{
+ struct fileattr fa;
+ struct path filepath;
+ struct mnt_idmap *idmap = file_mnt_idmap(dir);
+ int error = -EBADF;
+
+ if (!S_ISDIR(file_inode(dir)->i_mode))
+ return error;
+
+ error = copy_fsxattr_from_user(&fa, xreq->fsx);
+ if (error)
+ return error;
+
+ error = user_path_at(xreq->dfd, pathname, 0, &filepath);
+ if (error)
+ return error;
+
+ error = mnt_want_write(filepath.mnt);
+ if (error) {
+ path_put(&filepath);
+ return error;
+ }
+
+ fa.fsx_valid = true;
+ error = vfs_fileattr_set(idmap, filepath.dentry, &fa);
+
+ mnt_drop_write(filepath.mnt);
+ path_put(&filepath);
+ return error;
+}
+
/*
* These long-unused ioctls were removed from the official ioctl API in 5.17,
* but retain these definitions so that we can log warnings about them.
@@ -1652,6 +1720,24 @@ xfs_file_ioctl(
sb_end_write(mp->m_super);
return error;
}
+ case XFS_IOC_GETFSXATTRAT: {
+ struct xfs_xattrat_req xreq;
+
+ if (copy_from_user(&xreq, arg, sizeof(struct xfs_xattrat_req)))
+ return -EFAULT;
+
+ error = xfs_xattrat_get(filp, xreq.path, &xreq);
+ return error;
+ }
+ case XFS_IOC_SETFSXATTRAT: {
+ struct xfs_xattrat_req xreq;
+
+ if (copy_from_user(&xreq, arg, sizeof(struct xfs_xattrat_req)))
+ return -EFAULT;
+
+ error = xfs_xattrat_set(filp, xreq.path, &xreq);
+ return error;
+ }
case XFS_IOC_EXCHANGE_RANGE:
return xfs_ioc_exchange_range(filp, arg);
diff --git a/include/linux/fileattr.h b/include/linux/fileattr.h
index 3c4f8c75abc0..8598e94b530b 100644
--- a/include/linux/fileattr.h
+++ b/include/linux/fileattr.h
@@ -34,7 +34,7 @@ struct fileattr {
};
int copy_fsxattr_to_user(const struct fileattr *fa, struct fsxattr __user *ufa);
-int copy_fsxattr_from_user(struct fileattr *fa, struct fsxattr __user *ufa)
+int copy_fsxattr_from_user(struct fileattr *fa, struct fsxattr __user *ufa);
void fileattr_fill_xflags(struct fileattr *fa, u32 xflags);
void fileattr_fill_flags(struct fileattr *fa, u32 flags);
--
2.42.0
next prev parent reply other threads:[~2024-05-09 15:15 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-09 15:14 [PATCH 0/4] Introduce XFS_IOC_SETFSXATTRAT/XFS_IOC_GETFSXATTRAT ioctls Andrey Albershteyn
2024-05-09 15:14 ` [PATCH 1/4] fs: export copy_fsxattr_from_user() Andrey Albershteyn
2024-05-09 15:14 ` [PATCH 2/4] xfs: allow renames of project-less inodes Andrey Albershteyn
2024-05-09 23:28 ` Darrick J. Wong
2024-05-10 9:41 ` Andrey Albershteyn
2024-05-09 15:14 ` [PATCH 3/4] xfs: allow setting xattrs on special files Andrey Albershteyn
2024-05-09 23:34 ` Darrick J. Wong
2024-05-10 9:46 ` Andrey Albershteyn
2024-05-09 15:15 ` Andrey Albershteyn [this message]
2024-05-09 23:25 ` [PATCH 4/4] xfs: add XFS_IOC_SETFSXATTRAT and XFS_IOC_GETFSXATTRAT Darrick J. Wong
2024-05-10 10:38 ` Andrey Albershteyn
2024-05-09 23:55 ` Dave Chinner
2024-05-10 9:37 ` Andrey Albershteyn
2024-05-10 4:58 ` Christoph Hellwig
2024-05-10 9:50 ` Andrey Albershteyn
2024-05-10 15:10 ` Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240509151459.3622910-6-aalbersh@redhat.com \
--to=aalbersh@redhat.com \
--cc=linux-fsdevel@vgre.kernel.org \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).