diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 9d17e42d184bd7c43e86bb8f3fa41723939e97e5..6a471da0284fd4b94daa44b5e853faec002f51d8 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -784,6 +784,39 @@ static bool ovl_need_meta_copy_up(struct dentry *dentry, umode_t mode, return true; } +static ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value, + size_t padding) +{ + ssize_t res; + char *buf = NULL; + + res = vfs_getxattr(dentry, name, NULL, 0); + if (res < 0) { + if (res == -ENODATA || res == -EOPNOTSUPP) + return -ENODATA; + goto fail; + } + + if (res != 0) { + buf = kzalloc(res + padding, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + res = vfs_getxattr(dentry, name, buf, res); + if (res < 0) + goto fail; + } + *value = buf; + + return res; + +fail: + pr_warn_ratelimited("failed to get xattr %s: err=%zi)\n", + name, res); + kfree(buf); + return res; +} + /* Copy up data of an inode which was copied up metadata only in the past. */ static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c) { diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 29bc1ec699e7d7a2ef3c4d34534e665855a91de9..ebc03e08630013bbbafa18f48e9ede35ea8afc04 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -299,8 +299,6 @@ int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir); int ovl_check_metacopy_xattr(struct dentry *dentry); bool ovl_is_metacopy_dentry(struct dentry *dentry); char *ovl_get_redirect_xattr(struct dentry *dentry, int padding); -ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value, - size_t padding); static inline bool ovl_is_impuredir(struct dentry *dentry) { diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 56c1f89f20c9fd17e30839563f3a8298097ca90c..feca16a47f57b5d5c999b5cfa6fa50e93c83607d 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -882,8 +882,8 @@ bool ovl_is_metacopy_dentry(struct dentry *dentry) return (oe->numlower > 1); } -ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value, - size_t padding) +static ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value, + size_t padding) { ssize_t res; char *buf = NULL;