diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2016-09-29 17:48:35 +0200 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-10-06 22:17:38 -0400 |
commit | bba0bd31b117cba754322f337e61def53d9b22e5 (patch) | |
tree | 3f7375e4de89f61828f65c18f34359be80199f8d | |
parent | 971df15bd54ad46e907046ff33750a137b2f0096 (diff) |
sockfs: Get rid of getxattr iop
If we allow pseudo-filesystems created with mount_pseudo to have xattr
handlers, we can replace sockfs_getxattr with a sockfs_xattr_get handler
to use the xattr handler name parsing.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/libfs.c | 7 | ||||
-rw-r--r-- | include/linux/fs.h | 17 | ||||
-rw-r--r-- | net/socket.c | 50 |
3 files changed, 47 insertions, 27 deletions
diff --git a/fs/libfs.c b/fs/libfs.c index 74dc8b9e7f53..cfa9576ea886 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -236,8 +236,8 @@ static const struct super_operations simple_super_operations = { * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that * will never be mountable) */ -struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name, - const struct super_operations *ops, +struct dentry *mount_pseudo_xattr(struct file_system_type *fs_type, char *name, + const struct super_operations *ops, const struct xattr_handler **xattr, const struct dentry_operations *dops, unsigned long magic) { struct super_block *s; @@ -254,6 +254,7 @@ struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name, s->s_blocksize_bits = PAGE_SHIFT; s->s_magic = magic; s->s_op = ops ? ops : &simple_super_operations; + s->s_xattr = xattr; s->s_time_gran = 1; root = new_inode(s); if (!root) @@ -281,7 +282,7 @@ Enomem: deactivate_locked_super(s); return ERR_PTR(-ENOMEM); } -EXPORT_SYMBOL(mount_pseudo); +EXPORT_SYMBOL(mount_pseudo_xattr); int simple_open(struct inode *inode, struct file *file) { diff --git a/include/linux/fs.h b/include/linux/fs.h index 901e25d495cc..7540e872591a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2075,10 +2075,19 @@ struct super_block *sget(struct file_system_type *type, int (*test)(struct super_block *,void *), int (*set)(struct super_block *,void *), int flags, void *data); -extern struct dentry *mount_pseudo(struct file_system_type *, char *, - const struct super_operations *ops, - const struct dentry_operations *dops, - unsigned long); +extern struct dentry *mount_pseudo_xattr(struct file_system_type *, char *, + const struct super_operations *ops, + const struct xattr_handler **xattr, + const struct dentry_operations *dops, + unsigned long); + +static inline struct dentry * +mount_pseudo(struct file_system_type *fs_type, char *name, + const struct super_operations *ops, + const struct dentry_operations *dops, unsigned long magic) +{ + return mount_pseudo_xattr(fs_type, name, ops, NULL, dops, magic); +} /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ #define fops_get(fops) \ diff --git a/net/socket.c b/net/socket.c index 9b3dca699a3d..976f7324887b 100644 --- a/net/socket.c +++ b/net/socket.c @@ -320,11 +320,38 @@ static const struct dentry_operations sockfs_dentry_operations = { .d_dname = sockfs_dname, }; +static int sockfs_xattr_get(const struct xattr_handler *handler, + struct dentry *dentry, struct inode *inode, + const char *suffix, void *value, size_t size) +{ + if (value) { + if (dentry->d_name.len + 1 > size) + return -ERANGE; + memcpy(value, dentry->d_name.name, dentry->d_name.len + 1); + } + return dentry->d_name.len + 1; +} + +#define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname" +#define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX) +#define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1) + +static const struct xattr_handler sockfs_xattr_handler = { + .name = XATTR_NAME_SOCKPROTONAME, + .get = sockfs_xattr_get, +}; + +static const struct xattr_handler *sockfs_xattr_handlers[] = { + &sockfs_xattr_handler, + NULL +}; + static struct dentry *sockfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { - return mount_pseudo(fs_type, "socket:", &sockfs_ops, - &sockfs_dentry_operations, SOCKFS_MAGIC); + return mount_pseudo_xattr(fs_type, "socket:", &sockfs_ops, + sockfs_xattr_handlers, + &sockfs_dentry_operations, SOCKFS_MAGIC); } static struct vfsmount *sock_mnt __read_mostly; @@ -463,23 +490,6 @@ static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed) return NULL; } -#define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname" -#define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX) -#define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1) -static ssize_t sockfs_getxattr(struct dentry *dentry, struct inode *inode, - const char *name, void *value, size_t size) -{ - if (!strcmp(name, XATTR_NAME_SOCKPROTONAME)) { - if (value) { - if (dentry->d_name.len + 1 > size) - return -ERANGE; - memcpy(value, dentry->d_name.name, dentry->d_name.len + 1); - } - return dentry->d_name.len + 1; - } - return -EOPNOTSUPP; -} - static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer, size_t size) { @@ -509,7 +519,7 @@ static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer, } static const struct inode_operations sockfs_inode_ops = { - .getxattr = sockfs_getxattr, + .getxattr = generic_getxattr, .listxattr = sockfs_listxattr, }; |