Loading fs/overlayfs/copy_up.c +9 −7 Original line number Diff line number Diff line Loading @@ -43,7 +43,8 @@ static bool ovl_must_copy_xattr(const char *name) !strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN); } int ovl_copy_xattr(struct dentry *old, struct dentry *new) int ovl_copy_xattr(struct super_block *sb, struct dentry *old, struct dentry *new) { ssize_t list_size, size, value_size = 0; char *buf, *name, *value = NULL; Loading Loading @@ -81,7 +82,7 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new) } list_size -= slen; if (ovl_is_private_xattr(name)) if (ovl_is_private_xattr(sb, name)) continue; retry: size = vfs_getxattr(old, name, value, value_size); Loading Loading @@ -355,7 +356,8 @@ int ovl_set_origin(struct dentry *dentry, struct dentry *lower, } /* Store file handle of @upper dir in @index dir entry */ static int ovl_set_upper_fh(struct dentry *upper, struct dentry *index) static int ovl_set_upper_fh(struct ovl_fs *ofs, struct dentry *upper, struct dentry *index) { const struct ovl_fh *fh; int err; Loading @@ -364,7 +366,7 @@ static int ovl_set_upper_fh(struct dentry *upper, struct dentry *index) if (IS_ERR(fh)) return PTR_ERR(fh); err = ovl_do_setxattr(index, OVL_XATTR_UPPER, fh->buf, fh->fb.len); err = ovl_do_setxattr(ofs, index, OVL_XATTR_UPPER, fh->buf, fh->fb.len); kfree(fh); return err; Loading Loading @@ -409,7 +411,7 @@ static int ovl_create_index(struct dentry *dentry, struct dentry *origin, if (IS_ERR(temp)) goto free_name; err = ovl_set_upper_fh(upper, temp); err = ovl_set_upper_fh(OVL_FS(dentry->d_sb), upper, temp); if (err) goto out; Loading Loading @@ -507,7 +509,7 @@ static int ovl_copy_up_inode(struct ovl_copy_up_ctx *c, struct dentry *temp) return err; } err = ovl_copy_xattr(c->lowerpath.dentry, temp); err = ovl_copy_xattr(c->dentry->d_sb, c->lowerpath.dentry, temp); if (err) return err; Loading Loading @@ -847,7 +849,7 @@ static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c) } err = ovl_do_removexattr(upperpath.dentry, OVL_XATTR_METACOPY); err = ovl_do_removexattr(ofs, upperpath.dentry, OVL_XATTR_METACOPY); if (err) goto out_free; Loading fs/overlayfs/dir.c +1 −1 Original line number Diff line number Diff line Loading @@ -394,7 +394,7 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry, if (IS_ERR(opaquedir)) goto out_unlock; err = ovl_copy_xattr(upper, opaquedir); err = ovl_copy_xattr(dentry->d_sb, upper, opaquedir); if (err) goto out_cleanup; Loading fs/overlayfs/export.c +1 −1 Original line number Diff line number Diff line Loading @@ -752,7 +752,7 @@ static struct dentry *ovl_lower_fh_to_d(struct super_block *sb, goto out_err; } if (index) { err = ovl_verify_origin(index, origin.dentry, false); err = ovl_verify_origin(ofs, index, origin.dentry, false); if (err) goto out_err; } Loading fs/overlayfs/inode.c +12 −10 Original line number Diff line number Diff line Loading @@ -327,7 +327,7 @@ static const char *ovl_get_link(struct dentry *dentry, return p; } bool ovl_is_private_xattr(const char *name) bool ovl_is_private_xattr(struct super_block *sb, const char *name) { return strncmp(name, OVL_XATTR_PREFIX, sizeof(OVL_XATTR_PREFIX) - 1) == 0; Loading Loading @@ -391,14 +391,14 @@ int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, return res; } static bool ovl_can_list(const char *s) static bool ovl_can_list(struct super_block *sb, const char *s) { /* List all non-trusted xatts */ if (strncmp(s, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0) return true; /* Never list trusted.overlay, list other trusted for superuser only */ return !ovl_is_private_xattr(s) && return !ovl_is_private_xattr(sb, s) && ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN); } Loading @@ -425,7 +425,7 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) return -EIO; len -= slen; if (!ovl_can_list(s)) { if (!ovl_can_list(dentry->d_sb, s)) { res -= slen; memmove(s, s + slen, len); } else { Loading Loading @@ -722,7 +722,7 @@ static int ovl_set_nlink_common(struct dentry *dentry, if (WARN_ON(len >= sizeof(buf))) return -EIO; return ovl_do_setxattr(ovl_dentry_upper(dentry), return ovl_do_setxattr(OVL_FS(inode->i_sb), ovl_dentry_upper(dentry), OVL_XATTR_NLINK, buf, len); } Loading @@ -736,7 +736,7 @@ int ovl_set_nlink_lower(struct dentry *dentry) return ovl_set_nlink_common(dentry, ovl_dentry_lower(dentry), "L%+i"); } unsigned int ovl_get_nlink(struct dentry *lowerdentry, unsigned int ovl_get_nlink(struct ovl_fs *ofs, struct dentry *lowerdentry, struct dentry *upperdentry, unsigned int fallback) { Loading @@ -748,7 +748,7 @@ unsigned int ovl_get_nlink(struct dentry *lowerdentry, if (!lowerdentry || !upperdentry || d_inode(lowerdentry)->i_nlink == 1) return fallback; err = ovl_do_getxattr(upperdentry, OVL_XATTR_NLINK, err = ovl_do_getxattr(ofs, upperdentry, OVL_XATTR_NLINK, &buf, sizeof(buf) - 1); if (err < 0) goto fail; Loading Loading @@ -947,6 +947,7 @@ static struct inode *ovl_iget5(struct super_block *sb, struct inode *newinode, struct inode *ovl_get_inode(struct super_block *sb, struct ovl_inode_params *oip) { struct ovl_fs *ofs = OVL_FS(sb); struct dentry *upperdentry = oip->upperdentry; struct ovl_path *lowerpath = oip->lowerpath; struct inode *realinode = upperdentry ? d_inode(upperdentry) : NULL; Loading Loading @@ -994,7 +995,8 @@ struct inode *ovl_get_inode(struct super_block *sb, /* Recalculate nlink for non-dir due to indexing */ if (!is_dir) nlink = ovl_get_nlink(lowerdentry, upperdentry, nlink); nlink = ovl_get_nlink(ofs, lowerdentry, upperdentry, nlink); set_nlink(inode, nlink); ino = key->i_ino; } else { Loading @@ -1010,7 +1012,7 @@ struct inode *ovl_get_inode(struct super_block *sb, ovl_fill_inode(inode, realinode->i_mode, realinode->i_rdev); ovl_inode_init(inode, oip, ino, fsid); if (upperdentry && ovl_is_impuredir(upperdentry)) if (upperdentry && ovl_is_impuredir(sb, upperdentry)) ovl_set_flag(OVL_IMPURE, inode); if (oip->index) Loading @@ -1024,7 +1026,7 @@ struct inode *ovl_get_inode(struct super_block *sb, /* Check for non-merge dir that may have whiteouts */ if (is_dir) { if (((upperdentry && lowerdentry) || oip->numlower > 1) || ovl_check_origin_xattr(upperdentry ?: lowerdentry)) { ovl_check_origin_xattr(ofs, upperdentry ?: lowerdentry)) { ovl_set_flag(OVL_WHITEOUTS, inode); } } Loading fs/overlayfs/namei.c +30 −27 Original line number Diff line number Diff line Loading @@ -30,8 +30,9 @@ static int ovl_check_redirect(struct dentry *dentry, struct ovl_lookup_data *d, { int res; char *buf; struct ovl_fs *ofs = OVL_FS(d->sb); buf = ovl_get_redirect_xattr(dentry, prelen + strlen(post)); buf = ovl_get_redirect_xattr(ofs, dentry, prelen + strlen(post)); if (IS_ERR_OR_NULL(buf)) return PTR_ERR(buf); Loading Loading @@ -104,12 +105,13 @@ int ovl_check_fb_len(struct ovl_fb *fb, int fb_len) return 0; } static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name) static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *dentry, const char *name) { int res, err; struct ovl_fh *fh = NULL; res = ovl_do_getxattr(dentry, name, NULL, 0); res = ovl_do_getxattr(ofs, dentry, name, NULL, 0); if (res < 0) { if (res == -ENODATA || res == -EOPNOTSUPP) return NULL; Loading @@ -123,7 +125,7 @@ static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name) if (!fh) return ERR_PTR(-ENOMEM); res = ovl_do_getxattr(dentry, name, fh->buf, res); res = ovl_do_getxattr(ofs, dentry, name, fh->buf, res); if (res < 0) goto fail; Loading Loading @@ -186,9 +188,9 @@ struct dentry *ovl_decode_real_fh(struct ovl_fh *fh, struct vfsmount *mnt, return real; } static bool ovl_is_opaquedir(struct dentry *dentry) static bool ovl_is_opaquedir(struct super_block *sb, struct dentry *dentry) { return ovl_check_dir_xattr(dentry, OVL_XATTR_OPAQUE); return ovl_check_dir_xattr(sb, dentry, OVL_XATTR_OPAQUE); } static struct dentry *ovl_lookup_positive_unlocked(const char *name, Loading Loading @@ -251,7 +253,7 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d, d->stop = true; goto put_and_out; } err = ovl_check_metacopy_xattr(this); err = ovl_check_metacopy_xattr(OVL_FS(d->sb), this); if (err < 0) goto out_err; Loading @@ -271,7 +273,7 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d, if (d->last) goto out; if (ovl_is_opaquedir(this)) { if (ovl_is_opaquedir(d->sb, this)) { d->stop = true; if (last_element) d->opaque = true; Loading Loading @@ -391,7 +393,7 @@ int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected, static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry, struct ovl_path **stackp) { struct ovl_fh *fh = ovl_get_fh(upperdentry, OVL_XATTR_ORIGIN); struct ovl_fh *fh = ovl_get_fh(ofs, upperdentry, OVL_XATTR_ORIGIN); int err; if (IS_ERR_OR_NULL(fh)) Loading @@ -413,10 +415,10 @@ static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry, * Verify that @fh matches the file handle stored in xattr @name. * Return 0 on match, -ESTALE on mismatch, < 0 on error. */ static int ovl_verify_fh(struct dentry *dentry, const char *name, const struct ovl_fh *fh) static int ovl_verify_fh(struct ovl_fs *ofs, struct dentry *dentry, const char *name, const struct ovl_fh *fh) { struct ovl_fh *ofh = ovl_get_fh(dentry, name); struct ovl_fh *ofh = ovl_get_fh(ofs, dentry, name); int err = 0; if (!ofh) Loading @@ -440,8 +442,9 @@ static int ovl_verify_fh(struct dentry *dentry, const char *name, * * Return 0 on match, -ESTALE on mismatch, -ENODATA on no xattr, < 0 on error. */ int ovl_verify_set_fh(struct dentry *dentry, const char *name, struct dentry *real, bool is_upper, bool set) int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, const char *name, struct dentry *real, bool is_upper, bool set) { struct inode *inode; struct ovl_fh *fh; Loading @@ -454,9 +457,9 @@ int ovl_verify_set_fh(struct dentry *dentry, const char *name, goto fail; } err = ovl_verify_fh(dentry, name, fh); err = ovl_verify_fh(ofs, dentry, name, fh); if (set && err == -ENODATA) err = ovl_do_setxattr(dentry, name, fh->buf, fh->fb.len); err = ovl_do_setxattr(ofs, dentry, name, fh->buf, fh->fb.len); if (err) goto fail; Loading @@ -481,7 +484,7 @@ struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index) if (!d_is_dir(index)) return dget(index); fh = ovl_get_fh(index, OVL_XATTR_UPPER); fh = ovl_get_fh(ofs, index, OVL_XATTR_UPPER); if (IS_ERR_OR_NULL(fh)) return ERR_CAST(fh); Loading Loading @@ -574,7 +577,7 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index) goto fail; } err = ovl_verify_fh(upper, OVL_XATTR_ORIGIN, fh); err = ovl_verify_fh(ofs, upper, OVL_XATTR_ORIGIN, fh); dput(upper); if (err) goto fail; Loading @@ -585,7 +588,7 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index) if (err) goto fail; if (ovl_get_nlink(origin.dentry, index, 0) == 0) if (ovl_get_nlink(ofs, origin.dentry, index, 0) == 0) goto orphan; } Loading Loading @@ -741,7 +744,7 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper, } /* Verify that dir index 'upper' xattr points to upper dir */ err = ovl_verify_upper(index, upper, false); err = ovl_verify_upper(ofs, index, upper, false); if (err) { if (err == -ESTALE) { pr_warn_ratelimited("suspected multiply redirected dir found (upper=%pd2, origin=%pd2, index=%pd2).\n", Loading Loading @@ -790,12 +793,12 @@ int ovl_path_next(int idx, struct dentry *dentry, struct path *path) } /* Fix missing 'origin' xattr */ static int ovl_fix_origin(struct dentry *dentry, struct dentry *lower, struct dentry *upper) static int ovl_fix_origin(struct ovl_fs *ofs, struct dentry *dentry, struct dentry *lower, struct dentry *upper) { int err; if (ovl_check_origin_xattr(upper)) if (ovl_check_origin_xattr(ofs, upper)) return 0; err = ovl_want_write(dentry); Loading Loading @@ -920,7 +923,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, * of lower dir and set upper parent "impure". */ if (upperdentry && !ctr && !ofs->noxattr && d.is_dir) { err = ovl_fix_origin(dentry, this, upperdentry); err = ovl_fix_origin(ofs, dentry, this, upperdentry); if (err) { dput(this); goto out_put; Loading @@ -939,7 +942,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, if (upperdentry && !ctr && ((d.is_dir && ovl_verify_lower(dentry->d_sb)) || (!d.is_dir && ofs->config.index && origin_path))) { err = ovl_verify_origin(upperdentry, this, false); err = ovl_verify_origin(ofs, upperdentry, this, false); if (err) { dput(this); if (d.is_dir) Loading Loading @@ -1060,13 +1063,13 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ovl_dentry_set_upper_alias(dentry); else if (index) { upperdentry = dget(index); upperredirect = ovl_get_redirect_xattr(upperdentry, 0); upperredirect = ovl_get_redirect_xattr(ofs, upperdentry, 0); if (IS_ERR(upperredirect)) { err = PTR_ERR(upperredirect); upperredirect = NULL; goto out_free_oe; } err = ovl_check_metacopy_xattr(upperdentry); err = ovl_check_metacopy_xattr(ofs, upperdentry); if (err < 0) goto out_free_oe; uppermetacopy = err; Loading Loading
fs/overlayfs/copy_up.c +9 −7 Original line number Diff line number Diff line Loading @@ -43,7 +43,8 @@ static bool ovl_must_copy_xattr(const char *name) !strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN); } int ovl_copy_xattr(struct dentry *old, struct dentry *new) int ovl_copy_xattr(struct super_block *sb, struct dentry *old, struct dentry *new) { ssize_t list_size, size, value_size = 0; char *buf, *name, *value = NULL; Loading Loading @@ -81,7 +82,7 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new) } list_size -= slen; if (ovl_is_private_xattr(name)) if (ovl_is_private_xattr(sb, name)) continue; retry: size = vfs_getxattr(old, name, value, value_size); Loading Loading @@ -355,7 +356,8 @@ int ovl_set_origin(struct dentry *dentry, struct dentry *lower, } /* Store file handle of @upper dir in @index dir entry */ static int ovl_set_upper_fh(struct dentry *upper, struct dentry *index) static int ovl_set_upper_fh(struct ovl_fs *ofs, struct dentry *upper, struct dentry *index) { const struct ovl_fh *fh; int err; Loading @@ -364,7 +366,7 @@ static int ovl_set_upper_fh(struct dentry *upper, struct dentry *index) if (IS_ERR(fh)) return PTR_ERR(fh); err = ovl_do_setxattr(index, OVL_XATTR_UPPER, fh->buf, fh->fb.len); err = ovl_do_setxattr(ofs, index, OVL_XATTR_UPPER, fh->buf, fh->fb.len); kfree(fh); return err; Loading Loading @@ -409,7 +411,7 @@ static int ovl_create_index(struct dentry *dentry, struct dentry *origin, if (IS_ERR(temp)) goto free_name; err = ovl_set_upper_fh(upper, temp); err = ovl_set_upper_fh(OVL_FS(dentry->d_sb), upper, temp); if (err) goto out; Loading Loading @@ -507,7 +509,7 @@ static int ovl_copy_up_inode(struct ovl_copy_up_ctx *c, struct dentry *temp) return err; } err = ovl_copy_xattr(c->lowerpath.dentry, temp); err = ovl_copy_xattr(c->dentry->d_sb, c->lowerpath.dentry, temp); if (err) return err; Loading Loading @@ -847,7 +849,7 @@ static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c) } err = ovl_do_removexattr(upperpath.dentry, OVL_XATTR_METACOPY); err = ovl_do_removexattr(ofs, upperpath.dentry, OVL_XATTR_METACOPY); if (err) goto out_free; Loading
fs/overlayfs/dir.c +1 −1 Original line number Diff line number Diff line Loading @@ -394,7 +394,7 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry, if (IS_ERR(opaquedir)) goto out_unlock; err = ovl_copy_xattr(upper, opaquedir); err = ovl_copy_xattr(dentry->d_sb, upper, opaquedir); if (err) goto out_cleanup; Loading
fs/overlayfs/export.c +1 −1 Original line number Diff line number Diff line Loading @@ -752,7 +752,7 @@ static struct dentry *ovl_lower_fh_to_d(struct super_block *sb, goto out_err; } if (index) { err = ovl_verify_origin(index, origin.dentry, false); err = ovl_verify_origin(ofs, index, origin.dentry, false); if (err) goto out_err; } Loading
fs/overlayfs/inode.c +12 −10 Original line number Diff line number Diff line Loading @@ -327,7 +327,7 @@ static const char *ovl_get_link(struct dentry *dentry, return p; } bool ovl_is_private_xattr(const char *name) bool ovl_is_private_xattr(struct super_block *sb, const char *name) { return strncmp(name, OVL_XATTR_PREFIX, sizeof(OVL_XATTR_PREFIX) - 1) == 0; Loading Loading @@ -391,14 +391,14 @@ int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, return res; } static bool ovl_can_list(const char *s) static bool ovl_can_list(struct super_block *sb, const char *s) { /* List all non-trusted xatts */ if (strncmp(s, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0) return true; /* Never list trusted.overlay, list other trusted for superuser only */ return !ovl_is_private_xattr(s) && return !ovl_is_private_xattr(sb, s) && ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN); } Loading @@ -425,7 +425,7 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) return -EIO; len -= slen; if (!ovl_can_list(s)) { if (!ovl_can_list(dentry->d_sb, s)) { res -= slen; memmove(s, s + slen, len); } else { Loading Loading @@ -722,7 +722,7 @@ static int ovl_set_nlink_common(struct dentry *dentry, if (WARN_ON(len >= sizeof(buf))) return -EIO; return ovl_do_setxattr(ovl_dentry_upper(dentry), return ovl_do_setxattr(OVL_FS(inode->i_sb), ovl_dentry_upper(dentry), OVL_XATTR_NLINK, buf, len); } Loading @@ -736,7 +736,7 @@ int ovl_set_nlink_lower(struct dentry *dentry) return ovl_set_nlink_common(dentry, ovl_dentry_lower(dentry), "L%+i"); } unsigned int ovl_get_nlink(struct dentry *lowerdentry, unsigned int ovl_get_nlink(struct ovl_fs *ofs, struct dentry *lowerdentry, struct dentry *upperdentry, unsigned int fallback) { Loading @@ -748,7 +748,7 @@ unsigned int ovl_get_nlink(struct dentry *lowerdentry, if (!lowerdentry || !upperdentry || d_inode(lowerdentry)->i_nlink == 1) return fallback; err = ovl_do_getxattr(upperdentry, OVL_XATTR_NLINK, err = ovl_do_getxattr(ofs, upperdentry, OVL_XATTR_NLINK, &buf, sizeof(buf) - 1); if (err < 0) goto fail; Loading Loading @@ -947,6 +947,7 @@ static struct inode *ovl_iget5(struct super_block *sb, struct inode *newinode, struct inode *ovl_get_inode(struct super_block *sb, struct ovl_inode_params *oip) { struct ovl_fs *ofs = OVL_FS(sb); struct dentry *upperdentry = oip->upperdentry; struct ovl_path *lowerpath = oip->lowerpath; struct inode *realinode = upperdentry ? d_inode(upperdentry) : NULL; Loading Loading @@ -994,7 +995,8 @@ struct inode *ovl_get_inode(struct super_block *sb, /* Recalculate nlink for non-dir due to indexing */ if (!is_dir) nlink = ovl_get_nlink(lowerdentry, upperdentry, nlink); nlink = ovl_get_nlink(ofs, lowerdentry, upperdentry, nlink); set_nlink(inode, nlink); ino = key->i_ino; } else { Loading @@ -1010,7 +1012,7 @@ struct inode *ovl_get_inode(struct super_block *sb, ovl_fill_inode(inode, realinode->i_mode, realinode->i_rdev); ovl_inode_init(inode, oip, ino, fsid); if (upperdentry && ovl_is_impuredir(upperdentry)) if (upperdentry && ovl_is_impuredir(sb, upperdentry)) ovl_set_flag(OVL_IMPURE, inode); if (oip->index) Loading @@ -1024,7 +1026,7 @@ struct inode *ovl_get_inode(struct super_block *sb, /* Check for non-merge dir that may have whiteouts */ if (is_dir) { if (((upperdentry && lowerdentry) || oip->numlower > 1) || ovl_check_origin_xattr(upperdentry ?: lowerdentry)) { ovl_check_origin_xattr(ofs, upperdentry ?: lowerdentry)) { ovl_set_flag(OVL_WHITEOUTS, inode); } } Loading
fs/overlayfs/namei.c +30 −27 Original line number Diff line number Diff line Loading @@ -30,8 +30,9 @@ static int ovl_check_redirect(struct dentry *dentry, struct ovl_lookup_data *d, { int res; char *buf; struct ovl_fs *ofs = OVL_FS(d->sb); buf = ovl_get_redirect_xattr(dentry, prelen + strlen(post)); buf = ovl_get_redirect_xattr(ofs, dentry, prelen + strlen(post)); if (IS_ERR_OR_NULL(buf)) return PTR_ERR(buf); Loading Loading @@ -104,12 +105,13 @@ int ovl_check_fb_len(struct ovl_fb *fb, int fb_len) return 0; } static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name) static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *dentry, const char *name) { int res, err; struct ovl_fh *fh = NULL; res = ovl_do_getxattr(dentry, name, NULL, 0); res = ovl_do_getxattr(ofs, dentry, name, NULL, 0); if (res < 0) { if (res == -ENODATA || res == -EOPNOTSUPP) return NULL; Loading @@ -123,7 +125,7 @@ static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name) if (!fh) return ERR_PTR(-ENOMEM); res = ovl_do_getxattr(dentry, name, fh->buf, res); res = ovl_do_getxattr(ofs, dentry, name, fh->buf, res); if (res < 0) goto fail; Loading Loading @@ -186,9 +188,9 @@ struct dentry *ovl_decode_real_fh(struct ovl_fh *fh, struct vfsmount *mnt, return real; } static bool ovl_is_opaquedir(struct dentry *dentry) static bool ovl_is_opaquedir(struct super_block *sb, struct dentry *dentry) { return ovl_check_dir_xattr(dentry, OVL_XATTR_OPAQUE); return ovl_check_dir_xattr(sb, dentry, OVL_XATTR_OPAQUE); } static struct dentry *ovl_lookup_positive_unlocked(const char *name, Loading Loading @@ -251,7 +253,7 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d, d->stop = true; goto put_and_out; } err = ovl_check_metacopy_xattr(this); err = ovl_check_metacopy_xattr(OVL_FS(d->sb), this); if (err < 0) goto out_err; Loading @@ -271,7 +273,7 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d, if (d->last) goto out; if (ovl_is_opaquedir(this)) { if (ovl_is_opaquedir(d->sb, this)) { d->stop = true; if (last_element) d->opaque = true; Loading Loading @@ -391,7 +393,7 @@ int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected, static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry, struct ovl_path **stackp) { struct ovl_fh *fh = ovl_get_fh(upperdentry, OVL_XATTR_ORIGIN); struct ovl_fh *fh = ovl_get_fh(ofs, upperdentry, OVL_XATTR_ORIGIN); int err; if (IS_ERR_OR_NULL(fh)) Loading @@ -413,10 +415,10 @@ static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry, * Verify that @fh matches the file handle stored in xattr @name. * Return 0 on match, -ESTALE on mismatch, < 0 on error. */ static int ovl_verify_fh(struct dentry *dentry, const char *name, const struct ovl_fh *fh) static int ovl_verify_fh(struct ovl_fs *ofs, struct dentry *dentry, const char *name, const struct ovl_fh *fh) { struct ovl_fh *ofh = ovl_get_fh(dentry, name); struct ovl_fh *ofh = ovl_get_fh(ofs, dentry, name); int err = 0; if (!ofh) Loading @@ -440,8 +442,9 @@ static int ovl_verify_fh(struct dentry *dentry, const char *name, * * Return 0 on match, -ESTALE on mismatch, -ENODATA on no xattr, < 0 on error. */ int ovl_verify_set_fh(struct dentry *dentry, const char *name, struct dentry *real, bool is_upper, bool set) int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, const char *name, struct dentry *real, bool is_upper, bool set) { struct inode *inode; struct ovl_fh *fh; Loading @@ -454,9 +457,9 @@ int ovl_verify_set_fh(struct dentry *dentry, const char *name, goto fail; } err = ovl_verify_fh(dentry, name, fh); err = ovl_verify_fh(ofs, dentry, name, fh); if (set && err == -ENODATA) err = ovl_do_setxattr(dentry, name, fh->buf, fh->fb.len); err = ovl_do_setxattr(ofs, dentry, name, fh->buf, fh->fb.len); if (err) goto fail; Loading @@ -481,7 +484,7 @@ struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index) if (!d_is_dir(index)) return dget(index); fh = ovl_get_fh(index, OVL_XATTR_UPPER); fh = ovl_get_fh(ofs, index, OVL_XATTR_UPPER); if (IS_ERR_OR_NULL(fh)) return ERR_CAST(fh); Loading Loading @@ -574,7 +577,7 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index) goto fail; } err = ovl_verify_fh(upper, OVL_XATTR_ORIGIN, fh); err = ovl_verify_fh(ofs, upper, OVL_XATTR_ORIGIN, fh); dput(upper); if (err) goto fail; Loading @@ -585,7 +588,7 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index) if (err) goto fail; if (ovl_get_nlink(origin.dentry, index, 0) == 0) if (ovl_get_nlink(ofs, origin.dentry, index, 0) == 0) goto orphan; } Loading Loading @@ -741,7 +744,7 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper, } /* Verify that dir index 'upper' xattr points to upper dir */ err = ovl_verify_upper(index, upper, false); err = ovl_verify_upper(ofs, index, upper, false); if (err) { if (err == -ESTALE) { pr_warn_ratelimited("suspected multiply redirected dir found (upper=%pd2, origin=%pd2, index=%pd2).\n", Loading Loading @@ -790,12 +793,12 @@ int ovl_path_next(int idx, struct dentry *dentry, struct path *path) } /* Fix missing 'origin' xattr */ static int ovl_fix_origin(struct dentry *dentry, struct dentry *lower, struct dentry *upper) static int ovl_fix_origin(struct ovl_fs *ofs, struct dentry *dentry, struct dentry *lower, struct dentry *upper) { int err; if (ovl_check_origin_xattr(upper)) if (ovl_check_origin_xattr(ofs, upper)) return 0; err = ovl_want_write(dentry); Loading Loading @@ -920,7 +923,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, * of lower dir and set upper parent "impure". */ if (upperdentry && !ctr && !ofs->noxattr && d.is_dir) { err = ovl_fix_origin(dentry, this, upperdentry); err = ovl_fix_origin(ofs, dentry, this, upperdentry); if (err) { dput(this); goto out_put; Loading @@ -939,7 +942,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, if (upperdentry && !ctr && ((d.is_dir && ovl_verify_lower(dentry->d_sb)) || (!d.is_dir && ofs->config.index && origin_path))) { err = ovl_verify_origin(upperdentry, this, false); err = ovl_verify_origin(ofs, upperdentry, this, false); if (err) { dput(this); if (d.is_dir) Loading Loading @@ -1060,13 +1063,13 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, ovl_dentry_set_upper_alias(dentry); else if (index) { upperdentry = dget(index); upperredirect = ovl_get_redirect_xattr(upperdentry, 0); upperredirect = ovl_get_redirect_xattr(ofs, upperdentry, 0); if (IS_ERR(upperredirect)) { err = PTR_ERR(upperredirect); upperredirect = NULL; goto out_free_oe; } err = ovl_check_metacopy_xattr(upperdentry); err = ovl_check_metacopy_xattr(ofs, upperdentry); if (err < 0) goto out_free_oe; uppermetacopy = err; Loading