Commit 36bc191b authored by Andrew Morton's avatar Andrew Morton Committed by Jens Axboe

[PATCH] xattr: infrastructure for permission overrides

Patch from Andreas Gruenbacher <agruen@suse.de>

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).
parent af8e38c7
......@@ -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, struct inode *inode,
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, int type, void *buffer, size_t size)
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 *inode, const char *name,
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 *inode, const char *name,
}
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;
......
......@@ -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, const char *name,
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, const char *name,
* 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, const char *name,
* 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, const char *name)
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 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_get",
* 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_xattr_list",
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_xattr_list",
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;
......
......@@ -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, struct ext2_xattr_handler *);
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 *);
......
......@@ -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 inode *inode,
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;
......
......@@ -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, struct inode *inode,
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, int type, void *buffer, size_t size)
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 *inode, const char *name,
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 *inode, const char *name,
}
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;
......
......@@ -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, const char *name,
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, const char *name,
* 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, const char *name,
* 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, const char *name)
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 @@ bad_block: ext3_error(inode->i_sb, "ext3_xattr_get",
* 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_xattr_list",
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_xattr_list",
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;
......
......@@ -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, struct ext3_xattr_handler *);
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);
......
......@@ -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 inode *inode,
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;
......
......@@ -57,8 +57,8 @@ extern int __jfs_setxattr(struct inode *, const char *, const void *, size_t,
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 */
......@@ -962,12 +962,13 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
}
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 * dentry, char *data, size_t buf_size)
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);
}
......@@ -160,7 +160,7 @@ getxattr(struct dentry *d, char *name, void *value, size_t size)
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, size_t size)
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:
......
......@@ -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;
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment