Hi, the attached patches enhance the tmpfs invocation with --size=MAX-BYTES to set the maximum size, in addition to the current way (passing it as first parameter). This improves the compatibility with classic usages like putting tmpfs entries in fstab, or mounting it with mount.
Thanks, -- Pino Toscano
From a35bd267aba2954df85ee3403981395bf8c9e736 Mon Sep 17 00:00:00 2001 From: Pino Toscano <toscano.p...@tiscali.it> Date: Fri, 7 Sep 2012 18:21:00 +0200 Subject: [PATCH 1/2] tmpfs: extract size string parsing in an own function * tmpfs/tmpfs.c (parse_opt_size): New function, broken out of ... (parse_opt): ... here. Call it. --- tmpfs/tmpfs.c | 115 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 64 insertions(+), 51 deletions(-) diff --git a/tmpfs/tmpfs.c b/tmpfs/tmpfs.c index b72459f..2a98178 100644 --- a/tmpfs/tmpfs.c +++ b/tmpfs/tmpfs.c @@ -112,6 +112,66 @@ struct option_values mode_t mode; }; +/* Parse the size string ARG, and set *NEWSIZE with the resulting size. */ +static error_t +parse_opt_size (const char *arg, struct argp_state *state, off_t *newsize) +{ + char *end = NULL; + intmax_t size = strtoimax (arg, &end, 0); + if (end == NULL || end == arg) + { + argp_error (state, "argument must be a number"); + return EINVAL; + } + if (size < 0) + { + argp_error (state, "negative size not meaningful"); + return EINVAL; + } + switch (*end) + { + case 'g': + case 'G': + size <<= 10; + case 'm': + case 'M': + size <<= 10; + case 'k': + case 'K': + size <<= 10; + break; + case '%': + { + /* Set as a percentage of the machine's physical memory. */ + struct vm_statistics vmstats; + error_t err = vm_statistics (mach_task_self (), &vmstats); + if (err) + { + argp_error (state, "cannot find total physical memory: %s", + strerror (err)); + return err; + } + size = round_page ((((vmstats.free_count + + vmstats.active_count + + vmstats.inactive_count + + vmstats.wire_count) + * vm_page_size) + * size + 99) / 100); + break; + } + } + size = (off_t) size; + if (size < 0) + { + argp_error (state, "size too large"); + return EINVAL; + } + + *newsize = size; + + return 0; +} + /* Parse a command line option. */ static error_t parse_opt (int key, char *arg, struct argp_state *state) @@ -166,57 +226,10 @@ parse_opt (int key, char *arg, struct argp_state *state) } else { - char *end = NULL; - intmax_t size = strtoimax (state->argv[state->next], &end, 0); - if (end == NULL || end == arg) - { - argp_error (state, "argument must be a number"); - return EINVAL; - } - if (size < 0) - { - argp_error (state, "negative size not meaningful"); - return EINVAL; - } - switch (*end) - { - case 'g': - case 'G': - size <<= 10; - case 'm': - case 'M': - size <<= 10; - case 'k': - case 'K': - size <<= 10; - break; - case '%': - { - /* Set as a percentage of the machine's physical memory. */ - struct vm_statistics vmstats; - error_t err = vm_statistics (mach_task_self (), &vmstats); - if (err) - { - argp_error (state, "cannot find total physical memory: %s", - strerror (err)); - return err; - } - size = round_page ((((vmstats.free_count - + vmstats.active_count - + vmstats.inactive_count - + vmstats.wire_count) - * vm_page_size) - * size + 99) / 100); - break; - } - } - size = (off_t) size; - if (size < 0) - { - argp_error (state, "size too large"); - return EINVAL; - } - values->size = size; + error_t err = parse_opt_size (state->argv[state->next], state, + &values->size); + if (err) + return err; } break; -- 1.7.10.4
From b733cccf1a835b91de3fbdd098e0f2fd076a4793 Mon Sep 17 00:00:00 2001 From: Pino Toscano <toscano.p...@tiscali.it> Date: Fri, 7 Sep 2012 18:24:20 +0200 Subject: [PATCH 2/2] tmpfs: add --size Add the possibility to specify the size with the --size parameter; this makes tmpfs more usable in fstab or Linuxish mount invocations, since the size in such cases is a mount -o option, which gets translated to a --foo translator argument. The old way (specifying the size as the first argument) is left there; although, if --size is passed then the first argument must be "tmpfs", as it is what is passed by fstab/mount. * tmpfs/tmpfs.c (OPT_SIZE): New macro. (options): Add the "size" option. (parse_opt): Use -1 to indicate when SIZE is not yet set. <OPT_SIZE>: Handle case. <ARGP_KEY_NO_ARGS>: Error out only when SIZE is not set. <ARGP_KEY_ARGS>: Error out when SIZE is set and the argument is not "tmpfs". --- tmpfs/tmpfs.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/tmpfs/tmpfs.c b/tmpfs/tmpfs.c index 2a98178..8379528 100644 --- a/tmpfs/tmpfs.c +++ b/tmpfs/tmpfs.c @@ -100,9 +100,12 @@ diskfs_reload_global_state () int diskfs_synchronous = 0; +#define OPT_SIZE 600 /* --size */ + static const struct argp_option options[] = { {"mode", 'm', "MODE", 0, "Permissions (octal) for root directory"}, + {"size", OPT_SIZE, "MAX-BYTES", 0, "Maximum size"}, {NULL,} }; @@ -188,7 +191,7 @@ parse_opt (int key, char *arg, struct argp_state *state) if (values == 0) return ENOMEM; state->hook = values; - values->size = 0; + values->size = -1; values->mode = -1; break; case ARGP_KEY_FINI: @@ -214,9 +217,21 @@ parse_opt (int key, char *arg, struct argp_state *state) } break; + case OPT_SIZE: /* --size=MAX-BYTES */ + { + error_t err = parse_opt_size (arg, state, &values->size); + if (err) + return err; + } + break; + case ARGP_KEY_NO_ARGS: - argp_error (state, "must supply maximum size"); - return EINVAL; + if (values->size < 0) + { + argp_error (state, "must supply maximum size"); + return EINVAL; + } + break; case ARGP_KEY_ARGS: if (state->argv[state->next + 1] != 0) @@ -224,6 +239,14 @@ parse_opt (int key, char *arg, struct argp_state *state) argp_error (state, "too many arguments"); return EINVAL; } + else if (values->size >= 0) + { + if (strcmp (state->argv[state->next], "tmpfs") != 0) + { + argp_error (state, "size specified with --size and argument is not \"tmpfs\""); + return EINVAL; + } + } else { error_t err = parse_opt_size (state->argv[state->next], state, -- 1.7.10.4
signature.asc
Description: This is a digitally signed message part.