diff options
Diffstat (limited to 'libdiskfs/io-map.c')
-rw-r--r-- | libdiskfs/io-map.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/libdiskfs/io-map.c b/libdiskfs/io-map.c index d1c7f3b2..c9e897c6 100644 --- a/libdiskfs/io-map.c +++ b/libdiskfs/io-map.c @@ -15,6 +15,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <fcntl.h> + #include "priv.h" #include "io_S.h" @@ -26,14 +28,35 @@ diskfs_S_io_map (struct protid *cred, memory_object_t *wrobj, mach_msg_type_name_t *wrtype) { + int flags; + struct node *node; + if (!cred) return EOPNOTSUPP; - - mutex_lock (&cred->po->np->lock); - *rdobj = diskfs_get_filemap (cred->po->np); - *wrobj = diskfs_get_filemap (cred->po->np); - mutex_unlock (&cred->po->np->lock); + + *wrobj = *rdobj = MACH_PORT_NULL; + + node = cred->po->np; + flags = cred->po->openstat & (O_READ | O_WRITE); + + mutex_lock (&node->lock); + switch (flags) + { + case O_READ | O_WRITE: + *wrobj = *rdobj = diskfs_get_filemap (node, VM_PROT_READ |VM_PROT_WRITE); + mach_port_mod_refs (mach_task_self (), *rdobj, MACH_PORT_RIGHT_SEND, 1); + break; + case O_READ: + *rdobj = diskfs_get_filemap (node, VM_PROT_READ); + break; + case O_WRITE: + *wrobj = diskfs_get_filemap (node, VM_PROT_WRITE); + break; + } + mutex_unlock (&node->lock); + *rdtype = MACH_MSG_TYPE_MOVE_SEND; *wrtype = MACH_MSG_TYPE_MOVE_SEND; + return 0; } |