summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2016-09-29 17:48:35 +0200
committerAl Viro <viro@zeniv.linux.org.uk>2016-10-06 22:17:38 -0400
commitbba0bd31b117cba754322f337e61def53d9b22e5 (patch)
tree3f7375e4de89f61828f65c18f34359be80199f8d
parent971df15bd54ad46e907046ff33750a137b2f0096 (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.c7
-rw-r--r--include/linux/fs.h17
-rw-r--r--net/socket.c50
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,
};