From 43d193f8440d67f0dddd93ae973eb94174039e83 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 2 Sep 2020 10:58:49 +0200 Subject: ovl: enumerate private xattrs Instead of passing the xattr name down to the ovl_do_*xattr() accessor functions, pass an enumerated value. The enum can use the same names as the the previous #define for each xattr name. Signed-off-by: Miklos Szeredi --- fs/overlayfs/namei.c | 16 ++++++++-------- fs/overlayfs/overlayfs.h | 38 +++++++++++++++++++++++++------------- fs/overlayfs/util.c | 31 ++++++++++++++++++++++++++----- 3 files changed, 59 insertions(+), 26 deletions(-) (limited to 'fs/overlayfs') diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index 56b8d3afa1f2..a6162c4076db 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -106,12 +106,12 @@ int ovl_check_fb_len(struct ovl_fb *fb, int fb_len) } static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *dentry, - const char *name) + enum ovl_xattr ox) { int res, err; struct ovl_fh *fh = NULL; - res = ovl_do_getxattr(ofs, dentry, name, NULL, 0); + res = ovl_do_getxattr(ofs, dentry, ox, NULL, 0); if (res < 0) { if (res == -ENODATA || res == -EOPNOTSUPP) return NULL; @@ -125,7 +125,7 @@ static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *dentry, if (!fh) return ERR_PTR(-ENOMEM); - res = ovl_do_getxattr(ofs, dentry, name, fh->buf, res); + res = ovl_do_getxattr(ofs, dentry, ox, fh->buf, res); if (res < 0) goto fail; @@ -416,9 +416,9 @@ static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry, * Return 0 on match, -ESTALE on mismatch, < 0 on error. */ static int ovl_verify_fh(struct ovl_fs *ofs, struct dentry *dentry, - const char *name, const struct ovl_fh *fh) + enum ovl_xattr ox, const struct ovl_fh *fh) { - struct ovl_fh *ofh = ovl_get_fh(ofs, dentry, name); + struct ovl_fh *ofh = ovl_get_fh(ofs, dentry, ox); int err = 0; if (!ofh) @@ -443,7 +443,7 @@ static int ovl_verify_fh(struct ovl_fs *ofs, struct dentry *dentry, * Return 0 on match, -ESTALE on mismatch, -ENODATA on no xattr, < 0 on error. */ int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, - const char *name, struct dentry *real, bool is_upper, + enum ovl_xattr ox, struct dentry *real, bool is_upper, bool set) { struct inode *inode; @@ -457,9 +457,9 @@ int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, goto fail; } - err = ovl_verify_fh(ofs, dentry, name, fh); + err = ovl_verify_fh(ofs, dentry, ox, fh); if (set && err == -ENODATA) - err = ovl_do_setxattr(ofs, dentry, name, fh->buf, fh->fb.len); + err = ovl_do_setxattr(ofs, dentry, ox, fh->buf, fh->fb.len); if (err) goto fail; diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index feef0eadc5b3..7bce2469fe55 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -23,13 +23,16 @@ enum ovl_path_type { #define OVL_TYPE_ORIGIN(type) ((type) & __OVL_PATH_ORIGIN) #define OVL_XATTR_PREFIX XATTR_TRUSTED_PREFIX "overlay." -#define OVL_XATTR_OPAQUE OVL_XATTR_PREFIX "opaque" -#define OVL_XATTR_REDIRECT OVL_XATTR_PREFIX "redirect" -#define OVL_XATTR_ORIGIN OVL_XATTR_PREFIX "origin" -#define OVL_XATTR_IMPURE OVL_XATTR_PREFIX "impure" -#define OVL_XATTR_NLINK OVL_XATTR_PREFIX "nlink" -#define OVL_XATTR_UPPER OVL_XATTR_PREFIX "upper" -#define OVL_XATTR_METACOPY OVL_XATTR_PREFIX "metacopy" + +enum ovl_xattr { + OVL_XATTR_OPAQUE, + OVL_XATTR_REDIRECT, + OVL_XATTR_ORIGIN, + OVL_XATTR_IMPURE, + OVL_XATTR_NLINK, + OVL_XATTR_UPPER, + OVL_XATTR_METACOPY, +}; enum ovl_inode_flag { /* Pure upper dir that may contain non pure upper entries */ @@ -110,6 +113,12 @@ struct ovl_fh { #define OVL_FH_FID_OFFSET (OVL_FH_WIRE_OFFSET + \ offsetof(struct ovl_fb, fid)) +extern const char *ovl_xattr_table[]; +static inline const char *ovl_xattr(struct ovl_fs *ofs, enum ovl_xattr ox) +{ + return ovl_xattr_table[ox]; +} + static inline int ovl_do_rmdir(struct inode *dir, struct dentry *dentry) { int err = vfs_rmdir(dir, dentry); @@ -171,16 +180,18 @@ static inline int ovl_do_symlink(struct inode *dir, struct dentry *dentry, } static inline ssize_t ovl_do_getxattr(struct ovl_fs *ofs, struct dentry *dentry, - const char *name, void *value, + enum ovl_xattr ox, void *value, size_t size) { + const char *name = ovl_xattr(ofs, ox); return vfs_getxattr(dentry, name, value, size); } static inline int ovl_do_setxattr(struct ovl_fs *ofs, struct dentry *dentry, - const char *name, const void *value, + enum ovl_xattr ox, const void *value, size_t size) { + const char *name = ovl_xattr(ofs, ox); int err = vfs_setxattr(dentry, name, value, size, 0); pr_debug("setxattr(%pd2, \"%s\", \"%*pE\", %zu, 0) = %i\n", dentry, name, min((int)size, 48), value, size, err); @@ -188,8 +199,9 @@ static inline int ovl_do_setxattr(struct ovl_fs *ofs, struct dentry *dentry, } static inline int ovl_do_removexattr(struct ovl_fs *ofs, struct dentry *dentry, - const char *name) + enum ovl_xattr ox) { + const char *name = ovl_xattr(ofs, ox); int err = vfs_removexattr(dentry, name); pr_debug("removexattr(%pd2, \"%s\") = %i\n", dentry, name, err); return err; @@ -291,9 +303,9 @@ void ovl_copy_up_end(struct dentry *dentry); bool ovl_already_copied_up(struct dentry *dentry, int flags); bool ovl_check_origin_xattr(struct ovl_fs *ofs, struct dentry *dentry); bool ovl_check_dir_xattr(struct super_block *sb, struct dentry *dentry, - const char *name); + enum ovl_xattr ox); int ovl_check_setxattr(struct dentry *dentry, struct dentry *upperdentry, - const char *name, const void *value, size_t size, + enum ovl_xattr ox, const void *value, size_t size, int xerr); int ovl_set_impure(struct dentry *dentry, struct dentry *upperdentry); void ovl_set_flag(unsigned long flag, struct inode *inode); @@ -376,7 +388,7 @@ struct dentry *ovl_decode_real_fh(struct ovl_fh *fh, struct vfsmount *mnt, int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected, struct dentry *upperdentry, struct ovl_path **stackp); int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, - const char *name, struct dentry *real, bool is_upper, + enum ovl_xattr ox, struct dentry *real, bool is_upper, bool set); struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index); int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index); diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 17bfc19625d0..23f475627d07 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -558,7 +558,7 @@ bool ovl_check_origin_xattr(struct ovl_fs *ofs, struct dentry *dentry) } bool ovl_check_dir_xattr(struct super_block *sb, struct dentry *dentry, - const char *name) + enum ovl_xattr ox) { int res; char val; @@ -566,15 +566,36 @@ bool ovl_check_dir_xattr(struct super_block *sb, struct dentry *dentry, if (!d_is_dir(dentry)) return false; - res = ovl_do_getxattr(OVL_FS(sb), dentry, name, &val, 1); + res = ovl_do_getxattr(OVL_FS(sb), dentry, ox, &val, 1); if (res == 1 && val == 'y') return true; return false; } +#define OVL_XATTR_OPAQUE_POSTFIX "opaque" +#define OVL_XATTR_REDIRECT_POSTFIX "redirect" +#define OVL_XATTR_ORIGIN_POSTFIX "origin" +#define OVL_XATTR_IMPURE_POSTFIX "impure" +#define OVL_XATTR_NLINK_POSTFIX "nlink" +#define OVL_XATTR_UPPER_POSTFIX "upper" +#define OVL_XATTR_METACOPY_POSTFIX "metacopy" + +#define OVL_XATTR_TAB_ENTRY(x) \ + [x] = OVL_XATTR_PREFIX x ## _POSTFIX + +const char *ovl_xattr_table[] = { + OVL_XATTR_TAB_ENTRY(OVL_XATTR_OPAQUE), + OVL_XATTR_TAB_ENTRY(OVL_XATTR_REDIRECT), + OVL_XATTR_TAB_ENTRY(OVL_XATTR_ORIGIN), + OVL_XATTR_TAB_ENTRY(OVL_XATTR_IMPURE), + OVL_XATTR_TAB_ENTRY(OVL_XATTR_NLINK), + OVL_XATTR_TAB_ENTRY(OVL_XATTR_UPPER), + OVL_XATTR_TAB_ENTRY(OVL_XATTR_METACOPY), +}; + int ovl_check_setxattr(struct dentry *dentry, struct dentry *upperdentry, - const char *name, const void *value, size_t size, + enum ovl_xattr ox, const void *value, size_t size, int xerr) { int err; @@ -583,10 +604,10 @@ int ovl_check_setxattr(struct dentry *dentry, struct dentry *upperdentry, if (ofs->noxattr) return xerr; - err = ovl_do_setxattr(ofs, upperdentry, name, value, size); + err = ovl_do_setxattr(ofs, upperdentry, ox, value, size); if (err == -EOPNOTSUPP) { - pr_warn("cannot set %s xattr on upper\n", name); + pr_warn("cannot set %s xattr on upper\n", ovl_xattr(ofs, ox)); ofs->noxattr = true; return xerr; } -- cgit v1.2.3