diff options
Diffstat (limited to 'net/socket.c')
-rw-r--r-- | net/socket.c | 61 |
1 files changed, 29 insertions, 32 deletions
diff --git a/net/socket.c b/net/socket.c index a1bd16106625..5a9bf5ee2464 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -320,11 +320,38 @@ static const struct dentry_operations sockfs_dentry_operations = { | |||
320 | .d_dname = sockfs_dname, | 320 | .d_dname = sockfs_dname, |
321 | }; | 321 | }; |
322 | 322 | ||
323 | static int sockfs_xattr_get(const struct xattr_handler *handler, | ||
324 | struct dentry *dentry, struct inode *inode, | ||
325 | const char *suffix, void *value, size_t size) | ||
326 | { | ||
327 | if (value) { | ||
328 | if (dentry->d_name.len + 1 > size) | ||
329 | return -ERANGE; | ||
330 | memcpy(value, dentry->d_name.name, dentry->d_name.len + 1); | ||
331 | } | ||
332 | return dentry->d_name.len + 1; | ||
333 | } | ||
334 | |||
335 | #define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname" | ||
336 | #define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX) | ||
337 | #define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1) | ||
338 | |||
339 | static const struct xattr_handler sockfs_xattr_handler = { | ||
340 | .name = XATTR_NAME_SOCKPROTONAME, | ||
341 | .get = sockfs_xattr_get, | ||
342 | }; | ||
343 | |||
344 | static const struct xattr_handler *sockfs_xattr_handlers[] = { | ||
345 | &sockfs_xattr_handler, | ||
346 | NULL | ||
347 | }; | ||
348 | |||
323 | static struct dentry *sockfs_mount(struct file_system_type *fs_type, | 349 | static struct dentry *sockfs_mount(struct file_system_type *fs_type, |
324 | int flags, const char *dev_name, void *data) | 350 | int flags, const char *dev_name, void *data) |
325 | { | 351 | { |
326 | return mount_pseudo(fs_type, "socket:", &sockfs_ops, | 352 | return mount_pseudo_xattr(fs_type, "socket:", &sockfs_ops, |
327 | &sockfs_dentry_operations, SOCKFS_MAGIC); | 353 | sockfs_xattr_handlers, |
354 | &sockfs_dentry_operations, SOCKFS_MAGIC); | ||
328 | } | 355 | } |
329 | 356 | ||
330 | static struct vfsmount *sock_mnt __read_mostly; | 357 | static struct vfsmount *sock_mnt __read_mostly; |
@@ -463,35 +490,6 @@ static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed) | |||
463 | return NULL; | 490 | return NULL; |
464 | } | 491 | } |
465 | 492 | ||
466 | #define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname" | ||
467 | #define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX) | ||
468 | #define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1) | ||
469 | static ssize_t sockfs_getxattr(struct dentry *dentry, struct inode *inode, | ||
470 | const char *name, void *value, size_t size) | ||
471 | { | ||
472 | const char *proto_name; | ||
473 | size_t proto_size; | ||
474 | int error; | ||
475 | |||
476 | error = -ENODATA; | ||
477 | if (!strncmp(name, XATTR_NAME_SOCKPROTONAME, XATTR_NAME_SOCKPROTONAME_LEN)) { | ||
478 | proto_name = dentry->d_name.name; | ||
479 | proto_size = strlen(proto_name); | ||
480 | |||
481 | if (value) { | ||
482 | error = -ERANGE; | ||
483 | if (proto_size + 1 > size) | ||
484 | goto out; | ||
485 | |||
486 | strncpy(value, proto_name, proto_size + 1); | ||
487 | } | ||
488 | error = proto_size + 1; | ||
489 | } | ||
490 | |||
491 | out: | ||
492 | return error; | ||
493 | } | ||
494 | |||
495 | static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer, | 493 | static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer, |
496 | size_t size) | 494 | size_t size) |
497 | { | 495 | { |
@@ -521,7 +519,6 @@ static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer, | |||
521 | } | 519 | } |
522 | 520 | ||
523 | static const struct inode_operations sockfs_inode_ops = { | 521 | static const struct inode_operations sockfs_inode_ops = { |
524 | .getxattr = sockfs_getxattr, | ||
525 | .listxattr = sockfs_listxattr, | 522 | .listxattr = sockfs_listxattr, |
526 | }; | 523 | }; |
527 | 524 | ||