diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2013-11-14 15:36:36 +0100 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-01-12 15:58:59 +0100 |
commit | 8070f62fb5240ee5b924d0dae501a50f4662ffe9 (patch) | |
tree | a7fe95dddeda956e75da564e99e8d4baf801954c | |
parent | 19689c97a05e0a10691b671c4c37ca0bf51bdd2b (diff) |
trans/mtab: populate mtab objects on demand
Previously the mtab content was generated in the open hook. Delay this
until the data is needed. A follow up patch will take advantage of
this to both simplify the logic in mtab_populate and make it more
robust at the same time.
* trans/mtab.c (open_hook): Do not eagerly populate the mtab.
(trivfs_S_io_read): Populate the mtab struct on demand.
(trivfs_S_io_seek): Likewise.
(trivfs_S_io_readable): Likewise.
-rw-r--r-- | trans/mtab.c | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/trans/mtab.c b/trans/mtab.c index 250de7d6..9b867b7b 100644 --- a/trans/mtab.c +++ b/trans/mtab.c @@ -1,6 +1,6 @@ /* This is an mtab translator. - Copyright (C) 2013 Free Software Foundation, Inc. + Copyright (C) 2013,14 Free Software Foundation, Inc. Written by Justus Winter <4winter@informatik.uni-hamburg.de> @@ -594,7 +594,30 @@ open_hook (struct trivfs_peropen *peropen) mtab->contents = NULL; mtab->contents_len = 0; - return mtab_populate (mtab, target_path, insecure); + /* The mtab object is initialized, but not yet populated. We delay + that until that data is really needed. This avoids the following + problems: + + Suppose you have + + settrans -ac /foo /hurd/mtab / + + If you now access /foo, the mtab translator will walk the tree of + all active translators starting from /. If it visits /foo, it + will talk to itself. Previously the translator migitated this by + comparing the control port of the translator with its own. This + does not work if you got two mtab translators like this: + + settrans -ac /foo /hurd/mtab / + settrans -ac /bar /hurd/mtab / + + With a single-threaded mtab server this results in a dead-lock, + with a multi-threaded server this will create more and more + threads. + + Delaying the data generation until it is really needed cleanly + avoids these kind of problems. */ + return 0; } static void @@ -624,6 +647,14 @@ trivfs_S_io_read (struct trivfs_protid *cred, /* Get the offset. */ op = cred->po->hook; + + if (op->contents == NULL) + { + error_t err = mtab_populate (op, target_path, insecure); + if (err) + return err; + } + if (offs == -1) offs = op->offs; @@ -666,6 +697,13 @@ trivfs_S_io_seek (struct trivfs_protid *cred, struct mtab *op = cred->po->hook; + if (op->contents == NULL) + { + error_t err = mtab_populate (op, target_path, insecure); + if (err) + return err; + } + switch (whence) { case SEEK_CUR: @@ -711,6 +749,13 @@ trivfs_S_io_readable (struct trivfs_protid *cred, struct mtab *op = cred->po->hook; + if (op->contents == NULL) + { + error_t err = mtab_populate (op, target_path, insecure); + if (err) + return err; + } + *amount = op->contents_len - op->offs; return 0; } |