Patch from Andreas Gruenbacher This adds flags parameters to the getxattr, listxattr, and removexattr inode operations. This is in preparation for the next patch, which allows in-kernel code (i.e., modules) to override extended attribute permission restrictions (which in turn is used by HSM implementations and the like). ext2/acl.c | 11 ++++++----- ext2/xattr.c | 19 ++++++++++--------- ext2/xattr.h | 12 ++++++------ ext2/xattr_user.c | 4 ++-- ext3/acl.c | 11 ++++++----- ext3/xattr.c | 19 ++++++++++--------- ext3/xattr.h | 12 ++++++------ ext3/xattr_user.c | 4 ++-- jfs/jfs_xattr.h | 6 +++--- jfs/xattr.c | 7 ++++--- xattr.c | 6 +++--- xfs/linux/xfs_iops.c | 9 ++++++--- linux/fs.h | 6 +++--- 13 files changed, 67 insertions(+), 59 deletions(-) diff -puN fs/ext2/acl.c~xattr-flags fs/ext2/acl.c --- 25/fs/ext2/acl.c~xattr-flags 2003-02-14 18:24:02.000000000 -0800 +++ 25-akpm/fs/ext2/acl.c 2003-02-14 18:24:02.000000000 -0800 @@ -419,7 +419,7 @@ ext2_acl_chmod(struct inode *inode) */ static size_t ext2_xattr_list_acl_access(char *list, struct inode *inode, - const char *name, int name_len) + const char *name, int name_len, int flags) { const size_t size = sizeof(XATTR_NAME_ACL_ACCESS); @@ -432,7 +432,7 @@ ext2_xattr_list_acl_access(char *list, s static size_t ext2_xattr_list_acl_default(char *list, struct inode *inode, - const char *name, int name_len) + const char *name, int name_len, int flags) { const size_t size = sizeof(XATTR_NAME_ACL_DEFAULT); @@ -465,7 +465,7 @@ ext2_xattr_get_acl(struct inode *inode, static int ext2_xattr_get_acl_access(struct inode *inode, const char *name, - void *buffer, size_t size) + void *buffer, size_t size, int flags) { if (strcmp(name, "") != 0) return -EINVAL; @@ -474,7 +474,7 @@ ext2_xattr_get_acl_access(struct inode * static int ext2_xattr_get_acl_default(struct inode *inode, const char *name, - void *buffer, size_t size) + void *buffer, size_t size, int flags) { if (strcmp(name, "") != 0) return -EINVAL; @@ -482,7 +482,8 @@ ext2_xattr_get_acl_default(struct inode } static int -ext2_xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) +ext2_xattr_set_acl(struct inode *inode, int type, const void *value, + size_t size) { struct posix_acl *acl; int error; diff -puN fs/ext2/xattr.c~xattr-flags fs/ext2/xattr.c --- 25/fs/ext2/xattr.c~xattr-flags 2003-02-14 18:24:02.000000000 -0800 +++ 25-akpm/fs/ext2/xattr.c 2003-02-14 18:24:02.000000000 -0800 @@ -199,7 +199,7 @@ ext2_xattr_handler(int name_index) */ ssize_t ext2_getxattr(struct dentry *dentry, const char *name, - void *buffer, size_t size) + void *buffer, size_t size, int flags) { struct ext2_xattr_handler *handler; struct inode *inode = dentry->d_inode; @@ -207,7 +207,7 @@ ext2_getxattr(struct dentry *dentry, con handler = ext2_xattr_resolve_name(&name); if (!handler) return -EOPNOTSUPP; - return handler->get(inode, name, buffer, size); + return handler->get(inode, name, buffer, size, flags); } /* @@ -217,9 +217,9 @@ ext2_getxattr(struct dentry *dentry, con * BKL held [before 2.5.x] */ ssize_t -ext2_listxattr(struct dentry *dentry, char *buffer, size_t size) +ext2_listxattr(struct dentry *dentry, char *buffer, size_t size, int flags) { - return ext2_xattr_list(dentry->d_inode, buffer, size); + return ext2_xattr_list(dentry->d_inode, buffer, size, flags); } /* @@ -250,7 +250,7 @@ ext2_setxattr(struct dentry *dentry, con * BKL held [before 2.5.x] */ int -ext2_removexattr(struct dentry *dentry, const char *name) +ext2_removexattr(struct dentry *dentry, const char *name, int flags) { struct ext2_xattr_handler *handler; struct inode *inode = dentry->d_inode; @@ -258,7 +258,7 @@ ext2_removexattr(struct dentry *dentry, handler = ext2_xattr_resolve_name(&name); if (!handler) return -EOPNOTSUPP; - return handler->set(inode, name, NULL, 0, XATTR_REPLACE); + return handler->set(inode, name, NULL, 0, flags | XATTR_REPLACE); } /* @@ -371,7 +371,8 @@ cleanup: * used / required on success. */ int -ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) +ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size, + int flags) { struct buffer_head *bh = NULL; struct ext2_xattr_entry *entry; @@ -411,7 +412,7 @@ bad_block: ext2_error(inode->i_sb, "ext2 handler = ext2_xattr_handler(entry->e_name_index); if (handler) size += handler->list(NULL, inode, entry->e_name, - entry->e_name_len); + entry->e_name_len, flags); } if (ext2_xattr_cache_insert(bh)) @@ -434,7 +435,7 @@ bad_block: ext2_error(inode->i_sb, "ext2 handler = ext2_xattr_handler(entry->e_name_index); if (handler) buf += handler->list(buf, inode, entry->e_name, - entry->e_name_len); + entry->e_name_len, flags); } error = size; diff -puN fs/ext2/xattr.h~xattr-flags fs/ext2/xattr.h --- 25/fs/ext2/xattr.h~xattr-flags 2003-02-14 18:24:02.000000000 -0800 +++ 25-akpm/fs/ext2/xattr.h 2003-02-14 18:24:02.000000000 -0800 @@ -57,9 +57,9 @@ struct ext2_xattr_entry { struct ext2_xattr_handler { char *prefix; size_t (*list)(char *list, struct inode *inode, const char *name, - int name_len); + int name_len, int flags); int (*get)(struct inode *inode, const char *name, void *buffer, - size_t size); + size_t size, int flags); int (*set)(struct inode *inode, const char *name, const void *buffer, size_t size, int flags); }; @@ -68,12 +68,12 @@ extern int ext2_xattr_register(int, stru extern void ext2_xattr_unregister(int, struct ext2_xattr_handler *); extern int ext2_setxattr(struct dentry *, const char *, const void *, size_t, int); -extern ssize_t ext2_getxattr(struct dentry *, const char *, void *, size_t); -extern ssize_t ext2_listxattr(struct dentry *, char *, size_t); -extern int ext2_removexattr(struct dentry *, const char *); +extern ssize_t ext2_getxattr(struct dentry *, const char *, void *, size_t, int); +extern ssize_t ext2_listxattr(struct dentry *, char *, size_t, int); +extern int ext2_removexattr(struct dentry *, const char *, int); extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t); -extern int ext2_xattr_list(struct inode *, char *, size_t); +extern int ext2_xattr_list(struct inode *, char *, size_t, int flags); extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int); extern void ext2_xattr_delete_inode(struct inode *); diff -puN fs/ext2/xattr_user.c~xattr-flags fs/ext2/xattr_user.c --- 25/fs/ext2/xattr_user.c~xattr-flags 2003-02-14 18:24:02.000000000 -0800 +++ 25-akpm/fs/ext2/xattr_user.c 2003-02-14 18:24:02.000000000 -0800 @@ -19,7 +19,7 @@ static size_t ext2_xattr_user_list(char *list, struct inode *inode, - const char *name, int name_len) + const char *name, int name_len, int flags) { const int prefix_len = sizeof(XATTR_USER_PREFIX)-1; @@ -36,7 +36,7 @@ ext2_xattr_user_list(char *list, struct static int ext2_xattr_user_get(struct inode *inode, const char *name, - void *buffer, size_t size) + void *buffer, size_t size, int flags) { int error; diff -puN fs/ext3/acl.c~xattr-flags fs/ext3/acl.c --- 25/fs/ext3/acl.c~xattr-flags 2003-02-14 18:24:02.000000000 -0800 +++ 25-akpm/fs/ext3/acl.c 2003-02-14 18:24:02.000000000 -0800 @@ -431,7 +431,7 @@ ext3_acl_chmod(struct inode *inode) */ static size_t ext3_xattr_list_acl_access(char *list, struct inode *inode, - const char *name, int name_len) + const char *name, int name_len, int flags) { const size_t size = sizeof(XATTR_NAME_ACL_ACCESS); @@ -444,7 +444,7 @@ ext3_xattr_list_acl_access(char *list, s static size_t ext3_xattr_list_acl_default(char *list, struct inode *inode, - const char *name, int name_len) + const char *name, int name_len, int flags) { const size_t size = sizeof(XATTR_NAME_ACL_DEFAULT); @@ -477,7 +477,7 @@ ext3_xattr_get_acl(struct inode *inode, static int ext3_xattr_get_acl_access(struct inode *inode, const char *name, - void *buffer, size_t size) + void *buffer, size_t size, int flags) { if (strcmp(name, "") != 0) return -EINVAL; @@ -486,7 +486,7 @@ ext3_xattr_get_acl_access(struct inode * static int ext3_xattr_get_acl_default(struct inode *inode, const char *name, - void *buffer, size_t size) + void *buffer, size_t size, int flags) { if (strcmp(name, "") != 0) return -EINVAL; @@ -494,7 +494,8 @@ ext3_xattr_get_acl_default(struct inode } static int -ext3_xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) +ext3_xattr_set_acl(struct inode *inode, int type, const void *value, + size_t size) { handle_t *handle; struct posix_acl *acl; diff -puN fs/ext3/xattr.c~xattr-flags fs/ext3/xattr.c --- 25/fs/ext3/xattr.c~xattr-flags 2003-02-14 18:24:02.000000000 -0800 +++ 25-akpm/fs/ext3/xattr.c 2003-02-14 18:24:02.000000000 -0800 @@ -195,7 +195,7 @@ ext3_xattr_handler(int name_index) */ ssize_t ext3_getxattr(struct dentry *dentry, const char *name, - void *buffer, size_t size) + void *buffer, size_t size, int flags) { struct ext3_xattr_handler *handler; struct inode *inode = dentry->d_inode; @@ -203,7 +203,7 @@ ext3_getxattr(struct dentry *dentry, con handler = ext3_xattr_resolve_name(&name); if (!handler) return -EOPNOTSUPP; - return handler->get(inode, name, buffer, size); + return handler->get(inode, name, buffer, size, flags); } /* @@ -212,9 +212,9 @@ ext3_getxattr(struct dentry *dentry, con * dentry->d_inode->i_sem down */ ssize_t -ext3_listxattr(struct dentry *dentry, char *buffer, size_t size) +ext3_listxattr(struct dentry *dentry, char *buffer, size_t size, int flags) { - return ext3_xattr_list(dentry->d_inode, buffer, size); + return ext3_xattr_list(dentry->d_inode, buffer, size, flags); } /* @@ -243,7 +243,7 @@ ext3_setxattr(struct dentry *dentry, con * dentry->d_inode->i_sem down */ int -ext3_removexattr(struct dentry *dentry, const char *name) +ext3_removexattr(struct dentry *dentry, const char *name, int flags) { struct ext3_xattr_handler *handler; struct inode *inode = dentry->d_inode; @@ -251,7 +251,7 @@ ext3_removexattr(struct dentry *dentry, handler = ext3_xattr_resolve_name(&name); if (!handler) return -EOPNOTSUPP; - return handler->set(inode, name, NULL, 0, XATTR_REPLACE); + return handler->set(inode, name, NULL, 0, flags | XATTR_REPLACE); } /* @@ -364,7 +364,8 @@ cleanup: * used / required on success. */ int -ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) +ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size, + int flags) { struct buffer_head *bh = NULL; struct ext3_xattr_entry *entry; @@ -404,7 +405,7 @@ bad_block: ext3_error(inode->i_sb, "ext3 handler = ext3_xattr_handler(entry->e_name_index); if (handler) size += handler->list(NULL, inode, entry->e_name, - entry->e_name_len); + entry->e_name_len, flags); } if (ext3_xattr_cache_insert(bh)) @@ -427,7 +428,7 @@ bad_block: ext3_error(inode->i_sb, "ext3 handler = ext3_xattr_handler(entry->e_name_index); if (handler) buf += handler->list(buf, inode, entry->e_name, - entry->e_name_len); + entry->e_name_len, flags); } error = size; diff -puN fs/ext3/xattr.h~xattr-flags fs/ext3/xattr.h --- 25/fs/ext3/xattr.h~xattr-flags 2003-02-14 18:24:02.000000000 -0800 +++ 25-akpm/fs/ext3/xattr.h 2003-02-14 18:24:02.000000000 -0800 @@ -56,9 +56,9 @@ struct ext3_xattr_entry { struct ext3_xattr_handler { char *prefix; size_t (*list)(char *list, struct inode *inode, const char *name, - int name_len); + int name_len, int flags); int (*get)(struct inode *inode, const char *name, void *buffer, - size_t size); + size_t size, int flags); int (*set)(struct inode *inode, const char *name, const void *buffer, size_t size, int flags); }; @@ -67,12 +67,12 @@ extern int ext3_xattr_register(int, stru extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *); extern int ext3_setxattr(struct dentry *, const char *, const void *, size_t, int); -extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t); -extern ssize_t ext3_listxattr(struct dentry *, char *, size_t); -extern int ext3_removexattr(struct dentry *, const char *); +extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t, int); +extern ssize_t ext3_listxattr(struct dentry *, char *, size_t, int); +extern int ext3_removexattr(struct dentry *, const char *, int); extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t); -extern int ext3_xattr_list(struct inode *, char *, size_t); +extern int ext3_xattr_list(struct inode *, char *, size_t, int flags); extern int ext3_xattr_set(struct inode *, int, const char *, const void *, size_t, int); extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int); diff -puN fs/ext3/xattr_user.c~xattr-flags fs/ext3/xattr_user.c --- 25/fs/ext3/xattr_user.c~xattr-flags 2003-02-14 18:24:02.000000000 -0800 +++ 25-akpm/fs/ext3/xattr_user.c 2003-02-14 18:24:02.000000000 -0800 @@ -21,7 +21,7 @@ static size_t ext3_xattr_user_list(char *list, struct inode *inode, - const char *name, int name_len) + const char *name, int name_len, int flags) { const int prefix_len = sizeof(XATTR_USER_PREFIX)-1; @@ -38,7 +38,7 @@ ext3_xattr_user_list(char *list, struct static int ext3_xattr_user_get(struct inode *inode, const char *name, - void *buffer, size_t size) + void *buffer, size_t size, int flags) { int error; diff -puN fs/jfs/jfs_xattr.h~xattr-flags fs/jfs/jfs_xattr.h --- 25/fs/jfs/jfs_xattr.h~xattr-flags 2003-02-14 18:24:02.000000000 -0800 +++ 25-akpm/fs/jfs/jfs_xattr.h 2003-02-14 18:24:02.000000000 -0800 @@ -57,8 +57,8 @@ extern int __jfs_setxattr(struct inode * 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 *, const char *, void *, size_t); -extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); -extern int jfs_removexattr(struct dentry *, const char *); +extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t, int); +extern ssize_t jfs_listxattr(struct dentry *, char *, size_t, int); +extern int jfs_removexattr(struct dentry *, const char *, int); #endif /* H_JFS_XATTR */ diff -puN fs/jfs/xattr.c~xattr-flags fs/jfs/xattr.c --- 25/fs/jfs/xattr.c~xattr-flags 2003-02-14 18:24:02.000000000 -0800 +++ 25-akpm/fs/jfs/xattr.c 2003-02-14 18:24:02.000000000 -0800 @@ -962,12 +962,13 @@ ssize_t __jfs_getxattr(struct inode *ino } ssize_t jfs_getxattr(struct dentry *dentry, const char *name, void *data, - size_t buf_size) + size_t buf_size, int flags) { return __jfs_getxattr(dentry->d_inode, name, data, buf_size); } -ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size) +ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size, + int flags) { struct inode *inode = dentry->d_inode; char *buffer; @@ -1013,7 +1014,7 @@ ssize_t jfs_listxattr(struct dentry * de return size; } -int jfs_removexattr(struct dentry *dentry, const char *name) +int jfs_removexattr(struct dentry *dentry, const char *name, int flags) { return __jfs_setxattr(dentry->d_inode, name, 0, 0, XATTR_REPLACE); } diff -puN fs/xattr.c~xattr-flags fs/xattr.c --- 25/fs/xattr.c~xattr-flags 2003-02-14 18:24:02.000000000 -0800 +++ 25-akpm/fs/xattr.c 2003-02-14 18:24:02.000000000 -0800 @@ -160,7 +160,7 @@ getxattr(struct dentry *d, char *name, v if (error) goto out; down(&d->d_inode->i_sem); - error = d->d_inode->i_op->getxattr(d, kname, kvalue, size); + error = d->d_inode->i_op->getxattr(d, kname, kvalue, size, 0); up(&d->d_inode->i_sem); } @@ -233,7 +233,7 @@ listxattr(struct dentry *d, char *list, if (error) goto out; down(&d->d_inode->i_sem); - error = d->d_inode->i_op->listxattr(d, klist, size); + error = d->d_inode->i_op->listxattr(d, klist, size, 0); up(&d->d_inode->i_sem); } @@ -308,7 +308,7 @@ removexattr(struct dentry *d, char *name if (error) goto out; down(&d->d_inode->i_sem); - error = d->d_inode->i_op->removexattr(d, kname); + error = d->d_inode->i_op->removexattr(d, kname, 0); up(&d->d_inode->i_sem); } out: diff -puN fs/xfs/linux/xfs_iops.c~xattr-flags fs/xfs/linux/xfs_iops.c --- 25/fs/xfs/linux/xfs_iops.c~xattr-flags 2003-02-14 18:24:02.000000000 -0800 +++ 25-akpm/fs/xfs/linux/xfs_iops.c 2003-02-14 18:24:02.000000000 -0800 @@ -640,7 +640,8 @@ linvfs_getxattr( struct dentry *dentry, const char *name, void *data, - size_t size) + size_t size, + int flags) { ssize_t error; int xflags = 0; @@ -697,7 +698,8 @@ STATIC ssize_t linvfs_listxattr( struct dentry *dentry, char *data, - size_t size) + size_t size, + int flags) { ssize_t error; int result = 0; @@ -741,7 +743,8 @@ linvfs_listxattr( STATIC int linvfs_removexattr( struct dentry *dentry, - const char *name) + const char *name, + int flags) { int error; int xflags = 0; diff -puN include/linux/fs.h~xattr-flags include/linux/fs.h --- 25/include/linux/fs.h~xattr-flags 2003-02-14 18:24:02.000000000 -0800 +++ 25-akpm/include/linux/fs.h 2003-02-14 18:24:02.000000000 -0800 @@ -743,9 +743,9 @@ struct inode_operations { int (*setattr) (struct dentry *, struct iattr *); int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); - ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); - ssize_t (*listxattr) (struct dentry *, char *, size_t); - int (*removexattr) (struct dentry *, const char *); + ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t,int); + ssize_t (*listxattr) (struct dentry *, char *, size_t, int); + int (*removexattr) (struct dentry *, const char *, int); }; struct seq_file; _