Loading fs/overlayfs/copy_up.c +50 −36 Original line number Diff line number Diff line Loading @@ -317,6 +317,7 @@ static int ovl_set_origin(struct dentry *dentry, struct dentry *lower, } struct ovl_copy_up_ctx { struct dentry *parent; struct dentry *dentry; struct path lowerpath; struct kstat stat; Loading Loading @@ -493,39 +494,16 @@ static int ovl_copy_up_locked(struct ovl_copy_up_ctx *c) * is possible that the copy up will lock the old parent. At that point * the file will have already been copied up anyway. */ static int ovl_copy_up_one(struct dentry *parent, struct ovl_copy_up_ctx *c) static int ovl_do_copy_up(struct ovl_copy_up_ctx *c) { DEFINE_DELAYED_CALL(done); int err; struct path parentpath; struct dentry *lowerdentry = c->lowerpath.dentry; struct ovl_fs *ofs = c->dentry->d_sb->s_fs_info; c->workdir = ovl_workdir(c->dentry); if (WARN_ON(!c->workdir)) return -EROFS; ovl_do_check_copy_up(lowerdentry); ovl_path_upper(parent, &parentpath); c->upperdir = parentpath.dentry; /* Mark parent "impure" because it may now contain non-pure upper */ err = ovl_set_impure(parent, c->upperdir); if (err) return err; err = vfs_getattr(&parentpath, &c->pstat, STATX_ATIME | STATX_MTIME, AT_STATX_SYNC_AS_STAT); err = ovl_set_impure(c->parent, c->upperdir); if (err) return err; if (S_ISLNK(c->stat.mode)) { c->link = vfs_get_link(lowerdentry, &done); if (IS_ERR(c->link)) return PTR_ERR(c->link); } /* Should we copyup with O_TMPFILE or with workdir? */ if (S_ISREG(c->stat.mode) && ofs->tmpfile) { err = ovl_copy_up_start(c->dentry); Loading Loading @@ -558,6 +536,52 @@ static int ovl_copy_up_one(struct dentry *parent, struct ovl_copy_up_ctx *c) out_unlock: unlock_rename(c->workdir, c->upperdir); out_done: return err; } static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, int flags) { int err; DEFINE_DELAYED_CALL(done); struct path parentpath; struct ovl_copy_up_ctx ctx = { .parent = parent, .dentry = dentry, .workdir = ovl_workdir(dentry), }; if (WARN_ON(!ctx.workdir)) return -EROFS; ovl_path_lower(dentry, &ctx.lowerpath); err = vfs_getattr(&ctx.lowerpath, &ctx.stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT); if (err) return err; ovl_path_upper(parent, &parentpath); ctx.upperdir = parentpath.dentry; err = vfs_getattr(&parentpath, &ctx.pstat, STATX_ATIME | STATX_MTIME, AT_STATX_SYNC_AS_STAT); if (err) return err; /* maybe truncate regular file. this has no effect on dirs */ if (flags & O_TRUNC) ctx.stat.size = 0; if (S_ISLNK(ctx.stat.mode)) { ctx.link = vfs_get_link(ctx.lowerpath.dentry, &done); if (IS_ERR(ctx.link)) return PTR_ERR(ctx.link); } ovl_do_check_copy_up(ctx.lowerpath.dentry); err = ovl_do_copy_up(&ctx); do_delayed_call(&done); return err; Loading @@ -571,7 +595,6 @@ int ovl_copy_up_flags(struct dentry *dentry, int flags) while (!err) { struct dentry *next; struct dentry *parent; struct ovl_copy_up_ctx ctx = { }; enum ovl_path_type type = ovl_path_type(dentry); if (OVL_TYPE_UPPER(type)) Loading @@ -590,16 +613,7 @@ int ovl_copy_up_flags(struct dentry *dentry, int flags) next = parent; } ovl_path_lower(next, &ctx.lowerpath); err = vfs_getattr(&ctx.lowerpath, &ctx.stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT); /* maybe truncate regular file. this has no effect on dirs */ if (flags & O_TRUNC) ctx.stat.size = 0; if (!err) { ctx.dentry = next; err = ovl_copy_up_one(parent, &ctx); } err = ovl_copy_up_one(parent, next, flags); dput(parent); dput(next); Loading Loading
fs/overlayfs/copy_up.c +50 −36 Original line number Diff line number Diff line Loading @@ -317,6 +317,7 @@ static int ovl_set_origin(struct dentry *dentry, struct dentry *lower, } struct ovl_copy_up_ctx { struct dentry *parent; struct dentry *dentry; struct path lowerpath; struct kstat stat; Loading Loading @@ -493,39 +494,16 @@ static int ovl_copy_up_locked(struct ovl_copy_up_ctx *c) * is possible that the copy up will lock the old parent. At that point * the file will have already been copied up anyway. */ static int ovl_copy_up_one(struct dentry *parent, struct ovl_copy_up_ctx *c) static int ovl_do_copy_up(struct ovl_copy_up_ctx *c) { DEFINE_DELAYED_CALL(done); int err; struct path parentpath; struct dentry *lowerdentry = c->lowerpath.dentry; struct ovl_fs *ofs = c->dentry->d_sb->s_fs_info; c->workdir = ovl_workdir(c->dentry); if (WARN_ON(!c->workdir)) return -EROFS; ovl_do_check_copy_up(lowerdentry); ovl_path_upper(parent, &parentpath); c->upperdir = parentpath.dentry; /* Mark parent "impure" because it may now contain non-pure upper */ err = ovl_set_impure(parent, c->upperdir); if (err) return err; err = vfs_getattr(&parentpath, &c->pstat, STATX_ATIME | STATX_MTIME, AT_STATX_SYNC_AS_STAT); err = ovl_set_impure(c->parent, c->upperdir); if (err) return err; if (S_ISLNK(c->stat.mode)) { c->link = vfs_get_link(lowerdentry, &done); if (IS_ERR(c->link)) return PTR_ERR(c->link); } /* Should we copyup with O_TMPFILE or with workdir? */ if (S_ISREG(c->stat.mode) && ofs->tmpfile) { err = ovl_copy_up_start(c->dentry); Loading Loading @@ -558,6 +536,52 @@ static int ovl_copy_up_one(struct dentry *parent, struct ovl_copy_up_ctx *c) out_unlock: unlock_rename(c->workdir, c->upperdir); out_done: return err; } static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, int flags) { int err; DEFINE_DELAYED_CALL(done); struct path parentpath; struct ovl_copy_up_ctx ctx = { .parent = parent, .dentry = dentry, .workdir = ovl_workdir(dentry), }; if (WARN_ON(!ctx.workdir)) return -EROFS; ovl_path_lower(dentry, &ctx.lowerpath); err = vfs_getattr(&ctx.lowerpath, &ctx.stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT); if (err) return err; ovl_path_upper(parent, &parentpath); ctx.upperdir = parentpath.dentry; err = vfs_getattr(&parentpath, &ctx.pstat, STATX_ATIME | STATX_MTIME, AT_STATX_SYNC_AS_STAT); if (err) return err; /* maybe truncate regular file. this has no effect on dirs */ if (flags & O_TRUNC) ctx.stat.size = 0; if (S_ISLNK(ctx.stat.mode)) { ctx.link = vfs_get_link(ctx.lowerpath.dentry, &done); if (IS_ERR(ctx.link)) return PTR_ERR(ctx.link); } ovl_do_check_copy_up(ctx.lowerpath.dentry); err = ovl_do_copy_up(&ctx); do_delayed_call(&done); return err; Loading @@ -571,7 +595,6 @@ int ovl_copy_up_flags(struct dentry *dentry, int flags) while (!err) { struct dentry *next; struct dentry *parent; struct ovl_copy_up_ctx ctx = { }; enum ovl_path_type type = ovl_path_type(dentry); if (OVL_TYPE_UPPER(type)) Loading @@ -590,16 +613,7 @@ int ovl_copy_up_flags(struct dentry *dentry, int flags) next = parent; } ovl_path_lower(next, &ctx.lowerpath); err = vfs_getattr(&ctx.lowerpath, &ctx.stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT); /* maybe truncate regular file. this has no effect on dirs */ if (flags & O_TRUNC) ctx.stat.size = 0; if (!err) { ctx.dentry = next; err = ovl_copy_up_one(parent, &ctx); } err = ovl_copy_up_one(parent, next, flags); dput(parent); dput(next); Loading