diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-01-12 15:47:17 +0100 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-01-12 15:59:23 +0100 |
commit | c31404533f2fb70efd40d7b56d8165e2ab8bd160 (patch) | |
tree | 886f9e95cbd8e788c37f180d22e48623eef29906 | |
parent | dda3d358224c334c8fa4902b3e20c75caf8bddbc (diff) |
trans/mtab: properly lock mtab objects
* trans/mtab.c (struct mtab): Add lock.
(open_hook): Initialize lock.
(close_hook): Destroy lock.
(trivfs_S_io_read): Lock mtab object, adjust error handling accordingly.
(trivfs_S_io_seek): Likewise.
(trivfs_S_io_readable): Likewise.
-rw-r--r-- | trans/mtab.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/trans/mtab.c b/trans/mtab.c index 0bcd52b4..5a5a07df 100644 --- a/trans/mtab.c +++ b/trans/mtab.c @@ -27,6 +27,7 @@ #include <hurd/trivfs.h> #include <inttypes.h> #include <mntent.h> +#include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -47,6 +48,7 @@ struct trivfs_control *control; They keep track of the content and file position of the client. */ struct mtab { + pthread_mutex_t lock; char *contents; size_t contents_len; off_t offs; @@ -569,6 +571,7 @@ open_hook (struct trivfs_peropen *peropen) peropen->hook = mtab; /* Initialize the fields. */ + pthread_mutex_init (&mtab->lock, NULL); mtab->offs = 0; mtab->contents = NULL; mtab->contents_len = 0; @@ -602,8 +605,10 @@ open_hook (struct trivfs_peropen *peropen) static void close_hook (struct trivfs_peropen *peropen) { - free (((struct mtab *) peropen->hook)->contents); - free (peropen->hook); + struct mtab *op = peropen->hook; + pthread_mutex_destroy (&op->lock); + free (op->contents); + free (op); } /* Read data from an IO object. If offset is -1, read from the object @@ -615,6 +620,7 @@ trivfs_S_io_read (struct trivfs_protid *cred, char **data, mach_msg_type_number_t *data_len, loff_t offs, mach_msg_type_number_t amount) { + error_t err = 0; struct mtab *op; /* Deny access if they have bad credentials. */ @@ -626,12 +632,13 @@ trivfs_S_io_read (struct trivfs_protid *cred, /* Get the offset. */ op = cred->po->hook; + pthread_mutex_lock (&op->lock); if (op->contents == NULL) { - error_t err = mtab_populate (op, target_path, insecure); + err = mtab_populate (op, target_path, insecure); if (err) - return err; + goto out; } if (offs == -1) @@ -650,7 +657,10 @@ trivfs_S_io_read (struct trivfs_protid *cred, { *data = mmap (0, amount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); if (*data == MAP_FAILED) - return ENOMEM; + { + err = ENOMEM; + goto out; + } } /* Copy the constant data into the buffer. */ @@ -661,7 +671,9 @@ trivfs_S_io_read (struct trivfs_protid *cred, } *data_len = amount; - return 0; + out: + pthread_mutex_unlock (&op->lock); + return err; } @@ -671,16 +683,18 @@ trivfs_S_io_seek (struct trivfs_protid *cred, mach_port_t reply, mach_msg_type_name_t reply_type, off_t offs, int whence, off_t *new_offs) { + error_t err = 0; if (! cred) return EOPNOTSUPP; struct mtab *op = cred->po->hook; + pthread_mutex_lock (&op->lock); if (op->contents == NULL) { - error_t err = mtab_populate (op, target_path, insecure); + err = mtab_populate (op, target_path, insecure); if (err) - return err; + goto out; } switch (whence) @@ -698,10 +712,12 @@ trivfs_S_io_seek (struct trivfs_protid *cred, break; } default: - return EINVAL; + err = EINVAL; } - return 0; + out: + pthread_mutex_unlock (&op->lock); + return err; } /* If this variable is set, it is called every time a new peropen @@ -720,6 +736,7 @@ trivfs_S_io_readable (struct trivfs_protid *cred, mach_port_t reply, mach_msg_type_name_t replytype, mach_msg_type_number_t *amount) { + error_t err = 0; if (!cred) return EOPNOTSUPP; @@ -727,16 +744,19 @@ trivfs_S_io_readable (struct trivfs_protid *cred, return EINVAL; struct mtab *op = cred->po->hook; + pthread_mutex_lock (&op->lock); if (op->contents == NULL) { error_t err = mtab_populate (op, target_path, insecure); if (err) - return err; + goto out; } *amount = op->contents_len - op->offs; - return 0; + out: + pthread_mutex_unlock (&op->lock); + return err; } /* SELECT_TYPE is the bitwise OR of SELECT_READ, SELECT_WRITE, and SELECT_URG. |