kernfs: Add removed_size out param for simple_xattr_set
authorDaniel Xu <dxu@dxuuu.xyz>
Thu, 12 Mar 2020 20:03:15 +0000 (13:03 -0700)
committerTejun Heo <tj@kernel.org>
Mon, 16 Mar 2020 19:53:47 +0000 (15:53 -0400)
This helps set up size accounting in the next commit. Without this out
param, it's difficult to find out the removed xattr size without taking
a lock for longer and walking the xattr linked list twice.

Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>
Acked-by: Chris Down <chris@chrisdown.name>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Tejun Heo <tj@kernel.org>
fs/kernfs/inode.c
fs/xattr.c
include/linux/xattr.h
mm/shmem.c

index d0f7a5a..5f10ae9 100644 (file)
@@ -303,7 +303,7 @@ int kernfs_xattr_set(struct kernfs_node *kn, const char *name,
        if (!attrs)
                return -ENOMEM;
 
-       return simple_xattr_set(&attrs->xattrs, name, value, size, flags);
+       return simple_xattr_set(&attrs->xattrs, name, value, size, flags, NULL);
 }
 
 static int kernfs_vfs_xattr_get(const struct xattr_handler *handler,
index 0d3c9b4..e13265e 100644 (file)
@@ -860,6 +860,7 @@ int simple_xattr_get(struct simple_xattrs *xattrs, const char *name,
  * @value: value of the xattr. If %NULL, will remove the attribute.
  * @size: size of the new xattr
  * @flags: %XATTR_{CREATE|REPLACE}
+ * @removed_size: returns size of the removed xattr, -1 if none removed
  *
  * %XATTR_CREATE is set, the xattr shouldn't exist already; otherwise fails
  * with -EEXIST.  If %XATTR_REPLACE is set, the xattr should exist;
@@ -868,7 +869,8 @@ int simple_xattr_get(struct simple_xattrs *xattrs, const char *name,
  * Returns 0 on success, -errno on failure.
  */
 int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
-                    const void *value, size_t size, int flags)
+                    const void *value, size_t size, int flags,
+                    ssize_t *removed_size)
 {
        struct simple_xattr *xattr;
        struct simple_xattr *new_xattr = NULL;
@@ -895,8 +897,12 @@ int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
                                err = -EEXIST;
                        } else if (new_xattr) {
                                list_replace(&xattr->list, &new_xattr->list);
+                               if (removed_size)
+                                       *removed_size = xattr->size;
                        } else {
                                list_del(&xattr->list);
+                               if (removed_size)
+                                       *removed_size = xattr->size;
                        }
                        goto out;
                }
@@ -908,6 +914,9 @@ int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
                list_add(&new_xattr->list, &xattrs->head);
                xattr = NULL;
        }
+
+       if (removed_size)
+               *removed_size = -1;
 out:
        spin_unlock(&xattrs->lock);
        if (xattr) {
index 6dad031..4cf6e11 100644 (file)
@@ -102,7 +102,8 @@ struct simple_xattr *simple_xattr_alloc(const void *value, size_t size);
 int simple_xattr_get(struct simple_xattrs *xattrs, const char *name,
                     void *buffer, size_t size);
 int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
-                    const void *value, size_t size, int flags);
+                    const void *value, size_t size, int flags,
+                    ssize_t *removed_size);
 ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs, char *buffer,
                          size_t size);
 void simple_xattr_list_add(struct simple_xattrs *xattrs,
index c8f7540..e6a7549 100644 (file)
@@ -3243,7 +3243,7 @@ static int shmem_xattr_handler_set(const struct xattr_handler *handler,
        struct shmem_inode_info *info = SHMEM_I(inode);
 
        name = xattr_full_name(handler, name);
-       return simple_xattr_set(&info->xattrs, name, value, size, flags);
+       return simple_xattr_set(&info->xattrs, name, value, size, flags, NULL);
 }
 
 static const struct xattr_handler shmem_security_xattr_handler = {