mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	Linux 5.15 compat: get_acl()
Kernel commits 332f606b32b6 ovl: enable RCU'd ->get_acl() 0cad6246621b vfs: add rcu argument to ->get_acl() callback Added compatibility code to detect the new ->get_acl() interface and correctly handle the case where the new rcu argument is set. Reviewed-by: Coleman Kane <ckane@colemankane.org> Reviewed-by: Tony Hutter <hutter2@llnl.gov> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #12548
This commit is contained in:
		
							parent
							
								
									72d16a9b49
								
							
						
					
					
						commit
						7a41ef240a
					
				| @ -162,6 +162,9 @@ dnl # | ||||
| dnl # 3.1 API change, | ||||
| dnl # Check if inode_operations contains the function get_acl | ||||
| dnl # | ||||
| dnl # 5.15 API change, | ||||
| dnl # Added the bool rcu argument to get_acl for rcu path walk. | ||||
| dnl # | ||||
| AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [ | ||||
| 	ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [ | ||||
| 		#include <linux/fs.h> | ||||
| @ -174,14 +177,32 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [ | ||||
| 			.get_acl = get_acl_fn, | ||||
| 		}; | ||||
| 	],[]) | ||||
| 
 | ||||
| 	ZFS_LINUX_TEST_SRC([inode_operations_get_acl_rcu], [ | ||||
| 		#include <linux/fs.h> | ||||
| 
 | ||||
| 		struct posix_acl *get_acl_fn(struct inode *inode, int type, | ||||
| 		    bool rcu) { return NULL; } | ||||
| 
 | ||||
| 		static const struct inode_operations | ||||
| 		    iops __attribute__ ((unused)) = { | ||||
| 			.get_acl = get_acl_fn, | ||||
| 		}; | ||||
| 	],[]) | ||||
| ]) | ||||
| 
 | ||||
| AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [ | ||||
| 	AC_MSG_CHECKING([whether iops->get_acl() exists]) | ||||
| 	ZFS_LINUX_TEST_RESULT([inode_operations_get_acl], [ | ||||
| 		AC_MSG_RESULT(yes) | ||||
| 		AC_DEFINE(HAVE_GET_ACL, 1, [iops->get_acl() exists]) | ||||
| 	],[ | ||||
| 		ZFS_LINUX_TEST_ERROR([iops->get_acl()]) | ||||
| 		ZFS_LINUX_TEST_RESULT([inode_operations_get_acl_rcu], [ | ||||
| 			AC_MSG_RESULT(yes) | ||||
| 			AC_DEFINE(HAVE_GET_ACL_RCU, 1, [iops->get_acl() takes rcu]) | ||||
| 		],[ | ||||
| 			ZFS_LINUX_TEST_ERROR([iops->get_acl()]) | ||||
| 		]) | ||||
| 	]) | ||||
| ]) | ||||
| 
 | ||||
|  | ||||
| @ -70,7 +70,11 @@ extern int zpl_set_acl(struct user_namespace *userns, struct inode *ip, | ||||
| extern int zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type); | ||||
| #endif /* HAVE_SET_ACL_USERNS */ | ||||
| #endif /* HAVE_SET_ACL */ | ||||
| #if defined(HAVE_GET_ACL_RCU) | ||||
| extern struct posix_acl *zpl_get_acl(struct inode *ip, int type, bool rcu); | ||||
| #elif defined(HAVE_GET_ACL) | ||||
| extern struct posix_acl *zpl_get_acl(struct inode *ip, int type); | ||||
| #endif | ||||
| extern int zpl_init_acl(struct inode *ip, struct inode *dir); | ||||
| extern int zpl_chmod_acl(struct inode *ip); | ||||
| #else | ||||
|  | ||||
| @ -1012,13 +1012,12 @@ zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type) | ||||
| } | ||||
| #endif /* HAVE_SET_ACL */ | ||||
| 
 | ||||
