summaryrefslogtreecommitdiff
path: root/libdiskfs/io-map.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdiskfs/io-map.c')
-rw-r--r--libdiskfs/io-map.c33
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;
}