ovl: fix mount option checks for nfs_export with no upperdir
authorAmir Goldstein <amir73il@gmail.com>
Mon, 13 Jul 2020 14:19:44 +0000 (17:19 +0300)
committerMiklos Szeredi <mszeredi@redhat.com>
Wed, 15 Jul 2020 22:11:15 +0000 (00:11 +0200)
Without upperdir mount option, there is no index dir and the dependency
checks nfs_export => index for mount options parsing are incorrect.

Allow the combination nfs_export=on,index=off with no upperdir and move
the check for dependency redirect_dir=nofollow for non-upper mount case
to mount options parsing.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Documentation/filesystems/overlayfs.rst
fs/overlayfs/super.c

index 660dbaf..fcda5d6 100644 (file)
@@ -560,8 +560,8 @@ When the NFS export feature is enabled, all directory index entries are
 verified on mount time to check that upper file handles are not stale.
 This verification may cause significant overhead in some cases.
 
-Note: the mount options index=off,nfs_export=on are conflicting and will
-result in an error.
+Note: the mount options index=off,nfs_export=on are conflicting for a
+read-write mount and will result in an error.
 
 
 Testsuite
index f41ef1d..4b38141 100644 (file)
@@ -580,12 +580,19 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
                }
        }
 
-       /* Workdir is useless in non-upper mount */
-       if (!config->upperdir && config->workdir) {
-               pr_info("option \"workdir=%s\" is useless in a non-upper mount, ignore\n",
-                       config->workdir);
-               kfree(config->workdir);
-               config->workdir = NULL;
+       /* Workdir/index are useless in non-upper mount */
+       if (!config->upperdir) {
+               if (config->workdir) {
+                       pr_info("option \"workdir=%s\" is useless in a non-upper mount, ignore\n",
+                               config->workdir);
+                       kfree(config->workdir);
+                       config->workdir = NULL;
+               }
+               if (config->index && index_opt) {
+                       pr_info("option \"index=on\" is useless in a non-upper mount, ignore\n");
+                       index_opt = false;
+               }
+               config->index = false;
        }
 
        err = ovl_parse_redirect_mode(config, config->redirect_mode);
@@ -622,11 +629,13 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
 
        /* Resolve nfs_export -> index dependency */
        if (config->nfs_export && !config->index) {
-               if (nfs_export_opt && index_opt) {
+               if (!config->upperdir && config->redirect_follow) {
+                       pr_info("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n");
+                       config->nfs_export = false;
+               } else if (nfs_export_opt && index_opt) {
                        pr_err("conflicting options: nfs_export=on,index=off\n");
                        return -EINVAL;
-               }
-               if (index_opt) {
+               } else if (index_opt) {
                        /*
                         * There was an explicit index=off that resulted
                         * in this conflict.
@@ -1603,10 +1612,6 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
        if (!ofs->config.upperdir && numlower == 1) {
                pr_err("at least 2 lowerdir are needed while upperdir nonexistent\n");
                return ERR_PTR(-EINVAL);
-       } else if (!ofs->config.upperdir && ofs->config.nfs_export &&
-                  ofs->config.redirect_follow) {
-               pr_warn("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n");
-               ofs->config.nfs_export = false;
        }
 
        stack = kcalloc(numlower, sizeof(struct path), GFP_KERNEL);