| struct posix_acl * | ||||
| zpl_get_acl(struct inode *ip, int type) | ||||
| static struct posix_acl * | ||||
| zpl_get_acl_impl(struct inode *ip, int type) | ||||
| { | ||||
| 	struct posix_acl *acl; | ||||
| 	void *value = NULL; | ||||
| 	char *name; | ||||
| 	int size; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * As of Linux 3.14, the kernel get_acl will check this for us. | ||||
| @ -1042,7 +1041,7 @@ zpl_get_acl(struct inode *ip, int type) | ||||
| 		return (ERR_PTR(-EINVAL)); | ||||
| 	} | ||||
| 
 | ||||
| 	size = zpl_xattr_get(ip, name, NULL, 0); | ||||
| 	int size = zpl_xattr_get(ip, name, NULL, 0); | ||||
| 	if (size > 0) { | ||||
| 		value = kmem_alloc(size, KM_SLEEP); | ||||
| 		size = zpl_xattr_get(ip, name, value, size); | ||||
| @ -1068,6 +1067,25 @@ zpl_get_acl(struct inode *ip, int type) | ||||
| 	return (acl); | ||||
| } | ||||
| 
 | ||||
| #if defined(HAVE_GET_ACL_RCU) | ||||
| struct posix_acl * | ||||
| zpl_get_acl(struct inode *ip, int type, bool rcu) | ||||
| { | ||||
| 	if (rcu) | ||||
| 		return (ERR_PTR(-ECHILD)); | ||||
| 
 | ||||
| 	return (zpl_get_acl_impl(ip, type)); | ||||
| } | ||||
| #elif defined(HAVE_GET_ACL) | ||||
| struct posix_acl * | ||||
| zpl_get_acl(struct inode *ip, int type) | ||||
| { | ||||
| 	return (zpl_get_acl_impl(ip, type)); | ||||
| } | ||||
| #else | ||||
| #error "Unsupported iops->get_acl() implementation" | ||||
| #endif /* HAVE_GET_ACL_RCU */ | ||||
| 
 | ||||
| int | ||||
| zpl_init_acl(struct inode *ip, struct inode *dir) | ||||
| { | ||||
| @ -1078,7 +1096,7 @@ zpl_init_acl(struct inode *ip, struct inode *dir) | ||||
| 		return (0); | ||||
| 
 | ||||
| 	if (!S_ISLNK(ip->i_mode)) { | ||||
| 		acl = zpl_get_acl(dir, ACL_TYPE_DEFAULT); | ||||
| 		acl = zpl_get_acl_impl(dir, ACL_TYPE_DEFAULT); | ||||
| 		if (IS_ERR(acl)) | ||||
| 			return (PTR_ERR(acl)); | ||||
| 		if (!acl) { | ||||
| @ -1127,7 +1145,7 @@ zpl_chmod_acl(struct inode *ip) | ||||
| 	if (S_ISLNK(ip->i_mode)) | ||||
| 		return (-EOPNOTSUPP); | ||||
| 
 | ||||
| 	acl = zpl_get_acl(ip, ACL_TYPE_ACCESS); | ||||
| 	acl = zpl_get_acl_impl(ip, ACL_TYPE_ACCESS); | ||||
| 	if (IS_ERR(acl) || !acl) | ||||
| 		return (PTR_ERR(acl)); | ||||
| 
 | ||||
| @ -1189,7 +1207,7 @@ __zpl_xattr_acl_get_access(struct inode *ip, const char *name, | ||||
| 	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX) | ||||
| 		return (-EOPNOTSUPP); | ||||
| 
 | ||||
| 	acl = zpl_get_acl(ip, type); | ||||
| 	acl = zpl_get_acl_impl(ip, type); | ||||
| 	if (IS_ERR(acl)) | ||||
| 		return (PTR_ERR(acl)); | ||||
| 	if (acl == NULL) | ||||
| @ -1217,7 +1235,7 @@ __zpl_xattr_acl_get_default(struct inode *ip, const char *name, | ||||
| 	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX) | ||||
| 		return (-EOPNOTSUPP); | ||||
| 
 | ||||
| 	acl = zpl_get_acl(ip, type); | ||||
| 	acl = zpl_get_acl_impl(ip, type); | ||||
| 	if (IS_ERR(acl)) | ||||
| 		return (PTR_ERR(acl)); | ||||
| 	if (acl == NULL) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Brian Behlendorf
						Brian Behlendorf