Merge tag 'tags/bcm2835-dt-next-2019-03-04' into devicetree/fixes
[linux-2.6-microblaze.git] / fs / overlayfs / util.c
index 7c01327..4035e64 100644 (file)
@@ -863,28 +863,49 @@ bool ovl_is_metacopy_dentry(struct dentry *dentry)
        return (oe->numlower > 1);
 }
 
-char *ovl_get_redirect_xattr(struct dentry *dentry, int padding)
+ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value,
+                    size_t padding)
 {
-       int res;
-       char *s, *next, *buf = NULL;
+       ssize_t res;
+       char *buf = NULL;
 
-       res = vfs_getxattr(dentry, OVL_XATTR_REDIRECT, NULL, 0);
+       res = vfs_getxattr(dentry, name, NULL, 0);
        if (res < 0) {
                if (res == -ENODATA || res == -EOPNOTSUPP)
-                       return NULL;
+                       return -ENODATA;
                goto fail;
        }
 
-       buf = kzalloc(res + padding + 1, GFP_KERNEL);
-       if (!buf)
-               return ERR_PTR(-ENOMEM);
+       if (res != 0) {
+               buf = kzalloc(res + padding, GFP_KERNEL);
+               if (!buf)
+                       return -ENOMEM;
 
-       if (res == 0)
-               goto invalid;
+               res = vfs_getxattr(dentry, name, buf, res);
+               if (res < 0)
+                       goto fail;
+       }
+       *value = buf;
+
+       return res;
+
+fail:
+       pr_warn_ratelimited("overlayfs: failed to get xattr %s: err=%zi)\n",
+                           name, res);
+       kfree(buf);
+       return res;
+}
 
-       res = vfs_getxattr(dentry, OVL_XATTR_REDIRECT, buf, res);
+char *ovl_get_redirect_xattr(struct dentry *dentry, int padding)
+{
+       int res;
+       char *s, *next, *buf = NULL;
+
+       res = ovl_getxattr(dentry, OVL_XATTR_REDIRECT, &buf, padding + 1);
+       if (res == -ENODATA)
+               return NULL;
        if (res < 0)
-               goto fail;
+               return ERR_PTR(res);
        if (res == 0)
                goto invalid;
 
@@ -900,15 +921,9 @@ char *ovl_get_redirect_xattr(struct dentry *dentry, int padding)
        }
 
        return buf;
-
-err_free:
-       kfree(buf);
-       return ERR_PTR(res);
-fail:
-       pr_warn_ratelimited("overlayfs: failed to get redirect (%i)\n", res);
-       goto err_free;
 invalid:
        pr_warn_ratelimited("overlayfs: invalid redirect (%s)\n", buf);
        res = -EINVAL;
-       goto err_free;
+       kfree(buf);
+       return ERR_PTR(res);
 }