1 /* NFSv4.1 client for Windows
2 * Copyright © 2012 The Regents of the University of Michigan
4 * Olga Kornievskaia <aglo@umich.edu>
5 * Casey Bodley <cbodley@umich.edu>
7 * This library is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2.1 of the License, or (at
10 * your option) any later version.
12 * This library is distributed in the hope that it will be useful, but
13 * without any warranty; without even the implied warranty of merchantability
14 * or fitness for a particular purpose. See the GNU Lesser General Public
15 * License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 #include "daemon_debug.h"
27 #include "nfs41_ops.h"
33 static int parse_mount(unsigned char *buffer
, uint32_t length
, nfs41_upcall
*upcall
)
36 mount_upcall_args
*args
= &upcall
->args
.mount
;
38 status
= get_name(&buffer
, &length
, &args
->hostname
);
40 status
= get_name(&buffer
, &length
, &args
->path
);
42 status
= safe_read(&buffer
, &length
, &args
->sec_flavor
, sizeof(DWORD
));
44 status
= safe_read(&buffer
, &length
, &args
->rsize
, sizeof(DWORD
));
46 status
= safe_read(&buffer
, &length
, &args
->wsize
, sizeof(DWORD
));
49 dprintf(1, "parsing NFS14_MOUNT: srv_name=%s root=%s sec_flavor=%s "
50 "rsize=%d wsize=%d\n", args
->hostname
, args
->path
,
51 secflavorop2name(args
->sec_flavor
), args
->rsize
, args
->wsize
);
56 static int handle_mount(nfs41_upcall
*upcall
)
59 mount_upcall_args
*args
= &upcall
->args
.mount
;
66 // resolve hostname,port
67 status
= nfs41_server_resolve(args
->hostname
, 2049, &addrs
);
69 eprintf("nfs41_server_resolve() failed with %d\n", status
);
73 if (upcall
->root_ref
!= INVALID_HANDLE_VALUE
) {
74 /* use an existing root from a previous mount, but don't take an
75 * extra reference; we'll only get one UNMOUNT upcall for each root */
76 root
= upcall
->root_ref
;
79 status
= nfs41_root_create(args
->hostname
, args
->sec_flavor
,
80 args
->wsize
+ WRITE_OVERHEAD
, args
->rsize
+ READ_OVERHEAD
, &root
);
82 eprintf("nfs41_root_create() failed %d\n", status
);
85 root
->uid
= upcall
->uid
;
86 root
->gid
= upcall
->gid
;
89 // find or create the client/session
90 status
= nfs41_root_mount_addrs(root
, &addrs
, 0, 0, &client
);
92 eprintf("nfs41_root_mount_addrs() failed with %d\n", status
);
96 // make a copy of the path for nfs41_lookup()
97 InitializeSRWLock(&path
.lock
);
98 if (FAILED(StringCchCopyA(path
.path
, NFS41_MAX_PATH_LEN
, args
->path
))) {
99 status
= ERROR_FILENAME_EXCED_RANGE
;
102 path
.len
= (unsigned short)strlen(path
.path
);
104 // look up the mount path, and fail if it doesn't exist
105 status
= nfs41_lookup(root
, client
->session
,
106 &path
, NULL
, &file
, NULL
, NULL
);
108 eprintf("nfs41_lookup('%s') failed with %d\n", path
.path
, status
);
109 status
= ERROR_BAD_NETPATH
;
113 nfs41_superblock_fs_attributes(file
.fh
.superblock
, &args
->FsAttrs
);
115 if (upcall
->root_ref
== INVALID_HANDLE_VALUE
)
116 nfs41_root_ref(root
);
117 upcall
->root_ref
= root
;
118 args
->lease_time
= client
->session
->lease_time
;
123 if (upcall
->root_ref
== INVALID_HANDLE_VALUE
)
124 nfs41_root_deref(root
);
128 static int marshall_mount(unsigned char *buffer
, uint32_t *length
, nfs41_upcall
*upcall
)
130 mount_upcall_args
*args
= &upcall
->args
.mount
;
132 dprintf(2, "NFS41_MOUNT: writing pointer to nfs41_root %p, version %d, "
133 "lease_time %d\n", upcall
->root_ref
, NFS41D_VERSION
, args
->lease_time
);
134 status
= safe_write(&buffer
, length
, &upcall
->root_ref
, sizeof(HANDLE
));
135 if (status
) goto out
;
136 status
= safe_write(&buffer
, length
, &NFS41D_VERSION
, sizeof(DWORD
));
137 if (status
) goto out
;
138 status
= safe_write(&buffer
, length
, &args
->lease_time
, sizeof(DWORD
));
139 if (status
) goto out
;
140 status
= safe_write(&buffer
, length
, &args
->FsAttrs
, sizeof(args
->FsAttrs
));
145 static void cancel_mount(IN nfs41_upcall
*upcall
)
147 if (upcall
->root_ref
!= INVALID_HANDLE_VALUE
)
148 nfs41_root_deref(upcall
->root_ref
);
151 const nfs41_upcall_op nfs41_op_mount
= {
160 static int parse_unmount(unsigned char *buffer
, uint32_t length
, nfs41_upcall
*upcall
)
162 dprintf(1, "parsing NFS41_UNMOUNT: root=%p\n", upcall
->root_ref
);
163 return ERROR_SUCCESS
;
166 static int handle_unmount(nfs41_upcall
*upcall
)
168 /* release the original reference from nfs41_root_create() */
169 nfs41_root_deref(upcall
->root_ref
);
170 return ERROR_SUCCESS
;
173 const nfs41_upcall_op nfs41_op_unmount
= {