diff options
author | Miklos Szeredi <mszeredi@redhat.com> | 2017-07-04 16:03:18 -0400 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2017-07-04 16:03:18 -0400 |
commit | a6fb235a448b8eb731fd6d4de2c5c6269677cf5b (patch) | |
tree | 36f9c8ee0f1590150348248529683cdd1a20e5b8 | |
parent | 55acc6618259c8ff0a400a131f0f4b613e96010a (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.c | 86 |
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 | ||
319 | struct ovl_copy_up_ctx { | 319 | struct 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 | */ |
496 | static int ovl_copy_up_one(struct dentry *parent, struct ovl_copy_up_ctx *c) | 497 | static 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) | |||
558 | out_unlock: | 536 | out_unlock: |
559 | unlock_rename(c->workdir, c->upperdir); | 537 | unlock_rename(c->workdir, c->upperdir); |
560 | out_done: | 538 | out_done: |
539 | |||
540 | return err; | ||
541 | } | ||
542 | |||
543 | static 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); |