Commit fa0096e3 authored by Amir Goldstein's avatar Amir Goldstein Committed by Miklos Szeredi

ovl: do not cleanup unsupported index entries

With index=on, ovl_indexdir_cleanup() tries to cleanup invalid index
entries (e.g. bad index name). This behavior could result in cleaning of
entries created by newer kernels and is therefore undesirable.
Instead, abort mount if such entries are encountered. We still cleanup
'stale' entries and 'orphan' entries, both those cases can be a result
of offline changes to lower and upper dirs.

When encoutering an index entry of type directory or whiteout, kernel
was supposed to fallback to read-only mount, but the fill_super()
operation returns EROFS in this case instead of returning success with
read-only mount flag, so mount fails when encoutering directory or
whiteout index entries. Bless this behavior by returning -EINVAL on
directory and whiteout index entries as we do for all unsupported index
entries.

Fixes: 61b67471 ("ovl: do not cleanup directory and whiteout index..")
Cc: <stable@vger.kernel.org> # v4.13
Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
parent 7937a56f
...@@ -405,14 +405,13 @@ int ovl_verify_index(struct dentry *index, struct path *lowerstack, ...@@ -405,14 +405,13 @@ int ovl_verify_index(struct dentry *index, struct path *lowerstack,
* be treated as stale (i.e. after unlink of the overlay inode). * be treated as stale (i.e. after unlink of the overlay inode).
* We don't know the verification rules for directory and whiteout * We don't know the verification rules for directory and whiteout
* index entries, because they have not been implemented yet, so return * index entries, because they have not been implemented yet, so return
* EROFS if those entries are found to avoid corrupting an index that * EINVAL if those entries are found to abort the mount to avoid
* was created by a newer kernel. * corrupting an index that was created by a newer kernel.
*/ */
err = -EROFS; err = -EINVAL;
if (d_is_dir(index) || ovl_is_whiteout(index)) if (d_is_dir(index) || ovl_is_whiteout(index))
goto fail; goto fail;
err = -EINVAL;
if (index->d_name.len < sizeof(struct ovl_fh)*2) if (index->d_name.len < sizeof(struct ovl_fh)*2)
goto fail; goto fail;
......
...@@ -1021,13 +1021,12 @@ int ovl_indexdir_cleanup(struct dentry *dentry, struct vfsmount *mnt, ...@@ -1021,13 +1021,12 @@ int ovl_indexdir_cleanup(struct dentry *dentry, struct vfsmount *mnt,
break; break;
} }
err = ovl_verify_index(index, lowerstack, numlower); err = ovl_verify_index(index, lowerstack, numlower);
if (err) { /* Cleanup stale and orphan index entries */
if (err == -EROFS) if (err && (err == -ESTALE || err == -ENOENT))
break;
err = ovl_cleanup(dir, index); err = ovl_cleanup(dir, index);
if (err) if (err)
break; break;
}
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