File 0060-LU-15969-llite-add-support-for-fileattr_get-set.patch of Package lustre_2_12

From d7aa8de396f585e7001a7ae49dfcba3707005135 Mon Sep 17 00:00:00 2001
From: Mr NeilBrown <neilb@suse.de>
Date: Wed, 7 Dec 2022 18:55:57 +1100
Subject: [PATCH] LU-15969 llite: add support for  ->fileattr_get/set

From Linux 5.13, FS_IOC_SETFLAGS and GETFLAGS aren't passed down to
the filesystem, we need ->fileattr_get/set inode_operations instead.

Signed-off-by: Mr NeilBrown <neilb@suse.de>
Reviewed-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Change-Id: Ib3ffba3529ea32b702ad80abd4b9e4e3ad90b412
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/51107
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
---
 lustre/autoconf/lustre-core.m4 |   28 ++++++
 lustre/llite/file.c            |    8 +
 lustre/llite/llite_internal.h  |    7 +
 lustre/llite/llite_lib.c       |  186 ++++++++++++++++++++++++++---------------
 lustre/llite/namei.c           |    4 
 5 files changed, 167 insertions(+), 66 deletions(-)

--- a/lustre/autoconf/lustre-core.m4
+++ b/lustre/autoconf/lustre-core.m4
@@ -2342,6 +2342,31 @@ EXTRA_KCFLAGS="$tmp_flags"
 ]) # LC_HAVE_USER_NAMESPACE_ARG
 
 #
+# LC_HAVE_FILEATTR_GET
+#
+# kernel 5.13 4c5b479975212065ef39786e115fde42847e95a9
+# vfs: add fileattr ops
+# Add inode operations to replace FS_IOC_[SG]ETFLAGS ioctl
+# The type signature of ->fileattr_set is not stable for the
+# first few iterations, so don't commit to a particular signature
+# here.  Hopefully we will only want to support the final version.
+#
+AC_DEFUN([LC_HAVE_FILEATTR_GET], [
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_CHECK_COMPILE([if 'inode_operations' has fileattr_get (and fileattr_set)],
+fileattr_set, [
+	#include <linux/fs.h>
+],[
+	((struct inode_operations *)1)->fileattr_get(NULL, NULL);
+],[
+	AC_DEFINE(HAVE_FILEATTR_GET, 1,
+		['inode_operations' has fileattr_get and fileattr_set])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+]) # LC_HAVE_FILEATTR_GET
+
+#
 # LC_HAVE_GET_ACL_RCU_ARG
 #
 # kernel 5.15 commit 0cad6246621b5887d5b33fea84219d2a71f2f99a
@@ -3566,6 +3591,9 @@ AC_DEFUN([LC_PROG_LINUX], [
 	# 5.10
 	LC_FORCE_UACCESS_BEGIN
 
+	# 5.13
+	LC_HAVE_FILEATTR_GET
+
 	# 5.15
 	LC_HAVE_GET_ACL_RCU_ARG
 
--- a/lustre/llite/file.c
+++ b/lustre/llite/file.c
@@ -3040,6 +3040,7 @@ static int ll_lock_noexpand(struct file
 	return 0;
 }
 
+#ifndef HAVE_FILEATTR_GET
 int ll_ioctl_fsgetxattr(struct inode *inode, unsigned int cmd,
 			void __user *uarg)
 {
@@ -3057,6 +3058,7 @@ int ll_ioctl_fsgetxattr(struct inode *in
 
 	RETURN(0);
 }
+#endif
 
 int ll_ioctl_check_project(struct inode *inode, struct fsxattr *fa)
 {
@@ -3082,6 +3084,7 @@ int ll_ioctl_check_project(struct inode
 	return 0;
 }
 
+#ifndef HAVE_FILEATTR_GET
 int ll_ioctl_fssetxattr(struct inode *inode, unsigned int cmd,
 			void __user *uarg)
 {
@@ -3133,6 +3136,7 @@ out_fsxattr:
 	ll_finish_md_op_data(op_data);
 	RETURN(rc);
 }
+#endif
 
 static long ll_file_unlock_lease(struct file *file, struct ll_ioc_lease *ioc,
 				 void __user *uarg)
@@ -4833,6 +4837,10 @@ struct inode_operations ll_file_inode_op
 #ifdef HAVE_IOP_SET_ACL
 	.set_acl	= ll_set_acl,
 #endif
+#ifdef HAVE_FILEATTR_GET
+	.fileattr_get	= ll_fileattr_get,
+	.fileattr_set	= ll_fileattr_set,
+#endif
 };
 
 int ll_layout_conf(struct inode *inode, const struct cl_object_conf *conf)
--- a/lustre/llite/llite_internal.h
+++ b/lustre/llite/llite_internal.h
@@ -913,8 +913,10 @@ int ll_inode_permission(struct inode *in
 # endif
 #endif
 int ll_ioctl_check_project(struct inode *inode, struct fsxattr *fa);
+#ifndef HAVE_FILEATTR_GET
 int ll_ioctl_fsgetxattr(struct inode *inode, unsigned int cmd,
 			void __user *uarg);
+#endif
 int ll_ioctl_fssetxattr(struct inode *inode, unsigned int cmd,
 			void __user *uarg);
 int ll_lov_setstripe_ea_info(struct inode *inode, struct dentry *dentry,
@@ -976,6 +978,11 @@ int ll_update_inode(struct inode *inode,
 void ll_update_inode_flags(struct inode *inode, int ext_flags);
 int ll_read_inode2(struct inode *inode, void *opaque);
 void ll_delete_inode(struct inode *inode);
+#ifdef HAVE_FILEATTR_GET
+int ll_fileattr_get(struct dentry *dentry, struct fileattr *fa);
+int ll_fileattr_set(struct user_namespace *mnt_userns,
+		    struct dentry *dentry, struct fileattr *fa);
+#endif
 int ll_iocontrol(struct inode *inode, struct file *file,
 		 unsigned int cmd, void __user *uarg);
 int ll_flush_ctx(struct inode *inode);
--- a/lustre/llite/llite_lib.c
+++ b/lustre/llite/llite_lib.c
@@ -42,6 +42,11 @@
 #include <linux/types.h>
 #include <linux/uaccess.h>
 #include <linux/version.h>
+#ifdef HAVE_FILEATTR_GET
+#include <linux/fs.h>
+#include <linux/fileattr.h>
+#endif
+
 #include <linux/mm.h>
 #include <linux/user_namespace.h>
 #ifdef HAVE_UIDGID_HEADER
@@ -2154,16 +2159,117 @@ void ll_delete_inode(struct inode *inode
 #endif
 	clear_inode(inode);
 
-        EXIT;
+	EXIT;
+}
+
+static int fileattr_get(struct inode *inode, int *flags,
+			u32 *xflags,
+			u32 *projid)
+{
+	struct ll_sb_info *sbi = ll_i2sbi(inode);
+	struct ptlrpc_request *req = NULL;
+	struct md_op_data *op_data;
+	struct mdt_body *body;
+	int rc;
+
+	ENTRY;
+	op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL,
+				     0, 0, LUSTRE_OPC_ANY,
+				     NULL);
+	if (IS_ERR(op_data))
+		RETURN(PTR_ERR(op_data));
+
+	op_data->op_valid = OBD_MD_FLFLAGS;
+	rc = md_getattr(sbi->ll_md_exp, op_data, &req);
+	ll_finish_md_op_data(op_data);
+	if (rc) {
+		CERROR("%s: failure inode "DFID": rc = %d\n",
+		       sbi->ll_md_exp->exp_obd->obd_name,
+		       PFID(ll_inode2fid(inode)), rc);
+		RETURN(-abs(rc));
+	}
+
+	body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
+
+	*flags = body->mbo_flags;
+
+	ptlrpc_req_finished(req);
+
+	*xflags = ll_inode_flags_to_xflags(inode->i_flags);
+	if (test_bit(LLIF_PROJECT_INHERIT, &ll_i2info(inode)->lli_flags))
+		*xflags |= FS_XFLAG_PROJINHERIT;
+	*projid = ll_i2info(inode)->lli_projid;
+
+	RETURN(0);
+}
+
+static int fileattr_set(struct inode *inode, int flags)
+{
+	struct ll_sb_info *sbi = ll_i2sbi(inode);
+	struct ptlrpc_request *req = NULL;
+	struct md_op_data *op_data;
+	struct cl_object *obj;
+	struct fsxattr fa = { 0 };
+	struct iattr *attr;
+	int rc;
+
+	ENTRY;
+	fa.fsx_projid = ll_i2info(inode)->lli_projid;
+	if (flags & LUSTRE_PROJINHERIT_FL)
+		fa.fsx_xflags = FS_XFLAG_PROJINHERIT;
+
+	rc = ll_ioctl_check_project(inode, &fa);
+	if (rc)
+		RETURN(rc);
+
+	op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
+				     LUSTRE_OPC_ANY, NULL);
+	if (IS_ERR(op_data))
+		RETURN(PTR_ERR(op_data));
+
+	op_data->op_attr_flags = flags;
+	op_data->op_xvalid |= OP_XVALID_FLAGS;
+	rc = md_setattr(sbi->ll_md_exp, op_data, NULL, 0, &req);
+	ll_finish_md_op_data(op_data);
+	ptlrpc_req_finished(req);
+	if (rc)
+		RETURN(rc);
+
+	ll_update_inode_flags(inode, flags);
+
+	obj = ll_i2info(inode)->lli_clob;
+	if (obj == NULL)
+		RETURN(0);
+
+	OBD_ALLOC_PTR(attr);
+	if (attr == NULL)
+		RETURN(-ENOMEM);
+
+	rc = cl_setattr_ost(obj, attr, OP_XVALID_FLAGS, flags);
+
+	OBD_FREE_PTR(attr);
+	RETURN(rc);
+}
+
+#ifdef HAVE_FILEATTR_GET
+int ll_fileattr_get(struct dentry *dentry, struct fileattr *fa)
+{
+	return fileattr_get(d_inode(dentry), &fa->flags,
+			    &fa->fsx_xflags, &fa->fsx_projid);
 }
 
+int ll_fileattr_set(struct user_namespace *mnt_userns,
+		    struct dentry *dentry, struct fileattr *fa)
+{
+	return fileattr_set(d_inode(dentry), fa->flags);
+}
+#endif /* HAVE_FILEATTR_GET */
+
 /* ioctl commands shared between files and directories */
 int ll_iocontrol(struct inode *inode, struct file *file,
 		 unsigned int cmd, void __user *uarg)
 {
-	struct ll_sb_info *sbi = ll_i2sbi(inode);
-	struct ptlrpc_request *req = NULL;
-	int rc, flags = 0;
+	int rc;
 	ENTRY;
 
 	switch (cmd) {
@@ -2172,85 +2278,33 @@ int ll_iocontrol(struct inode *inode, st
 	case FSFILT_IOC_GETVERSION:
 	case FS_IOC_GETVERSION:
 		RETURN(put_user(inode->i_generation, (int __user *)uarg));
+
+#ifndef HAVE_FILEATTR_GET
 	case FS_IOC_GETFLAGS: {
-		struct mdt_body *body;
-		struct md_op_data *op_data;
+		u32 xflags = 0, projid = 0;
+		int flags = 0;
 
 		if (!ll_access_ok(uarg, sizeof(int)))
 			RETURN(-EFAULT);
-
-		op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
-					     LUSTRE_OPC_ANY, NULL);
-		if (IS_ERR(op_data))
-			RETURN(PTR_ERR(op_data));
-
-		op_data->op_valid = OBD_MD_FLFLAGS;
-		rc = md_getattr(sbi->ll_md_exp, op_data, &req);
-		ll_finish_md_op_data(op_data);
-		if (rc) {
-			CERROR("%s: failure inode "DFID": rc = %d\n",
-			       sbi->ll_md_exp->exp_obd->obd_name,
-			       PFID(ll_inode2fid(inode)), rc);
-			RETURN(-abs(rc));
-		}
-
-		body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
-
-		flags = body->mbo_flags;
-
-		ptlrpc_req_finished(req);
+		rc = fileattr_get(file->f_inode, &flags, &xflags, &projid);
+		if (rc)
+			RETURN(rc);
 
 		RETURN(put_user(flags, (int __user *)uarg));
 	}
 	case FS_IOC_SETFLAGS: {
-		struct iattr *attr;
-		struct md_op_data *op_data;
-		struct cl_object *obj;
-		struct fsxattr fa = { 0 };
+		int flags = 0;
 
 		if (get_user(flags, (int __user *)uarg))
 			RETURN(-EFAULT);
 
-		fa.fsx_projid = ll_i2info(inode)->lli_projid;
-		if (flags & LUSTRE_PROJINHERIT_FL)
-			fa.fsx_xflags = FS_XFLAG_PROJINHERIT;
-
-		rc = ll_ioctl_check_project(inode, &fa);
-		if (rc)
-			RETURN(rc);
-
-		op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
-					     LUSTRE_OPC_ANY, NULL);
-		if (IS_ERR(op_data))
-			RETURN(PTR_ERR(op_data));
-
-		op_data->op_attr_flags = flags;
-		op_data->op_xvalid |= OP_XVALID_FLAGS;
-		rc = md_setattr(sbi->ll_md_exp, op_data, NULL, 0, &req);
-		ll_finish_md_op_data(op_data);
-		ptlrpc_req_finished(req);
-		if (rc)
-			RETURN(rc);
-
-		ll_update_inode_flags(inode, flags);
-
-		obj = ll_i2info(inode)->lli_clob;
-		if (obj == NULL)
-			RETURN(0);
-
-		OBD_ALLOC_PTR(attr);
-		if (attr == NULL)
-			RETURN(-ENOMEM);
-
-		rc = cl_setattr_ost(obj, attr, OP_XVALID_FLAGS, flags);
-
-		OBD_FREE_PTR(attr);
-		RETURN(rc);
+		RETURN(fileattr_set(file->f_inode, flags));
 	}
 	case FS_IOC_FSGETXATTR:
 		RETURN(ll_ioctl_fsgetxattr(inode, cmd, uarg));
 	case FS_IOC_FSSETXATTR:
 		RETURN(ll_ioctl_fssetxattr(inode, cmd, uarg));
+#endif /* HAVE_FILEATTR_GET */
 	case IOC_OBD_STATFS:
 		RETURN(ll_obd_statfs(inode, uarg));
 	case LL_IOC_GET_MDTIDX: {
--- a/lustre/llite/namei.c
+++ b/lustre/llite/namei.c
@@ -1778,6 +1778,10 @@ const struct inode_operations ll_dir_ino
 #ifdef HAVE_IOP_SET_ACL
 	.set_acl	= ll_set_acl,
 #endif
+#ifdef HAVE_FILEATTR_GET
+	.fileattr_get	= ll_fileattr_get,
+	.fileattr_set	= ll_fileattr_set,
+#endif
 };
 
 const struct inode_operations ll_special_inode_operations = {
openSUSE Build Service is sponsored by