aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2017-07-04 16:03:18 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2017-07-04 16:03:18 -0400
commita6fb235a448b8eb731fd6d4de2c5c6269677cf5b (patch)
tree36f9c8ee0f1590150348248529683cdd1a20e5b8
parent55acc6618259c8ff0a400a131f0f4b613e96010a (diff)
ovl: rearrange copy up
Split up and rearrange copy up functions to make them better readable. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-rw-r--r--fs/overlayfs/copy_up.c86
1 files changed, 50 insertions, 36 deletions
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index 58c06bd58a96..15668d3bbbc4 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -317,6 +317,7 @@ static int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
317} 317}
318 318
319struct ovl_copy_up_ctx { 319struct ovl_copy_up_ctx {
320 struct dentry *parent;
320 struct dentry *dentry; 321 struct dentry *dentry;
321 struct path lowerpath; 322 struct path lowerpath;
322 struct kstat stat; 323 struct kstat stat;
@@ -493,39 +494,16 @@ out_cleanup:
493 * is possible that the copy up will lock the old parent. At that point 494 * is possible that the copy up will lock the old parent. At that point
494 * the file will have already been copied up anyway. 495 * the file will have already been copied up anyway.
495 */ 496 */
496static int ovl_copy_up_one(struct dentry *parent, struct ovl_copy_up_ctx *c) 497static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
497{ 498{
498 DEFINE_DELAYED_CALL(done);
499 int err; 499 int err;
500 struct path parentpath;
501 struct dentry *lowerdentry = c->lowerpath.dentry;
502 struct ovl_fs *ofs = c->dentry->d_sb->s_fs_info; 500 struct ovl_fs *ofs = c->dentry->d_sb->s_fs_info;
503 501
504 c->workdir = ovl_workdir(c->dentry);
505 if (WARN_ON(!c->workdir))
506 return -EROFS;
507
508 ovl_do_check_copy_up(lowerdentry);
509
510 ovl_path_upper(parent, &parentpath);
511 c->upperdir = parentpath.dentry;
512
513 /* Mark parent "impure" because it may now contain non-pure upper */ 502 /* Mark parent "impure" because it may now contain non-pure upper */
514 err = ovl_set_impure(parent, c->upperdir); 503 err = ovl_set_impure(c->parent, c->upperdir);
515 if (err)
516 return err;
517
518 err = vfs_getattr(&parentpath, &c->pstat,
519 STATX_ATIME | STATX_MTIME, AT_STATX_SYNC_AS_STAT);
520 if (err) 504 if (err)
521 return err; 505 return err;
522 506
523 if (S_ISLNK(c->stat.mode)) {
524 c->link = vfs_get_link(lowerdentry, &done);
525 if (IS_ERR(c->link))
526 return PTR_ERR(c->link);
527 }
528
529 /* Should we copyup with O_TMPFILE or with workdir? */ 507 /* Should we copyup with O_TMPFILE or with workdir? */
530 if (S_ISREG(c->stat.mode) && ofs->tmpfile) { 508 if (S_ISREG(c->stat.mode) && ofs->tmpfile) {
531 err = ovl_copy_up_start(c->dentry); 509 err = ovl_copy_up_start(c->dentry);
@@ -558,6 +536,52 @@ static int ovl_copy_up_one(struct dentry *parent, struct ovl_copy_up_ctx *c)
558out_unlock: 536out_unlock:
559 unlock_rename(c->workdir, c->upperdir); 537 unlock_rename(c->workdir, c->upperdir);
560out_done: 538out_done:
539
540 return err;
541}
542
543static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
544 int flags)
545{
546 int err;
547 DEFINE_DELAYED_CALL(done);
548 struct path parentpath;
549 struct ovl_copy_up_ctx ctx = {
550 .parent = parent,
551 .dentry = dentry,
552 .workdir = ovl_workdir(dentry),
553 };
554
555 if (WARN_ON(!ctx.workdir))
556 return -EROFS;
557
558 ovl_path_lower(dentry, &ctx.lowerpath);
559 err = vfs_getattr(&ctx.lowerpath, &ctx.stat,
560 STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
561 if (err)
562 return err;
563
564 ovl_path_upper(parent, &parentpath);
565 ctx.upperdir = parentpath.dentry;
566
567 err = vfs_getattr(&parentpath, &ctx.pstat,
568 STATX_ATIME | STATX_MTIME, AT_STATX_SYNC_AS_STAT);
569 if (err)
570 return err;
571
572 /* maybe truncate regular file. this has no effect on dirs */
573 if (flags & O_TRUNC)
574 ctx.stat.size = 0;
575
576 if (S_ISLNK(ctx.stat.mode)) {
577 ctx.link = vfs_get_link(ctx.lowerpath.dentry, &done);
578 if (IS_ERR(ctx.link))
579 return PTR_ERR(ctx.link);
580 }
581 ovl_do_check_copy_up(ctx.lowerpath.dentry);
582
583 err = ovl_do_copy_up(&ctx);
584
561 do_delayed_call(&done); 585 do_delayed_call(&done);
562 586
563 return err; 587 return err;
@@ -571,7 +595,6 @@ int ovl_copy_up_flags(struct dentry *dentry, int flags)
571 while (!err) { 595 while (!err) {
572 struct dentry *next; 596 struct dentry *next;
573 struct dentry *parent; 597 struct dentry *parent;
574 struct ovl_copy_up_ctx ctx = { };
575 enum ovl_path_type type = ovl_path_type(dentry); 598 enum ovl_path_type type = ovl_path_type(dentry);
576 599
577 if (OVL_TYPE_UPPER(type)) 600 if (OVL_TYPE_UPPER(type))
@@ -590,16 +613,7 @@ int ovl_copy_up_flags(struct dentry *dentry, int flags)
590 next = parent; 613 next = parent;
591 } 614 }
592 615
593 ovl_path_lower(next, &ctx.lowerpath); 616 err = ovl_copy_up_one(parent, next, flags);
594 err = vfs_getattr(&ctx.lowerpath, &ctx.stat,
595 STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
596 /* maybe truncate regular file. this has no effect on dirs */
597 if (flags & O_TRUNC)
598 ctx.stat.size = 0;
599 if (!err) {
600 ctx.dentry = next;
601 err = ovl_copy_up_one(parent, &ctx);
602 }
603 617
604 dput(parent); 618 dput(parent);
605 dput(next); 619 dput(next);