aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2017-11-06 09:48:02 -0500
committerMiklos Szeredi <mszeredi@redhat.com>2018-04-12 06:04:50 -0400
commitadbf4f7ea834671c9d12002136c8162b34e011d5 (patch)
treeda12574cba5a268ec1b92c2a0b3cb91afa32613e
parent12574a9f4c9cc9d8d6fd9078cbb8ec7d3e9ed46b (diff)
ovl: consistent d_ino for non-samefs with xino
When overlay layers are not all on the same fs, but all inode numbers of underlying fs do not use the high 'xino' bits, overlay st_ino values are constant and persistent. In that case, relax non-samefs constraint for consistent d_ino and always iterate non-merge dir using ovl_fill_real() actor so we can remap lower inode numbers to unique lower fs range. Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-rw-r--r--fs/overlayfs/readdir.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
index c11f5c0906c3..ef1fe42ff7bb 100644
--- a/fs/overlayfs/readdir.c
+++ b/fs/overlayfs/readdir.c
@@ -120,6 +120,10 @@ static bool ovl_calc_d_ino(struct ovl_readdir_data *rdd,
120 if (!rdd->dentry) 120 if (!rdd->dentry)
121 return false; 121 return false;
122 122
123 /* Always recalc d_ino when remapping lower inode numbers */
124 if (ovl_xino_bits(rdd->dentry->d_sb))
125 return true;
126
123 /* Always recalc d_ino for parent */ 127 /* Always recalc d_ino for parent */
124 if (strcmp(p->name, "..") == 0) 128 if (strcmp(p->name, "..") == 0)
125 return true; 129 return true;
@@ -435,6 +439,19 @@ static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry)
435 return cache; 439 return cache;
436} 440}
437 441
442/* Map inode number to lower fs unique range */
443static u64 ovl_remap_lower_ino(u64 ino, int xinobits, int fsid,
444 const char *name, int namelen)
445{
446 if (ino >> (64 - xinobits)) {
447 pr_warn_ratelimited("overlayfs: d_ino too big (%.*s, ino=%llu, xinobits=%d)\n",
448 namelen, name, ino, xinobits);
449 return ino;
450 }
451
452 return ino | ((u64)fsid) << (64 - xinobits);
453}
454
438/* 455/*
439 * Set d_ino for upper entries. Non-upper entries should always report 456 * Set d_ino for upper entries. Non-upper entries should always report
440 * the uppermost real inode ino and should not call this function. 457 * the uppermost real inode ino and should not call this function.
@@ -452,9 +469,10 @@ static int ovl_cache_update_ino(struct path *path, struct ovl_cache_entry *p)
452 struct dentry *this = NULL; 469 struct dentry *this = NULL;
453 enum ovl_path_type type; 470 enum ovl_path_type type;
454 u64 ino = p->real_ino; 471 u64 ino = p->real_ino;
472 int xinobits = ovl_xino_bits(dir->d_sb);
455 int err = 0; 473 int err = 0;
456 474
457 if (!ovl_same_sb(dir->d_sb)) 475 if (!ovl_same_sb(dir->d_sb) && !xinobits)
458 goto out; 476 goto out;
459 477
460 if (p->name[0] == '.') { 478 if (p->name[0] == '.') {
@@ -491,6 +509,10 @@ get:
491 509
492 WARN_ON_ONCE(dir->d_sb->s_dev != stat.dev); 510 WARN_ON_ONCE(dir->d_sb->s_dev != stat.dev);
493 ino = stat.ino; 511 ino = stat.ino;
512 } else if (xinobits && !OVL_TYPE_UPPER(type)) {
513 ino = ovl_remap_lower_ino(ino, xinobits,
514 ovl_layer_lower(this)->fsid,
515 p->name, p->len);
494 } 516 }
495 517
496out: 518out:
@@ -618,6 +640,8 @@ struct ovl_readdir_translate {
618 struct ovl_dir_cache *cache; 640 struct ovl_dir_cache *cache;
619 struct dir_context ctx; 641 struct dir_context ctx;
620 u64 parent_ino; 642 u64 parent_ino;
643 int fsid;
644 int xinobits;
621}; 645};
622 646
623static int ovl_fill_real(struct dir_context *ctx, const char *name, 647static int ovl_fill_real(struct dir_context *ctx, const char *name,
@@ -628,14 +652,17 @@ static int ovl_fill_real(struct dir_context *ctx, const char *name,
628 container_of(ctx, struct ovl_readdir_translate, ctx); 652 container_of(ctx, struct ovl_readdir_translate, ctx);
629 struct dir_context *orig_ctx = rdt->orig_ctx; 653 struct dir_context *orig_ctx = rdt->orig_ctx;
630 654
631 if (rdt->parent_ino && strcmp(name, "..") == 0) 655 if (rdt->parent_ino && strcmp(name, "..") == 0) {
632 ino = rdt->parent_ino; 656 ino = rdt->parent_ino;
633 else if (rdt->cache) { 657 } else if (rdt->cache) {
634 struct ovl_cache_entry *p; 658 struct ovl_cache_entry *p;
635 659
636 p = ovl_cache_entry_find(&rdt->cache->root, name, namelen); 660 p = ovl_cache_entry_find(&rdt->cache->root, name, namelen);
637 if (p) 661 if (p)
638 ino = p->ino; 662 ino = p->ino;
663 } else if (rdt->xinobits) {
664 ino = ovl_remap_lower_ino(ino, rdt->xinobits, rdt->fsid,
665 name, namelen);
639 } 666 }
640 667
641 return orig_ctx->actor(orig_ctx, name, namelen, offset, ino, d_type); 668 return orig_ctx->actor(orig_ctx, name, namelen, offset, ino, d_type);
@@ -646,11 +673,16 @@ static int ovl_iterate_real(struct file *file, struct dir_context *ctx)
646 int err; 673 int err;
647 struct ovl_dir_file *od = file->private_data; 674 struct ovl_dir_file *od = file->private_data;
648 struct dentry *dir = file->f_path.dentry; 675 struct dentry *dir = file->f_path.dentry;
676 struct ovl_layer *lower_layer = ovl_layer_lower(dir);
649 struct ovl_readdir_translate rdt = { 677 struct ovl_readdir_translate rdt = {
650 .ctx.actor = ovl_fill_real, 678 .ctx.actor = ovl_fill_real,
651 .orig_ctx = ctx, 679 .orig_ctx = ctx,
680 .xinobits = ovl_xino_bits(dir->d_sb),
652 }; 681 };
653 682
683 if (rdt.xinobits && lower_layer)
684 rdt.fsid = lower_layer->fsid;
685
654 if (OVL_TYPE_MERGE(ovl_path_type(dir->d_parent))) { 686 if (OVL_TYPE_MERGE(ovl_path_type(dir->d_parent))) {
655 struct kstat stat; 687 struct kstat stat;
656 struct path statpath = file->f_path; 688 struct path statpath = file->f_path;
@@ -693,9 +725,10 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx)
693 * dir is impure then need to adjust d_ino for copied up 725 * dir is impure then need to adjust d_ino for copied up
694 * entries. 726 * entries.
695 */ 727 */
696 if (ovl_same_sb(dentry->d_sb) && 728 if (ovl_xino_bits(dentry->d_sb) ||
697 (ovl_test_flag(OVL_IMPURE, d_inode(dentry)) || 729 (ovl_same_sb(dentry->d_sb) &&
698 OVL_TYPE_MERGE(ovl_path_type(dentry->d_parent)))) { 730 (ovl_test_flag(OVL_IMPURE, d_inode(dentry)) ||
731 OVL_TYPE_MERGE(ovl_path_type(dentry->d_parent))))) {
699 return ovl_iterate_real(file, ctx); 732 return ovl_iterate_real(file, ctx);
700 } 733 }
701 return iterate_dir(od->realfile, ctx); 734 return iterate_dir(od->realfile, ctx);