Commit 24f0b172 authored by Amir Goldstein's avatar Amir Goldstein Committed by Miklos Szeredi

ovl: whiteout orphan index entries on mount

Orphan index entries are non-dir index entries whose union nlink count
dropped to zero. With index=on, orphan index entries are removed on
mount. With NFS export feature enabled, orphan index entries are replaced
with white out index entries to block future open by handle from opening
the lower file.

When dir index has a stale 'upper' xattr, we assume that the upper dir
was removed and we treat the dir index as orphan entry that needs to be
whited out or removed.
Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent e7dd0e71
...@@ -539,7 +539,15 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index) ...@@ -539,7 +539,15 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index)
upper = ovl_index_upper(ofs, index); upper = ovl_index_upper(ofs, index);
if (IS_ERR_OR_NULL(upper)) { if (IS_ERR_OR_NULL(upper)) {
err = PTR_ERR(upper); err = PTR_ERR(upper);
if (!err) /*
* Directory index entries with no 'upper' xattr need to be
* removed. When dir index entry has a stale 'upper' xattr,
* we assume that upper dir was removed and we treat the dir
* index as orphan entry that needs to be whited out.
*/
if (err == -ESTALE)
goto orphan;
else if (!err)
err = -ESTALE; err = -ESTALE;
goto fail; goto fail;
} }
...@@ -556,7 +564,7 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index) ...@@ -556,7 +564,7 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index)
goto fail; goto fail;
if (ovl_get_nlink(origin.dentry, index, 0) == 0) if (ovl_get_nlink(origin.dentry, index, 0) == 0)
err = -ENOENT; goto orphan;
} }
out: out:
...@@ -568,6 +576,13 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index) ...@@ -568,6 +576,13 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index)
pr_warn_ratelimited("overlayfs: failed to verify index (%pd2, ftype=%x, err=%i)\n", pr_warn_ratelimited("overlayfs: failed to verify index (%pd2, ftype=%x, err=%i)\n",
index, d_inode(index)->i_mode & S_IFMT, err); index, d_inode(index)->i_mode & S_IFMT, err);
goto out; goto out;
orphan:
pr_warn_ratelimited("overlayfs: orphan index entry (%pd2, ftype=%x, nlink=%u)\n",
index, d_inode(index)->i_mode & S_IFMT,
d_inode(index)->i_nlink);
err = -ENOENT;
goto out;
} }
/* /*
......
...@@ -1067,12 +1067,33 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs) ...@@ -1067,12 +1067,33 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs)
break; break;
} }
err = ovl_verify_index(ofs, index); err = ovl_verify_index(ofs, index);
/* Cleanup stale and orphan index entries */ if (!err) {
if (err && (err == -ESTALE || err == -ENOENT)) goto next;
} else if (err == -ESTALE) {
/* Cleanup stale index entries */
err = ovl_cleanup(dir, index);
} else if (err != -ENOENT) {
/*
* Abort mount to avoid corrupting the index if
* an incompatible index entry was found or on out
* of memory.
*/
break;
} else if (ofs->config.nfs_export) {
/*
* Whiteout orphan index to block future open by
* handle after overlay nlink dropped to zero.
*/
err = ovl_cleanup_and_whiteout(indexdir, dir, index);
} else {
/* Cleanup orphan index entries */
err = ovl_cleanup(dir, index); err = ovl_cleanup(dir, index);
}
if (err) if (err)
break; break;
next:
dput(index); dput(index);
index = NULL; index = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment