Skip to content

Commit ac51962

Browse files
committed
ovl: factor out ovl_parse_options() helper
For parsing a single mount option. Signed-off-by: Amir Goldstein <amir73il@gmail.com>
1 parent af5f239 commit ac51962

2 files changed

Lines changed: 135 additions & 116 deletions

File tree

fs/overlayfs/overlayfs.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ enum {
7070
OVL_XINO_ON,
7171
};
7272

73+
/* The set of options that user requested explicitly via mount options */
74+
struct ovl_opt_set {
75+
bool metacopy;
76+
bool redirect;
77+
bool nfs_export;
78+
bool index;
79+
};
80+
7381
/*
7482
* The tuple (fh,uuid) is a universal unique identifier for a copy up origin,
7583
* where:

fs/overlayfs/super.c

Lines changed: 127 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -514,131 +514,142 @@ static char *ovl_next_opt(char **s)
514514
return sbegin;
515515
}
516516

517-
static int ovl_parse_opt(char *opt, struct ovl_config *config)
517+
static int ovl_parse_opt(char *opt, struct ovl_config *config,
518+
struct ovl_opt_set *set)
518519
{
519-
char *p;
520-
bool metacopy_opt = false, redirect_opt = false;
521-
bool nfs_export_opt = false, index_opt = false;
522-
523-
while ((p = ovl_next_opt(&opt)) != NULL) {
524-
int token;
525-
substring_t args[MAX_OPT_ARGS];
526-
527-
if (!*p)
528-
continue;
520+
int err = 0;
521+
int token;
522+
substring_t args[MAX_OPT_ARGS];
529523

530-
token = match_token(p, ovl_tokens, args);
531-
switch (token) {
532-
case OPT_UPPERDIR:
533-
kfree(config->upperdir);
534-
config->upperdir = match_strdup(&args[0]);
535-
if (!config->upperdir)
536-
return -ENOMEM;
537-
break;
524+
if (!*opt)
525+
return 0;
538526

539-
case OPT_LOWERDIR:
540-
kfree(config->lowerdir);
541-
config->lowerdir = match_strdup(&args[0]);
542-
if (!config->lowerdir)
543-
return -ENOMEM;
544-
break;
527+
token = match_token(opt, ovl_tokens, args);
528+
switch (token) {
529+
case OPT_UPPERDIR:
530+
kfree(config->upperdir);
531+
config->upperdir = match_strdup(&args[0]);
532+
if (!config->upperdir)
533+
return -ENOMEM;
534+
break;
535+
536+
case OPT_LOWERDIR:
537+
kfree(config->lowerdir);
538+
config->lowerdir = match_strdup(&args[0]);
539+
if (!config->lowerdir)
540+
return -ENOMEM;
541+
break;
542+
543+
case OPT_WORKDIR:
544+
kfree(config->workdir);
545+
config->workdir = match_strdup(&args[0]);
546+
if (!config->workdir)
547+
return -ENOMEM;
548+
break;
549+
550+
case OPT_DEFAULT_PERMISSIONS:
551+
config->default_permissions = true;
552+
break;
553+
554+
case OPT_REDIRECT_DIR_ON:
555+
config->redirect_mode = OVL_REDIRECT_ON;
556+
set->redirect = true;
557+
break;
558+
559+
case OPT_REDIRECT_DIR_OFF:
560+
config->redirect_mode = ovl_redirect_always_follow ?
561+
OVL_REDIRECT_FOLLOW :
562+
OVL_REDIRECT_NOFOLLOW;
563+
set->redirect = true;
564+
break;
565+
566+
case OPT_REDIRECT_DIR_FOLLOW:
567+
config->redirect_mode = OVL_REDIRECT_FOLLOW;
568+
set->redirect = true;
569+
break;
570+
571+
case OPT_REDIRECT_DIR_NOFOLLOW:
572+
config->redirect_mode = OVL_REDIRECT_NOFOLLOW;
573+
set->redirect = true;
574+
break;
545575

546-
case OPT_WORKDIR:
547-
kfree(config->workdir);
548-
config->workdir = match_strdup(&args[0]);
549-
if (!config->workdir)
550-
return -ENOMEM;
551-
break;
576+
case OPT_INDEX_ON:
577+
config->index = true;
578+
set->index = true;
579+
break;
552580

553-
case OPT_DEFAULT_PERMISSIONS:
554-
config->default_permissions = true;
555-
break;
581+
case OPT_INDEX_OFF:
582+
config->index = false;
583+
set->index = true;
584+
break;
556585

557-
case OPT_REDIRECT_DIR_ON:
558-
config->redirect_mode = OVL_REDIRECT_ON;
559-
redirect_opt = true;
560-
break;
586+
case OPT_UUID_ON:
587+
config->uuid = true;
588+
break;
561589

562-
case OPT_REDIRECT_DIR_OFF:
563-
config->redirect_mode = ovl_redirect_always_follow ?
564-
OVL_REDIRECT_FOLLOW :
565-
OVL_REDIRECT_NOFOLLOW;
566-
redirect_opt = true;
567-
break;
590+
case OPT_UUID_OFF:
591+
config->uuid = false;
592+
break;
568593

569-
case OPT_REDIRECT_DIR_FOLLOW:
570-
config->redirect_mode = OVL_REDIRECT_FOLLOW;
571-
redirect_opt = true;
572-
break;
594+
case OPT_NFS_EXPORT_ON:
595+
config->nfs_export = true;
596+
set->nfs_export = true;
597+
break;
573598

574-
case OPT_REDIRECT_DIR_NOFOLLOW:
575-
config->redirect_mode = OVL_REDIRECT_NOFOLLOW;
576-
redirect_opt = true;
577-
break;
599+
case OPT_NFS_EXPORT_OFF:
600+
config->nfs_export = false;
601+
set->nfs_export = true;
602+
break;
578603

579-
case OPT_INDEX_ON:
580-
config->index = true;
581-
index_opt = true;
582-
break;
604+
case OPT_XINO_ON:
605+
config->xino = OVL_XINO_ON;
606+
break;
583607

584-
case OPT_INDEX_OFF:
585-
config->index = false;
586-
index_opt = true;
587-
break;
608+
case OPT_XINO_OFF:
609+
config->xino = OVL_XINO_OFF;
610+
break;
588611

589-
case OPT_UUID_ON:
590-
config->uuid = true;
591-
break;
612+
case OPT_XINO_AUTO:
613+
config->xino = OVL_XINO_AUTO;
614+
break;
592615

593-
case OPT_UUID_OFF:
594-
config->uuid = false;
595-
break;
616+
case OPT_METACOPY_ON:
617+
config->metacopy = true;
618+
set->metacopy = true;
619+
break;
596620

597-
case OPT_NFS_EXPORT_ON:
598-
config->nfs_export = true;
599-
nfs_export_opt = true;
600-
break;
601-
602-
case OPT_NFS_EXPORT_OFF:
603-
config->nfs_export = false;
604-
nfs_export_opt = true;
605-
break;
606-
607-
case OPT_XINO_ON:
608-
config->xino = OVL_XINO_ON;
609-
break;
610-
611-
case OPT_XINO_OFF:
612-
config->xino = OVL_XINO_OFF;
613-
break;
621+
case OPT_METACOPY_OFF:
622+
config->metacopy = false;
623+
set->metacopy = true;
624+
break;
614625

615-
case OPT_XINO_AUTO:
616-
config->xino = OVL_XINO_AUTO;
617-
break;
626+
case OPT_VOLATILE:
627+
config->ovl_volatile = true;
628+
break;
618629

619-
case OPT_METACOPY_ON:
620-
config->metacopy = true;
621-
metacopy_opt = true;
622-
break;
630+
case OPT_USERXATTR:
631+
config->userxattr = true;
632+
break;
623633

624-
case OPT_METACOPY_OFF:
625-
config->metacopy = false;
626-
metacopy_opt = true;
627-
break;
634+
default:
635+
pr_err("unrecognized mount option \"%s\" or missing value\n",
636+
opt);
637+
return -EINVAL;
638+
}
628639

629-
case OPT_VOLATILE:
630-
config->ovl_volatile = true;
631-
break;
640+
return err;
641+
}
632642

633-
case OPT_USERXATTR:
634-
config->userxattr = true;
635-
break;
643+
static int ovl_parse_options(char *opt, struct ovl_config *config)
644+
{
645+
char *p;
646+
int err;
647+
struct ovl_opt_set set = {};
636648

637-
default:
638-
pr_err("unrecognized mount option \"%s\" or missing value\n",
639-
p);
640-
return -EINVAL;
641-
}
649+
while ((p = ovl_next_opt(&opt)) != NULL) {
650+
err = ovl_parse_opt(p, config, &set);
651+
if (err)
652+
return err;
642653
}
643654

644655
/* Workdir/index are useless in non-upper mount */
@@ -649,9 +660,9 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
649660
kfree(config->workdir);
650661
config->workdir = NULL;
651662
}
652-
if (config->index && index_opt) {
663+
if (config->index && set.index) {
653664
pr_info("option \"index=on\" is useless in a non-upper mount, ignore\n");
654-
index_opt = false;
665+
set.index = false;
655666
}
656667
config->index = false;
657668
}
@@ -670,12 +681,12 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
670681

