summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGianluca Guida <glguida@gmail.com>2005-06-30 18:49:55 +0000
committerGianluca Guida <glguida@gmail.com>2005-06-30 18:49:55 +0000
commit3054767a46e0142cacef895c13edb4391435c722 (patch)
treec3dd42959eabd48d87bb7d4c66c325197943c245
parentecdca81b8c88107d4a23dd412f603d5b8ddd43bf (diff)
2005-06-27 Ben Asselstine <benasselstine@gmail.com>
* ulfs.c (ulfs_install): Rewrote to allow insertions of filesystems based on priority. (ulfs_register): Added new argument 'priority'. Set the priority value in ulfs structure. * ulfs.h (ulfs): Added 'priority' field to struct. Updated ulfs_register declaration. * netfs.c (netfs_append_args): Appending new priority option. * stow.c (stow_privdata): Added 'priority' field to struct. (stow_diradd): Added new 'priority' argument. Fill priority field of 'mypriv'. (_stow_scanstowentry): Changed caller to ulfs_register. (_stow_registermatchingdirs): Likewise. * options.c (arg_common_options): Added entries for OPT_PRIORITY and OPT_ADD. (arg_parse_common_options): Handle OPT_PRIORITY and OPT_ADD case. Renamed 'ulfs_removed' to 'ulfs_mode'. New variable 'ulfs_priority'. Changed caller to 'stow_diradd'. Changed caller to 'ulfs_register'. * options.h (OPT_ADD, OPT_PRIORITY, OPT_LONG_ADD) (OPT_LONG_PRIORITY, ULFS_MODE_ADD, ULFS_MODE_REMOVE): New declarations.
-rw-r--r--ChangeLog24
-rw-r--r--netfs.c12
-rw-r--r--options.c30
-rw-r--r--options.h7
-rw-r--r--stow.c9
-rw-r--r--ulfs.c52
-rw-r--r--ulfs.h3
7 files changed, 117 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 0df1f3e..a733036 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2005-06-27 Ben Asselstine <benasselstine@gmail.com>
+
+ * ulfs.c (ulfs_install): Rewrote to allow insertions of
+ filesystems based on priority.
+ (ulfs_register): Added new argument 'priority'. Set the priority
+ value in ulfs structure.
+ * ulfs.h (ulfs): Added 'priority' field to struct.
+ Updated ulfs_register declaration.
+ * netfs.c (netfs_append_args): Appending new priority option.
+ * stow.c (stow_privdata): Added 'priority' field to struct.
+ (stow_diradd): Added new 'priority' argument. Fill priority field
+ of 'mypriv'.
+ (_stow_scanstowentry): Changed caller to ulfs_register.
+ (_stow_registermatchingdirs): Likewise.
+ * options.c (arg_common_options): Added entries for OPT_PRIORITY
+ and OPT_ADD.
+ (arg_parse_common_options): Handle OPT_PRIORITY and OPT_ADD
+ case. Renamed 'ulfs_removed' to 'ulfs_mode'. New variable
+ 'ulfs_priority'. Changed caller to 'stow_diradd'. Changed caller
+ to 'ulfs_register'.
+ * options.h (OPT_ADD, OPT_PRIORITY, OPT_LONG_ADD)
+ (OPT_LONG_PRIORITY, ULFS_MODE_ADD, ULFS_MODE_REMOVE): New
+ declarations.
+
2005-06-13 Gianluca Guida <glguida@gmail.com>
* main.c (main): Set properly netfs_root_node permissions when
diff --git a/netfs.c b/netfs.c
index c1057ab..89d1bf6 100644
--- a/netfs.c
+++ b/netfs.c
@@ -56,6 +56,18 @@ netfs_append_args (char **argz, size_t *argz_len)
err = argz_add (argz, argz_len,
OPT_LONG (OPT_LONG_WRITABLE));
if (! err)
+ if (ulfs->priority)
+ {
+ char *buf = NULL;
+ if ((err = asprintf (&buf, "%s=%s", OPT_LONG (OPT_LONG_PRIORITY),
+ ulfs->priority)) != -1)
+ {
+ err = argz_add (argz, argz_len, buf);
+ free (buf);
+ }
+ }
+
+ if (! err)
{
if (ulfs->path)
err = argz_add (argz, argz_len, ulfs->path);
diff --git a/options.c b/options.c
index 4ca3fca..c3a872d 100644
--- a/options.c
+++ b/options.c
@@ -54,10 +54,14 @@ const struct argp_option argp_common_options[] =
{ 0, 0, 0, 0, "Runtime options:", 1 },
{ OPT_LONG_STOW, OPT_STOW, "STOWDIR", 0,
"stow given directory", 1},
+ { OPT_LONG_PRIORITY, OPT_PRIORITY, "VALUE", 0,
+ "Set the priority for the following filesystem to VALUE", 1},
{ OPT_LONG_PATTERN, OPT_PATTERN, "PATTERN", 0,
"add only nodes of the underlying filesystem matching pattern", 1},
{ OPT_LONG_REMOVE, OPT_REMOVE, 0, 0,
"remove the following filesystem", 1 },
+ { OPT_LONG_ADD, OPT_ADD, 0, 0,
+ "add the following filesystem (Default)", 1 },
{ 0 }
};
@@ -71,8 +75,8 @@ const struct argp_option argp_startup_options[] =
error_t
argp_parse_common_options (int key, char *arg, struct argp_state *state)
{
- static int ulfs_flags = 0, ulfs_remove = 0, ulfs_modified = 0,
- ulfs_match = 0;
+ static int ulfs_flags = 0, ulfs_mode = 0, ulfs_modified = 0,
+ ulfs_match = 0, ulfs_priority = 0;
static struct patternlist ulfs_patternlist =
{
.lock = MUTEX_INITIALIZER,
@@ -86,6 +90,10 @@ argp_parse_common_options (int key, char *arg, struct argp_state *state)
ulfs_flags |= FLAG_ULFS_WRITABLE;
break;
+ case OPT_PRIORITY: /* --priority */
+ ulfs_priority = strtol (arg, NULL, 10);
+ break;
+
case OPT_DEBUG: /* --debug */
unionfs_flags |= FLAG_UNIONFS_MODE_DEBUG;
break;
@@ -94,8 +102,12 @@ argp_parse_common_options (int key, char *arg, struct argp_state *state)
ncache_size = strtol (arg, NULL, 10);
break;
+ case OPT_ADD: /* --add */
+ ulfs_mode = ULFS_MODE_ADD;
+ break;
+
case OPT_REMOVE: /* --remove */
- ulfs_remove = 1;
+ ulfs_mode = ULFS_MODE_REMOVE;
break;
case OPT_PATTERN: /* --match */
@@ -104,18 +116,18 @@ argp_parse_common_options (int key, char *arg, struct argp_state *state)
break;
case OPT_STOW: /* --stow */
- err = stow_diradd (arg, ulfs_flags, &ulfs_patternlist, ulfs_remove);
+ err = stow_diradd (arg, ulfs_flags, &ulfs_patternlist, ulfs_priority);
if (err)
error (EXIT_FAILURE, err, "stow_diradd");
ulfs_modified = 1;
- ulfs_flags = ulfs_remove = 0;
+ ulfs_flags = ulfs_mode = ulfs_priority = 0;
ulfs_match = 0;
break;
case OPT_UNDERLYING: /* --underlying */
case ARGP_KEY_ARG:
- if (ulfs_remove)
+ if (ulfs_mode == ULFS_MODE_REMOVE)
{
err = ulfs_unregister (arg);
if (err == ENOENT)
@@ -124,16 +136,16 @@ argp_parse_common_options (int key, char *arg, struct argp_state *state)
err = 0;
}
else
- err = ulfs_register (arg, ulfs_flags);
+ err = ulfs_register (arg, ulfs_flags, ulfs_priority);
if (err)
error (EXIT_FAILURE, err, "ulfs_register");
ulfs_modified = 1;
- ulfs_flags = ulfs_remove = 0;
+ ulfs_flags = ulfs_mode = ulfs_priority = 0;
ulfs_match = 0;
break;
case ARGP_KEY_END:
- ulfs_flags = ulfs_remove = 0;
+ ulfs_flags = ulfs_mode = 0;
if (ulfs_modified && parsing_startup_options_finished)
{
root_update_schedule ();
diff --git a/options.h b/options.h
index 5ad2404..eb74ce6 100644
--- a/options.h
+++ b/options.h
@@ -25,7 +25,9 @@
#define OPT_DEBUG 'd'
#define OPT_CACHE_SIZE 'c'
#define OPT_REMOVE 'r'
+#define OPT_ADD 'a'
#define OPT_PATTERN 'm'
+#define OPT_PRIORITY 'p'
#define OPT_STOW 's'
/* The long options. */
@@ -34,7 +36,9 @@
#define OPT_LONG_DEBUG "debug"
#define OPT_LONG_CACHE_SIZE "cache-size"
#define OPT_LONG_REMOVE "remove"
+#define OPT_LONG_ADD "add"
#define OPT_LONG_PATTERN "match"
+#define OPT_LONG_PRIORITY "priority"
#define OPT_LONG_STOW "stow"
#define OPT_LONG(o) "--" o
@@ -44,3 +48,6 @@ extern struct argp argp_startup;
/* The final argp parser for startup arguments. */
extern struct argp argp_runtime;
+
+#define ULFS_MODE_ADD 0
+#define ULFS_MODE_REMOVE 1
diff --git a/stow.c b/stow.c
index 827af63..fa99747 100644
--- a/stow.c
+++ b/stow.c
@@ -34,6 +34,7 @@ struct stow_privdata
{
struct patternlist *patternlist;
int flags;
+ int priority;
struct mutex lock;
};
@@ -51,7 +52,7 @@ _stow_registermatchingdirs (char *arg, char *dirpath, void *priv)
filepath = make_filepath (dirpath, arg);
- err = ulfs_register (filepath, privdata->flags);
+ err = ulfs_register (filepath, privdata->flags, privdata->priority);
free (filepath);
@@ -82,7 +83,7 @@ _stow_scanstowentry (char *arg, char *dirpath, void *priv)
if (patternlist_isempty (privdata->patternlist))
{
- err = ulfs_register (filepath, privdata->flags);
+ err = ulfs_register (filepath, privdata->flags, privdata->priority);
if (err)
{
mutex_unlock (&privdata->lock);
@@ -253,7 +254,8 @@ _stow_notify_thread()
/* Interface to unionfs. */
error_t
-stow_diradd (char *dir, int flags, struct patternlist *patternlist)
+stow_diradd (char *dir, int flags, struct patternlist *patternlist,
+ int priority)
{
error_t err;
@@ -291,6 +293,7 @@ stow_diradd (char *dir, int flags, struct patternlist *patternlist)
mypriv->patternlist = patternlist;
mypriv->flags = flags;
+ mypriv->priority = priority;
mutex_init (&mypriv->lock);
err = for_each_subdir_priv (dir, _stow_scanstowentry, (void *)mypriv);
diff --git a/ulfs.c b/ulfs.c
index 5a8896a..d924b0c 100644
--- a/ulfs.c
+++ b/ulfs.c
@@ -83,17 +83,54 @@ ulfs_destroy (ulfs_t *ulfs)
free (ulfs);
}
-/* Install ULFS into the linked list of registered filesystems. */
+/* Install ULFS into the linked list of registered filesystems in
+ * priority order. */
void
ulfs_install (ulfs_t *ulfs)
{
- ulfs->next = ulfs_chain_start;
- ulfs->prev = NULL;
+ ulfs_t *u = ulfs_chain_start;
+ int insert_at_end = 0;
+ if (ulfs_num == 0)
+ {
+ ulfs_chain_start = ulfs;
+ return;
+ }
- if (ulfs->next)
- ulfs->next->prev = ulfs;
+ /* walk the chain until a filesystem has a priority that's too high. */
+ while (u->priority > ulfs->priority)
+ {
+ if (u->next == NULL)
+ {
+ insert_at_end = 1;
+ break;
+ }
+ u = u->next;
+ }
+
+ if (insert_at_end)
+ {
+ u->next = ulfs;
+ ulfs->prev = u;
+ }
+ else
+ {
+ if (u == ulfs_chain_start)
+ {
+ ulfs_chain_start = ulfs;
+ ulfs->next = u;
+ ulfs->prev = NULL;
+ u->prev = ulfs;
+ }
+ else
+ {
+ ulfs->next = u;
+ ulfs->prev = u->prev;
+ u->prev->next = ulfs;
+ u->prev = ulfs;
+ }
+ }
- ulfs_chain_start = ulfs;
+ return;
}
/* Remove ULFS from the linked list of registered filesystems. */
@@ -177,7 +214,7 @@ ulfs_for_each_under_priv (char *path_under,
/* Register a new underlying filesystem. */
error_t
-ulfs_register (char *path, int flags)
+ulfs_register (char *path, int flags, int priority)
{
ulfs_t *ulfs;
error_t err;
@@ -194,6 +231,7 @@ ulfs_register (char *path, int flags)
if (! err)
{
ulfs->flags = flags;
+ ulfs->priority = priority;
ulfs_install (ulfs);
ulfs_num++;
}
diff --git a/ulfs.h b/ulfs.h
index dbb59d3..186718c 100644
--- a/ulfs.h
+++ b/ulfs.h
@@ -27,6 +27,7 @@ typedef struct ulfs
{
char *path;
int flags;
+ int priority;
struct ulfs *next, *prev;
} ulfs_t;
@@ -49,7 +50,7 @@ extern unsigned int ulfs_num;
extern struct mutex ulfs_lock;
/* Register a new underlying filesystem. */
-error_t ulfs_register (char *path, int flags);
+error_t ulfs_register (char *path, int flags, int priority);
/* Unregister an underlying filesystem. */
error_t ulfs_unregister (char *path);