* [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name [not found] <20160413182026.GR25498@ZenIV.linux.org.uk> @ 2016-04-13 22:27 ` Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks Andreas Gruenbacher ` (7 more replies) 2016-04-13 22:30 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher 1 sibling, 8 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:27 UTC (permalink / raw) To: cluster-devel.redhat.com On Wed, Apr 13, 2016 at 8:20 PM, Al Viro <viro@zeniv.linux.org.uk> wrote: > On Wed, Apr 13, 2016 at 05:40:34PM +0200, Andreas Gruenbacher wrote: >> Export xattr_resolve_name and make it easier to use by filesystems. >> Use it to remove reiserfs's own copy of the same functionality. > > Nah - I've switched that sucker to generic_*xattr() already. See > #work.xattr for the current state (commit 79a628d14 in there, should > propagate in a few). Sorry, should've pushed that last week... Okay, here are some more xattr-related patches. Andreas Andreas Gruenbacher (7): cifs: Fix xattr name checks cifs: Check for equality with ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT cifs: Fix removexattr for os2.* xattrs ceph: Get rid of d_find_alias in ceph_set_acl ceph: Switch to generic xattr handlers posix acls: Export xattr_handler functions gfs2: Switch to generic xattr handlers Yan, Zheng (1): ceph: kill __ceph_removexattr() fs/ceph/acl.c | 14 ++- fs/ceph/dir.c | 7 +- fs/ceph/inode.c | 29 +++--- fs/ceph/super.h | 8 +- fs/ceph/xattr.c | 192 ++++++---------------------------------- fs/cifs/cifssmb.c | 4 +- fs/cifs/xattr.c | 50 +++++------ fs/gfs2/inode.c | 78 ++-------------- fs/gfs2/xattr.c | 108 ++++++++++++++++++++-- fs/posix_acl.c | 9 +- include/linux/posix_acl_xattr.h | 8 ++ 11 files changed, 203 insertions(+), 304 deletions(-) -- 2.4.11 ^ permalink raw reply [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks 2016-04-13 22:27 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher @ 2016-04-13 22:27 ` Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 2/8] cifs: Check for equality with ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT Andreas Gruenbacher ` (6 subsequent siblings) 7 siblings, 0 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:27 UTC (permalink / raw) To: cluster-devel.redhat.com Use strcmp(str, name) instead of strncmp(str, name, strlen(name)) for checking if str and name are the same (as opposed to name being a prefix of str) in the gexattr and setxattr inode operations. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> --- fs/cifs/xattr.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 5d57c85..6e73ba9 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -129,7 +129,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, == 0) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) goto set_ea_exit; - if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) + if (strcmp(ea_name, CIFS_XATTR_DOS_ATTRIB) == 0) cifs_dbg(FYI, "attempt to set cifs inode metadata\n"); ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */ @@ -147,8 +147,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, rc = pTcon->ses->server->ops->set_EA(xid, pTcon, full_path, ea_name, ea_value, (__u16)value_size, cifs_sb->local_nls, cifs_remap(cifs_sb)); - } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL, - strlen(CIFS_XATTR_CIFS_ACL)) == 0) { + } else if (strcmp(ea_name, CIFS_XATTR_CIFS_ACL) == 0) { #ifdef CONFIG_CIFS_ACL struct cifs_ntsd *pacl; pacl = kmalloc(value_size, GFP_KERNEL); @@ -170,10 +169,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, cifs_dbg(FYI, "Set CIFS ACL not supported yet\n"); #endif /* CONFIG_CIFS_ACL */ } else { - int temp; - temp = strncmp(ea_name, XATTR_NAME_POSIX_ACL_ACCESS, - strlen(XATTR_NAME_POSIX_ACL_ACCESS)); - if (temp == 0) { + if (strcmp(ea_name, XATTR_NAME_POSIX_ACL_ACCESS) == 0) { #ifdef CONFIG_CIFS_POSIX if (sb->s_flags & MS_POSIXACL) rc = CIFSSMBSetPosixACL(xid, pTcon, full_path, @@ -184,8 +180,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, #else cifs_dbg(FYI, "set POSIX ACL not supported\n"); #endif - } else if (strncmp(ea_name, XATTR_NAME_POSIX_ACL_DEFAULT, - strlen(XATTR_NAME_POSIX_ACL_DEFAULT)) == 0) { + } else if (strcmp(ea_name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0) { #ifdef CONFIG_CIFS_POSIX if (sb->s_flags & MS_POSIXACL) rc = CIFSSMBSetPosixACL(xid, pTcon, full_path, @@ -246,7 +241,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, struct inode *inode, if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) goto get_ea_exit; - if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) { + if (strcmp(ea_name, CIFS_XATTR_DOS_ATTRIB) == 0) { cifs_dbg(FYI, "attempt to query cifs inode metadata\n"); /* revalidate/getattr then populate from inode */ } /* BB add else when above is implemented */ @@ -264,8 +259,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, struct inode *inode, rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon, full_path, ea_name, ea_value, buf_size, cifs_sb->local_nls, cifs_remap(cifs_sb)); - } else if (strncmp(ea_name, XATTR_NAME_POSIX_ACL_ACCESS, - strlen(XATTR_NAME_POSIX_ACL_ACCESS)) == 0) { + } else if (strcmp(ea_name, XATTR_NAME_POSIX_ACL_ACCESS) == 0) { #ifdef CONFIG_CIFS_POSIX if (sb->s_flags & MS_POSIXACL) rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, @@ -275,8 +269,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, struct inode *inode, #else cifs_dbg(FYI, "Query POSIX ACL not supported yet\n"); #endif /* CONFIG_CIFS_POSIX */ - } else if (strncmp(ea_name, XATTR_NAME_POSIX_ACL_DEFAULT, - strlen(XATTR_NAME_POSIX_ACL_DEFAULT)) == 0) { + } else if (strcmp(ea_name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0) { #ifdef CONFIG_CIFS_POSIX if (sb->s_flags & MS_POSIXACL) rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, @@ -286,8 +279,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, struct inode *inode, #else cifs_dbg(FYI, "Query POSIX default ACL not supported yet\n"); #endif /* CONFIG_CIFS_POSIX */ - } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL, - strlen(CIFS_XATTR_CIFS_ACL)) == 0) { + } else if (strcmp(ea_name, CIFS_XATTR_CIFS_ACL) == 0) { #ifdef CONFIG_CIFS_ACL u32 acllen; struct cifs_ntsd *pacl; -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 2/8] cifs: Check for equality with ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT 2016-04-13 22:27 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks Andreas Gruenbacher @ 2016-04-13 22:27 ` Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 3/8] cifs: Fix removexattr for os2.* xattrs Andreas Gruenbacher ` (5 subsequent siblings) 7 siblings, 0 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:27 UTC (permalink / raw) To: cluster-devel.redhat.com The two values ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT are meant to be enumerations, not bits in a bit mask. Use '==' instead of '&' to check for these values. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> --- fs/cifs/cifssmb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 76fcb50..f24a89c 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -3366,7 +3366,7 @@ static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen, if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION) return -EOPNOTSUPP; - if (acl_type & ACL_TYPE_ACCESS) { + if (acl_type == ACL_TYPE_ACCESS) { count = le16_to_cpu(cifs_acl->access_entry_count); pACE = &cifs_acl->ace_array[0]; size = sizeof(struct cifs_posix_acl); @@ -3377,7 +3377,7 @@ static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen, size_of_data_area, size); return -EINVAL; } - } else if (acl_type & ACL_TYPE_DEFAULT) { + } else if (acl_type == ACL_TYPE_DEFAULT) { count = le16_to_cpu(cifs_acl->access_entry_count); size = sizeof(struct cifs_posix_acl); size += sizeof(struct cifs_posix_ace) * count; -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 3/8] cifs: Fix removexattr for os2.* xattrs 2016-04-13 22:27 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 2/8] cifs: Check for equality with ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT Andreas Gruenbacher @ 2016-04-13 22:27 ` Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 4/8] ceph: Get rid of d_find_alias in ceph_set_acl Andreas Gruenbacher ` (4 subsequent siblings) 7 siblings, 0 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:27 UTC (permalink / raw) To: cluster-devel.redhat.com If cifs_removexattr finds a "user." or "os2." xattr name prefix, it skips 5 bytes, one byte too many for "os2.". Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> --- fs/cifs/xattr.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 6e73ba9..721c6db 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -61,15 +61,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name) } if (ea_name == NULL) { cifs_dbg(FYI, "Null xattr names not supported\n"); - } else if (strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) - && (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN))) { - cifs_dbg(FYI, - "illegal xattr request %s (only user namespace supported)\n", - ea_name); - /* BB what if no namespace prefix? */ - /* Should we just pass them to server, except for - system and perhaps security prefixes? */ - } else { + } else if (!strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) goto remove_ea_exit; @@ -78,6 +70,22 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name) rc = pTcon->ses->server->ops->set_EA(xid, pTcon, full_path, ea_name, NULL, (__u16)0, cifs_sb->local_nls, cifs_remap(cifs_sb)); + } else if (!strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) { + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) + goto remove_ea_exit; + + ea_name += XATTR_OS2_PREFIX_LEN; /* skip past os2. prefix */ + if (pTcon->ses->server->ops->set_EA) + rc = pTcon->ses->server->ops->set_EA(xid, pTcon, + full_path, ea_name, NULL, (__u16)0, + cifs_sb->local_nls, cifs_remap(cifs_sb)); + } else { + cifs_dbg(FYI, + "illegal xattr request %s (only user namespace supported)\n", + ea_name); + /* BB what if no namespace prefix? */ + /* Should we just pass them to server, except for + system and perhaps security prefixes? */ } remove_ea_exit: kfree(full_path); -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 4/8] ceph: Get rid of d_find_alias in ceph_set_acl 2016-04-13 22:27 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher ` (2 preceding siblings ...) 2016-04-13 22:27 ` [Cluster-devel] [PATCH 3/8] cifs: Fix removexattr for os2.* xattrs Andreas Gruenbacher @ 2016-04-13 22:27 ` Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 5/8] ceph: Switch to generic xattr handlers Andreas Gruenbacher ` (3 subsequent siblings) 7 siblings, 0 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:27 UTC (permalink / raw) To: cluster-devel.redhat.com Create a variant of ceph_setattr that takes an inode instead of a dentry. Change __ceph_setxattr (and also __ceph_removexattr) to take an inode instead of a dentry. Use those in ceph_set_acl so that we no longer need a dentry there. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: "Yan, Zheng" <zyan@redhat.com> --- fs/ceph/acl.c | 14 +++++--------- fs/ceph/inode.c | 16 ++++++++++------ fs/ceph/super.h | 4 ++-- fs/ceph/xattr.c | 28 ++++++++++++---------------- 4 files changed, 29 insertions(+), 33 deletions(-) diff --git a/fs/ceph/acl.c b/fs/ceph/acl.c index 5457f216..4f67227 100644 --- a/fs/ceph/acl.c +++ b/fs/ceph/acl.c @@ -90,7 +90,6 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type) char *value = NULL; struct iattr newattrs; umode_t new_mode = inode->i_mode, old_mode = inode->i_mode; - struct dentry *dentry; switch (type) { case ACL_TYPE_ACCESS: @@ -128,29 +127,26 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type) goto out_free; } - dentry = d_find_alias(inode); if (new_mode != old_mode) { newattrs.ia_mode = new_mode; newattrs.ia_valid = ATTR_MODE; - ret = ceph_setattr(dentry, &newattrs); + ret = __ceph_setattr(inode, &newattrs); if (ret) - goto out_dput; + goto out_free; } - ret = __ceph_setxattr(dentry, name, value, size, 0); + ret = __ceph_setxattr(inode, name, value, size, 0); if (ret) { if (new_mode != old_mode) { newattrs.ia_mode = old_mode; newattrs.ia_valid = ATTR_MODE; - ceph_setattr(dentry, &newattrs); + __ceph_setattr(inode, &newattrs); } - goto out_dput; + goto out_free; } ceph_set_cached_acl(inode, type, acl); -out_dput: - dput(dentry); out_free: kfree(value); out: diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index ed58b16..cadb6ae 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1776,16 +1776,12 @@ static const struct inode_operations ceph_symlink_iops = { .removexattr = ceph_removexattr, }; -/* - * setattr - */ -int ceph_setattr(struct dentry *dentry, struct iattr *attr) +int __ceph_setattr(struct inode *inode, struct iattr *attr) { - struct inode *inode = d_inode(dentry); struct ceph_inode_info *ci = ceph_inode(inode); const unsigned int ia_valid = attr->ia_valid; struct ceph_mds_request *req; - struct ceph_mds_client *mdsc = ceph_sb_to_client(dentry->d_sb)->mdsc; + struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; struct ceph_cap_flush *prealloc_cf; int issued; int release = 0, dirtied = 0; @@ -2010,6 +2006,14 @@ out_put: } /* + * setattr + */ +int ceph_setattr(struct dentry *dentry, struct iattr *attr) +{ + return __ceph_setattr(d_inode(dentry), attr); +} + +/* * Verify that we have a lease on the given mask. If not, * do a getattr against an mds. */ diff --git a/fs/ceph/super.h b/fs/ceph/super.h index beb893b..1e41bc2 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -785,6 +785,7 @@ static inline int ceph_do_getattr(struct inode *inode, int mask, bool force) return __ceph_do_getattr(inode, NULL, mask, force); } extern int ceph_permission(struct inode *inode, int mask); +extern int __ceph_setattr(struct inode *inode, struct iattr *attr); extern int ceph_setattr(struct dentry *dentry, struct iattr *attr); extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); @@ -792,9 +793,8 @@ extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, /* xattr.c */ extern int ceph_setxattr(struct dentry *, const char *, const void *, size_t, int); -int __ceph_setxattr(struct dentry *, const char *, const void *, size_t, int); +int __ceph_setxattr(struct inode *, const char *, const void *, size_t, int); ssize_t __ceph_getxattr(struct inode *, const char *, void *, size_t); -int __ceph_removexattr(struct dentry *, const char *); extern ssize_t ceph_getxattr(struct dentry *, struct inode *, const char *, void *, size_t); extern ssize_t ceph_listxattr(struct dentry *, char *, size_t); extern int ceph_removexattr(struct dentry *, const char *); diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index c6e917d..248e32e3 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -877,11 +877,10 @@ out: return err; } -static int ceph_sync_setxattr(struct dentry *dentry, const char *name, +static int ceph_sync_setxattr(struct inode *inode, const char *name, const char *value, size_t size, int flags) { - struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb); - struct inode *inode = d_inode(dentry); + struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb); struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_mds_request *req; struct ceph_mds_client *mdsc = fsc->mdsc; @@ -939,13 +938,12 @@ out: return err; } -int __ceph_setxattr(struct dentry *dentry, const char *name, +int __ceph_setxattr(struct inode *inode, const char *name, const void *value, size_t size, int flags) { - struct inode *inode = d_inode(dentry); struct ceph_vxattr *vxattr; struct ceph_inode_info *ci = ceph_inode(inode); - struct ceph_mds_client *mdsc = ceph_sb_to_client(dentry->d_sb)->mdsc; + struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; struct ceph_cap_flush *prealloc_cf = NULL; int issued; int err; @@ -1056,7 +1054,7 @@ do_sync_unlocked: "during filling trace\n", inode); err = -EBUSY; } else { - err = ceph_sync_setxattr(dentry, name, value, size, flags); + err = ceph_sync_setxattr(inode, name, value, size, flags); } out: ceph_free_cap_flush(prealloc_cf); @@ -1078,14 +1076,13 @@ int ceph_setxattr(struct dentry *dentry, const char *name, if (size == 0) value = ""; /* empty EA, do not remove */ - return __ceph_setxattr(dentry, name, value, size, flags); + return __ceph_setxattr(d_inode(dentry), name, value, size, flags); } -static int ceph_send_removexattr(struct dentry *dentry, const char *name) +static int ceph_send_removexattr(struct inode *inode, const char *name) { - struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb); + struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb); struct ceph_mds_client *mdsc = fsc->mdsc; - struct inode *inode = d_inode(dentry); struct ceph_mds_request *req; int err; @@ -1106,12 +1103,11 @@ static int ceph_send_removexattr(struct dentry *dentry, const char *name) return err; } -int __ceph_removexattr(struct dentry *dentry, const char *name) +static int __ceph_removexattr(struct inode *inode, const char *name) { - struct inode *inode = d_inode(dentry); struct ceph_vxattr *vxattr; struct ceph_inode_info *ci = ceph_inode(inode); - struct ceph_mds_client *mdsc = ceph_sb_to_client(dentry->d_sb)->mdsc; + struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; struct ceph_cap_flush *prealloc_cf = NULL; int issued; int err; @@ -1192,7 +1188,7 @@ do_sync_unlocked: if (lock_snap_rwsem) up_read(&mdsc->snap_rwsem); ceph_free_cap_flush(prealloc_cf); - err = ceph_send_removexattr(dentry, name); + err = ceph_send_removexattr(inode, name); return err; } @@ -1204,7 +1200,7 @@ int ceph_removexattr(struct dentry *dentry, const char *name) if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) return generic_removexattr(dentry, name); - return __ceph_removexattr(dentry, name); + return __ceph_removexattr(d_inode(dentry), name); } #ifdef CONFIG_SECURITY -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 5/8] ceph: Switch to generic xattr handlers 2016-04-13 22:27 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher ` (3 preceding siblings ...) 2016-04-13 22:27 ` [Cluster-devel] [PATCH 4/8] ceph: Get rid of d_find_alias in ceph_set_acl Andreas Gruenbacher @ 2016-04-13 22:27 ` Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 6/8] ceph: kill __ceph_removexattr() Andreas Gruenbacher ` (2 subsequent siblings) 7 siblings, 0 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:27 UTC (permalink / raw) To: cluster-devel.redhat.com Add a catch-all xattr handler at the end of ceph_xattr_handlers. Check for valid attribute names there, and remove those checks from __ceph_{get,set,remove}xattr instead. No "system.*" xattrs need to be handled by the catch-all handler anymore. The set xattr handler is called with a NULL value to indicate that the attribute should be removed; __ceph_setxattr already handles that case correctly (ceph_set_acl could already calling __ceph_setxattr with a NULL value). Move the check for snapshots from ceph_{set,remove}xattr into __ceph_{set,remove}xattr. With that, ceph_{get,set,remove}xattr can be replaced with the generic iops. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: "Yan, Zheng" <zyan@redhat.com> --- fs/ceph/dir.c | 7 +++--- fs/ceph/inode.c | 13 ++++++------ fs/ceph/super.h | 4 ---- fs/ceph/xattr.c | 66 +++++++++++++++++++++++---------------------------------- 4 files changed, 38 insertions(+), 52 deletions(-) diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index fadc243..2e0afdc 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -5,6 +5,7 @@ #include <linux/namei.h> #include <linux/slab.h> #include <linux/sched.h> +#include <linux/xattr.h> #include "super.h" #include "mds_client.h" @@ -1342,10 +1343,10 @@ const struct inode_operations ceph_dir_iops = { .permission = ceph_permission, .getattr = ceph_getattr, .setattr = ceph_setattr, - .setxattr = ceph_setxattr, - .getxattr = ceph_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = ceph_listxattr, - .removexattr = ceph_removexattr, + .removexattr = generic_removexattr, .get_acl = ceph_get_acl, .set_acl = ceph_set_acl, .mknod = ceph_mknod, diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index cadb6ae..addf8ef 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -8,6 +8,7 @@ #include <linux/kernel.h> #include <linux/writeback.h> #include <linux/vmalloc.h> +#include <linux/xattr.h> #include <linux/posix_acl.h> #include <linux/random.h> @@ -92,10 +93,10 @@ const struct inode_operations ceph_file_iops = { .permission = ceph_permission, .setattr = ceph_setattr, .getattr = ceph_getattr, - .setxattr = ceph_setxattr, - .getxattr = ceph_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = ceph_listxattr, - .removexattr = ceph_removexattr, + .removexattr = generic_removexattr, .get_acl = ceph_get_acl, .set_acl = ceph_set_acl, }; @@ -1770,10 +1771,10 @@ static const struct inode_operations ceph_symlink_iops = { .get_link = simple_get_link, .setattr = ceph_setattr, .getattr = ceph_getattr, - .setxattr = ceph_setxattr, - .getxattr = ceph_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = ceph_listxattr, - .removexattr = ceph_removexattr, + .removexattr = generic_removexattr, }; int __ceph_setattr(struct inode *inode, struct iattr *attr) diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 1e41bc2..7b99eb7 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -791,13 +791,9 @@ extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); /* xattr.c */ -extern int ceph_setxattr(struct dentry *, const char *, const void *, - size_t, int); int __ceph_setxattr(struct inode *, const char *, const void *, size_t, int); ssize_t __ceph_getxattr(struct inode *, const char *, void *, size_t); -extern ssize_t ceph_getxattr(struct dentry *, struct inode *, const char *, void *, size_t); extern ssize_t ceph_listxattr(struct dentry *, char *, size_t); -extern int ceph_removexattr(struct dentry *, const char *); extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci); extern void __ceph_destroy_xattrs(struct ceph_inode_info *ci); extern void __init ceph_xattr_init(void); diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 248e32e3..8966e9d 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -16,6 +16,8 @@ static int __remove_xattr(struct ceph_inode_info *ci, struct ceph_inode_xattr *xattr); +const struct xattr_handler ceph_other_xattr_handler; + /* * List of handlers for synthetic system.* attributes. Other * attributes are handled directly. @@ -25,6 +27,7 @@ const struct xattr_handler *ceph_xattr_handlers[] = { &posix_acl_access_xattr_handler, &posix_acl_default_xattr_handler, #endif + &ceph_other_xattr_handler, NULL, }; @@ -33,7 +36,6 @@ static bool ceph_is_valid_xattr(const char *name) return !strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN) || !strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) || - !strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) || !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) || !strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); } @@ -740,9 +742,6 @@ ssize_t __ceph_getxattr(struct inode *inode, const char *name, void *value, int req_mask; int err; - if (!ceph_is_valid_xattr(name)) - return -ENODATA; - /* let's see if a virtual xattr was requested */ vxattr = ceph_match_vxattr(inode, name); if (vxattr) { @@ -804,15 +803,6 @@ out: return err; } -ssize_t ceph_getxattr(struct dentry *dentry, struct inode *inode, - const char *name, void *value, size_t size) -{ - if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) - return generic_getxattr(dentry, inode, name, value, size); - - return __ceph_getxattr(inode, name, value, size); -} - ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size) { struct inode *inode = d_inode(dentry); @@ -956,8 +946,8 @@ int __ceph_setxattr(struct inode *inode, const char *name, int required_blob_size; bool lock_snap_rwsem = false; - if (!ceph_is_valid_xattr(name)) - return -EOPNOTSUPP; + if (ceph_snap(inode) != CEPH_NOSNAP) + return -EROFS; vxattr = ceph_match_vxattr(inode, name); if (vxattr && vxattr->readonly) @@ -1064,21 +1054,6 @@ out: return err; } -int ceph_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) -{ - if (ceph_snap(d_inode(dentry)) != CEPH_NOSNAP) - return -EROFS; - - if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) - return generic_setxattr(dentry, name, value, size, flags); - - if (size == 0) - value = ""; /* empty EA, do not remove */ - - return __ceph_setxattr(d_inode(dentry), name, value, size, flags); -} - static int ceph_send_removexattr(struct inode *inode, const char *name) { struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb); @@ -1115,8 +1090,8 @@ static int __ceph_removexattr(struct inode *inode, const char *name) int dirty; bool lock_snap_rwsem = false; - if (!ceph_is_valid_xattr(name)) - return -EOPNOTSUPP; + if (ceph_snap(inode) != CEPH_NOSNAP) + return -EROFS; vxattr = ceph_match_vxattr(inode, name); if (vxattr && vxattr->readonly) @@ -1192,17 +1167,30 @@ do_sync_unlocked: return err; } -int ceph_removexattr(struct dentry *dentry, const char *name) +static int ceph_get_xattr_handler(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, void *value, size_t size) { - if (ceph_snap(d_inode(dentry)) != CEPH_NOSNAP) - return -EROFS; - - if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) - return generic_removexattr(dentry, name); + if (!ceph_is_valid_xattr(name)) + return -EOPNOTSUPP; + return __ceph_getxattr(inode, name, value, size); +} - return __ceph_removexattr(d_inode(dentry), name); +static int ceph_set_xattr_handler(const struct xattr_handler *handler, + struct dentry *dentry, const char *name, + const void *value, size_t size, int flags) +{ + if (!ceph_is_valid_xattr(name)) + return -EOPNOTSUPP; + return __ceph_setxattr(d_inode(dentry), name, value, size, flags); } +const struct xattr_handler ceph_other_xattr_handler = { + .prefix = "", /* match any name => handlers called with full name */ + .get = ceph_get_xattr_handler, + .set = ceph_set_xattr_handler, +}; + #ifdef CONFIG_SECURITY bool ceph_security_xattr_wanted(struct inode *in) { -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 6/8] ceph: kill __ceph_removexattr() 2016-04-13 22:27 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher ` (4 preceding siblings ...) 2016-04-13 22:27 ` [Cluster-devel] [PATCH 5/8] ceph: Switch to generic xattr handlers Andreas Gruenbacher @ 2016-04-13 22:27 ` Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 7/8] posix acls: Export xattr_handler functions Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 8/8] gfs2: Switch to generic xattr handlers Andreas Gruenbacher 7 siblings, 0 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:27 UTC (permalink / raw) To: cluster-devel.redhat.com From: "Yan, Zheng" <zyan@redhat.com> when removing a xattr, generic_removexattr() calls __ceph_setxattr() with NULL value and XATTR_REPLACE flag. __ceph_removexattr() is not used any more. Signed-off-by: "Yan, Zheng" <zyan@redhat.com> --- fs/ceph/xattr.c | 126 -------------------------------------------------------- 1 file changed, 126 deletions(-) diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 8966e9d..0d66722 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -498,19 +498,6 @@ static int __remove_xattr(struct ceph_inode_info *ci, return 0; } -static int __remove_xattr_by_name(struct ceph_inode_info *ci, - const char *name) -{ - struct rb_node **p; - struct ceph_inode_xattr *xattr; - int err; - - p = &ci->i_xattrs.index.rb_node; - xattr = __get_xattr(ci, name); - err = __remove_xattr(ci, xattr); - return err; -} - static char *__copy_xattr_names(struct ceph_inode_info *ci, char *dest) { @@ -1054,119 +1041,6 @@ out: return err; } -static int ceph_send_removexattr(struct inode *inode, const char *name) -{ - struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb); - struct ceph_mds_client *mdsc = fsc->mdsc; - struct ceph_mds_request *req; - int err; - - req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RMXATTR, - USE_AUTH_MDS); - if (IS_ERR(req)) - return PTR_ERR(req); - req->r_path2 = kstrdup(name, GFP_NOFS); - if (!req->r_path2) - return -ENOMEM; - - req->r_inode = inode; - ihold(inode); - req->r_num_caps = 1; - req->r_inode_drop = CEPH_CAP_XATTR_SHARED; - err = ceph_mdsc_do_request(mdsc, NULL, req); - ceph_mdsc_put_request(req); - return err; -} - -static int __ceph_removexattr(struct inode *inode, const char *name) -{ - struct ceph_vxattr *vxattr; - struct ceph_inode_info *ci = ceph_inode(inode); - struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; - struct ceph_cap_flush *prealloc_cf = NULL; - int issued; - int err; - int required_blob_size; - int dirty; - bool lock_snap_rwsem = false; - - if (ceph_snap(inode) != CEPH_NOSNAP) - return -EROFS; - - vxattr = ceph_match_vxattr(inode, name); - if (vxattr && vxattr->readonly) - return -EOPNOTSUPP; - - /* pass any unhandled ceph.* xattrs through to the MDS */ - if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN)) - goto do_sync_unlocked; - - prealloc_cf = ceph_alloc_cap_flush(); - if (!prealloc_cf) - return -ENOMEM; - - err = -ENOMEM; - spin_lock(&ci->i_ceph_lock); -retry: - issued = __ceph_caps_issued(ci, NULL); - if (ci->i_xattrs.version == 0 || !(issued & CEPH_CAP_XATTR_EXCL)) - goto do_sync; - - if (!lock_snap_rwsem && !ci->i_head_snapc) { - lock_snap_rwsem = true; - if (!down_read_trylock(&mdsc->snap_rwsem)) { - spin_unlock(&ci->i_ceph_lock); - down_read(&mdsc->snap_rwsem); - spin_lock(&ci->i_ceph_lock); - goto retry; - } - } - - dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued)); - - __build_xattrs(inode); - - required_blob_size = __get_required_blob_size(ci, 0, 0); - - if (!ci->i_xattrs.prealloc_blob || - required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) { - struct ceph_buffer *blob; - - spin_unlock(&ci->i_ceph_lock); - dout(" preaallocating new blob size=%d\n", required_blob_size); - blob = ceph_buffer_new(required_blob_size, GFP_NOFS); - if (!blob) - goto do_sync_unlocked; - spin_lock(&ci->i_ceph_lock); - if (ci->i_xattrs.prealloc_blob) - ceph_buffer_put(ci->i_xattrs.prealloc_blob); - ci->i_xattrs.prealloc_blob = blob; - goto retry; - } - - err = __remove_xattr_by_name(ceph_inode(inode), name); - - dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL, - &prealloc_cf); - ci->i_xattrs.dirty = true; - inode->i_ctime = current_fs_time(inode->i_sb); - spin_unlock(&ci->i_ceph_lock); - if (lock_snap_rwsem) - up_read(&mdsc->snap_rwsem); - if (dirty) - __mark_inode_dirty(inode, dirty); - ceph_free_cap_flush(prealloc_cf); - return err; -do_sync: - spin_unlock(&ci->i_ceph_lock); -do_sync_unlocked: - if (lock_snap_rwsem) - up_read(&mdsc->snap_rwsem); - ceph_free_cap_flush(prealloc_cf); - err = ceph_send_removexattr(inode, name); - return err; -} - static int ceph_get_xattr_handler(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, void *value, size_t size) -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 7/8] posix acls: Export xattr_handler functions 2016-04-13 22:27 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher ` (5 preceding siblings ...) 2016-04-13 22:27 ` [Cluster-devel] [PATCH 6/8] ceph: kill __ceph_removexattr() Andreas Gruenbacher @ 2016-04-13 22:27 ` Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 8/8] gfs2: Switch to generic xattr handlers Andreas Gruenbacher 7 siblings, 0 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:27 UTC (permalink / raw) To: cluster-devel.redhat.com These functions are useful in filesystems like gfs2 which require pre-/postamble code around xattr operations. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Reviewed-by: Bob Peterson <rpeterso@redhat.com> --- fs/posix_acl.c | 9 ++++++--- include/linux/posix_acl_xattr.h | 8 ++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 2c60f17..1da2c63 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -795,7 +795,7 @@ posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl, } EXPORT_SYMBOL (posix_acl_to_xattr); -static int +int posix_acl_xattr_get(const struct xattr_handler *handler, struct dentry *unused, struct inode *inode, const char *name, void *value, size_t size) @@ -819,8 +819,9 @@ posix_acl_xattr_get(const struct xattr_handler *handler, return error; } +EXPORT_SYMBOL(posix_acl_xattr_get); -static int +int posix_acl_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, const char *name, const void *value, size_t size, int flags) @@ -856,12 +857,14 @@ out: posix_acl_release(acl); return ret; } +EXPORT_SYMBOL(posix_acl_xattr_set); -static bool +bool posix_acl_xattr_list(struct dentry *dentry) { return IS_POSIXACL(d_backing_inode(dentry)); } +EXPORT_SYMBOL(posix_acl_xattr_list); const struct xattr_handler posix_acl_access_xattr_handler = { .name = XATTR_NAME_POSIX_ACL_ACCESS, diff --git a/include/linux/posix_acl_xattr.h b/include/linux/posix_acl_xattr.h index e5e8ec4..c92607c 100644 --- a/include/linux/posix_acl_xattr.h +++ b/include/linux/posix_acl_xattr.h @@ -65,6 +65,14 @@ struct posix_acl *posix_acl_from_xattr(struct user_namespace *user_ns, int posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl, void *buffer, size_t size); +int posix_acl_xattr_get(const struct xattr_handler *handler, + struct dentry *unused, struct inode *inode, + const char *name, void *value, size_t size); +int posix_acl_xattr_set(const struct xattr_handler *handler, + struct dentry *dentry, const char *name, + const void *value, size_t size, int flags); +bool posix_acl_xattr_list(struct dentry *dentry); + extern const struct xattr_handler posix_acl_access_xattr_handler; extern const struct xattr_handler posix_acl_default_xattr_handler; -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 8/8] gfs2: Switch to generic xattr handlers 2016-04-13 22:27 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher ` (6 preceding siblings ...) 2016-04-13 22:27 ` [Cluster-devel] [PATCH 7/8] posix acls: Export xattr_handler functions Andreas Gruenbacher @ 2016-04-13 22:27 ` Andreas Gruenbacher 7 siblings, 0 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:27 UTC (permalink / raw) To: cluster-devel.redhat.com Move the pre- and postamble code in gfs2_{get,set,remove}xattr into the handlers in gfs2_xattr_handlers. Replace the generic POSIX ACL handlers in there with gfs2-specific versions that wrap the generic handlers into the pre- and postamble code. With that, gfs2_{get,set,remove}xattr can be removed and replaced with the generic inode operations. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Reviewed-by: Bob Peterson <rpeterso@redhat.com> --- fs/gfs2/inode.c | 78 +++++----------------------------------- fs/gfs2/xattr.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 109 insertions(+), 77 deletions(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 45f516ca..3398342 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -1948,66 +1948,6 @@ static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, return 0; } -static int gfs2_setxattr(struct dentry *dentry, const char *name, - const void *data, size_t size, int flags) -{ - struct inode *inode = d_inode(dentry); - struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_holder gh; - int ret; - - gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); - ret = gfs2_glock_nq(&gh); - if (ret == 0) { - ret = gfs2_rsqa_alloc(ip); - if (ret == 0) - ret = generic_setxattr(dentry, name, data, size, flags); - gfs2_glock_dq(&gh); - } - gfs2_holder_uninit(&gh); - return ret; -} - -static ssize_t gfs2_getxattr(struct dentry *dentry, struct inode *inode, - const char *name, void *data, size_t size) -{ - struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_holder gh; - int ret; - - /* For selinux during lookup */ - if (gfs2_glock_is_locked_by_me(ip->i_gl)) - return generic_getxattr(dentry, inode, name, data, size); - - gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); - ret = gfs2_glock_nq(&gh); - if (ret == 0) { - ret = generic_getxattr(dentry, inode, name, data, size); - gfs2_glock_dq(&gh); - } - gfs2_holder_uninit(&gh); - return ret; -} - -static int gfs2_removexattr(struct dentry *dentry, const char *name) -{ - struct inode *inode = d_inode(dentry); - struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_holder gh; - int ret; - - gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); - ret = gfs2_glock_nq(&gh); - if (ret == 0) { - ret = gfs2_rsqa_alloc(ip); - if (ret == 0) - ret = generic_removexattr(dentry, name); - gfs2_glock_dq(&gh); - } - gfs2_holder_uninit(&gh); - return ret; -} - static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, u64 start, u64 len) { @@ -2054,10 +1994,10 @@ const struct inode_operations gfs2_file_iops = { .permission = gfs2_permission, .setattr = gfs2_setattr, .getattr = gfs2_getattr, - .setxattr = gfs2_setxattr, - .getxattr = gfs2_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = gfs2_listxattr, - .removexattr = gfs2_removexattr, + .removexattr = generic_removexattr, .fiemap = gfs2_fiemap, .get_acl = gfs2_get_acl, .set_acl = gfs2_set_acl, @@ -2076,10 +2016,10 @@ const struct inode_operations gfs2_dir_iops = { .permission = gfs2_permission, .setattr = gfs2_setattr, .getattr = gfs2_getattr, - .setxattr = gfs2_setxattr, - .getxattr = gfs2_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = gfs2_listxattr, - .removexattr = gfs2_removexattr, + .removexattr = generic_removexattr, .fiemap = gfs2_fiemap, .get_acl = gfs2_get_acl, .set_acl = gfs2_set_acl, @@ -2092,10 +2032,10 @@ const struct inode_operations gfs2_symlink_iops = { .permission = gfs2_permission, .setattr = gfs2_setattr, .getattr = gfs2_getattr, - .setxattr = gfs2_setxattr, - .getxattr = gfs2_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = gfs2_listxattr, - .removexattr = gfs2_removexattr, + .removexattr = generic_removexattr, .fiemap = gfs2_fiemap, }; diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 619886b..92d5b4c 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c @@ -583,13 +583,11 @@ out: * * Returns: actual size of data on success, -errno on error */ -static int gfs2_xattr_get(const struct xattr_handler *handler, - struct dentry *unused, struct inode *inode, - const char *name, void *buffer, size_t size) +static int __gfs2_xattr_get(struct inode *inode, const char *name, + void *buffer, size_t size, int type) { struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_ea_location el; - int type = handler->flags; int error; if (!ip->i_eattr) @@ -611,6 +609,28 @@ static int gfs2_xattr_get(const struct xattr_handler *handler, return error; } +static int gfs2_xattr_get(const struct xattr_handler *handler, + struct dentry *unused, struct inode *inode, + const char *name, void *buffer, size_t size) +{ + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_holder gh; + int ret; + + /* For selinux during lookup */ + if (gfs2_glock_is_locked_by_me(ip->i_gl)) + return __gfs2_xattr_get(inode, name, buffer, size, handler->flags); + + gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); + ret = gfs2_glock_nq(&gh); + if (ret == 0) { + ret = __gfs2_xattr_get(inode, name, buffer, size, handler->flags); + gfs2_glock_dq(&gh); + } + gfs2_holder_uninit(&gh); + return ret; +} + /** * ea_alloc_blk - allocates a new block for extended attributes. * @ip: A pointer to the inode that's getting extended attributes @@ -1233,8 +1253,23 @@ static int gfs2_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { - return __gfs2_xattr_set(d_inode(dentry), name, value, - size, flags, handler->flags); + struct inode *inode = d_inode(dentry); + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_holder gh; + int ret; + + ret = gfs2_rsqa_alloc(ip); + if (ret) + return ret; + + gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); + ret = gfs2_glock_nq(&gh); + if (ret == 0) { + ret = __gfs2_xattr_set(inode, name, value, size, flags, handler->flags); + gfs2_glock_dq(&gh); + } + gfs2_holder_uninit(&gh); + return ret; } static int ea_dealloc_indirect(struct gfs2_inode *ip) @@ -1437,6 +1472,63 @@ out_quota: return error; } +static int gfs2_posix_acl_xattr_get(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, void *buffer, size_t size) +{ + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_holder gh; + int ret; + + /* For selinux during lookup */ + if (gfs2_glock_is_locked_by_me(ip->i_gl)) + return posix_acl_xattr_get(handler, dentry, inode, name, buffer, size); + + gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); + ret = gfs2_glock_nq(&gh); + if (ret == 0) { + ret = posix_acl_xattr_get(handler, dentry, inode, name, buffer, size); + gfs2_glock_dq(&gh); + } + gfs2_holder_uninit(&gh); + return ret; +} + +static int gfs2_posix_acl_xattr_set(const struct xattr_handler *handler, + struct dentry *dentry, const char *name, + const void *value, size_t size, int flags) +{ + struct inode *inode = d_inode(dentry); + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_holder gh; + int ret; + + gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); + ret = gfs2_glock_nq(&gh); + if (ret == 0) { + ret = posix_acl_xattr_set(handler, dentry, name, value, size, flags); + gfs2_glock_dq(&gh); + } + gfs2_holder_uninit(&gh); + return ret; +} + +static const struct xattr_handler gfs2_posix_acl_access_xattr_handler = { + .name = XATTR_NAME_POSIX_ACL_ACCESS, + .flags = ACL_TYPE_ACCESS, + .list = posix_acl_xattr_list, + .get = gfs2_posix_acl_xattr_get, + .set = gfs2_posix_acl_xattr_set, +}; + +static const struct xattr_handler gfs2_posix_acl_default_xattr_handler = { + .name = XATTR_NAME_POSIX_ACL_DEFAULT, + .flags = ACL_TYPE_DEFAULT, + .list = posix_acl_xattr_list, + .get = gfs2_posix_acl_xattr_get, + .set = gfs2_posix_acl_xattr_set, +}; + static const struct xattr_handler gfs2_xattr_user_handler = { .prefix = XATTR_USER_PREFIX, .flags = GFS2_EATYPE_USR, @@ -1454,8 +1546,8 @@ static const struct xattr_handler gfs2_xattr_security_handler = { const struct xattr_handler *gfs2_xattr_handlers[] = { &gfs2_xattr_user_handler, &gfs2_xattr_security_handler, - &posix_acl_access_xattr_handler, - &posix_acl_default_xattr_handler, + &gfs2_posix_acl_access_xattr_handler, + &gfs2_posix_acl_default_xattr_handler, NULL, }; -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name [not found] <20160413182026.GR25498@ZenIV.linux.org.uk> 2016-04-13 22:27 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher @ 2016-04-13 22:30 ` Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks Andreas Gruenbacher ` (7 more replies) 1 sibling, 8 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:30 UTC (permalink / raw) To: cluster-devel.redhat.com On Wed, Apr 13, 2016 at 8:20 PM, Al Viro <viro@zeniv.linux.org.uk> wrote: > On Wed, Apr 13, 2016 at 05:40:34PM +0200, Andreas Gruenbacher wrote: >> Export xattr_resolve_name and make it easier to use by filesystems. >> Use it to remove reiserfs's own copy of the same functionality. > > Nah - I've switched that sucker to generic_*xattr() already. See > #work.xattr for the current state (commit 79a628d14 in there, should > propagate in a few). Sorry, should've pushed that last week... Okay, here are some more xattr-related patches. Andreas Andreas Gruenbacher (7): cifs: Fix xattr name checks cifs: Check for equality with ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT cifs: Fix removexattr for os2.* xattrs ceph: Get rid of d_find_alias in ceph_set_acl ceph: Switch to generic xattr handlers posix acls: Export xattr_handler functions gfs2: Switch to generic xattr handlers Yan, Zheng (1): ceph: kill __ceph_removexattr() fs/ceph/acl.c | 14 ++- fs/ceph/dir.c | 7 +- fs/ceph/inode.c | 29 +++--- fs/ceph/super.h | 8 +- fs/ceph/xattr.c | 192 ++++++---------------------------------- fs/cifs/cifssmb.c | 4 +- fs/cifs/xattr.c | 50 +++++------ fs/gfs2/inode.c | 78 ++-------------- fs/gfs2/xattr.c | 108 ++++++++++++++++++++-- fs/posix_acl.c | 9 +- include/linux/posix_acl_xattr.h | 8 ++ 11 files changed, 203 insertions(+), 304 deletions(-) -- 2.4.11 ^ permalink raw reply [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks 2016-04-13 22:30 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher @ 2016-04-13 22:30 ` Andreas Gruenbacher 2016-04-14 4:26 ` Steve French 2016-04-13 22:30 ` [Cluster-devel] [PATCH 2/8] cifs: Check for equality with ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT Andreas Gruenbacher ` (6 subsequent siblings) 7 siblings, 1 reply; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:30 UTC (permalink / raw) To: cluster-devel.redhat.com Use strcmp(str, name) instead of strncmp(str, name, strlen(name)) for checking if str and name are the same (as opposed to name being a prefix of str) in the gexattr and setxattr inode operations. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> --- fs/cifs/xattr.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 5d57c85..6e73ba9 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -129,7 +129,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, == 0) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) goto set_ea_exit; - if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) + if (strcmp(ea_name, CIFS_XATTR_DOS_ATTRIB) == 0) cifs_dbg(FYI, "attempt to set cifs inode metadata\n"); ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */ @@ -147,8 +147,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, rc = pTcon->ses->server->ops->set_EA(xid, pTcon, full_path, ea_name, ea_value, (__u16)value_size, cifs_sb->local_nls, cifs_remap(cifs_sb)); - } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL, - strlen(CIFS_XATTR_CIFS_ACL)) == 0) { + } else if (strcmp(ea_name, CIFS_XATTR_CIFS_ACL) == 0) { #ifdef CONFIG_CIFS_ACL struct cifs_ntsd *pacl; pacl = kmalloc(value_size, GFP_KERNEL); @@ -170,10 +169,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, cifs_dbg(FYI, "Set CIFS ACL not supported yet\n"); #endif /* CONFIG_CIFS_ACL */ } else { - int temp; - temp = strncmp(ea_name, XATTR_NAME_POSIX_ACL_ACCESS, - strlen(XATTR_NAME_POSIX_ACL_ACCESS)); - if (temp == 0) { + if (strcmp(ea_name, XATTR_NAME_POSIX_ACL_ACCESS) == 0) { #ifdef CONFIG_CIFS_POSIX if (sb->s_flags & MS_POSIXACL) rc = CIFSSMBSetPosixACL(xid, pTcon, full_path, @@ -184,8 +180,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, #else cifs_dbg(FYI, "set POSIX ACL not supported\n"); #endif - } else if (strncmp(ea_name, XATTR_NAME_POSIX_ACL_DEFAULT, - strlen(XATTR_NAME_POSIX_ACL_DEFAULT)) == 0) { + } else if (strcmp(ea_name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0) { #ifdef CONFIG_CIFS_POSIX if (sb->s_flags & MS_POSIXACL) rc = CIFSSMBSetPosixACL(xid, pTcon, full_path, @@ -246,7 +241,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, struct inode *inode, if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) goto get_ea_exit; - if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) { + if (strcmp(ea_name, CIFS_XATTR_DOS_ATTRIB) == 0) { cifs_dbg(FYI, "attempt to query cifs inode metadata\n"); /* revalidate/getattr then populate from inode */ } /* BB add else when above is implemented */ @@ -264,8 +259,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, struct inode *inode, rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon, full_path, ea_name, ea_value, buf_size, cifs_sb->local_nls, cifs_remap(cifs_sb)); - } else if (strncmp(ea_name, XATTR_NAME_POSIX_ACL_ACCESS, - strlen(XATTR_NAME_POSIX_ACL_ACCESS)) == 0) { + } else if (strcmp(ea_name, XATTR_NAME_POSIX_ACL_ACCESS) == 0) { #ifdef CONFIG_CIFS_POSIX if (sb->s_flags & MS_POSIXACL) rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, @@ -275,8 +269,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, struct inode *inode, #else cifs_dbg(FYI, "Query POSIX ACL not supported yet\n"); #endif /* CONFIG_CIFS_POSIX */ - } else if (strncmp(ea_name, XATTR_NAME_POSIX_ACL_DEFAULT, - strlen(XATTR_NAME_POSIX_ACL_DEFAULT)) == 0) { + } else if (strcmp(ea_name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0) { #ifdef CONFIG_CIFS_POSIX if (sb->s_flags & MS_POSIXACL) rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, @@ -286,8 +279,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, struct inode *inode, #else cifs_dbg(FYI, "Query POSIX default ACL not supported yet\n"); #endif /* CONFIG_CIFS_POSIX */ - } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL, - strlen(CIFS_XATTR_CIFS_ACL)) == 0) { + } else if (strcmp(ea_name, CIFS_XATTR_CIFS_ACL) == 0) { #ifdef CONFIG_CIFS_ACL u32 acllen; struct cifs_ntsd *pacl; -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks 2016-04-13 22:30 ` [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks Andreas Gruenbacher @ 2016-04-14 4:26 ` Steve French 2016-04-14 4:37 ` Al Viro 0 siblings, 1 reply; 26+ messages in thread From: Steve French @ 2016-04-14 4:26 UTC (permalink / raw) To: cluster-devel.redhat.com Thanks for spotting this - merged into cifs-2.6.git. checkpatch spotted and old indentation issue so I cleaned that up in a followon patch that I will send. On Wed, Apr 13, 2016 at 5:30 PM, Andreas Gruenbacher <agruenba@redhat.com> wrote: > Use strcmp(str, name) instead of strncmp(str, name, strlen(name)) for > checking if str and name are the same (as opposed to name being a prefix > of str) in the gexattr and setxattr inode operations. > > Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> > --- > fs/cifs/xattr.c | 24 ++++++++---------------- > 1 file changed, 8 insertions(+), 16 deletions(-) > > diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c > index 5d57c85..6e73ba9 100644 > --- a/fs/cifs/xattr.c > +++ b/fs/cifs/xattr.c > @@ -129,7 +129,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, > == 0) { > if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) > goto set_ea_exit; > - if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) > + if (strcmp(ea_name, CIFS_XATTR_DOS_ATTRIB) == 0) > cifs_dbg(FYI, "attempt to set cifs inode metadata\n"); > > ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */ > @@ -147,8 +147,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, > rc = pTcon->ses->server->ops->set_EA(xid, pTcon, > full_path, ea_name, ea_value, (__u16)value_size, > cifs_sb->local_nls, cifs_remap(cifs_sb)); > - } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL, > - strlen(CIFS_XATTR_CIFS_ACL)) == 0) { > + } else if (strcmp(ea_name, CIFS_XATTR_CIFS_ACL) == 0) { > #ifdef CONFIG_CIFS_ACL > struct cifs_ntsd *pacl; > pacl = kmalloc(value_size, GFP_KERNEL); > @@ -170,10 +169,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, > cifs_dbg(FYI, "Set CIFS ACL not supported yet\n"); > #endif /* CONFIG_CIFS_ACL */ > } else { > - int temp; > - temp = strncmp(ea_name, XATTR_NAME_POSIX_ACL_ACCESS, > - strlen(XATTR_NAME_POSIX_ACL_ACCESS)); > - if (temp == 0) { > + if (strcmp(ea_name, XATTR_NAME_POSIX_ACL_ACCESS) == 0) { > #ifdef CONFIG_CIFS_POSIX > if (sb->s_flags & MS_POSIXACL) > rc = CIFSSMBSetPosixACL(xid, pTcon, full_path, > @@ -184,8 +180,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, > #else > cifs_dbg(FYI, "set POSIX ACL not supported\n"); > #endif > - } else if (strncmp(ea_name, XATTR_NAME_POSIX_ACL_DEFAULT, > - strlen(XATTR_NAME_POSIX_ACL_DEFAULT)) == 0) { > + } else if (strcmp(ea_name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0) { > #ifdef CONFIG_CIFS_POSIX > if (sb->s_flags & MS_POSIXACL) > rc = CIFSSMBSetPosixACL(xid, pTcon, full_path, > @@ -246,7 +241,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, struct inode *inode, > if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) > goto get_ea_exit; > > - if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) { > + if (strcmp(ea_name, CIFS_XATTR_DOS_ATTRIB) == 0) { > cifs_dbg(FYI, "attempt to query cifs inode metadata\n"); > /* revalidate/getattr then populate from inode */ > } /* BB add else when above is implemented */ > @@ -264,8 +259,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, struct inode *inode, > rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon, > full_path, ea_name, ea_value, buf_size, > cifs_sb->local_nls, cifs_remap(cifs_sb)); > - } else if (strncmp(ea_name, XATTR_NAME_POSIX_ACL_ACCESS, > - strlen(XATTR_NAME_POSIX_ACL_ACCESS)) == 0) { > + } else if (strcmp(ea_name, XATTR_NAME_POSIX_ACL_ACCESS) == 0) { > #ifdef CONFIG_CIFS_POSIX > if (sb->s_flags & MS_POSIXACL) > rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, > @@ -275,8 +269,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, struct inode *inode, > #else > cifs_dbg(FYI, "Query POSIX ACL not supported yet\n"); > #endif /* CONFIG_CIFS_POSIX */ > - } else if (strncmp(ea_name, XATTR_NAME_POSIX_ACL_DEFAULT, > - strlen(XATTR_NAME_POSIX_ACL_DEFAULT)) == 0) { > + } else if (strcmp(ea_name, XATTR_NAME_POSIX_ACL_DEFAULT) == 0) { > #ifdef CONFIG_CIFS_POSIX > if (sb->s_flags & MS_POSIXACL) > rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, > @@ -286,8 +279,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, struct inode *inode, > #else > cifs_dbg(FYI, "Query POSIX default ACL not supported yet\n"); > #endif /* CONFIG_CIFS_POSIX */ > - } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL, > - strlen(CIFS_XATTR_CIFS_ACL)) == 0) { > + } else if (strcmp(ea_name, CIFS_XATTR_CIFS_ACL) == 0) { > #ifdef CONFIG_CIFS_ACL > u32 acllen; > struct cifs_ntsd *pacl; > -- > 2.4.11 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-cifs" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Thanks, Steve ^ permalink raw reply [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks 2016-04-14 4:26 ` Steve French @ 2016-04-14 4:37 ` Al Viro 2016-04-14 4:43 ` Steve French 0 siblings, 1 reply; 26+ messages in thread From: Al Viro @ 2016-04-14 4:37 UTC (permalink / raw) To: cluster-devel.redhat.com On Wed, Apr 13, 2016 at 11:26:24PM -0500, Steve French wrote: > Thanks for spotting this - merged into cifs-2.6.git. checkpatch > spotted and old indentation issue so I cleaned that up in a followon > patch that I will send. *ugh* And in the meanwhile I'd picked those into my queue... Could you put that stuff on a separate branch so that both cifs-2.6.git and vfs.git could merge it? ^ permalink raw reply [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks 2016-04-14 4:37 ` Al Viro @ 2016-04-14 4:43 ` Steve French 2016-04-14 4:49 ` Steve French 2016-04-14 4:59 ` Al Viro 0 siblings, 2 replies; 26+ messages in thread From: Steve French @ 2016-04-14 4:43 UTC (permalink / raw) To: cluster-devel.redhat.com If you are planning to merge it in next few weeks (they fix bugs, and are safe so why not), I can simply just back out my changes from cifs-2.6.git for-next branch and let you merge the trivial checkpatch cleanup attached. On Wed, Apr 13, 2016 at 11:37 PM, Al Viro <viro@zeniv.linux.org.uk> wrote: > On Wed, Apr 13, 2016 at 11:26:24PM -0500, Steve French wrote: >> Thanks for spotting this - merged into cifs-2.6.git. checkpatch >> spotted and old indentation issue so I cleaned that up in a followon >> patch that I will send. > > *ugh* > > And in the meanwhile I'd picked those into my queue... Could you put that > stuff on a separate branch so that both cifs-2.6.git and vfs.git could > merge it? -- Thanks, Steve -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-CIFS-Fix-formatting-issues-on-previous-patches-spott.patch Type: application/mbox Size: 2876 bytes Desc: not available URL: <http://listman.redhat.com/archives/cluster-devel/attachments/20160413/4720e3dd/attachment.mbox> ^ permalink raw reply [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks 2016-04-14 4:43 ` Steve French @ 2016-04-14 4:49 ` Steve French 2016-04-14 4:59 ` Al Viro 1 sibling, 0 replies; 26+ messages in thread From: Steve French @ 2016-04-14 4:49 UTC (permalink / raw) To: cluster-devel.redhat.com If you prefer merging those out of your tree, you can add my Reviewed-by if needed (for the three cifs patches) On Wed, Apr 13, 2016 at 11:43 PM, Steve French <smfrench@gmail.com> wrote: > If you are planning to merge it in next few weeks (they fix bugs, and > are safe so why not), I can simply just back out my changes from > cifs-2.6.git for-next branch and let you merge the trivial checkpatch > cleanup attached. > > On Wed, Apr 13, 2016 at 11:37 PM, Al Viro <viro@zeniv.linux.org.uk> wrote: >> On Wed, Apr 13, 2016 at 11:26:24PM -0500, Steve French wrote: >>> Thanks for spotting this - merged into cifs-2.6.git. checkpatch >>> spotted and old indentation issue so I cleaned that up in a followon >>> patch that I will send. >> >> *ugh* >> >> And in the meanwhile I'd picked those into my queue... Could you put that >> stuff on a separate branch so that both cifs-2.6.git and vfs.git could >> merge it? > > > > -- > Thanks, > > Steve -- Thanks, Steve ^ permalink raw reply [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks 2016-04-14 4:43 ` Steve French 2016-04-14 4:49 ` Steve French @ 2016-04-14 4:59 ` Al Viro 2016-04-15 3:01 ` Steve French 1 sibling, 1 reply; 26+ messages in thread From: Al Viro @ 2016-04-14 4:59 UTC (permalink / raw) To: cluster-devel.redhat.com On Wed, Apr 13, 2016 at 11:43:19PM -0500, Steve French wrote: > If you are planning to merge it in next few weeks (they fix bugs, and > are safe so why not), I can simply just back out my changes from > cifs-2.6.git for-next branch and let you merge the trivial checkpatch > cleanup attached. Do you want it in mainline before 4.6-final? If that can wait until 4.7-rc1 (and these are both old and not earth-shattering), I've no problem with putting the entire series (including cleanup) into a branch merged into vfs.git#for-next; if you consider it 4.6-final fodder, it's probably better be your pull request. PS: are there any docs re setup for cifs testing? ^ permalink raw reply [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks 2016-04-14 4:59 ` Al Viro @ 2016-04-15 3:01 ` Steve French 0 siblings, 0 replies; 26+ messages in thread From: Steve French @ 2016-04-15 3:01 UTC (permalink / raw) To: cluster-devel.redhat.com On Wed, Apr 13, 2016 at 11:59 PM, Al Viro <viro@zeniv.linux.org.uk> wrote: > On Wed, Apr 13, 2016 at 11:43:19PM -0500, Steve French wrote: >> If you are planning to merge it in next few weeks (they fix bugs, and >> are safe so why not), I can simply just back out my changes from >> cifs-2.6.git for-next branch and let you merge the trivial checkpatch >> cleanup attached. > > Do you want it in mainline before 4.6-final? If that can wait until 4.7-rc1 > (and these are both old and not earth-shattering), I've no problem with > putting the entire series (including cleanup) into a branch merged into > vfs.git#for-next; if you consider it 4.6-final fodder, it's probably better > be your pull request. They are old, but I don't mind taking care of them now, and seem low risk. > PS: are there any docs re setup for cifs testing? There are probably more but I have been using the page https://wiki.samba.org/index.php/Xfstesting-cifs cifs has more xfstest issues than NFS, but some of the same kinds of problems (caching of metadata time stamps e.g.) are similar. -- Thanks, Steve ^ permalink raw reply [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 2/8] cifs: Check for equality with ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT 2016-04-13 22:30 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks Andreas Gruenbacher @ 2016-04-13 22:30 ` Andreas Gruenbacher 2016-04-14 4:26 ` Steve French 2016-04-13 22:30 ` [Cluster-devel] [PATCH 3/8] cifs: Fix removexattr for os2.* xattrs Andreas Gruenbacher ` (5 subsequent siblings) 7 siblings, 1 reply; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:30 UTC (permalink / raw) To: cluster-devel.redhat.com The two values ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT are meant to be enumerations, not bits in a bit mask. Use '==' instead of '&' to check for these values. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> --- fs/cifs/cifssmb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 76fcb50..f24a89c 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -3366,7 +3366,7 @@ static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen, if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION) return -EOPNOTSUPP; - if (acl_type & ACL_TYPE_ACCESS) { + if (acl_type == ACL_TYPE_ACCESS) { count = le16_to_cpu(cifs_acl->access_entry_count); pACE = &cifs_acl->ace_array[0]; size = sizeof(struct cifs_posix_acl); @@ -3377,7 +3377,7 @@ static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen, size_of_data_area, size); return -EINVAL; } - } else if (acl_type & ACL_TYPE_DEFAULT) { + } else if (acl_type == ACL_TYPE_DEFAULT) { count = le16_to_cpu(cifs_acl->access_entry_count); size = sizeof(struct cifs_posix_acl); size += sizeof(struct cifs_posix_ace) * count; -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 2/8] cifs: Check for equality with ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT 2016-04-13 22:30 ` [Cluster-devel] [PATCH 2/8] cifs: Check for equality with ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT Andreas Gruenbacher @ 2016-04-14 4:26 ` Steve French 0 siblings, 0 replies; 26+ messages in thread From: Steve French @ 2016-04-14 4:26 UTC (permalink / raw) To: cluster-devel.redhat.com merged into cifs-2.6.git On Wed, Apr 13, 2016 at 5:30 PM, Andreas Gruenbacher <agruenba@redhat.com> wrote: > The two values ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT are meant to be > enumerations, not bits in a bit mask. Use '==' instead of '&' to check > for these values. > > Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> > --- > fs/cifs/cifssmb.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c > index 76fcb50..f24a89c 100644 > --- a/fs/cifs/cifssmb.c > +++ b/fs/cifs/cifssmb.c > @@ -3366,7 +3366,7 @@ static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen, > if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION) > return -EOPNOTSUPP; > > - if (acl_type & ACL_TYPE_ACCESS) { > + if (acl_type == ACL_TYPE_ACCESS) { > count = le16_to_cpu(cifs_acl->access_entry_count); > pACE = &cifs_acl->ace_array[0]; > size = sizeof(struct cifs_posix_acl); > @@ -3377,7 +3377,7 @@ static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen, > size_of_data_area, size); > return -EINVAL; > } > - } else if (acl_type & ACL_TYPE_DEFAULT) { > + } else if (acl_type == ACL_TYPE_DEFAULT) { > count = le16_to_cpu(cifs_acl->access_entry_count); > size = sizeof(struct cifs_posix_acl); > size += sizeof(struct cifs_posix_ace) * count; > -- > 2.4.11 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-cifs" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Thanks, Steve ^ permalink raw reply [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 3/8] cifs: Fix removexattr for os2.* xattrs 2016-04-13 22:30 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH 2/8] cifs: Check for equality with ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT Andreas Gruenbacher @ 2016-04-13 22:30 ` Andreas Gruenbacher 2016-04-14 4:27 ` Steve French 2016-04-13 22:30 ` [Cluster-devel] [PATCH 4/8] ceph: Get rid of d_find_alias in ceph_set_acl Andreas Gruenbacher ` (4 subsequent siblings) 7 siblings, 1 reply; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:30 UTC (permalink / raw) To: cluster-devel.redhat.com If cifs_removexattr finds a "user." or "os2." xattr name prefix, it skips 5 bytes, one byte too many for "os2.". Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> --- fs/cifs/xattr.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 6e73ba9..721c6db 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -61,15 +61,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name) } if (ea_name == NULL) { cifs_dbg(FYI, "Null xattr names not supported\n"); - } else if (strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) - && (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN))) { - cifs_dbg(FYI, - "illegal xattr request %s (only user namespace supported)\n", - ea_name); - /* BB what if no namespace prefix? */ - /* Should we just pass them to server, except for - system and perhaps security prefixes? */ - } else { + } else if (!strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) goto remove_ea_exit; @@ -78,6 +70,22 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name) rc = pTcon->ses->server->ops->set_EA(xid, pTcon, full_path, ea_name, NULL, (__u16)0, cifs_sb->local_nls, cifs_remap(cifs_sb)); + } else if (!strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) { + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) + goto remove_ea_exit; + + ea_name += XATTR_OS2_PREFIX_LEN; /* skip past os2. prefix */ + if (pTcon->ses->server->ops->set_EA) + rc = pTcon->ses->server->ops->set_EA(xid, pTcon, + full_path, ea_name, NULL, (__u16)0, + cifs_sb->local_nls, cifs_remap(cifs_sb)); + } else { + cifs_dbg(FYI, + "illegal xattr request %s (only user namespace supported)\n", + ea_name); + /* BB what if no namespace prefix? */ + /* Should we just pass them to server, except for + system and perhaps security prefixes? */ } remove_ea_exit: kfree(full_path); -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 3/8] cifs: Fix removexattr for os2.* xattrs 2016-04-13 22:30 ` [Cluster-devel] [PATCH 3/8] cifs: Fix removexattr for os2.* xattrs Andreas Gruenbacher @ 2016-04-14 4:27 ` Steve French 0 siblings, 0 replies; 26+ messages in thread From: Steve French @ 2016-04-14 4:27 UTC (permalink / raw) To: cluster-devel.redhat.com merged into cifs-2.6.git checkpatch complained about comment formatting so I cleaned that up in attached trivial followon patch. On Wed, Apr 13, 2016 at 5:30 PM, Andreas Gruenbacher <agruenba@redhat.com> wrote: > If cifs_removexattr finds a "user." or "os2." xattr name prefix, it > skips 5 bytes, one byte too many for "os2.". > > Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> > --- > fs/cifs/xattr.c | 26 +++++++++++++++++--------- > 1 file changed, 17 insertions(+), 9 deletions(-) > > diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c > index 6e73ba9..721c6db 100644 > --- a/fs/cifs/xattr.c > +++ b/fs/cifs/xattr.c > @@ -61,15 +61,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name) > } > if (ea_name == NULL) { > cifs_dbg(FYI, "Null xattr names not supported\n"); > - } else if (strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) > - && (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN))) { > - cifs_dbg(FYI, > - "illegal xattr request %s (only user namespace supported)\n", > - ea_name); > - /* BB what if no namespace prefix? */ > - /* Should we just pass them to server, except for > - system and perhaps security prefixes? */ > - } else { > + } else if (!strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { > if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) > goto remove_ea_exit; > > @@ -78,6 +70,22 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name) > rc = pTcon->ses->server->ops->set_EA(xid, pTcon, > full_path, ea_name, NULL, (__u16)0, > cifs_sb->local_nls, cifs_remap(cifs_sb)); > + } else if (!strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) { > + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) > + goto remove_ea_exit; > + > + ea_name += XATTR_OS2_PREFIX_LEN; /* skip past os2. prefix */ > + if (pTcon->ses->server->ops->set_EA) > + rc = pTcon->ses->server->ops->set_EA(xid, pTcon, > + full_path, ea_name, NULL, (__u16)0, > + cifs_sb->local_nls, cifs_remap(cifs_sb)); > + } else { > + cifs_dbg(FYI, > + "illegal xattr request %s (only user namespace supported)\n", > + ea_name); > + /* BB what if no namespace prefix? */ > + /* Should we just pass them to server, except for > + system and perhaps security prefixes? */ > } > remove_ea_exit: > kfree(full_path); > -- > 2.4.11 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-cifs" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Thanks, Steve -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-CIFS-Fix-formatting-issues-on-previous-patches-spott.patch Type: application/mbox Size: 2876 bytes Desc: not available URL: <http://listman.redhat.com/archives/cluster-devel/attachments/20160413/9afd70c0/attachment.mbox> ^ permalink raw reply [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 4/8] ceph: Get rid of d_find_alias in ceph_set_acl 2016-04-13 22:30 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher ` (2 preceding siblings ...) 2016-04-13 22:30 ` [Cluster-devel] [PATCH 3/8] cifs: Fix removexattr for os2.* xattrs Andreas Gruenbacher @ 2016-04-13 22:30 ` Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH 5/8] ceph: Switch to generic xattr handlers Andreas Gruenbacher ` (3 subsequent siblings) 7 siblings, 0 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:30 UTC (permalink / raw) To: cluster-devel.redhat.com Create a variant of ceph_setattr that takes an inode instead of a dentry. Change __ceph_setxattr (and also __ceph_removexattr) to take an inode instead of a dentry. Use those in ceph_set_acl so that we no longer need a dentry there. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: "Yan, Zheng" <zyan@redhat.com> --- fs/ceph/acl.c | 14 +++++--------- fs/ceph/inode.c | 16 ++++++++++------ fs/ceph/super.h | 4 ++-- fs/ceph/xattr.c | 28 ++++++++++++---------------- 4 files changed, 29 insertions(+), 33 deletions(-) diff --git a/fs/ceph/acl.c b/fs/ceph/acl.c index 5457f216..4f67227 100644 --- a/fs/ceph/acl.c +++ b/fs/ceph/acl.c @@ -90,7 +90,6 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type) char *value = NULL; struct iattr newattrs; umode_t new_mode = inode->i_mode, old_mode = inode->i_mode; - struct dentry *dentry; switch (type) { case ACL_TYPE_ACCESS: @@ -128,29 +127,26 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type) goto out_free; } - dentry = d_find_alias(inode); if (new_mode != old_mode) { newattrs.ia_mode = new_mode; newattrs.ia_valid = ATTR_MODE; - ret = ceph_setattr(dentry, &newattrs); + ret = __ceph_setattr(inode, &newattrs); if (ret) - goto out_dput; + goto out_free; } - ret = __ceph_setxattr(dentry, name, value, size, 0); + ret = __ceph_setxattr(inode, name, value, size, 0); if (ret) { if (new_mode != old_mode) { newattrs.ia_mode = old_mode; newattrs.ia_valid = ATTR_MODE; - ceph_setattr(dentry, &newattrs); + __ceph_setattr(inode, &newattrs); } - goto out_dput; + goto out_free; } ceph_set_cached_acl(inode, type, acl); -out_dput: - dput(dentry); out_free: kfree(value); out: diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index ed58b16..cadb6ae 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1776,16 +1776,12 @@ static const struct inode_operations ceph_symlink_iops = { .removexattr = ceph_removexattr, }; -/* - * setattr - */ -int ceph_setattr(struct dentry *dentry, struct iattr *attr) +int __ceph_setattr(struct inode *inode, struct iattr *attr) { - struct inode *inode = d_inode(dentry); struct ceph_inode_info *ci = ceph_inode(inode); const unsigned int ia_valid = attr->ia_valid; struct ceph_mds_request *req; - struct ceph_mds_client *mdsc = ceph_sb_to_client(dentry->d_sb)->mdsc; + struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; struct ceph_cap_flush *prealloc_cf; int issued; int release = 0, dirtied = 0; @@ -2010,6 +2006,14 @@ out_put: } /* + * setattr + */ +int ceph_setattr(struct dentry *dentry, struct iattr *attr) +{ + return __ceph_setattr(d_inode(dentry), attr); +} + +/* * Verify that we have a lease on the given mask. If not, * do a getattr against an mds. */ diff --git a/fs/ceph/super.h b/fs/ceph/super.h index beb893b..1e41bc2 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -785,6 +785,7 @@ static inline int ceph_do_getattr(struct inode *inode, int mask, bool force) return __ceph_do_getattr(inode, NULL, mask, force); } extern int ceph_permission(struct inode *inode, int mask); +extern int __ceph_setattr(struct inode *inode, struct iattr *attr); extern int ceph_setattr(struct dentry *dentry, struct iattr *attr); extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); @@ -792,9 +793,8 @@ extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, /* xattr.c */ extern int ceph_setxattr(struct dentry *, const char *, const void *, size_t, int); -int __ceph_setxattr(struct dentry *, const char *, const void *, size_t, int); +int __ceph_setxattr(struct inode *, const char *, const void *, size_t, int); ssize_t __ceph_getxattr(struct inode *, const char *, void *, size_t); -int __ceph_removexattr(struct dentry *, const char *); extern ssize_t ceph_getxattr(struct dentry *, struct inode *, const char *, void *, size_t); extern ssize_t ceph_listxattr(struct dentry *, char *, size_t); extern int ceph_removexattr(struct dentry *, const char *); diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index c6e917d..248e32e3 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -877,11 +877,10 @@ out: return err; } -static int ceph_sync_setxattr(struct dentry *dentry, const char *name, +static int ceph_sync_setxattr(struct inode *inode, const char *name, const char *value, size_t size, int flags) { - struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb); - struct inode *inode = d_inode(dentry); + struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb); struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_mds_request *req; struct ceph_mds_client *mdsc = fsc->mdsc; @@ -939,13 +938,12 @@ out: return err; } -int __ceph_setxattr(struct dentry *dentry, const char *name, +int __ceph_setxattr(struct inode *inode, const char *name, const void *value, size_t size, int flags) { - struct inode *inode = d_inode(dentry); struct ceph_vxattr *vxattr; struct ceph_inode_info *ci = ceph_inode(inode); - struct ceph_mds_client *mdsc = ceph_sb_to_client(dentry->d_sb)->mdsc; + struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; struct ceph_cap_flush *prealloc_cf = NULL; int issued; int err; @@ -1056,7 +1054,7 @@ do_sync_unlocked: "during filling trace\n", inode); err = -EBUSY; } else { - err = ceph_sync_setxattr(dentry, name, value, size, flags); + err = ceph_sync_setxattr(inode, name, value, size, flags); } out: ceph_free_cap_flush(prealloc_cf); @@ -1078,14 +1076,13 @@ int ceph_setxattr(struct dentry *dentry, const char *name, if (size == 0) value = ""; /* empty EA, do not remove */ - return __ceph_setxattr(dentry, name, value, size, flags); + return __ceph_setxattr(d_inode(dentry), name, value, size, flags); } -static int ceph_send_removexattr(struct dentry *dentry, const char *name) +static int ceph_send_removexattr(struct inode *inode, const char *name) { - struct ceph_fs_client *fsc = ceph_sb_to_client(dentry->d_sb); + struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb); struct ceph_mds_client *mdsc = fsc->mdsc; - struct inode *inode = d_inode(dentry); struct ceph_mds_request *req; int err; @@ -1106,12 +1103,11 @@ static int ceph_send_removexattr(struct dentry *dentry, const char *name) return err; } -int __ceph_removexattr(struct dentry *dentry, const char *name) +static int __ceph_removexattr(struct inode *inode, const char *name) { - struct inode *inode = d_inode(dentry); struct ceph_vxattr *vxattr; struct ceph_inode_info *ci = ceph_inode(inode); - struct ceph_mds_client *mdsc = ceph_sb_to_client(dentry->d_sb)->mdsc; + struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; struct ceph_cap_flush *prealloc_cf = NULL; int issued; int err; @@ -1192,7 +1188,7 @@ do_sync_unlocked: if (lock_snap_rwsem) up_read(&mdsc->snap_rwsem); ceph_free_cap_flush(prealloc_cf); - err = ceph_send_removexattr(dentry, name); + err = ceph_send_removexattr(inode, name); return err; } @@ -1204,7 +1200,7 @@ int ceph_removexattr(struct dentry *dentry, const char *name) if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) return generic_removexattr(dentry, name); - return __ceph_removexattr(dentry, name); + return __ceph_removexattr(d_inode(dentry), name); } #ifdef CONFIG_SECURITY -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 5/8] ceph: Switch to generic xattr handlers 2016-04-13 22:30 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher ` (3 preceding siblings ...) 2016-04-13 22:30 ` [Cluster-devel] [PATCH 4/8] ceph: Get rid of d_find_alias in ceph_set_acl Andreas Gruenbacher @ 2016-04-13 22:30 ` Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH 6/8] ceph: kill __ceph_removexattr() Andreas Gruenbacher ` (2 subsequent siblings) 7 siblings, 0 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:30 UTC (permalink / raw) To: cluster-devel.redhat.com Add a catch-all xattr handler at the end of ceph_xattr_handlers. Check for valid attribute names there, and remove those checks from __ceph_{get,set,remove}xattr instead. No "system.*" xattrs need to be handled by the catch-all handler anymore. The set xattr handler is called with a NULL value to indicate that the attribute should be removed; __ceph_setxattr already handles that case correctly (ceph_set_acl could already calling __ceph_setxattr with a NULL value). Move the check for snapshots from ceph_{set,remove}xattr into __ceph_{set,remove}xattr. With that, ceph_{get,set,remove}xattr can be replaced with the generic iops. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: "Yan, Zheng" <zyan@redhat.com> --- fs/ceph/dir.c | 7 +++--- fs/ceph/inode.c | 13 ++++++------ fs/ceph/super.h | 4 ---- fs/ceph/xattr.c | 66 +++++++++++++++++++++++---------------------------------- 4 files changed, 38 insertions(+), 52 deletions(-) diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index fadc243..2e0afdc 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -5,6 +5,7 @@ #include <linux/namei.h> #include <linux/slab.h> #include <linux/sched.h> +#include <linux/xattr.h> #include "super.h" #include "mds_client.h" @@ -1342,10 +1343,10 @@ const struct inode_operations ceph_dir_iops = { .permission = ceph_permission, .getattr = ceph_getattr, .setattr = ceph_setattr, - .setxattr = ceph_setxattr, - .getxattr = ceph_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = ceph_listxattr, - .removexattr = ceph_removexattr, + .removexattr = generic_removexattr, .get_acl = ceph_get_acl, .set_acl = ceph_set_acl, .mknod = ceph_mknod, diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index cadb6ae..addf8ef 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -8,6 +8,7 @@ #include <linux/kernel.h> #include <linux/writeback.h> #include <linux/vmalloc.h> +#include <linux/xattr.h> #include <linux/posix_acl.h> #include <linux/random.h> @@ -92,10 +93,10 @@ const struct inode_operations ceph_file_iops = { .permission = ceph_permission, .setattr = ceph_setattr, .getattr = ceph_getattr, - .setxattr = ceph_setxattr, - .getxattr = ceph_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = ceph_listxattr, - .removexattr = ceph_removexattr, + .removexattr = generic_removexattr, .get_acl = ceph_get_acl, .set_acl = ceph_set_acl, }; @@ -1770,10 +1771,10 @@ static const struct inode_operations ceph_symlink_iops = { .get_link = simple_get_link, .setattr = ceph_setattr, .getattr = ceph_getattr, - .setxattr = ceph_setxattr, - .getxattr = ceph_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = ceph_listxattr, - .removexattr = ceph_removexattr, + .removexattr = generic_removexattr, }; int __ceph_setattr(struct inode *inode, struct iattr *attr) diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 1e41bc2..7b99eb7 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -791,13 +791,9 @@ extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); /* xattr.c */ -extern int ceph_setxattr(struct dentry *, const char *, const void *, - size_t, int); int __ceph_setxattr(struct inode *, const char *, const void *, size_t, int); ssize_t __ceph_getxattr(struct inode *, const char *, void *, size_t); -extern ssize_t ceph_getxattr(struct dentry *, struct inode *, const char *, void *, size_t); extern ssize_t ceph_listxattr(struct dentry *, char *, size_t); -extern int ceph_removexattr(struct dentry *, const char *); extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci); extern void __ceph_destroy_xattrs(struct ceph_inode_info *ci); extern void __init ceph_xattr_init(void); diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 248e32e3..8966e9d 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -16,6 +16,8 @@ static int __remove_xattr(struct ceph_inode_info *ci, struct ceph_inode_xattr *xattr); +const struct xattr_handler ceph_other_xattr_handler; + /* * List of handlers for synthetic system.* attributes. Other * attributes are handled directly. @@ -25,6 +27,7 @@ const struct xattr_handler *ceph_xattr_handlers[] = { &posix_acl_access_xattr_handler, &posix_acl_default_xattr_handler, #endif + &ceph_other_xattr_handler, NULL, }; @@ -33,7 +36,6 @@ static bool ceph_is_valid_xattr(const char *name) return !strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN) || !strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) || - !strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) || !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) || !strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); } @@ -740,9 +742,6 @@ ssize_t __ceph_getxattr(struct inode *inode, const char *name, void *value, int req_mask; int err; - if (!ceph_is_valid_xattr(name)) - return -ENODATA; - /* let's see if a virtual xattr was requested */ vxattr = ceph_match_vxattr(inode, name); if (vxattr) { @@ -804,15 +803,6 @@ out: return err; } -ssize_t ceph_getxattr(struct dentry *dentry, struct inode *inode, - const char *name, void *value, size_t size) -{ - if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) - return generic_getxattr(dentry, inode, name, value, size); - - return __ceph_getxattr(inode, name, value, size); -} - ssize_t ceph_listxattr(struct dentry *dentry, char *names, size_t size) { struct inode *inode = d_inode(dentry); @@ -956,8 +946,8 @@ int __ceph_setxattr(struct inode *inode, const char *name, int required_blob_size; bool lock_snap_rwsem = false; - if (!ceph_is_valid_xattr(name)) - return -EOPNOTSUPP; + if (ceph_snap(inode) != CEPH_NOSNAP) + return -EROFS; vxattr = ceph_match_vxattr(inode, name); if (vxattr && vxattr->readonly) @@ -1064,21 +1054,6 @@ out: return err; } -int ceph_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) -{ - if (ceph_snap(d_inode(dentry)) != CEPH_NOSNAP) - return -EROFS; - - if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) - return generic_setxattr(dentry, name, value, size, flags); - - if (size == 0) - value = ""; /* empty EA, do not remove */ - - return __ceph_setxattr(d_inode(dentry), name, value, size, flags); -} - static int ceph_send_removexattr(struct inode *inode, const char *name) { struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb); @@ -1115,8 +1090,8 @@ static int __ceph_removexattr(struct inode *inode, const char *name) int dirty; bool lock_snap_rwsem = false; - if (!ceph_is_valid_xattr(name)) - return -EOPNOTSUPP; + if (ceph_snap(inode) != CEPH_NOSNAP) + return -EROFS; vxattr = ceph_match_vxattr(inode, name); if (vxattr && vxattr->readonly) @@ -1192,17 +1167,30 @@ do_sync_unlocked: return err; } -int ceph_removexattr(struct dentry *dentry, const char *name) +static int ceph_get_xattr_handler(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, void *value, size_t size) { - if (ceph_snap(d_inode(dentry)) != CEPH_NOSNAP) - return -EROFS; - - if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) - return generic_removexattr(dentry, name); + if (!ceph_is_valid_xattr(name)) + return -EOPNOTSUPP; + return __ceph_getxattr(inode, name, value, size); +} - return __ceph_removexattr(d_inode(dentry), name); +static int ceph_set_xattr_handler(const struct xattr_handler *handler, + struct dentry *dentry, const char *name, + const void *value, size_t size, int flags) +{ + if (!ceph_is_valid_xattr(name)) + return -EOPNOTSUPP; + return __ceph_setxattr(d_inode(dentry), name, value, size, flags); } +const struct xattr_handler ceph_other_xattr_handler = { + .prefix = "", /* match any name => handlers called with full name */ + .get = ceph_get_xattr_handler, + .set = ceph_set_xattr_handler, +}; + #ifdef CONFIG_SECURITY bool ceph_security_xattr_wanted(struct inode *in) { -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 6/8] ceph: kill __ceph_removexattr() 2016-04-13 22:30 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher ` (4 preceding siblings ...) 2016-04-13 22:30 ` [Cluster-devel] [PATCH 5/8] ceph: Switch to generic xattr handlers Andreas Gruenbacher @ 2016-04-13 22:30 ` Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH 7/8] posix acls: Export xattr_handler functions Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH 8/8] gfs2: Switch to generic xattr handlers Andreas Gruenbacher 7 siblings, 0 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:30 UTC (permalink / raw) To: cluster-devel.redhat.com From: "Yan, Zheng" <zyan@redhat.com> when removing a xattr, generic_removexattr() calls __ceph_setxattr() with NULL value and XATTR_REPLACE flag. __ceph_removexattr() is not used any more. Signed-off-by: "Yan, Zheng" <zyan@redhat.com> --- fs/ceph/xattr.c | 126 -------------------------------------------------------- 1 file changed, 126 deletions(-) diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 8966e9d..0d66722 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -498,19 +498,6 @@ static int __remove_xattr(struct ceph_inode_info *ci, return 0; } -static int __remove_xattr_by_name(struct ceph_inode_info *ci, - const char *name) -{ - struct rb_node **p; - struct ceph_inode_xattr *xattr; - int err; - - p = &ci->i_xattrs.index.rb_node; - xattr = __get_xattr(ci, name); - err = __remove_xattr(ci, xattr); - return err; -} - static char *__copy_xattr_names(struct ceph_inode_info *ci, char *dest) { @@ -1054,119 +1041,6 @@ out: return err; } -static int ceph_send_removexattr(struct inode *inode, const char *name) -{ - struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb); - struct ceph_mds_client *mdsc = fsc->mdsc; - struct ceph_mds_request *req; - int err; - - req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_RMXATTR, - USE_AUTH_MDS); - if (IS_ERR(req)) - return PTR_ERR(req); - req->r_path2 = kstrdup(name, GFP_NOFS); - if (!req->r_path2) - return -ENOMEM; - - req->r_inode = inode; - ihold(inode); - req->r_num_caps = 1; - req->r_inode_drop = CEPH_CAP_XATTR_SHARED; - err = ceph_mdsc_do_request(mdsc, NULL, req); - ceph_mdsc_put_request(req); - return err; -} - -static int __ceph_removexattr(struct inode *inode, const char *name) -{ - struct ceph_vxattr *vxattr; - struct ceph_inode_info *ci = ceph_inode(inode); - struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; - struct ceph_cap_flush *prealloc_cf = NULL; - int issued; - int err; - int required_blob_size; - int dirty; - bool lock_snap_rwsem = false; - - if (ceph_snap(inode) != CEPH_NOSNAP) - return -EROFS; - - vxattr = ceph_match_vxattr(inode, name); - if (vxattr && vxattr->readonly) - return -EOPNOTSUPP; - - /* pass any unhandled ceph.* xattrs through to the MDS */ - if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN)) - goto do_sync_unlocked; - - prealloc_cf = ceph_alloc_cap_flush(); - if (!prealloc_cf) - return -ENOMEM; - - err = -ENOMEM; - spin_lock(&ci->i_ceph_lock); -retry: - issued = __ceph_caps_issued(ci, NULL); - if (ci->i_xattrs.version == 0 || !(issued & CEPH_CAP_XATTR_EXCL)) - goto do_sync; - - if (!lock_snap_rwsem && !ci->i_head_snapc) { - lock_snap_rwsem = true; - if (!down_read_trylock(&mdsc->snap_rwsem)) { - spin_unlock(&ci->i_ceph_lock); - down_read(&mdsc->snap_rwsem); - spin_lock(&ci->i_ceph_lock); - goto retry; - } - } - - dout("removexattr %p issued %s\n", inode, ceph_cap_string(issued)); - - __build_xattrs(inode); - - required_blob_size = __get_required_blob_size(ci, 0, 0); - - if (!ci->i_xattrs.prealloc_blob || - required_blob_size > ci->i_xattrs.prealloc_blob->alloc_len) { - struct ceph_buffer *blob; - - spin_unlock(&ci->i_ceph_lock); - dout(" preaallocating new blob size=%d\n", required_blob_size); - blob = ceph_buffer_new(required_blob_size, GFP_NOFS); - if (!blob) - goto do_sync_unlocked; - spin_lock(&ci->i_ceph_lock); - if (ci->i_xattrs.prealloc_blob) - ceph_buffer_put(ci->i_xattrs.prealloc_blob); - ci->i_xattrs.prealloc_blob = blob; - goto retry; - } - - err = __remove_xattr_by_name(ceph_inode(inode), name); - - dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL, - &prealloc_cf); - ci->i_xattrs.dirty = true; - inode->i_ctime = current_fs_time(inode->i_sb); - spin_unlock(&ci->i_ceph_lock); - if (lock_snap_rwsem) - up_read(&mdsc->snap_rwsem); - if (dirty) - __mark_inode_dirty(inode, dirty); - ceph_free_cap_flush(prealloc_cf); - return err; -do_sync: - spin_unlock(&ci->i_ceph_lock); -do_sync_unlocked: - if (lock_snap_rwsem) - up_read(&mdsc->snap_rwsem); - ceph_free_cap_flush(prealloc_cf); - err = ceph_send_removexattr(inode, name); - return err; -} - static int ceph_get_xattr_handler(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, void *value, size_t size) -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 7/8] posix acls: Export xattr_handler functions 2016-04-13 22:30 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher ` (5 preceding siblings ...) 2016-04-13 22:30 ` [Cluster-devel] [PATCH 6/8] ceph: kill __ceph_removexattr() Andreas Gruenbacher @ 2016-04-13 22:30 ` Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH 8/8] gfs2: Switch to generic xattr handlers Andreas Gruenbacher 7 siblings, 0 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:30 UTC (permalink / raw) To: cluster-devel.redhat.com These functions are useful in filesystems like gfs2 which require pre-/postamble code around xattr operations. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Reviewed-by: Bob Peterson <rpeterso@redhat.com> --- fs/posix_acl.c | 9 ++++++--- include/linux/posix_acl_xattr.h | 8 ++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 2c60f17..1da2c63 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -795,7 +795,7 @@ posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl, } EXPORT_SYMBOL (posix_acl_to_xattr); -static int +int posix_acl_xattr_get(const struct xattr_handler *handler, struct dentry *unused, struct inode *inode, const char *name, void *value, size_t size) @@ -819,8 +819,9 @@ posix_acl_xattr_get(const struct xattr_handler *handler, return error; } +EXPORT_SYMBOL(posix_acl_xattr_get); -static int +int posix_acl_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, const char *name, const void *value, size_t size, int flags) @@ -856,12 +857,14 @@ out: posix_acl_release(acl); return ret; } +EXPORT_SYMBOL(posix_acl_xattr_set); -static bool +bool posix_acl_xattr_list(struct dentry *dentry) { return IS_POSIXACL(d_backing_inode(dentry)); } +EXPORT_SYMBOL(posix_acl_xattr_list); const struct xattr_handler posix_acl_access_xattr_handler = { .name = XATTR_NAME_POSIX_ACL_ACCESS, diff --git a/include/linux/posix_acl_xattr.h b/include/linux/posix_acl_xattr.h index e5e8ec4..c92607c 100644 --- a/include/linux/posix_acl_xattr.h +++ b/include/linux/posix_acl_xattr.h @@ -65,6 +65,14 @@ struct posix_acl *posix_acl_from_xattr(struct user_namespace *user_ns, int posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl, void *buffer, size_t size); +int posix_acl_xattr_get(const struct xattr_handler *handler, + struct dentry *unused, struct inode *inode, + const char *name, void *value, size_t size); +int posix_acl_xattr_set(const struct xattr_handler *handler, + struct dentry *dentry, const char *name, + const void *value, size_t size, int flags); +bool posix_acl_xattr_list(struct dentry *dentry); + extern const struct xattr_handler posix_acl_access_xattr_handler; extern const struct xattr_handler posix_acl_default_xattr_handler; -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* [Cluster-devel] [PATCH 8/8] gfs2: Switch to generic xattr handlers 2016-04-13 22:30 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher ` (6 preceding siblings ...) 2016-04-13 22:30 ` [Cluster-devel] [PATCH 7/8] posix acls: Export xattr_handler functions Andreas Gruenbacher @ 2016-04-13 22:30 ` Andreas Gruenbacher 7 siblings, 0 replies; 26+ messages in thread From: Andreas Gruenbacher @ 2016-04-13 22:30 UTC (permalink / raw) To: cluster-devel.redhat.com Move the pre- and postamble code in gfs2_{get,set,remove}xattr into the handlers in gfs2_xattr_handlers. Replace the generic POSIX ACL handlers in there with gfs2-specific versions that wrap the generic handlers into the pre- and postamble code. With that, gfs2_{get,set,remove}xattr can be removed and replaced with the generic inode operations. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Reviewed-by: Bob Peterson <rpeterso@redhat.com> --- fs/gfs2/inode.c | 78 +++++----------------------------------- fs/gfs2/xattr.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 109 insertions(+), 77 deletions(-) diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 45f516ca..3398342 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -1948,66 +1948,6 @@ static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, return 0; } -static int gfs2_setxattr(struct dentry *dentry, const char *name, - const void *data, size_t size, int flags) -{ - struct inode *inode = d_inode(dentry); - struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_holder gh; - int ret; - - gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); - ret = gfs2_glock_nq(&gh); - if (ret == 0) { - ret = gfs2_rsqa_alloc(ip); - if (ret == 0) - ret = generic_setxattr(dentry, name, data, size, flags); - gfs2_glock_dq(&gh); - } - gfs2_holder_uninit(&gh); - return ret; -} - -static ssize_t gfs2_getxattr(struct dentry *dentry, struct inode *inode, - const char *name, void *data, size_t size) -{ - struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_holder gh; - int ret; - - /* For selinux during lookup */ - if (gfs2_glock_is_locked_by_me(ip->i_gl)) - return generic_getxattr(dentry, inode, name, data, size); - - gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); - ret = gfs2_glock_nq(&gh); - if (ret == 0) { - ret = generic_getxattr(dentry, inode, name, data, size); - gfs2_glock_dq(&gh); - } - gfs2_holder_uninit(&gh); - return ret; -} - -static int gfs2_removexattr(struct dentry *dentry, const char *name) -{ - struct inode *inode = d_inode(dentry); - struct gfs2_inode *ip = GFS2_I(inode); - struct gfs2_holder gh; - int ret; - - gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); - ret = gfs2_glock_nq(&gh); - if (ret == 0) { - ret = gfs2_rsqa_alloc(ip); - if (ret == 0) - ret = generic_removexattr(dentry, name); - gfs2_glock_dq(&gh); - } - gfs2_holder_uninit(&gh); - return ret; -} - static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, u64 start, u64 len) { @@ -2054,10 +1994,10 @@ const struct inode_operations gfs2_file_iops = { .permission = gfs2_permission, .setattr = gfs2_setattr, .getattr = gfs2_getattr, - .setxattr = gfs2_setxattr, - .getxattr = gfs2_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = gfs2_listxattr, - .removexattr = gfs2_removexattr, + .removexattr = generic_removexattr, .fiemap = gfs2_fiemap, .get_acl = gfs2_get_acl, .set_acl = gfs2_set_acl, @@ -2076,10 +2016,10 @@ const struct inode_operations gfs2_dir_iops = { .permission = gfs2_permission, .setattr = gfs2_setattr, .getattr = gfs2_getattr, - .setxattr = gfs2_setxattr, - .getxattr = gfs2_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = gfs2_listxattr, - .removexattr = gfs2_removexattr, + .removexattr = generic_removexattr, .fiemap = gfs2_fiemap, .get_acl = gfs2_get_acl, .set_acl = gfs2_set_acl, @@ -2092,10 +2032,10 @@ const struct inode_operations gfs2_symlink_iops = { .permission = gfs2_permission, .setattr = gfs2_setattr, .getattr = gfs2_getattr, - .setxattr = gfs2_setxattr, - .getxattr = gfs2_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = gfs2_listxattr, - .removexattr = gfs2_removexattr, + .removexattr = generic_removexattr, .fiemap = gfs2_fiemap, }; diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 619886b..92d5b4c 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c @@ -583,13 +583,11 @@ out: * * Returns: actual size of data on success, -errno on error */ -static int gfs2_xattr_get(const struct xattr_handler *handler, - struct dentry *unused, struct inode *inode, - const char *name, void *buffer, size_t size) +static int __gfs2_xattr_get(struct inode *inode, const char *name, + void *buffer, size_t size, int type) { struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_ea_location el; - int type = handler->flags; int error; if (!ip->i_eattr) @@ -611,6 +609,28 @@ static int gfs2_xattr_get(const struct xattr_handler *handler, return error; } +static int gfs2_xattr_get(const struct xattr_handler *handler, + struct dentry *unused, struct inode *inode, + const char *name, void *buffer, size_t size) +{ + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_holder gh; + int ret; + + /* For selinux during lookup */ + if (gfs2_glock_is_locked_by_me(ip->i_gl)) + return __gfs2_xattr_get(inode, name, buffer, size, handler->flags); + + gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); + ret = gfs2_glock_nq(&gh); + if (ret == 0) { + ret = __gfs2_xattr_get(inode, name, buffer, size, handler->flags); + gfs2_glock_dq(&gh); + } + gfs2_holder_uninit(&gh); + return ret; +} + /** * ea_alloc_blk - allocates a new block for extended attributes. * @ip: A pointer to the inode that's getting extended attributes @@ -1233,8 +1253,23 @@ static int gfs2_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { - return __gfs2_xattr_set(d_inode(dentry), name, value, - size, flags, handler->flags); + struct inode *inode = d_inode(dentry); + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_holder gh; + int ret; + + ret = gfs2_rsqa_alloc(ip); + if (ret) + return ret; + + gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); + ret = gfs2_glock_nq(&gh); + if (ret == 0) { + ret = __gfs2_xattr_set(inode, name, value, size, flags, handler->flags); + gfs2_glock_dq(&gh); + } + gfs2_holder_uninit(&gh); + return ret; } static int ea_dealloc_indirect(struct gfs2_inode *ip) @@ -1437,6 +1472,63 @@ out_quota: return error; } +static int gfs2_posix_acl_xattr_get(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *name, void *buffer, size_t size) +{ + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_holder gh; + int ret; + + /* For selinux during lookup */ + if (gfs2_glock_is_locked_by_me(ip->i_gl)) + return posix_acl_xattr_get(handler, dentry, inode, name, buffer, size); + + gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); + ret = gfs2_glock_nq(&gh); + if (ret == 0) { + ret = posix_acl_xattr_get(handler, dentry, inode, name, buffer, size); + gfs2_glock_dq(&gh); + } + gfs2_holder_uninit(&gh); + return ret; +} + +static int gfs2_posix_acl_xattr_set(const struct xattr_handler *handler, + struct dentry *dentry, const char *name, + const void *value, size_t size, int flags) +{ + struct inode *inode = d_inode(dentry); + struct gfs2_inode *ip = GFS2_I(inode); + struct gfs2_holder gh; + int ret; + + gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); + ret = gfs2_glock_nq(&gh); + if (ret == 0) { + ret = posix_acl_xattr_set(handler, dentry, name, value, size, flags); + gfs2_glock_dq(&gh); + } + gfs2_holder_uninit(&gh); + return ret; +} + +static const struct xattr_handler gfs2_posix_acl_access_xattr_handler = { + .name = XATTR_NAME_POSIX_ACL_ACCESS, + .flags = ACL_TYPE_ACCESS, + .list = posix_acl_xattr_list, + .get = gfs2_posix_acl_xattr_get, + .set = gfs2_posix_acl_xattr_set, +}; + +static const struct xattr_handler gfs2_posix_acl_default_xattr_handler = { + .name = XATTR_NAME_POSIX_ACL_DEFAULT, + .flags = ACL_TYPE_DEFAULT, + .list = posix_acl_xattr_list, + .get = gfs2_posix_acl_xattr_get, + .set = gfs2_posix_acl_xattr_set, +}; + static const struct xattr_handler gfs2_xattr_user_handler = { .prefix = XATTR_USER_PREFIX, .flags = GFS2_EATYPE_USR, @@ -1454,8 +1546,8 @@ static const struct xattr_handler gfs2_xattr_security_handler = { const struct xattr_handler *gfs2_xattr_handlers[] = { &gfs2_xattr_user_handler, &gfs2_xattr_security_handler, - &posix_acl_access_xattr_handler, - &posix_acl_default_xattr_handler, + &gfs2_posix_acl_access_xattr_handler, + &gfs2_posix_acl_default_xattr_handler, NULL, }; -- 2.4.11 ^ permalink raw reply related [flat|nested] 26+ messages in thread
end of thread, other threads:[~2016-04-15 3:01 UTC | newest] Thread overview: 26+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <20160413182026.GR25498@ZenIV.linux.org.uk> 2016-04-13 22:27 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 2/8] cifs: Check for equality with ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 3/8] cifs: Fix removexattr for os2.* xattrs Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 4/8] ceph: Get rid of d_find_alias in ceph_set_acl Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 5/8] ceph: Switch to generic xattr handlers Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 6/8] ceph: kill __ceph_removexattr() Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 7/8] posix acls: Export xattr_handler functions Andreas Gruenbacher 2016-04-13 22:27 ` [Cluster-devel] [PATCH 8/8] gfs2: Switch to generic xattr handlers Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH] xattr: Export xattr_resolve_name Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH 1/8] cifs: Fix xattr name checks Andreas Gruenbacher 2016-04-14 4:26 ` Steve French 2016-04-14 4:37 ` Al Viro 2016-04-14 4:43 ` Steve French 2016-04-14 4:49 ` Steve French 2016-04-14 4:59 ` Al Viro 2016-04-15 3:01 ` Steve French 2016-04-13 22:30 ` [Cluster-devel] [PATCH 2/8] cifs: Check for equality with ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT Andreas Gruenbacher 2016-04-14 4:26 ` Steve French 2016-04-13 22:30 ` [Cluster-devel] [PATCH 3/8] cifs: Fix removexattr for os2.* xattrs Andreas Gruenbacher 2016-04-14 4:27 ` Steve French 2016-04-13 22:30 ` [Cluster-devel] [PATCH 4/8] ceph: Get rid of d_find_alias in ceph_set_acl Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH 5/8] ceph: Switch to generic xattr handlers Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH 6/8] ceph: kill __ceph_removexattr() Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH 7/8] posix acls: Export xattr_handler functions Andreas Gruenbacher 2016-04-13 22:30 ` [Cluster-devel] [PATCH 8/8] gfs2: Switch to generic xattr handlers Andreas Gruenbacher
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).