@@ -218,64 +218,30 @@ NFS Client and Server Interlock
218
218
===============================
219
219
220
220
LOCALIO provides the nfs_uuid_t object and associated interfaces to
221
- allow proper network namespace (net-ns) and NFSD object refcounting:
222
-
223
- We don't want to keep a long-term counted reference on each NFSD's
224
- net-ns in the client because that prevents a server container from
225
- completely shutting down.
226
-
227
- So we avoid taking a reference at all and rely on the per-cpu
228
- reference to the server (detailed below) being sufficient to keep
229
- the net-ns active. This involves allowing the NFSD's net-ns exit
230
- code to iterate all active clients and clear their ->net pointers
231
- (which are needed to find the per-cpu-refcount for the nfsd_serv).
232
-
233
- Details:
234
-
235
- - Embed nfs_uuid_t in nfs_client. nfs_uuid_t provides a list_head
236
- that can be used to find the client. It does add the 16-byte
237
- uuid_t to nfs_client so it is bigger than needed (given that
238
- uuid_t is only used during the initial NFS client and server
239
- LOCALIO handshake to determine if they are local to each other).
240
- If that is really a problem we can find a fix.
241
-
242
- - When the nfs server confirms that the uuid_t is local, it moves
243
- the nfs_uuid_t onto a per-net-ns list in NFSD's nfsd_net.
244
-
245
- - When each server's net-ns is shutting down - in a "pre_exit"
246
- handler, all these nfs_uuid_t have their ->net cleared. There is
247
- an rcu_synchronize() call between pre_exit() handlers and exit()
248
- handlers so any caller that sees nfs_uuid_t ->net as not NULL can
249
- safely manage the per-cpu-refcount for nfsd_serv.
250
-
251
- - The client's nfs_uuid_t is passed to nfsd_open_local_fh() so it
252
- can safely dereference ->net in a private rcu_read_lock() section
253
- to allow safe access to the associated nfsd_net and nfsd_serv.
254
-
255
- So LOCALIO required the introduction and use of NFSD's percpu_ref to
256
- interlock nfsd_destroy_serv() and nfsd_open_local_fh(), to ensure each
257
- nn->nfsd_serv is not destroyed while in use by nfsd_open_local_fh(), and
221
+ allow proper network namespace (net-ns) and NFSD object refcounting.
222
+
223
+ LOCALIO required the introduction and use of NFSD's percpu nfsd_net_ref
224
+ to interlock nfsd_shutdown_net() and nfsd_open_local_fh(), to ensure
225
+ each net-ns is not destroyed while in use by nfsd_open_local_fh(), and
258
226
warrants a more detailed explanation:
259
227
260
- nfsd_open_local_fh() uses nfsd_serv_try_get () before opening its
228
+ nfsd_open_local_fh() uses nfsd_net_try_get () before opening its
261
229
nfsd_file handle and then the caller (NFS client) must drop the
262
- reference for the nfsd_file and associated nn->nfsd_serv using
263
- nfs_file_put_local () once it has completed its IO.
230
+ reference for the nfsd_file and associated net-ns using
231
+ nfsd_file_put_local () once it has completed its IO.
264
232
265
233
This interlock working relies heavily on nfsd_open_local_fh() being
266
234
afforded the ability to safely deal with the possibility that the
267
235
NFSD's net-ns (and nfsd_net by association) may have been destroyed
268
- by nfsd_destroy_serv() via nfsd_shutdown_net() -- which is only
269
- possible given the nfs_uuid_t ->net pointer managemenet detailed
270
- above.
271
-
272
- All told, this elaborate interlock of the NFS client and server has been
273
- verified to fix an easy to hit crash that would occur if an NFSD
274
- instance running in a container, with a LOCALIO client mounted, is
275
- shutdown. Upon restart of the container and associated NFSD the client
276
- would go on to crash due to NULL pointer dereference that occurred due
277
- to the LOCALIO client's attempting to nfsd_open_local_fh(), using
278
- nn->nfsd_serv, without having a proper reference on nn->nfsd_serv.
236
+ by nfsd_destroy_serv() via nfsd_shutdown_net().
237
+
238
+ This interlock of the NFS client and server has been verified to fix an
239
+ easy to hit crash that would occur if an NFSD instance running in a
240
+ container, with a LOCALIO client mounted, is shutdown. Upon restart of
241
+ the container and associated NFSD, the client would go on to crash due
242
+ to NULL pointer dereference that occurred due to the LOCALIO client's
243
+ attempting to nfsd_open_local_fh() without having a proper reference on
244
+ NFSD's net-ns.
279
245
280
246
NFS Client issues IO instead of Server
281
247
======================================
@@ -308,16 +274,19 @@ fs/nfs/localio.c:nfs_local_commit().
308
274
309
275
With normal NFS that makes use of RPC to issue IO to the server, if an
310
276
application uses O_DIRECT the NFS client will bypass the pagecache but
311
- the NFS server will not. Because the NFS server's use of buffered IO
312
- affords applications to be less precise with their alignment when
313
- issuing IO to the NFS client. LOCALIO can be configured to use O_DIRECT
314
- semantics by setting the 'localio_O_DIRECT_semantics' nfs module
277
+ the NFS server will not. The NFS server's use of buffered IO affords
278
+ applications to be less precise with their alignment when issuing IO to
279
+ the NFS client. But if all applications properly align their IO, LOCALIO
280
+ can be configured to use end-to-end O_DIRECT semantics from the NFS
281
+ client to the underlying local filesystem, that it is sharing with
282
+ the NFS server, by setting the 'localio_O_DIRECT_semantics' nfs module
315
283
parameter to Y, e.g.:
316
284
317
- echo Y > /sys/module/nfs/parameters/localio_O_DIRECT_semantics
285
+ echo Y > /sys/module/nfs/parameters/localio_O_DIRECT_semantics
318
286
319
- Once enabled, it will cause LOCALIO to use O_DIRECT semantics (this may
320
- cause IO to fail if applications do not properly align their IO).
287
+ Once enabled, it will cause LOCALIO to use end-to-end O_DIRECT semantics
288
+ (but again, this may cause IO to fail if applications do not properly
289
+ align their IO).
321
290
322
291
Security
323
292
========
0 commit comments