summaryrefslogtreecommitdiff
path: root/libdiskfs/opts-set.c
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1995-10-19 19:40:33 +0000
committerMiles Bader <miles@gnu.org>1995-10-19 19:40:33 +0000
commitdb7c68a28467a43e7c3c09f6103ba37a5a272a7b (patch)
tree449be2dd10d8b2ca65593f5a5dff5deae9918471 /libdiskfs/opts-set.c
parent009327de14ccfb6165a623d02190b1de9e31d03a (diff)
(diskfs_set_options):
Rework readonly transition & remounting. Now they should actually work. (std_runtime_options): Remove options common to both runtime and startup. (diskfs_set_options): Use the common options.
Diffstat (limited to 'libdiskfs/opts-set.c')
-rw-r--r--libdiskfs/opts-set.c46
1 files changed, 24 insertions, 22 deletions
diff --git a/libdiskfs/opts-set.c b/libdiskfs/opts-set.c
index 51b7119b..450a9347 100644
--- a/libdiskfs/opts-set.c
+++ b/libdiskfs/opts-set.c
@@ -20,20 +20,9 @@
#include "priv.h"
-#define SHORT_OPTIONS "rwsnm"
-
static struct argp_option
std_runtime_options[] =
{
- {"readonly", 'r', 0, 0, "Never write to disk or allow opens for writing"},
- {"rdonly", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
- {"writable", 'w', 0, 0, "Use normal read/write behavior"},
- {"rdwr", 0, 0, OPTION_ALIAS | OPTION_HIDDEN},
- {"sync", 's', "INTERVAL", OPTION_ARG_OPTIONAL,
- "If INTERVAL is supplied, sync all data not actually written to disk"
- " every INTERVAL seconds, otherwise operate in synchronous mode (the"
- " default is to sync every 30 seconds)"},
- {"nosync", 'n', 0, 0, "Don't automatically sync data to disk"},
{"remount", 'u', 0, 0, "Flush any meta-data cached in core"},
{0, 0}
};
@@ -41,9 +30,11 @@ std_runtime_options[] =
error_t
diskfs_set_options (int argc, char **argv)
{
+ error_t err;
int readonly = diskfs_readonly;
int sync = diskfs_synchronous;
int sync_interval = -1;
+ int remount = 0;
error_t parse_opt (int opt, char *arg, struct argp_state *argp)
{
switch (opt)
@@ -52,6 +43,8 @@ diskfs_set_options (int argc, char **argv)
readonly = 1; break;
case 'w':
readonly = 0; break;
+ case 'u':
+ remount = 1; break;
case 'n':
sync_interval = 0; sync = 0; break;
case 's':
@@ -60,29 +53,38 @@ diskfs_set_options (int argc, char **argv)
else
sync = 1;
break;
+
default:
return EINVAL;
}
return 0;
}
- struct argp argp = { std_runtime_options, parse_opt };
+ struct argp common_argp = { diskfs_common_options, parse_opt };
+ struct argp *parents[] = { &common_argp, 0 };
+ struct argp argp = { std_runtime_options, parse_opt, 0, 0, parents };
/* Call the user option parsing routine, giving it our set of options to do
with as it pleases. */
- error_t err = diskfs_parse_runtime_options (argc, argv, &argp);
-
+ err = diskfs_parse_runtime_options (argc, argv, &argp);
if (err)
return err;
- /* Do things in this order: change-read/write, remount, change-sync. */
+ /* Do things in this order: remount, change readonly, change-sync; always
+ do the remount while the disk is readonly, even if only temporarily. */
- /* Going writable seems easy, but how do we switch to readonly mode? There
- might be thread that are past the initial readonly checks which would
- fail a !readonly assertion if we just set the variable... */
- if (!readonly)
- diskfs_readonly = 0;
+ if (remount)
+ {
+ /* We can only remount while readonly. */
+ err = diskfs_set_readonly (1);
+ if (!err)
+ err = diskfs_remount ();
+ }
- /* Remount... */
+ if (readonly != diskfs_readonly)
+ if (err)
+ diskfs_set_readonly (readonly); /* keep the old error. */
+ else
+ err = diskfs_set_readonly (readonly);
/* Change sync mode. */
if (sync)
@@ -97,5 +99,5 @@ diskfs_set_options (int argc, char **argv)
diskfs_set_sync_interval (sync_interval);
}
- return 0;
+ return err;
}