This is mostly the same as on other filesystems except for attribute names with an "os2." prefix: for those, the prefix is not stored on disk, and on-attribute names without a prefix have "os2." added. As on several other filesystems, the underlying function for setting/removing xattrs (__jfs_setxattr) removes attributes when the value is NULL, so the set xattr handlers will work as expected. Signed-off-by: Andreas Gruenbacher <agruenba@xxxxxxxxxx> --- fs/jfs/file.c | 6 +- fs/jfs/jfs_xattr.h | 6 +- fs/jfs/namei.c | 6 +- fs/jfs/symlink.c | 12 ++-- fs/jfs/xattr.c | 170 ++++++++++++++++++++++------------------------------- 5 files changed, 84 insertions(+), 116 deletions(-) diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 4ce7735..7f1a585 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -140,10 +140,10 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr) } const struct inode_operations jfs_file_inode_operations = { - .setxattr = jfs_setxattr, - .getxattr = jfs_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = jfs_listxattr, - .removexattr = jfs_removexattr, + .removexattr = generic_removexattr, .setattr = jfs_setattr, #ifdef CONFIG_JFS_POSIX_ACL .get_acl = jfs_get_acl, diff --git a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h index e69e14f..561f6af 100644 --- a/fs/jfs/jfs_xattr.h +++ b/fs/jfs/jfs_xattr.h @@ -19,6 +19,8 @@ #ifndef H_JFS_XATTR #define H_JFS_XATTR +#include <linux/xattr.h> + /* * jfs_ea_list describe the on-disk format of the extended attributes. * I know the null-terminator is redundant since namelen is stored, but @@ -54,12 +56,8 @@ struct jfs_ea_list { extern int __jfs_setxattr(tid_t, struct inode *, const char *, const void *, size_t, int); -extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t, - int); extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t); -extern ssize_t jfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t); extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); -extern int jfs_removexattr(struct dentry *, const char *); extern const struct xattr_handler *jfs_xattr_handlers[]; diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 8a40941..7040062 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -1537,10 +1537,10 @@ const struct inode_operations jfs_dir_inode_operations = { .rmdir = jfs_rmdir, .mknod = jfs_mknod, .rename = jfs_rename, - .setxattr = jfs_setxattr, - .getxattr = jfs_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = jfs_listxattr, - .removexattr = jfs_removexattr, + .removexattr = generic_removexattr, .setattr = jfs_setattr, #ifdef CONFIG_JFS_POSIX_ACL .get_acl = jfs_get_acl, diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c index f8db4fd..c94c7e4 100644 --- a/fs/jfs/symlink.c +++ b/fs/jfs/symlink.c @@ -25,19 +25,19 @@ const struct inode_operations jfs_fast_symlink_inode_operations = { .readlink = generic_readlink, .get_link = simple_get_link, .setattr = jfs_setattr, - .setxattr = jfs_setxattr, - .getxattr = jfs_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = jfs_listxattr, - .removexattr = jfs_removexattr, + .removexattr = generic_removexattr, }; const struct inode_operations jfs_symlink_inode_operations = { .readlink = generic_readlink, .get_link = page_get_link, .setattr = jfs_setattr, - .setxattr = jfs_setxattr, - .getxattr = jfs_getxattr, + .setxattr = generic_setxattr, + .getxattr = generic_getxattr, .listxattr = jfs_listxattr, - .removexattr = jfs_removexattr, + .removexattr = generic_removexattr, }; diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 9cdf7dc..beb182b 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c @@ -663,30 +663,6 @@ static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf, return 0; } -/* - * Most of the permission checking is done by xattr_permission in the vfs. - * We also need to verify that this is a namespace that we recognize. - */ -static bool map_name_to_disk(const char **name) -{ - if (!strncmp(*name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)) { - /* - * This makes sure that we aren't trying to set an - * attribute in a different namespace by prefixing it - * with "os2." - */ - if (is_known_namespace(*name + XATTR_OS2_PREFIX_LEN)) - return false; - *name += XATTR_OS2_PREFIX_LEN; - return true; - } - - /* - * Don't allow setting an attribute in an unknown namespace. - */ - return is_known_namespace(*name); -} - int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, const void *value, size_t value_len, int flags) { @@ -826,42 +802,6 @@ int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, return rc; } -int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, - size_t value_len, int flags) -{ - struct inode *inode = d_inode(dentry); - struct jfs_inode_info *ji = JFS_IP(inode); - int rc; - tid_t tid; - - /* - * If this is a request for a synthetic attribute in the system.* - * namespace use the generic infrastructure to resolve a handler - * for it via sb->s_xattr. - */ - if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) - return generic_setxattr(dentry, name, value, value_len, flags); - - if (!map_name_to_disk(&name)) - return -EOPNOTSUPP; - - if (value == NULL) { /* empty EA, do not remove */ - value = ""; - value_len = 0; - } - - tid = txBegin(inode->i_sb, 0); - mutex_lock(&ji->commit_mutex); - rc = __jfs_setxattr(tid, d_inode(dentry), name, value, value_len, - flags); - if (!rc) - rc = txCommit(tid, 1, &inode, 0); - txEnd(tid); - mutex_unlock(&ji->commit_mutex); - - return rc; -} - ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data, size_t buf_size) { @@ -913,27 +853,6 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data, return size; } -ssize_t jfs_getxattr(struct dentry *dentry, struct inode *inode, - const char *name, void *data, size_t buf_size) -{ - int err; - - /* - * If this is a request for a synthetic attribute in the system.* - * namespace use the generic infrastructure to resolve a handler - * for it via sb->s_xattr. - */ - if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) - return generic_getxattr(dentry, inode, name, data, buf_size); - - if (!map_name_to_disk(&name)) - return -EOPNOTSUPP; - - err = __jfs_getxattr(inode, name, data, buf_size); - - return err; -} - /* * No special permissions are needed to list attributes except for trusted.* */ @@ -997,27 +916,16 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size) return size; } -int jfs_removexattr(struct dentry *dentry, const char *name) +static int __jfs_xattr_set(struct inode *inode, const char *name, + const void *value, size_t size, int flags) { - struct inode *inode = d_inode(dentry); struct jfs_inode_info *ji = JFS_IP(inode); - int rc; tid_t tid; - - /* - * If this is a request for a synthetic attribute in the system.* - * namespace use the generic infrastructure to resolve a handler - * for it via sb->s_xattr. - */ - if (!strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) - return generic_removexattr(dentry, name); - - if (!map_name_to_disk(&name)) - return -EOPNOTSUPP; + int rc; tid = txBegin(inode->i_sb, 0); mutex_lock(&ji->commit_mutex); - rc = __jfs_setxattr(tid, d_inode(dentry), name, NULL, 0, XATTR_REPLACE); + rc = __jfs_setxattr(tid, inode, name, value, size, flags); if (!rc) rc = txCommit(tid, 1, &inode, 0); txEnd(tid); @@ -1026,15 +934,77 @@ int jfs_removexattr(struct dentry *dentry, const char *name) return rc; } -/* - * List of handlers for synthetic system.* attributes. All real ondisk - * attributes are handled directly. - */ +static int jfs_xattr_get(const struct xattr_handler *handler, + struct dentry *unused, struct inode *inode, + const char *name, void *value, size_t size) +{ + name = xattr_full_name(handler, name); + return __jfs_getxattr(inode, name, value, size); +} + +static int jfs_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); + + name = xattr_full_name(handler, name); + return __jfs_xattr_set(inode, name, value, size, flags); +} + +static int jfs_xattr_get_os2(const struct xattr_handler *handler, + struct dentry *unused, struct inode *inode, + const char *name, void *value, size_t size) +{ + if (is_known_namespace(name)) + return -EOPNOTSUPP; + return __jfs_getxattr(inode, name, value, size); +} + +static int jfs_xattr_set_os2(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); + + if (is_known_namespace(name)) + return -EOPNOTSUPP; + return __jfs_xattr_set(inode, name, value, size, flags); +} + +static const struct xattr_handler jfs_user_xattr_handler = { + .prefix = XATTR_USER_PREFIX, + .get = jfs_xattr_get, + .set = jfs_xattr_set, +}; + +static const struct xattr_handler jfs_os2_xattr_handler = { + .prefix = XATTR_OS2_PREFIX, + .get = jfs_xattr_get_os2, + .set = jfs_xattr_set_os2, +}; + +static const struct xattr_handler jfs_security_xattr_handler = { + .prefix = XATTR_SECURITY_PREFIX, + .get = jfs_xattr_get, + .set = jfs_xattr_set, +}; + +static const struct xattr_handler jfs_trusted_xattr_handler = { + .prefix = XATTR_TRUSTED_PREFIX, + .get = jfs_xattr_get, + .set = jfs_xattr_set, +}; + const struct xattr_handler *jfs_xattr_handlers[] = { #ifdef CONFIG_JFS_POSIX_ACL &posix_acl_access_xattr_handler, &posix_acl_default_xattr_handler, #endif + &jfs_os2_xattr_handler, + &jfs_user_xattr_handler, + &jfs_security_xattr_handler, + &jfs_trusted_xattr_handler, NULL, }; -- 2.5.5 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html