671682
/* Resolve metacopy -> redirect_dir dependency */
672683
if (config->metacopy && config->redirect_mode != OVL_REDIRECT_ON) {
673-
if (metacopy_opt && redirect_opt) {
684+
if (set.metacopy && set.redirect) {
674685
pr_err("conflicting options: metacopy=on,redirect_dir=%s\n",
675686
ovl_redirect_mode(config));
676687
return -EINVAL;
677688
}
678-
if (redirect_opt) {
689+
if (set.redirect) {
679690
/*
680691
* There was an explicit redirect_dir=... that resulted
681692
* in this conflict.
@@ -695,10 +706,10 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
695706
config->redirect_mode != OVL_REDIRECT_NOFOLLOW) {
696707
pr_info("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n");
697708
config->nfs_export = false;
698-
} else if (nfs_export_opt && index_opt) {
709+
} else if (set.nfs_export && set.index) {
699710
pr_err("conflicting options: nfs_export=on,index=off\n");
700711
return -EINVAL;
701-
} else if (index_opt) {
712+
} else if (set.index) {
702713
/*
703714
* There was an explicit index=off that resulted
704715
* in this conflict.
@@ -713,11 +724,11 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
713724

714725
/* Resolve nfs_export -> !metacopy dependency */
715726
if (config->nfs_export && config->metacopy) {
716-
if (nfs_export_opt && metacopy_opt) {
727+
if (set.nfs_export && set.metacopy) {
717728
pr_err("conflicting options: nfs_export=on,metacopy=on\n");
718729
return -EINVAL;
719730
}
720-
if (metacopy_opt) {
731+
if (set.metacopy) {
721732
/*
722733
* There was an explicit metacopy=on that resulted
723734
* in this conflict.
@@ -737,13 +748,13 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
737748

738749
/* Resolve userxattr -> !redirect && !metacopy dependency */
739750
if (config->userxattr) {
740-
if (redirect_opt &&
751+
if (set.redirect &&
741752
config->redirect_mode != OVL_REDIRECT_NOFOLLOW) {
742753
pr_err("conflicting options: userxattr,redirect_dir=%s\n",
743754
ovl_redirect_mode(config));
744755
return -EINVAL;
745756
}
746-
if (config->metacopy && metacopy_opt) {
757+
if (config->metacopy && set.metacopy) {
747758
pr_err("conflicting options: userxattr,metacopy=on\n");
748759
return -EINVAL;
749760
}
@@ -1981,7 +1992,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
19811992
ofs->config.nfs_export = ovl_nfs_export_def;
19821993
ofs->config.xino = ovl_xino_def();
19831994
ofs->config.metacopy = ovl_metacopy_def;
1984-
err = ovl_parse_opt((char *) data, &ofs->config);
1995+
err = ovl_parse_options((char *) data, &ofs->config);
19851996
if (err)
19861997
goto out_err;
19871998

0 commit comments

Comments
 (0)