Commit dad7017a authored by Christian Brauner's avatar Christian Brauner Committed by Miklos Szeredi

ovl: use ovl_path_getxattr() wrapper

Add a helper that allows to retrieve ovl xattrs from either lower or
upper layers. To stop passing mnt and dentry separately everywhere use
struct path which more accurately reflects the tight coupling between
mount and dentry in this helper. Swich over all places to pass a path
argument that can operate on either upper or lower layers. This is
needed to support idmapped base layers with overlayfs.

Some helpers are always called with an upper dentry, which is now utilized
by these helpers to create the path.  Make this usage explicit by renaming
the argument to "upperdentry" and by renaming the function as well in some
cases.  Also add a check in ovl_do_getxattr() to catch misuse of these
functions.

Cc: <linux-unionfs@vger.kernel.org>
Tested-by: default avatarGiuseppe Scrivano <gscrivan@redhat.com>
Reviewed-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarChristian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent 22f289ce
...@@ -44,9 +44,9 @@ static bool ovl_must_copy_xattr(const char *name) ...@@ -44,9 +44,9 @@ static bool ovl_must_copy_xattr(const char *name)
!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN); !strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN);
} }
int ovl_copy_xattr(struct super_block *sb, struct dentry *old, int ovl_copy_xattr(struct super_block *sb, struct path *oldpath, struct dentry *new)
struct dentry *new)
{ {
struct dentry *old = oldpath->dentry;
ssize_t list_size, size, value_size = 0; ssize_t list_size, size, value_size = 0;
char *buf, *name, *value = NULL; char *buf, *name, *value = NULL;
int error = 0; int error = 0;
...@@ -94,9 +94,9 @@ int ovl_copy_xattr(struct super_block *sb, struct dentry *old, ...@@ -94,9 +94,9 @@ int ovl_copy_xattr(struct super_block *sb, struct dentry *old,
continue; /* Discard */ continue; /* Discard */
} }
retry: retry:
size = vfs_getxattr(&init_user_ns, old, name, value, value_size); size = ovl_do_getxattr(oldpath, name, value, value_size);
if (size == -ERANGE) if (size == -ERANGE)
size = vfs_getxattr(&init_user_ns, old, name, NULL, 0); size = ovl_do_getxattr(oldpath, name, NULL, 0);
if (size < 0) { if (size < 0) {
error = size; error = size;
...@@ -582,7 +582,7 @@ static int ovl_copy_up_inode(struct ovl_copy_up_ctx *c, struct dentry *temp) ...@@ -582,7 +582,7 @@ static int ovl_copy_up_inode(struct ovl_copy_up_ctx *c, struct dentry *temp)
return err; return err;
} }
err = ovl_copy_xattr(c->dentry->d_sb, c->lowerpath.dentry, temp); err = ovl_copy_xattr(c->dentry->d_sb, &c->lowerpath, temp);
if (err) if (err)
return err; return err;
...@@ -873,13 +873,12 @@ static bool ovl_need_meta_copy_up(struct dentry *dentry, umode_t mode, ...@@ -873,13 +873,12 @@ static bool ovl_need_meta_copy_up(struct dentry *dentry, umode_t mode,
return true; return true;
} }
static ssize_t ovl_getxattr_value(struct ovl_fs *ofs, struct dentry *dentry, static ssize_t ovl_getxattr_value(struct path *path, char *name, char **value)
char *name, char **value)
{ {
ssize_t res; ssize_t res;
char *buf; char *buf;
res = ovl_do_getxattr(ofs, dentry, name, NULL, 0); res = ovl_do_getxattr(path, name, NULL, 0);
if (res == -ENODATA || res == -EOPNOTSUPP) if (res == -ENODATA || res == -EOPNOTSUPP)
res = 0; res = 0;
...@@ -888,7 +887,7 @@ static ssize_t ovl_getxattr_value(struct ovl_fs *ofs, struct dentry *dentry, ...@@ -888,7 +887,7 @@ static ssize_t ovl_getxattr_value(struct ovl_fs *ofs, struct dentry *dentry,
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
res = ovl_do_getxattr(ofs, dentry, name, buf, res); res = ovl_do_getxattr(path, name, buf, res);
if (res < 0) if (res < 0)
kfree(buf); kfree(buf);
else else
...@@ -915,8 +914,8 @@ static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c) ...@@ -915,8 +914,8 @@ static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c)
return -EIO; return -EIO;
if (c->stat.size) { if (c->stat.size) {
err = cap_size = ovl_getxattr_value(ofs, upperpath.dentry, err = cap_size = ovl_getxattr_value(&upperpath, XATTR_NAME_CAPS,
XATTR_NAME_CAPS, &capability); &capability);
if (cap_size < 0) if (cap_size < 0)
goto out; goto out;
} }
......
...@@ -398,7 +398,7 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry, ...@@ -398,7 +398,7 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry,
if (IS_ERR(opaquedir)) if (IS_ERR(opaquedir))
goto out_unlock; goto out_unlock;
err = ovl_copy_xattr(dentry->d_sb, upper, opaquedir); err = ovl_copy_xattr(dentry->d_sb, &upperpath, opaquedir);
if (err) if (err)
goto out_cleanup; goto out_cleanup;
......
...@@ -899,8 +899,8 @@ unsigned int ovl_get_nlink(struct ovl_fs *ofs, struct dentry *lowerdentry, ...@@ -899,8 +899,8 @@ unsigned int ovl_get_nlink(struct ovl_fs *ofs, struct dentry *lowerdentry,
if (!lowerdentry || !upperdentry || d_inode(lowerdentry)->i_nlink == 1) if (!lowerdentry || !upperdentry || d_inode(lowerdentry)->i_nlink == 1)
return fallback; return fallback;
err = ovl_getxattr(ofs, upperdentry, OVL_XATTR_NLINK, err = ovl_getxattr_upper(ofs, upperdentry, OVL_XATTR_NLINK,
&buf, sizeof(buf) - 1); &buf, sizeof(buf) - 1);
if (err < 0) if (err < 0)
goto fail; goto fail;
...@@ -1104,6 +1104,10 @@ struct inode *ovl_get_inode(struct super_block *sb, ...@@ -1104,6 +1104,10 @@ struct inode *ovl_get_inode(struct super_block *sb,
struct inode *realinode = upperdentry ? d_inode(upperdentry) : NULL; struct inode *realinode = upperdentry ? d_inode(upperdentry) : NULL;
struct inode *inode; struct inode *inode;
struct dentry *lowerdentry = lowerpath ? lowerpath->dentry : NULL; struct dentry *lowerdentry = lowerpath ? lowerpath->dentry : NULL;
struct path realpath = {
.dentry = upperdentry ?: lowerdentry,
.mnt = upperdentry ? ovl_upper_mnt(ofs) : lowerpath->layer->mnt,
};
bool bylower = ovl_hash_bylower(sb, upperdentry, lowerdentry, bool bylower = ovl_hash_bylower(sb, upperdentry, lowerdentry,
oip->index); oip->index);
int fsid = bylower ? lowerpath->layer->fsid : 0; int fsid = bylower ? lowerpath->layer->fsid : 0;
...@@ -1177,7 +1181,7 @@ struct inode *ovl_get_inode(struct super_block *sb, ...@@ -1177,7 +1181,7 @@ struct inode *ovl_get_inode(struct super_block *sb,
/* Check for non-merge dir that may have whiteouts */ /* Check for non-merge dir that may have whiteouts */
if (is_dir) { if (is_dir) {
if (((upperdentry && lowerdentry) || oip->numlower > 1) || if (((upperdentry && lowerdentry) || oip->numlower > 1) ||
ovl_check_origin_xattr(ofs, upperdentry ?: lowerdentry)) { ovl_path_check_origin_xattr(ofs, &realpath)) {
ovl_set_flag(OVL_WHITEOUTS, inode); ovl_set_flag(OVL_WHITEOUTS, inode);
} }
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
struct ovl_lookup_data { struct ovl_lookup_data {
struct super_block *sb; struct super_block *sb;
struct vfsmount *mnt;
struct qstr name; struct qstr name;
bool is_dir; bool is_dir;
bool opaque; bool opaque;
...@@ -25,14 +26,14 @@ struct ovl_lookup_data { ...@@ -25,14 +26,14 @@ struct ovl_lookup_data {
bool metacopy; bool metacopy;
}; };
static int ovl_check_redirect(struct dentry *dentry, struct ovl_lookup_data *d, static int ovl_check_redirect(struct path *path, struct ovl_lookup_data *d,
size_t prelen, const char *post) size_t prelen, const char *post)
{ {
int res; int res;
char *buf; char *buf;
struct ovl_fs *ofs = OVL_FS(d->sb); struct ovl_fs *ofs = OVL_FS(d->sb);
buf = ovl_get_redirect_xattr(ofs, dentry, prelen + strlen(post)); buf = ovl_get_redirect_xattr(ofs, path, prelen + strlen(post));
if (IS_ERR_OR_NULL(buf)) if (IS_ERR_OR_NULL(buf))
return PTR_ERR(buf); return PTR_ERR(buf);
...@@ -105,13 +106,13 @@ int ovl_check_fb_len(struct ovl_fb *fb, int fb_len) ...@@ -105,13 +106,13 @@ int ovl_check_fb_len(struct ovl_fb *fb, int fb_len)
return 0; return 0;
} }
static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *dentry, static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *upperdentry,
enum ovl_xattr ox) enum ovl_xattr ox)
{ {
int res, err; int res, err;
struct ovl_fh *fh = NULL; struct ovl_fh *fh = NULL;
res = ovl_getxattr(ofs, dentry, ox, NULL, 0); res = ovl_getxattr_upper(ofs, upperdentry, ox, NULL, 0);
if (res < 0) { if (res < 0) {
if (res == -ENODATA || res == -EOPNOTSUPP) if (res == -ENODATA || res == -EOPNOTSUPP)
return NULL; return NULL;
...@@ -125,7 +126,7 @@ static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *dentry, ...@@ -125,7 +126,7 @@ static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *dentry,
if (!fh) if (!fh)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
res = ovl_getxattr(ofs, dentry, ox, fh->buf, res); res = ovl_getxattr_upper(ofs, upperdentry, ox, fh->buf, res);
if (res < 0) if (res < 0)
goto fail; goto fail;
...@@ -193,9 +194,9 @@ struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh, ...@@ -193,9 +194,9 @@ struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh,
return real; return real;
} }
static bool ovl_is_opaquedir(struct super_block *sb, struct dentry *dentry) static bool ovl_is_opaquedir(struct ovl_fs *ofs, struct path *path)
{ {
return ovl_check_dir_xattr(sb, dentry, OVL_XATTR_OPAQUE); return ovl_path_check_dir_xattr(ofs, path, OVL_XATTR_OPAQUE);
} }
static struct dentry *ovl_lookup_positive_unlocked(const char *name, static struct dentry *ovl_lookup_positive_unlocked(const char *name,
...@@ -224,6 +225,7 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d, ...@@ -224,6 +225,7 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
struct dentry **ret, bool drop_negative) struct dentry **ret, bool drop_negative)
{ {
struct dentry *this; struct dentry *this;
struct path path;
int err; int err;
bool last_element = !post[0]; bool last_element = !post[0];
...@@ -253,12 +255,15 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d, ...@@ -253,12 +255,15 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
d->stop = true; d->stop = true;
goto put_and_out; goto put_and_out;
} }
path.dentry = this;
path.mnt = d->mnt;
if (!d_can_lookup(this)) { if (!d_can_lookup(this)) {
if (d->is_dir || !last_element) { if (d->is_dir || !last_element) {
d->stop = true; d->stop = true;
goto put_and_out; goto put_and_out;
} }
err = ovl_check_metacopy_xattr(OVL_FS(d->sb), this); err = ovl_check_metacopy_xattr(OVL_FS(d->sb), &path);
if (err < 0) if (err < 0)
goto out_err; goto out_err;
...@@ -278,14 +283,14 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d, ...@@ -278,14 +283,14 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
if (d->last) if (d->last)
goto out; goto out;
if (ovl_is_opaquedir(d->sb, this)) { if (ovl_is_opaquedir(OVL_FS(d->sb), &path)) {
d->stop = true; d->stop = true;
if (last_element) if (last_element)
d->opaque = true; d->opaque = true;
goto out; goto out;
} }
} }
err = ovl_check_redirect(this, d, prelen, post); err = ovl_check_redirect(&path, d, prelen, post);
if (err) if (err)
goto out_err; goto out_err;
out: out:
...@@ -856,6 +861,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ...@@ -856,6 +861,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
old_cred = ovl_override_creds(dentry->d_sb); old_cred = ovl_override_creds(dentry->d_sb);
upperdir = ovl_dentry_upper(dentry->d_parent); upperdir = ovl_dentry_upper(dentry->d_parent);
if (upperdir) { if (upperdir) {
d.mnt = ovl_upper_mnt(ofs);
err = ovl_lookup_layer(upperdir, &d, &upperdentry, true); err = ovl_lookup_layer(upperdir, &d, &upperdentry, true);
if (err) if (err)
goto out; goto out;
...@@ -911,6 +917,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ...@@ -911,6 +917,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
else else
d.last = lower.layer->idx == roe->numlower; d.last = lower.layer->idx == roe->numlower;
d.mnt = lower.layer->mnt;
err = ovl_lookup_layer(lower.dentry, &d, &this, false); err = ovl_lookup_layer(lower.dentry, &d, &this, false);
if (err) if (err)
goto out_put; goto out_put;
...@@ -1071,14 +1078,18 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ...@@ -1071,14 +1078,18 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
if (upperdentry) if (upperdentry)
ovl_dentry_set_upper_alias(dentry); ovl_dentry_set_upper_alias(dentry);
else if (index) { else if (index) {
upperdentry = dget(index); struct path upperpath = {
upperredirect = ovl_get_redirect_xattr(ofs, upperdentry, 0); .dentry = upperdentry = dget(index),
.mnt = ovl_upper_mnt(ofs),
};
upperredirect = ovl_get_redirect_xattr(ofs, &upperpath, 0);
if (IS_ERR(upperredirect)) { if (IS_ERR(upperredirect)) {
err = PTR_ERR(upperredirect); err = PTR_ERR(upperredirect);
upperredirect = NULL; upperredirect = NULL;
goto out_free_oe; goto out_free_oe;
} }
err = ovl_check_metacopy_xattr(ofs, upperdentry); err = ovl_check_metacopy_xattr(ofs, &upperpath);
if (err < 0) if (err < 0)
goto out_free_oe; goto out_free_oe;
uppermetacopy = err; uppermetacopy = err;
......
...@@ -218,30 +218,48 @@ static inline int ovl_do_symlink(struct ovl_fs *ofs, ...@@ -218,30 +218,48 @@ static inline int ovl_do_symlink(struct ovl_fs *ofs,
return err; return err;
} }
static inline ssize_t ovl_do_getxattr(struct ovl_fs *ofs, struct dentry *dentry, static inline ssize_t ovl_do_getxattr(struct path *path, const char *name,
const char *name, void *value, void *value, size_t size)
size_t size)
{ {
int err = vfs_getxattr(&init_user_ns, dentry, name, value, size); int err, len;
int len = (value && err > 0) ? err : 0;
WARN_ON(path->dentry->d_sb != path->mnt->mnt_sb);
err = vfs_getxattr(mnt_user_ns(path->mnt), path->dentry,
name, value, size);
len = (value && err > 0) ? err : 0;
pr_debug("getxattr(%pd2, \"%s\", \"%*pE\", %zu, 0) = %i\n", pr_debug("getxattr(%pd2, \"%s\", \"%*pE\", %zu, 0) = %i\n",
dentry, name, min(len, 48), value, size, err); path->dentry, name, min(len, 48), value, size, err);
return err; return err;
} }
static inline ssize_t ovl_getxattr(struct ovl_fs *ofs, struct dentry *dentry, static inline ssize_t ovl_getxattr_upper(struct ovl_fs *ofs,
enum ovl_xattr ox, void *value, struct dentry *upperdentry,
size_t size) enum ovl_xattr ox, void *value,
size_t size)
{
struct path upperpath = {
.dentry = upperdentry,
.mnt = ovl_upper_mnt(ofs),
};
return ovl_do_getxattr(&upperpath, ovl_xattr(ofs, ox), value, size);
}
static inline ssize_t ovl_path_getxattr(struct ovl_fs *ofs,
struct path *path,
enum ovl_xattr ox, void *value,
size_t size)
{ {
return ovl_do_getxattr(ofs, dentry, ovl_xattr(ofs, ox), value, size); return ovl_do_getxattr(path, ovl_xattr(ofs, ox), value, size);
} }
static inline int ovl_do_setxattr(struct ovl_fs *ofs, struct dentry *dentry, static inline int ovl_do_setxattr(struct ovl_fs *ofs, struct dentry *dentry,
const char *name, const void *value, const char *name, const void *value,
size_t size, int flags) size_t size, int flags)
{ {
int err = vfs_setxattr(&init_user_ns, dentry, name, value, size, flags); int err = vfs_setxattr(ovl_upper_mnt_userns(ofs), dentry, name, value, size, flags);
pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, %d) = %i\n", pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, %d) = %i\n",
dentry, name, min((int)size, 48), value, size, flags, err); dentry, name, min((int)size, 48), value, size, flags, err);
...@@ -258,7 +276,7 @@ static inline int ovl_setxattr(struct ovl_fs *ofs, struct dentry *dentry, ...@@ -258,7 +276,7 @@ static inline int ovl_setxattr(struct ovl_fs *ofs, struct dentry *dentry,
static inline int ovl_do_removexattr(struct ovl_fs *ofs, struct dentry *dentry, static inline int ovl_do_removexattr(struct ovl_fs *ofs, struct dentry *dentry,
const char *name) const char *name)
{ {
int err = vfs_removexattr(&init_user_ns, dentry, name); int err = vfs_removexattr(ovl_upper_mnt_userns(ofs), dentry, name);
pr_debug("removexattr(%pd2, \"%s\") = %i\n", dentry, name, err); pr_debug("removexattr(%pd2, \"%s\") = %i\n", dentry, name, err);
return err; return err;
} }
...@@ -394,9 +412,20 @@ struct file *ovl_path_open(struct path *path, int flags); ...@@ -394,9 +412,20 @@ struct file *ovl_path_open(struct path *path, int flags);
int ovl_copy_up_start(struct dentry *dentry, int flags); int ovl_copy_up_start(struct dentry *dentry, int flags);
void ovl_copy_up_end(struct dentry *dentry); void ovl_copy_up_end(struct dentry *dentry);
bool ovl_already_copied_up(struct dentry *dentry, int flags); bool ovl_already_copied_up(struct dentry *dentry, int flags);
bool ovl_check_origin_xattr(struct ovl_fs *ofs, struct dentry *dentry); bool ovl_path_check_dir_xattr(struct ovl_fs *ofs, struct path *path,
bool ovl_check_dir_xattr(struct super_block *sb, struct dentry *dentry, enum ovl_xattr ox);
enum ovl_xattr ox); bool ovl_path_check_origin_xattr(struct ovl_fs *ofs, struct path *path);
static inline bool ovl_check_origin_xattr(struct ovl_fs *ofs,
struct dentry *upperdentry)
{
struct path upperpath = {
.dentry = upperdentry,
.mnt = ovl_upper_mnt(ofs),
};
return ovl_path_check_origin_xattr(ofs, &upperpath);
}
int ovl_check_setxattr(struct ovl_fs *ofs, struct dentry *upperdentry, int ovl_check_setxattr(struct ovl_fs *ofs, struct dentry *upperdentry,
enum ovl_xattr ox, const void *value, size_t size, enum ovl_xattr ox, const void *value, size_t size,
int xerr); int xerr);
...@@ -408,10 +437,9 @@ bool ovl_need_index(struct dentry *dentry); ...@@ -408,10 +437,9 @@ bool ovl_need_index(struct dentry *dentry);
int ovl_nlink_start(struct dentry *dentry); int ovl_nlink_start(struct dentry *dentry);
void ovl_nlink_end(struct dentry *dentry); void ovl_nlink_end(struct dentry *dentry);
int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir); int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir);
int ovl_check_metacopy_xattr(struct ovl_fs *ofs, struct dentry *dentry); int ovl_check_metacopy_xattr(struct ovl_fs *ofs, struct path *path);
bool ovl_is_metacopy_dentry(struct dentry *dentry); bool ovl_is_metacopy_dentry(struct dentry *dentry);
char *ovl_get_redirect_xattr(struct ovl_fs *ofs, struct dentry *dentry, char *ovl_get_redirect_xattr(struct ovl_fs *ofs, struct path *path, int padding);
int padding);
int ovl_sync_status(struct ovl_fs *ofs); int ovl_sync_status(struct ovl_fs *ofs);
static inline void ovl_set_flag(unsigned long flag, struct inode *inode) static inline void ovl_set_flag(unsigned long flag, struct inode *inode)
...@@ -430,9 +458,15 @@ static inline bool ovl_test_flag(unsigned long flag, struct inode *inode) ...@@ -430,9 +458,15 @@ static inline bool ovl_test_flag(unsigned long flag, struct inode *inode)
} }
static inline bool ovl_is_impuredir(struct super_block *sb, static inline bool ovl_is_impuredir(struct super_block *sb,
struct dentry *dentry) struct dentry *upperdentry)
{ {
return ovl_check_dir_xattr(sb, dentry, OVL_XATTR_IMPURE); struct ovl_fs *ofs = OVL_FS(sb);
struct path upperpath = {
.dentry = upperdentry,
.mnt = ovl_upper_mnt(ofs),
};
return ovl_path_check_dir_xattr(ofs, &upperpath, OVL_XATTR_IMPURE);
} }
/* /*
...@@ -659,8 +693,7 @@ int ovl_fileattr_set(struct user_namespace *mnt_userns, ...@@ -659,8 +693,7 @@ int ovl_fileattr_set(struct user_namespace *mnt_userns,
int ovl_copy_up(struct dentry *dentry); int ovl_copy_up(struct dentry *dentry);
int ovl_copy_up_with_data(struct dentry *dentry); int ovl_copy_up_with_data(struct dentry *dentry);
int ovl_maybe_copy_up(struct dentry *dentry, int flags); int ovl_maybe_copy_up(struct dentry *dentry, int flags);
int ovl_copy_xattr(struct super_block *sb, struct dentry *old, int ovl_copy_xattr(struct super_block *sb, struct path *path, struct dentry *new);
struct dentry *new);
int ovl_set_attr(struct ovl_fs *ofs, struct dentry *upper, struct kstat *stat); int ovl_set_attr(struct ovl_fs *ofs, struct dentry *upper, struct kstat *stat);
struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct dentry *real, struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct dentry *real,
bool is_upper); bool is_upper);
......
...@@ -564,11 +564,11 @@ void ovl_copy_up_end(struct dentry *dentry) ...@@ -564,11 +564,11 @@ void ovl_copy_up_end(struct dentry *dentry)
ovl_inode_unlock(d_inode(dentry)); ovl_inode_unlock(d_inode(dentry));
} }
bool ovl_check_origin_xattr(struct ovl_fs *ofs, struct dentry *dentry) bool ovl_path_check_origin_xattr(struct ovl_fs *ofs, struct path *path)
{ {
int res; int res;
res = ovl_getxattr(ofs, dentry, OVL_XATTR_ORIGIN, NULL, 0); res = ovl_path_getxattr(ofs, path, OVL_XATTR_ORIGIN, NULL, 0);
/* Zero size value means "copied up but origin unknown" */ /* Zero size value means "copied up but origin unknown" */
if (res >= 0) if (res >= 0)
...@@ -577,16 +577,16 @@ bool ovl_check_origin_xattr(struct ovl_fs *ofs, struct dentry *dentry) ...@@ -577,16 +577,16 @@ bool ovl_check_origin_xattr(struct ovl_fs *ofs, struct dentry *dentry)
return false; return false;
} }
bool ovl_check_dir_xattr(struct super_block *sb, struct dentry *dentry, bool ovl_path_check_dir_xattr(struct ovl_fs *ofs, struct path *path,
enum ovl_xattr ox) enum ovl_xattr ox)
{ {
int res; int res;
char val; char val;
if (!d_is_dir(dentry)) if (!d_is_dir(path->dentry))
return false; return false;
res = ovl_getxattr(OVL_FS(sb), dentry, ox, &val, 1); res = ovl_path_getxattr(ofs, path, ox, &val, 1);
if (res == 1 && val == 'y') if (res == 1 && val == 'y')
return true; return true;
...@@ -666,8 +666,8 @@ void ovl_check_protattr(struct inode *inode, struct dentry *upper) ...@@ -666,8 +666,8 @@ void ovl_check_protattr(struct inode *inode, struct dentry *upper)
char buf[OVL_PROTATTR_MAX+1]; char buf[OVL_PROTATTR_MAX+1];
int res, n; int res, n;
res = ovl_getxattr(ofs, upper, OVL_XATTR_PROTATTR, buf, res = ovl_getxattr_upper(ofs, upper, OVL_XATTR_PROTATTR, buf,
OVL_PROTATTR_MAX); OVL_PROTATTR_MAX);
if (res < 0) if (res < 0)
return; return;
...@@ -957,15 +957,15 @@ int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir) ...@@ -957,15 +957,15 @@ int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir)
} }
/* err < 0, 0 if no metacopy xattr, 1 if metacopy xattr found */ /* err < 0, 0 if no metacopy xattr, 1 if metacopy xattr found */
int ovl_check_metacopy_xattr(struct ovl_fs *ofs, struct dentry *dentry) int ovl_check_metacopy_xattr(struct ovl_fs *ofs, struct path *path)
{ {
int res; int res;
/* Only regular files can have metacopy xattr */ /* Only regular files can have metacopy xattr */
if (!S_ISREG(d_inode(dentry)->i_mode)) if (!S_ISREG(d_inode(path->dentry)->i_mode))
return 0; return 0;
res = ovl_getxattr(ofs, dentry, OVL_XATTR_METACOPY, NULL, 0); res = ovl_path_getxattr(ofs, path, OVL_XATTR_METACOPY, NULL, 0);
if (res < 0) { if (res < 0) {
if (res == -ENODATA || res == -EOPNOTSUPP) if (res == -ENODATA || res == -EOPNOTSUPP)
return 0; return 0;
...@@ -1001,13 +1001,12 @@ bool ovl_is_metacopy_dentry(struct dentry *dentry) ...@@ -1001,13 +1001,12 @@ bool ovl_is_metacopy_dentry(struct dentry *dentry)
return (oe->numlower > 1); return (oe->numlower > 1);
} }
char *ovl_get_redirect_xattr(struct ovl_fs *ofs, struct dentry *dentry, char *ovl_get_redirect_xattr(struct ovl_fs *ofs, struct path *path, int padding)
int padding)
{ {
int res; int res;
char *s, *next, *buf = NULL; char *s, *next, *buf = NULL;
res = ovl_getxattr(ofs, dentry, OVL_XATTR_REDIRECT, NULL, 0); res = ovl_path_getxattr(ofs, path, OVL_XATTR_REDIRECT, NULL, 0);
if (res == -ENODATA || res == -EOPNOTSUPP) if (res == -ENODATA || res == -EOPNOTSUPP)
return NULL; return NULL;
if (res < 0) if (res < 0)
...@@ -1019,7 +1018,7 @@ char *ovl_get_redirect_xattr(struct ovl_fs *ofs, struct dentry *dentry, ...@@ -1019,7 +1018,7 @@ char *ovl_get_redirect_xattr(struct ovl_fs *ofs, struct dentry *dentry,
if (!buf) if (!buf)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
res = ovl_getxattr(ofs, dentry, OVL_XATTR_REDIRECT, buf, res); res = ovl_path_getxattr(ofs, path, OVL_XATTR_REDIRECT, buf, res);
if (res < 0) if (res < 0)
goto fail; goto fail;
if (res == 0) if (res == 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment