===== fs/reiserfs/super.c 1.31 vs edited ===== --- 1.31/fs/reiserfs/super.c Thu Mar 13 14:52:15 2003 +++ edited/fs/reiserfs/super.c Fri Apr 4 19:37:42 2003 @@ -403,8 +403,11 @@ mount options that have values rather than being toggles. */ typedef struct { char * value; - int bitmask; /* bit which is to be set in mount_options bitmask when this - value is found, 0 is no bits are to be set */ + int setmask; /* bitmask which is to set on mount_options bitmask when this + value is found, 0 is no bits are to be changed. */ + int clrmask; /* bitmask which is to clear on mount_options bitmask when this + value is found, 0 is no bits are to be changed. This is + applied BEFORE setmask */ } arg_desc_t; @@ -414,37 +417,42 @@ char * option_name; int arg_required; /* 0 is argument is not required, not 0 otherwise */ const arg_desc_t * values; /* list of values accepted by an option */ - int bitmask; /* bit which is to be set in mount_options bitmask when this - option is selected, 0 is not bits are to be set */ + int setmask; /* bitmask which is to set on mount_options bitmask when this + value is found, 0 is no bits are to be changed. */ + int clrmask; /* bitmask which is to clear on mount_options bitmask when this + value is found, 0 is no bits are to be changed. This is + applied BEFORE setmask */ } opt_desc_t; /* possible values for "-o hash=" and bits which are to be set in s_mount_opt of reiserfs specific part of in-core super block */ static const arg_desc_t hash[] = { - {"rupasov", FORCE_RUPASOV_HASH}, - {"tea", FORCE_TEA_HASH}, - {"r5", FORCE_R5_HASH}, - {"detect", FORCE_HASH_DETECT}, - {NULL, 0} + {"rupasov", 1<option_name; opt ++) { if (!strncmp (p, opt->option_name, strlen (opt->option_name))) { - if (bit_flags && opt->bitmask != -1 ) - set_bit (opt->bitmask, bit_flags); + if (bit_flags) { + *bit_flags &= ~opt->clrmask; + *bit_flags |= opt->setmask; + } break; } } @@ -529,7 +539,7 @@ } if (!opt->values) { - /* *opt_arg contains pointer to argument */ + /* *=NULLopt_arg contains pointer to argument */ *opt_arg = p; return opt->arg_required; } @@ -537,8 +547,10 @@ /* values possible for this option are listed in opt->values */ for (arg = opt->values; arg->value; arg ++) { if (!strcmp (p, arg->value)) { - if (bit_flags && arg->bitmask != -1 ) - set_bit (arg->bitmask, bit_flags); + if (bit_flags) { + *bit_flags &= ~arg->clrmask; + *bit_flags |= arg->setmask; + } return opt->arg_required; } } @@ -547,7 +559,6 @@ return -1; } - /* returns 0 if something is wrong in option string, 1 - otherwise */ static int reiserfs_parse_options (struct super_block * s, char * options, /* string given via mount's -o */ unsigned long * mount_options, @@ -560,18 +571,21 @@ char * arg = NULL; char * pos; opt_desc_t opts[] = { - {"tails", 't', tails, -1}, - {"notail", 0, 0, -1}, /* Compatibility stuff, so that -o notail for old setups still work */ - {"conv", 0, 0, REISERFS_CONVERT}, - {"nolog", 0, 0, -1}, - {"replayonly", 0, 0, REPLAYONLY}, + {"tails", 't', tails, 0, 0}, + /* Compatibility stuff, so that -o notail + for old setups still work */ + {"notail", 0, 0, 0, (1<u.reiserfs_sb.s_mount_opt; + unsigned long safe_mask = 0; rs = SB_DISK_SUPER_BLOCK (s); if (!reiserfs_parse_options(s, data, &mount_options, &blocks)) - return 0; + return -EINVAL; -#define SET_OPT( opt, bits, super ) \ - if( ( bits ) & ( 1 << ( opt ) ) ) \ - ( super ) -> u.reiserfs_sb.s_mount_opt |= ( 1 << ( opt ) ) - - /* set options in the super-block bitmask */ - SET_OPT( REISERFS_SMALLTAIL, mount_options, s ); - SET_OPT( REISERFS_LARGETAIL, mount_options, s ); - SET_OPT( REISERFS_NO_BORDER, mount_options, s ); - SET_OPT( REISERFS_NO_UNHASHED_RELOCATION, mount_options, s ); - SET_OPT( REISERFS_HASHED_RELOCATION, mount_options, s ); - SET_OPT( REISERFS_TEST4, mount_options, s ); - SET_OPT( REISERFS_ATTRS, mount_options, s ); -#undef SET_OPT + /* Add options that are safe here */ + safe_mask |= 1 << REISERFS_SMALLTAIL; + safe_mask |= 1 << REISERFS_LARGETAIL; + safe_mask |= 1 << REISERFS_NO_BORDER; + safe_mask |= 1 << REISERFS_NO_UNHASHED_RELOCATION; + safe_mask |= 1 << REISERFS_HASHED_RELOCATION; + safe_mask |= 1 << REISERFS_TEST4; + safe_mask |= 1 << REISERFS_ATTRS; + + /* Update the bitmask, taking care to keep + * the bits we're not allowed to change here */ + s->u.reiserfs_sb.s_mount_opt = (s->u.reiserfs_sb.s_mount_opt & ~safe_mask) | (mount_options & safe_mask); handle_attrs( s );