License cleanup: add SPDX GPL-2.0 license identifier to files with no license
Many source files in the tree are missing licensing information, which
makes it harder for compliance tools to determine the correct license.
By default all files without license information are under the default
license of the kernel, which is GPL version 2.
Update the files which contain no license information with the 'GPL-2.0'
SPDX license identifier. The SPDX identifier is a legally binding
shorthand, which can be used instead of the full boiler plate text.
This patch is based on work done by Thomas Gleixner and Kate Stewart and
Philippe Ombredanne.
How this work was done:
Patches were generated and checked against linux-4.14-rc6 for a subset of
the use cases:
- file had no licensing information it it.
- file was a */uapi/* one with no licensing information in it,
- file was a */uapi/* one with existing licensing information,
Further patches will be generated in subsequent months to fix up cases
where non-standard license headers were used, and references to license
had to be inferred by heuristics based on keywords.
The analysis to determine which SPDX License Identifier to be applied to
a file was done in a spreadsheet of side by side results from of the
output of two independent scanners (ScanCode & Windriver) producing SPDX
tag:value files created by Philippe Ombredanne. Philippe prepared the
base worksheet, and did an initial spot review of a few 1000 files.
The 4.13 kernel was the starting point of the analysis with 60,537 files
assessed. Kate Stewart did a file by file comparison of the scanner
results in the spreadsheet to determine which SPDX license identifier(s)
to be applied to the file. She confirmed any determination that was not
immediately clear with lawyers working with the Linux Foundation.
Criteria used to select files for SPDX license identifier tagging was:
- Files considered eligible had to be source code files.
- Make and config files were included as candidates if they contained >5
lines of source
- File already had some variant of a license header in it (even if <5
lines).
All documentation files were explicitly excluded.
The following heuristics were used to determine which SPDX license
identifiers to apply.
- when both scanners couldn't find any license traces, file was
considered to have no license information in it, and the top level
COPYING file license applied.
For non */uapi/* files that summary was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 11139
and resulted in the first patch in this series.
If that file was a */uapi/* path one, it was "GPL-2.0 WITH
Linux-syscall-note" otherwise it was "GPL-2.0". Results of that was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 WITH Linux-syscall-note 930
and resulted in the second patch in this series.
- if a file had some form of licensing information in it, and was one
of the */uapi/* ones, it was denoted with the Linux-syscall-note if
any GPL family license was found in the file or had no licensing in
it (per prior point). Results summary:
SPDX license identifier # files
---------------------------------------------------|------
GPL-2.0 WITH Linux-syscall-note 270
GPL-2.0+ WITH Linux-syscall-note 169
((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) 21
((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 17
LGPL-2.1+ WITH Linux-syscall-note 15
GPL-1.0+ WITH Linux-syscall-note 14
((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) 5
LGPL-2.0+ WITH Linux-syscall-note 4
LGPL-2.1 WITH Linux-syscall-note 3
((GPL-2.0 WITH Linux-syscall-note) OR MIT) 3
((GPL-2.0 WITH Linux-syscall-note) AND MIT) 1
and that resulted in the third patch in this series.
- when the two scanners agreed on the detected license(s), that became
the concluded license(s).
- when there was disagreement between the two scanners (one detected a
license but the other didn't, or they both detected different
licenses) a manual inspection of the file occurred.
- In most cases a manual inspection of the information in the file
resulted in a clear resolution of the license that should apply (and
which scanner probably needed to revisit its heuristics).
- When it was not immediately clear, the license identifier was
confirmed with lawyers working with the Linux Foundation.
- If there was any question as to the appropriate license identifier,
the file was flagged for further research and to be revisited later
in time.
In total, over 70 hours of logged manual review was done on the
spreadsheet to determine the SPDX license identifiers to apply to the
source files by Kate, Philippe, Thomas and, in some cases, confirmation
by lawyers working with the Linux Foundation.
Kate also obtained a third independent scan of the 4.13 code base from
FOSSology, and compared selected files where the other two scanners
disagreed against that SPDX file, to see if there was new insights. The
Windriver scanner is based on an older version of FOSSology in part, so
they are related.
Thomas did random spot checks in about 500 files from the spreadsheets
for the uapi headers and agreed with SPDX license identifier in the
files he inspected. For the non-uapi files Thomas did random spot checks
in about 15000 files.
In initial set of patches against 4.14-rc6, 3 files were found to have
copy/paste license identifier errors, and have been fixed to reflect the
correct identifier.
Additionally Philippe spent 10 hours this week doing a detailed manual
inspection and review of the 12,461 patched files from the initial patch
version early this week with:
- a full scancode scan run, collecting the matched texts, detected
license ids and scores
- reviewing anything where there was a license detected (about 500+
files) to ensure that the applied SPDX license was correct
- reviewing anything where there was no detection but the patch license
was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied
SPDX license was correct
This produced a worksheet with 20 files needing minor correction. This
worksheet was then exported into 3 different .csv files for the
different types of files to be modified.
These .csv files were then reviewed by Greg. Thomas wrote a script to
parse the csv files and add the proper SPDX tag to the file, in the
format that the file expected. This script was further refined by Greg
based on the output to detect more types of files automatically and to
distinguish between header and source .c files (which need different
comment types.) Finally Greg ran the script using the .csv files to
generate the patches.
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-01 22:07:57 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
2005-04-17 06:20:36 +08:00
|
|
|
#ifndef _NFS_FS_SB
|
|
|
|
#define _NFS_FS_SB
|
|
|
|
|
|
|
|
#include <linux/list.h>
|
|
|
|
#include <linux/backing-dev.h>
|
2012-01-18 11:04:24 +08:00
|
|
|
#include <linux/idr.h>
|
2007-11-08 17:05:04 +08:00
|
|
|
#include <linux/wait.h>
|
2009-04-01 21:21:53 +08:00
|
|
|
#include <linux/nfs_xdr.h>
|
|
|
|
#include <linux/sunrpc/xprt.h>
|
2007-11-08 17:05:04 +08:00
|
|
|
|
2011-07-27 07:09:06 +08:00
|
|
|
#include <linux/atomic.h>
|
2017-10-20 17:53:38 +08:00
|
|
|
#include <linux/refcount.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2009-04-01 21:21:53 +08:00
|
|
|
struct nfs4_session;
|
2006-03-21 02:44:13 +08:00
|
|
|
struct nfs_iostats;
|
2008-01-12 06:09:52 +08:00
|
|
|
struct nlm_host;
|
2009-04-01 21:22:03 +08:00
|
|
|
struct nfs4_sequence_args;
|
|
|
|
struct nfs4_sequence_res;
|
|
|
|
struct nfs_server;
|
2010-06-16 21:52:26 +08:00
|
|
|
struct nfs4_minor_version_ops;
|
2012-05-22 10:44:31 +08:00
|
|
|
struct nfs41_server_scope;
|
2012-02-18 04:20:26 +08:00
|
|
|
struct nfs41_impl_id;
|
2006-03-21 02:44:13 +08:00
|
|
|
|
2006-08-23 08:06:10 +08:00
|
|
|
/*
|
|
|
|
* The nfs_client identifies our client state to the server.
|
|
|
|
*/
|
|
|
|
struct nfs_client {
|
2017-10-20 17:53:38 +08:00
|
|
|
refcount_t cl_count;
|
2012-06-15 01:08:38 +08:00
|
|
|
atomic_t cl_mds_count;
|
2006-08-23 08:06:10 +08:00
|
|
|
int cl_cons_state; /* current construction state (-ve: init error) */
|
|
|
|
#define NFS_CS_READY 0 /* ready to be used */
|
|
|
|
#define NFS_CS_INITING 1 /* busy initialising */
|
2009-04-01 21:22:38 +08:00
|
|
|
#define NFS_CS_SESSION_INITING 2 /* busy initialising session */
|
2006-08-23 08:06:10 +08:00
|
|
|
unsigned long cl_res_state; /* NFS resources state */
|
|
|
|
#define NFS_CS_CALLBACK 1 /* - callback started */
|
|
|
|
#define NFS_CS_IDMAP 2 /* - idmap started */
|
2006-08-24 13:03:05 +08:00
|
|
|
#define NFS_CS_RENEWD 3 /* - renewd started */
|
2011-03-01 09:34:10 +08:00
|
|
|
#define NFS_CS_STOP_RENEW 4 /* no more state to renew */
|
2011-03-01 09:34:11 +08:00
|
|
|
#define NFS_CS_CHECK_LEASE_TIME 5 /* need to check lease time */
|
2012-05-22 10:46:07 +08:00
|
|
|
unsigned long cl_flags; /* behavior switches */
|
|
|
|
#define NFS_CS_NORESVPORT 0 /* - use ephemeral src port */
|
|
|
|
#define NFS_CS_DISCRTRY 1 /* - disconnect on RPC retry */
|
2012-09-15 05:24:11 +08:00
|
|
|
#define NFS_CS_MIGRATION 2 /* - transparent state migr */
|
2013-04-14 23:49:51 +08:00
|
|
|
#define NFS_CS_INFINITE_SLOTS 3 /* - don't limit TCP slots */
|
2013-09-25 00:06:07 +08:00
|
|
|
#define NFS_CS_NO_RETRANS_TIMEOUT 4 /* - Disable retransmit timeouts */
|
2017-06-08 23:52:44 +08:00
|
|
|
#define NFS_CS_TSM_POSSIBLE 5 /* - Maybe state migration */
|
2007-12-11 03:58:15 +08:00
|
|
|
struct sockaddr_storage cl_addr; /* server identifier */
|
|
|
|
size_t cl_addrlen;
|
2006-08-23 08:06:10 +08:00
|
|
|
char * cl_hostname; /* hostname of server */
|
2014-06-22 08:52:17 +08:00
|
|
|
char * cl_acceptor; /* GSSAPI acceptor name */
|
2006-08-23 08:06:10 +08:00
|
|
|
struct list_head cl_share_link; /* link in global client list */
|
|
|
|
struct list_head cl_superblocks; /* List of nfs_server structs */
|
|
|
|
|
|
|
|
struct rpc_clnt * cl_rpcclient;
|
2006-08-23 08:06:12 +08:00
|
|
|
const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */
|
2008-01-04 05:29:06 +08:00
|
|
|
int cl_proto; /* Network transport protocol */
|
2012-07-31 04:05:16 +08:00
|
|
|
struct nfs_subversion * cl_nfs_mod; /* pointer to nfs version module */
|
2006-08-23 08:06:10 +08:00
|
|
|
|
2009-04-01 21:21:49 +08:00
|
|
|
u32 cl_minorversion;/* NFSv4 minorversion */
|
2017-04-27 23:13:40 +08:00
|
|
|
unsigned int cl_nconnect; /* Number of connections */
|
2018-12-03 08:30:30 +08:00
|
|
|
const char * cl_principal; /* used for machine cred */
|
2008-04-08 08:50:11 +08:00
|
|
|
|
2012-07-31 04:05:25 +08:00
|
|
|
#if IS_ENABLED(CONFIG_NFS_V4)
|
2013-09-07 02:14:00 +08:00
|
|
|
struct list_head cl_ds_clients; /* auth flavor data servers */
|
2006-08-23 08:06:10 +08:00
|
|
|
u64 cl_clientid; /* constant */
|
2011-04-25 02:28:18 +08:00
|
|
|
nfs4_verifier cl_confirm; /* Clientid verifier */
|
2006-08-23 08:06:10 +08:00
|
|
|
unsigned long cl_state;
|
|
|
|
|
|
|
|
spinlock_t cl_lock;
|
|
|
|
|
|
|
|
unsigned long cl_lease_time;
|
|
|
|
unsigned long cl_last_renewal;
|
2006-11-22 22:54:01 +08:00
|
|
|
struct delayed_work cl_renewd;
|
2006-08-23 08:06:10 +08:00
|
|
|
|
|
|
|
struct rpc_wait_queue cl_rpcwaitq;
|
|
|
|
|
|
|
|
/* idmapper */
|
|
|
|
struct idmap * cl_idmap;
|
|
|
|
|
2015-01-04 04:16:04 +08:00
|
|
|
/* Client owner identifier */
|
|
|
|
const char * cl_owner_id;
|
|
|
|
|
2011-01-06 10:04:30 +08:00
|
|
|
u32 cl_cb_ident; /* v4.0 callback identifier */
|
2010-06-16 21:52:26 +08:00
|
|
|
const struct nfs4_minor_version_ops *cl_mvops;
|
2013-10-18 02:13:02 +08:00
|
|
|
unsigned long cl_mig_gen;
|
2009-04-03 23:42:42 +08:00
|
|
|
|
2013-08-10 00:49:11 +08:00
|
|
|
/* NFSv4.0 transport blocking */
|
|
|
|
struct nfs4_slot_table *cl_slot_tbl;
|
|
|
|
|
2009-04-01 21:22:29 +08:00
|
|
|
/* The sequence id to use for the next CREATE_SESSION */
|
|
|
|
u32 cl_seqid;
|
|
|
|
/* The flags used for obtaining the clientid during EXCHANGE_ID */
|
|
|
|
u32 cl_exchange_flags;
|
2012-05-22 10:44:22 +08:00
|
|
|
struct nfs4_session *cl_session; /* shared session */
|
2012-09-15 05:24:32 +08:00
|
|
|
bool cl_preserve_clid;
|
2012-05-22 10:46:16 +08:00
|
|
|
struct nfs41_server_owner *cl_serverowner;
|
2012-05-22 10:44:31 +08:00
|
|
|
struct nfs41_server_scope *cl_serverscope;
|
2012-05-22 10:44:41 +08:00
|
|
|
struct nfs41_impl_id *cl_implid;
|
2013-08-14 04:37:32 +08:00
|
|
|
/* nfs 4.1+ state protection modes: */
|
|
|
|
unsigned long cl_sp4_flags;
|
|
|
|
#define NFS_SP4_MACH_CRED_MINIMAL 1 /* Minimal sp4_mach_cred - state ops
|
|
|
|
* must use machine cred */
|
2013-08-14 04:37:34 +08:00
|
|
|
#define NFS_SP4_MACH_CRED_CLEANUP 2 /* CLOSE and LOCKU */
|
2013-08-14 04:37:35 +08:00
|
|
|
#define NFS_SP4_MACH_CRED_SECINFO 3 /* SECINFO and SECINFO_NO_NAME */
|
2013-08-14 04:37:36 +08:00
|
|
|
#define NFS_SP4_MACH_CRED_STATEID 4 /* TEST_STATEID and FREE_STATEID */
|
2013-08-14 04:37:37 +08:00
|
|
|
#define NFS_SP4_MACH_CRED_WRITE 5 /* WRITE */
|
|
|
|
#define NFS_SP4_MACH_CRED_COMMIT 6 /* COMMIT */
|
2015-12-02 22:39:51 +08:00
|
|
|
#define NFS_SP4_MACH_CRED_PNFS_CLEANUP 7 /* LAYOUTRETURN */
|
2016-09-18 06:17:39 +08:00
|
|
|
#if IS_ENABLED(CONFIG_NFS_V4_1)
|
|
|
|
wait_queue_head_t cl_lock_waitq;
|
|
|
|
#endif /* CONFIG_NFS_V4_1 */
|
2011-03-10 05:00:53 +08:00
|
|
|
#endif /* CONFIG_NFS_V4 */
|
2009-04-01 21:21:53 +08:00
|
|
|
|
2014-05-30 18:15:57 +08:00
|
|
|
/* Our own IP address, as a null-terminated string.
|
|
|
|
* This is used to generate the mv0 callback address.
|
|
|
|
*/
|
|
|
|
char cl_ipaddr[48];
|
|
|
|
|
2009-04-03 23:42:42 +08:00
|
|
|
#ifdef CONFIG_NFS_FSCACHE
|
|
|
|
struct fscache_cookie *fscache; /* client index cache cookie */
|
|
|
|
#endif
|
2011-06-01 07:05:47 +08:00
|
|
|
|
2012-05-22 10:44:50 +08:00
|
|
|
struct net *cl_net;
|
2018-07-10 03:13:32 +08:00
|
|
|
struct list_head pending_cb_stateids;
|
2006-08-23 08:06:10 +08:00
|
|
|
};
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
/*
|
|
|
|
* NFS client parameters stored in the superblock.
|
|
|
|
*/
|
|
|
|
struct nfs_server {
|
2006-08-23 08:06:11 +08:00
|
|
|
struct nfs_client * nfs_client; /* shared client and NFS4 state */
|
NFS: Share NFS superblocks per-protocol per-server per-FSID
The attached patch makes NFS share superblocks between mounts from the same
server and FSID over the same protocol.
It does this by creating each superblock with a false root and returning the
real root dentry in the vfsmount presented by get_sb(). The root dentry set
starts off as an anonymous dentry if we don't already have the dentry for its
inode, otherwise it simply returns the dentry we already have.
We may thus end up with several trees of dentries in the superblock, and if at
some later point one of anonymous tree roots is discovered by normal filesystem
activity to be located in another tree within the superblock, the anonymous
root is named and materialises attached to the second tree at the appropriate
point.
Why do it this way? Why not pass an extra argument to the mount() syscall to
indicate the subpath and then pathwalk from the server root to the desired
directory? You can't guarantee this will work for two reasons:
(1) The root and intervening nodes may not be accessible to the client.
With NFS2 and NFS3, for instance, mountd is called on the server to get
the filehandle for the tip of a path. mountd won't give us handles for
anything we don't have permission to access, and so we can't set up NFS
inodes for such nodes, and so can't easily set up dentries (we'd have to
have ghost inodes or something).
With this patch we don't actually create dentries until we get handles
from the server that we can use to set up their inodes, and we don't
actually bind them into the tree until we know for sure where they go.
(2) Inaccessible symbolic links.
If we're asked to mount two exports from the server, eg:
mount warthog:/warthog/aaa/xxx /mmm
mount warthog:/warthog/bbb/yyy /nnn
We may not be able to access anything nearer the root than xxx and yyy,
but we may find out later that /mmm/www/yyy, say, is actually the same
directory as the one mounted on /nnn. What we might then find out, for
example, is that /warthog/bbb was actually a symbolic link to
/warthog/aaa/xxx/www, but we can't actually determine that by talking to
the server until /warthog is made available by NFS.
This would lead to having constructed an errneous dentry tree which we
can't easily fix. We can end up with a dentry marked as a directory when
it should actually be a symlink, or we could end up with an apparently
hardlinked directory.
With this patch we need not make assumptions about the type of a dentry
for which we can't retrieve information, nor need we assume we know its
place in the grand scheme of things until we actually see that place.
This patch reduces the possibility of aliasing in the inode and page caches for
inodes that may be accessed by more than one NFS export. It also reduces the
number of superblocks required for NFS where there are many NFS exports being
used from a server (home directory server + autofs for example).
This in turn makes it simpler to do local caching of network filesystems, as it
can then be guaranteed that there won't be links from multiple inodes in
separate superblocks to the same cache file.
Obviously, cache aliasing between different levels of NFS protocol could still
be a problem, but at least that gives us another key to use when indexing the
cache.
This patch makes the following changes:
(1) The server record construction/destruction has been abstracted out into
its own set of functions to make things easier to get right. These have
been moved into fs/nfs/client.c.
All the code in fs/nfs/client.c has to do with the management of
connections to servers, and doesn't touch superblocks in any way; the
remaining code in fs/nfs/super.c has to do with VFS superblock management.
(2) The sequence of events undertaken by NFS mount is now reordered:
(a) A volume representation (struct nfs_server) is allocated.
(b) A server representation (struct nfs_client) is acquired. This may be
allocated or shared, and is keyed on server address, port and NFS
version.
(c) If allocated, the client representation is initialised. The state
member variable of nfs_client is used to prevent a race during
initialisation from two mounts.
(d) For NFS4 a simple pathwalk is performed, walking from FH to FH to find
the root filehandle for the mount (fs/nfs/getroot.c). For NFS2/3 we
are given the root FH in advance.
(e) The volume FSID is probed for on the root FH.
(f) The volume representation is initialised from the FSINFO record
retrieved on the root FH.
(g) sget() is called to acquire a superblock. This may be allocated or
shared, keyed on client pointer and FSID.
(h) If allocated, the superblock is initialised.
(i) If the superblock is shared, then the new nfs_server record is
discarded.
(j) The root dentry for this mount is looked up from the root FH.
(k) The root dentry for this mount is assigned to the vfsmount.
(3) nfs_readdir_lookup() creates dentries for each of the entries readdir()
returns; this function now attaches disconnected trees from alternate
roots that happen to be discovered attached to a directory being read (in
the same way nfs_lookup() is made to do for lookup ops).
The new d_materialise_unique() function is now used to do this, thus
permitting the whole thing to be done under one set of locks, and thus
avoiding any race between mount and lookup operations on the same
directory.
(4) The client management code uses a new debug facility: NFSDBG_CLIENT which
is set by echoing 1024 to /proc/net/sunrpc/nfs_debug.
(5) Clone mounts are now called xdev mounts.
(6) Use the dentry passed to the statfs() op as the handle for retrieving fs
statistics rather than the root dentry of the superblock (which is now a
dummy).
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2006-08-23 08:06:13 +08:00
|
|
|
struct list_head client_link; /* List of other nfs_server structs
|
|
|
|
* that share the same client
|
|
|
|
*/
|
|
|
|
struct list_head master_link; /* link in master servers list */
|
2005-04-17 06:20:36 +08:00
|
|
|
struct rpc_clnt * client; /* RPC client handle */
|
2005-06-23 01:16:27 +08:00
|
|
|
struct rpc_clnt * client_acl; /* ACL RPC client handle */
|
2008-01-12 06:09:52 +08:00
|
|
|
struct nlm_host *nlm_host; /* NLM client handle */
|
2010-02-02 13:39:01 +08:00
|
|
|
struct nfs_iostats __percpu *io_stats; /* I/O statistics */
|
2007-05-08 15:35:12 +08:00
|
|
|
atomic_long_t writeback; /* number of writeback pages */
|
2005-04-17 06:20:36 +08:00
|
|
|
int flags; /* various flags */
|
2019-04-08 01:59:00 +08:00
|
|
|
|
|
|
|
/* The following are for internal use only. Also see uapi/linux/nfs_mount.h */
|
|
|
|
#define NFS_MOUNT_LOOKUP_CACHE_NONEG 0x10000
|
|
|
|
#define NFS_MOUNT_LOOKUP_CACHE_NONE 0x20000
|
|
|
|
#define NFS_MOUNT_NORESVPORT 0x40000
|
|
|
|
#define NFS_MOUNT_LEGACY_INTERFACE 0x80000
|
|
|
|
#define NFS_MOUNT_LOCAL_FLOCK 0x100000
|
|
|
|
#define NFS_MOUNT_LOCAL_FCNTL 0x200000
|
2019-04-08 01:59:01 +08:00
|
|
|
#define NFS_MOUNT_SOFTERR 0x400000
|
2019-04-08 01:59:00 +08:00
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
unsigned int caps; /* server capabilities */
|
|
|
|
unsigned int rsize; /* read size */
|
|
|
|
unsigned int rpages; /* read size (in pages) */
|
|
|
|
unsigned int wsize; /* write size */
|
|
|
|
unsigned int wpages; /* write size (in pages) */
|
|
|
|
unsigned int wtmult; /* server disk block size */
|
|
|
|
unsigned int dtsize; /* readdir size */
|
2008-03-15 02:10:22 +08:00
|
|
|
unsigned short port; /* "port=" setting */
|
2005-04-17 06:20:36 +08:00
|
|
|
unsigned int bsize; /* server block size */
|
|
|
|
unsigned int acregmin; /* attr cache timeouts */
|
|
|
|
unsigned int acregmax;
|
|
|
|
unsigned int acdirmin;
|
|
|
|
unsigned int acdirmax;
|
|
|
|
unsigned int namelen;
|
2009-04-03 23:42:42 +08:00
|
|
|
unsigned int options; /* extra options enabled by mount */
|
2015-09-26 02:24:37 +08:00
|
|
|
unsigned int clone_blksize; /* granularity of a CLONE operation */
|
2009-04-03 23:42:42 +08:00
|
|
|
#define NFS_OPTION_FSCACHE 0x00000001 /* - local caching enabled */
|
2012-09-15 05:24:11 +08:00
|
|
|
#define NFS_OPTION_MIGRATION 0x00000002 /* - NFSv4 migration enabled */
|
NFS: Share NFS superblocks per-protocol per-server per-FSID
The attached patch makes NFS share superblocks between mounts from the same
server and FSID over the same protocol.
It does this by creating each superblock with a false root and returning the
real root dentry in the vfsmount presented by get_sb(). The root dentry set
starts off as an anonymous dentry if we don't already have the dentry for its
inode, otherwise it simply returns the dentry we already have.
We may thus end up with several trees of dentries in the superblock, and if at
some later point one of anonymous tree roots is discovered by normal filesystem
activity to be located in another tree within the superblock, the anonymous
root is named and materialises attached to the second tree at the appropriate
point.
Why do it this way? Why not pass an extra argument to the mount() syscall to
indicate the subpath and then pathwalk from the server root to the desired
directory? You can't guarantee this will work for two reasons:
(1) The root and intervening nodes may not be accessible to the client.
With NFS2 and NFS3, for instance, mountd is called on the server to get
the filehandle for the tip of a path. mountd won't give us handles for
anything we don't have permission to access, and so we can't set up NFS
inodes for such nodes, and so can't easily set up dentries (we'd have to
have ghost inodes or something).
With this patch we don't actually create dentries until we get handles
from the server that we can use to set up their inodes, and we don't
actually bind them into the tree until we know for sure where they go.
(2) Inaccessible symbolic links.
If we're asked to mount two exports from the server, eg:
mount warthog:/warthog/aaa/xxx /mmm
mount warthog:/warthog/bbb/yyy /nnn
We may not be able to access anything nearer the root than xxx and yyy,
but we may find out later that /mmm/www/yyy, say, is actually the same
directory as the one mounted on /nnn. What we might then find out, for
example, is that /warthog/bbb was actually a symbolic link to
/warthog/aaa/xxx/www, but we can't actually determine that by talking to
the server until /warthog is made available by NFS.
This would lead to having constructed an errneous dentry tree which we
can't easily fix. We can end up with a dentry marked as a directory when
it should actually be a symlink, or we could end up with an apparently
hardlinked directory.
With this patch we need not make assumptions about the type of a dentry
for which we can't retrieve information, nor need we assume we know its
place in the grand scheme of things until we actually see that place.
This patch reduces the possibility of aliasing in the inode and page caches for
inodes that may be accessed by more than one NFS export. It also reduces the
number of superblocks required for NFS where there are many NFS exports being
used from a server (home directory server + autofs for example).
This in turn makes it simpler to do local caching of network filesystems, as it
can then be guaranteed that there won't be links from multiple inodes in
separate superblocks to the same cache file.
Obviously, cache aliasing between different levels of NFS protocol could still
be a problem, but at least that gives us another key to use when indexing the
cache.
This patch makes the following changes:
(1) The server record construction/destruction has been abstracted out into
its own set of functions to make things easier to get right. These have
been moved into fs/nfs/client.c.
All the code in fs/nfs/client.c has to do with the management of
connections to servers, and doesn't touch superblocks in any way; the
remaining code in fs/nfs/super.c has to do with VFS superblock management.
(2) The sequence of events undertaken by NFS mount is now reordered:
(a) A volume representation (struct nfs_server) is allocated.
(b) A server representation (struct nfs_client) is acquired. This may be
allocated or shared, and is keyed on server address, port and NFS
version.
(c) If allocated, the client representation is initialised. The state
member variable of nfs_client is used to prevent a race during
initialisation from two mounts.
(d) For NFS4 a simple pathwalk is performed, walking from FH to FH to find
the root filehandle for the mount (fs/nfs/getroot.c). For NFS2/3 we
are given the root FH in advance.
(e) The volume FSID is probed for on the root FH.
(f) The volume representation is initialised from the FSINFO record
retrieved on the root FH.
(g) sget() is called to acquire a superblock. This may be allocated or
shared, keyed on client pointer and FSID.
(h) If allocated, the superblock is initialised.
(i) If the superblock is shared, then the new nfs_server record is
discarded.
(j) The root dentry for this mount is looked up from the root FH.
(k) The root dentry for this mount is assigned to the vfsmount.
(3) nfs_readdir_lookup() creates dentries for each of the entries readdir()
returns; this function now attaches disconnected trees from alternate
roots that happen to be discovered attached to a directory being read (in
the same way nfs_lookup() is made to do for lookup ops).
The new d_materialise_unique() function is now used to do this, thus
permitting the whole thing to be done under one set of locks, and thus
avoiding any race between mount and lookup operations on the same
directory.
(4) The client management code uses a new debug facility: NFSDBG_CLIENT which
is set by echoing 1024 to /proc/net/sunrpc/nfs_debug.
(5) Clone mounts are now called xdev mounts.
(6) Use the dentry passed to the statfs() op as the handle for retrieving fs
statistics rather than the root dentry of the superblock (which is now a
dummy).
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2006-08-23 08:06:13 +08:00
|
|
|
|
2006-06-09 21:34:19 +08:00
|
|
|
struct nfs_fsid fsid;
|
NFS: Share NFS superblocks per-protocol per-server per-FSID
The attached patch makes NFS share superblocks between mounts from the same
server and FSID over the same protocol.
It does this by creating each superblock with a false root and returning the
real root dentry in the vfsmount presented by get_sb(). The root dentry set
starts off as an anonymous dentry if we don't already have the dentry for its
inode, otherwise it simply returns the dentry we already have.
We may thus end up with several trees of dentries in the superblock, and if at
some later point one of anonymous tree roots is discovered by normal filesystem
activity to be located in another tree within the superblock, the anonymous
root is named and materialises attached to the second tree at the appropriate
point.
Why do it this way? Why not pass an extra argument to the mount() syscall to
indicate the subpath and then pathwalk from the server root to the desired
directory? You can't guarantee this will work for two reasons:
(1) The root and intervening nodes may not be accessible to the client.
With NFS2 and NFS3, for instance, mountd is called on the server to get
the filehandle for the tip of a path. mountd won't give us handles for
anything we don't have permission to access, and so we can't set up NFS
inodes for such nodes, and so can't easily set up dentries (we'd have to
have ghost inodes or something).
With this patch we don't actually create dentries until we get handles
from the server that we can use to set up their inodes, and we don't
actually bind them into the tree until we know for sure where they go.
(2) Inaccessible symbolic links.
If we're asked to mount two exports from the server, eg:
mount warthog:/warthog/aaa/xxx /mmm
mount warthog:/warthog/bbb/yyy /nnn
We may not be able to access anything nearer the root than xxx and yyy,
but we may find out later that /mmm/www/yyy, say, is actually the same
directory as the one mounted on /nnn. What we might then find out, for
example, is that /warthog/bbb was actually a symbolic link to
/warthog/aaa/xxx/www, but we can't actually determine that by talking to
the server until /warthog is made available by NFS.
This would lead to having constructed an errneous dentry tree which we
can't easily fix. We can end up with a dentry marked as a directory when
it should actually be a symlink, or we could end up with an apparently
hardlinked directory.
With this patch we need not make assumptions about the type of a dentry
for which we can't retrieve information, nor need we assume we know its
place in the grand scheme of things until we actually see that place.
This patch reduces the possibility of aliasing in the inode and page caches for
inodes that may be accessed by more than one NFS export. It also reduces the
number of superblocks required for NFS where there are many NFS exports being
used from a server (home directory server + autofs for example).
This in turn makes it simpler to do local caching of network filesystems, as it
can then be guaranteed that there won't be links from multiple inodes in
separate superblocks to the same cache file.
Obviously, cache aliasing between different levels of NFS protocol could still
be a problem, but at least that gives us another key to use when indexing the
cache.
This patch makes the following changes:
(1) The server record construction/destruction has been abstracted out into
its own set of functions to make things easier to get right. These have
been moved into fs/nfs/client.c.
All the code in fs/nfs/client.c has to do with the management of
connections to servers, and doesn't touch superblocks in any way; the
remaining code in fs/nfs/super.c has to do with VFS superblock management.
(2) The sequence of events undertaken by NFS mount is now reordered:
(a) A volume representation (struct nfs_server) is allocated.
(b) A server representation (struct nfs_client) is acquired. This may be
allocated or shared, and is keyed on server address, port and NFS
version.
(c) If allocated, the client representation is initialised. The state
member variable of nfs_client is used to prevent a race during
initialisation from two mounts.
(d) For NFS4 a simple pathwalk is performed, walking from FH to FH to find
the root filehandle for the mount (fs/nfs/getroot.c). For NFS2/3 we
are given the root FH in advance.
(e) The volume FSID is probed for on the root FH.
(f) The volume representation is initialised from the FSINFO record
retrieved on the root FH.
(g) sget() is called to acquire a superblock. This may be allocated or
shared, keyed on client pointer and FSID.
(h) If allocated, the superblock is initialised.
(i) If the superblock is shared, then the new nfs_server record is
discarded.
(j) The root dentry for this mount is looked up from the root FH.
(k) The root dentry for this mount is assigned to the vfsmount.
(3) nfs_readdir_lookup() creates dentries for each of the entries readdir()
returns; this function now attaches disconnected trees from alternate
roots that happen to be discovered attached to a directory being read (in
the same way nfs_lookup() is made to do for lookup ops).
The new d_materialise_unique() function is now used to do this, thus
permitting the whole thing to be done under one set of locks, and thus
avoiding any race between mount and lookup operations on the same
directory.
(4) The client management code uses a new debug facility: NFSDBG_CLIENT which
is set by echoing 1024 to /proc/net/sunrpc/nfs_debug.
(5) Clone mounts are now called xdev mounts.
(6) Use the dentry passed to the statfs() op as the handle for retrieving fs
statistics rather than the root dentry of the superblock (which is now a
dummy).
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2006-08-23 08:06:13 +08:00
|
|
|
__u64 maxfilesize; /* maximum file size */
|
2010-10-13 07:30:05 +08:00
|
|
|
struct timespec time_delta; /* smallest time granularity */
|
2006-03-21 02:44:15 +08:00
|
|
|
unsigned long mount_time; /* when this fs was mounted */
|
2013-10-18 02:12:56 +08:00
|
|
|
struct super_block *super; /* VFS super block */
|
NFS: Share NFS superblocks per-protocol per-server per-FSID
The attached patch makes NFS share superblocks between mounts from the same
server and FSID over the same protocol.
It does this by creating each superblock with a false root and returning the
real root dentry in the vfsmount presented by get_sb(). The root dentry set
starts off as an anonymous dentry if we don't already have the dentry for its
inode, otherwise it simply returns the dentry we already have.
We may thus end up with several trees of dentries in the superblock, and if at
some later point one of anonymous tree roots is discovered by normal filesystem
activity to be located in another tree within the superblock, the anonymous
root is named and materialises attached to the second tree at the appropriate
point.
Why do it this way? Why not pass an extra argument to the mount() syscall to
indicate the subpath and then pathwalk from the server root to the desired
directory? You can't guarantee this will work for two reasons:
(1) The root and intervening nodes may not be accessible to the client.
With NFS2 and NFS3, for instance, mountd is called on the server to get
the filehandle for the tip of a path. mountd won't give us handles for
anything we don't have permission to access, and so we can't set up NFS
inodes for such nodes, and so can't easily set up dentries (we'd have to
have ghost inodes or something).
With this patch we don't actually create dentries until we get handles
from the server that we can use to set up their inodes, and we don't
actually bind them into the tree until we know for sure where they go.
(2) Inaccessible symbolic links.
If we're asked to mount two exports from the server, eg:
mount warthog:/warthog/aaa/xxx /mmm
mount warthog:/warthog/bbb/yyy /nnn
We may not be able to access anything nearer the root than xxx and yyy,
but we may find out later that /mmm/www/yyy, say, is actually the same
directory as the one mounted on /nnn. What we might then find out, for
example, is that /warthog/bbb was actually a symbolic link to
/warthog/aaa/xxx/www, but we can't actually determine that by talking to
the server until /warthog is made available by NFS.
This would lead to having constructed an errneous dentry tree which we
can't easily fix. We can end up with a dentry marked as a directory when
it should actually be a symlink, or we could end up with an apparently
hardlinked directory.
With this patch we need not make assumptions about the type of a dentry
for which we can't retrieve information, nor need we assume we know its
place in the grand scheme of things until we actually see that place.
This patch reduces the possibility of aliasing in the inode and page caches for
inodes that may be accessed by more than one NFS export. It also reduces the
number of superblocks required for NFS where there are many NFS exports being
used from a server (home directory server + autofs for example).
This in turn makes it simpler to do local caching of network filesystems, as it
can then be guaranteed that there won't be links from multiple inodes in
separate superblocks to the same cache file.
Obviously, cache aliasing between different levels of NFS protocol could still
be a problem, but at least that gives us another key to use when indexing the
cache.
This patch makes the following changes:
(1) The server record construction/destruction has been abstracted out into
its own set of functions to make things easier to get right. These have
been moved into fs/nfs/client.c.
All the code in fs/nfs/client.c has to do with the management of
connections to servers, and doesn't touch superblocks in any way; the
remaining code in fs/nfs/super.c has to do with VFS superblock management.
(2) The sequence of events undertaken by NFS mount is now reordered:
(a) A volume representation (struct nfs_server) is allocated.
(b) A server representation (struct nfs_client) is acquired. This may be
allocated or shared, and is keyed on server address, port and NFS
version.
(c) If allocated, the client representation is initialised. The state
member variable of nfs_client is used to prevent a race during
initialisation from two mounts.
(d) For NFS4 a simple pathwalk is performed, walking from FH to FH to find
the root filehandle for the mount (fs/nfs/getroot.c). For NFS2/3 we
are given the root FH in advance.
(e) The volume FSID is probed for on the root FH.
(f) The volume representation is initialised from the FSINFO record
retrieved on the root FH.
(g) sget() is called to acquire a superblock. This may be allocated or
shared, keyed on client pointer and FSID.
(h) If allocated, the superblock is initialised.
(i) If the superblock is shared, then the new nfs_server record is
discarded.
(j) The root dentry for this mount is looked up from the root FH.
(k) The root dentry for this mount is assigned to the vfsmount.
(3) nfs_readdir_lookup() creates dentries for each of the entries readdir()
returns; this function now attaches disconnected trees from alternate
roots that happen to be discovered attached to a directory being read (in
the same way nfs_lookup() is made to do for lookup ops).
The new d_materialise_unique() function is now used to do this, thus
permitting the whole thing to be done under one set of locks, and thus
avoiding any race between mount and lookup operations on the same
directory.
(4) The client management code uses a new debug facility: NFSDBG_CLIENT which
is set by echoing 1024 to /proc/net/sunrpc/nfs_debug.
(5) Clone mounts are now called xdev mounts.
(6) Use the dentry passed to the statfs() op as the handle for retrieving fs
statistics rather than the root dentry of the superblock (which is now a
dummy).
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2006-08-23 08:06:13 +08:00
|
|
|
dev_t s_dev; /* superblock dev numbers */
|
2013-10-19 03:15:17 +08:00
|
|
|
struct nfs_auth_info auth_info; /* parsed auth flavors */
|
NFS: Share NFS superblocks per-protocol per-server per-FSID
The attached patch makes NFS share superblocks between mounts from the same
server and FSID over the same protocol.
It does this by creating each superblock with a false root and returning the
real root dentry in the vfsmount presented by get_sb(). The root dentry set
starts off as an anonymous dentry if we don't already have the dentry for its
inode, otherwise it simply returns the dentry we already have.
We may thus end up with several trees of dentries in the superblock, and if at
some later point one of anonymous tree roots is discovered by normal filesystem
activity to be located in another tree within the superblock, the anonymous
root is named and materialises attached to the second tree at the appropriate
point.
Why do it this way? Why not pass an extra argument to the mount() syscall to
indicate the subpath and then pathwalk from the server root to the desired
directory? You can't guarantee this will work for two reasons:
(1) The root and intervening nodes may not be accessible to the client.
With NFS2 and NFS3, for instance, mountd is called on the server to get
the filehandle for the tip of a path. mountd won't give us handles for
anything we don't have permission to access, and so we can't set up NFS
inodes for such nodes, and so can't easily set up dentries (we'd have to
have ghost inodes or something).
With this patch we don't actually create dentries until we get handles
from the server that we can use to set up their inodes, and we don't
actually bind them into the tree until we know for sure where they go.
(2) Inaccessible symbolic links.
If we're asked to mount two exports from the server, eg:
mount warthog:/warthog/aaa/xxx /mmm
mount warthog:/warthog/bbb/yyy /nnn
We may not be able to access anything nearer the root than xxx and yyy,
but we may find out later that /mmm/www/yyy, say, is actually the same
directory as the one mounted on /nnn. What we might then find out, for
example, is that /warthog/bbb was actually a symbolic link to
/warthog/aaa/xxx/www, but we can't actually determine that by talking to
the server until /warthog is made available by NFS.
This would lead to having constructed an errneous dentry tree which we
can't easily fix. We can end up with a dentry marked as a directory when
it should actually be a symlink, or we could end up with an apparently
hardlinked directory.
With this patch we need not make assumptions about the type of a dentry
for which we can't retrieve information, nor need we assume we know its
place in the grand scheme of things until we actually see that place.
This patch reduces the possibility of aliasing in the inode and page caches for
inodes that may be accessed by more than one NFS export. It also reduces the
number of superblocks required for NFS where there are many NFS exports being
used from a server (home directory server + autofs for example).
This in turn makes it simpler to do local caching of network filesystems, as it
can then be guaranteed that there won't be links from multiple inodes in
separate superblocks to the same cache file.
Obviously, cache aliasing between different levels of NFS protocol could still
be a problem, but at least that gives us another key to use when indexing the
cache.
This patch makes the following changes:
(1) The server record construction/destruction has been abstracted out into
its own set of functions to make things easier to get right. These have
been moved into fs/nfs/client.c.
All the code in fs/nfs/client.c has to do with the management of
connections to servers, and doesn't touch superblocks in any way; the
remaining code in fs/nfs/super.c has to do with VFS superblock management.
(2) The sequence of events undertaken by NFS mount is now reordered:
(a) A volume representation (struct nfs_server) is allocated.
(b) A server representation (struct nfs_client) is acquired. This may be
allocated or shared, and is keyed on server address, port and NFS
version.
(c) If allocated, the client representation is initialised. The state
member variable of nfs_client is used to prevent a race during
initialisation from two mounts.
(d) For NFS4 a simple pathwalk is performed, walking from FH to FH to find
the root filehandle for the mount (fs/nfs/getroot.c). For NFS2/3 we
are given the root FH in advance.
(e) The volume FSID is probed for on the root FH.
(f) The volume representation is initialised from the FSINFO record
retrieved on the root FH.
(g) sget() is called to acquire a superblock. This may be allocated or
shared, keyed on client pointer and FSID.
(h) If allocated, the superblock is initialised.
(i) If the superblock is shared, then the new nfs_server record is
discarded.
(j) The root dentry for this mount is looked up from the root FH.
(k) The root dentry for this mount is assigned to the vfsmount.
(3) nfs_readdir_lookup() creates dentries for each of the entries readdir()
returns; this function now attaches disconnected trees from alternate
roots that happen to be discovered attached to a directory being read (in
the same way nfs_lookup() is made to do for lookup ops).
The new d_materialise_unique() function is now used to do this, thus
permitting the whole thing to be done under one set of locks, and thus
avoiding any race between mount and lookup operations on the same
directory.
(4) The client management code uses a new debug facility: NFSDBG_CLIENT which
is set by echoing 1024 to /proc/net/sunrpc/nfs_debug.
(5) Clone mounts are now called xdev mounts.
(6) Use the dentry passed to the statfs() op as the handle for retrieving fs
statistics rather than the root dentry of the superblock (which is now a
dummy).
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2006-08-23 08:06:13 +08:00
|
|
|
|
2009-04-03 23:42:42 +08:00
|
|
|
#ifdef CONFIG_NFS_FSCACHE
|
|
|
|
struct nfs_fscache_key *fscache_key; /* unique key for superblock */
|
|
|
|
struct fscache_cookie *fscache; /* superblock cookie */
|
|
|
|
#endif
|
|
|
|
|
2011-08-01 04:39:04 +08:00
|
|
|
u32 pnfs_blksize; /* layout_blksize attr */
|
2012-07-31 04:05:25 +08:00
|
|
|
#if IS_ENABLED(CONFIG_NFS_V4)
|
2011-07-31 08:52:37 +08:00
|
|
|
u32 attr_bitmask[3];/* V4 bitmask representing the set
|
2005-04-17 06:20:36 +08:00
|
|
|
of attributes supported on this
|
|
|
|
filesystem */
|
2013-05-23 00:50:44 +08:00
|
|
|
u32 attr_bitmask_nl[3];
|
|
|
|
/* V4 bitmask representing the
|
|
|
|
set of attributes supported
|
|
|
|
on this filesystem excluding
|
|
|
|
the label support bit. */
|
2015-08-26 21:12:58 +08:00
|
|
|
u32 exclcreat_bitmask[3];
|
|
|
|
/* V4 bitmask representing the
|
|
|
|
set of attributes supported
|
|
|
|
on this filesystem for the
|
|
|
|
exclusive create. */
|
2013-05-23 00:50:41 +08:00
|
|
|
u32 cache_consistency_bitmask[3];
|
2009-03-12 02:10:28 +08:00
|
|
|
/* V4 bitmask representing the subset
|
|
|
|
of change attribute, size, ctime
|
|
|
|
and mtime attributes supported by
|
|
|
|
the server */
|
2005-04-17 06:20:36 +08:00
|
|
|
u32 acl_bitmask; /* V4 bitmask representing the ACEs
|
|
|
|
that are supported on this
|
|
|
|
filesystem */
|
2012-03-02 06:02:05 +08:00
|
|
|
u32 fh_expire_type; /* V4 bitmask representing file
|
|
|
|
handle volatility type for
|
|
|
|
this filesystem */
|
2010-10-20 12:17:58 +08:00
|
|
|
struct pnfs_layoutdriver_type *pnfs_curr_ld; /* Active layout driver */
|
2011-01-06 19:36:32 +08:00
|
|
|
struct rpc_wait_queue roc_rpcwaitq;
|
2011-07-31 08:52:46 +08:00
|
|
|
void *pnfs_ld_data; /* per mount point data */
|
2010-12-24 09:32:43 +08:00
|
|
|
|
|
|
|
/* the following fields are protected by nfs_client->cl_lock */
|
|
|
|
struct rb_root state_owners;
|
2005-04-17 06:20:36 +08:00
|
|
|
#endif
|
2012-01-18 11:04:24 +08:00
|
|
|
struct ida openowner_id;
|
2012-01-18 11:04:25 +08:00
|
|
|
struct ida lockowner_id;
|
NFS: Cache state owners after files are closed
Servers have a finite amount of memory to store NFSv4 open and lock
owners. Moreover, servers may have a difficult time determining when
they can reap their state owner table, thanks to gray areas in the
NFSv4 protocol specification. Thus clients should be careful to reuse
state owners when possible.
Currently Linux is not too careful. When a user has closed all her
files on one mount point, the state owner's reference count goes to
zero, and it is released. The next OPEN allocates a new one. A
workload that serially opens and closes files can run through a large
number of open owners this way.
When a state owner's reference count goes to zero, slap it onto a free
list for that nfs_server, with an expiry time. Garbage collect before
looking for a state owner. This makes state owners for active users
available for re-use.
Now that there can be unused state owners remaining at umount time,
purge the state owner free list when a server is destroyed. Also be
sure not to reclaim unused state owners during state recovery.
This change has benefits for the client as well. For some workloads,
this approach drops the number of OPEN_CONFIRM calls from the same as
the number of OPEN calls, down to just one. This reduces wire traffic
and thus open(2) latency. Before this patch, untarring a kernel
source tarball shows the OPEN_CONFIRM call counter steadily increasing
through the test. With the patch, the OPEN_CONFIRM count remains at 1
throughout the entire untar.
As long as the expiry time is kept short, I don't think garbage
collection should be terribly expensive, although it does bounce the
clp->cl_lock around a bit.
[ At some point we should rationalize the use of the nfs_server
->destroy method. ]
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
[Trond: Fixed a garbage collection race and a few efficiency issues]
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2011-12-07 05:13:48 +08:00
|
|
|
struct list_head state_owners_lru;
|
2011-06-02 04:44:44 +08:00
|
|
|
struct list_head layouts;
|
2010-12-24 09:33:04 +08:00
|
|
|
struct list_head delegations;
|
2018-07-10 03:13:31 +08:00
|
|
|
struct list_head ss_copies;
|
2013-10-18 02:13:02 +08:00
|
|
|
|
|
|
|
unsigned long mig_gen;
|
|
|
|
unsigned long mig_status;
|
|
|
|
#define NFS_MIG_IN_TRANSITION (1)
|
|
|
|
#define NFS_MIG_FAILED (2)
|
2017-06-08 23:52:44 +08:00
|
|
|
#define NFS_MIG_TSM_POSSIBLE (3)
|
2013-10-18 02:13:02 +08:00
|
|
|
|
NFS: Share NFS superblocks per-protocol per-server per-FSID
The attached patch makes NFS share superblocks between mounts from the same
server and FSID over the same protocol.
It does this by creating each superblock with a false root and returning the
real root dentry in the vfsmount presented by get_sb(). The root dentry set
starts off as an anonymous dentry if we don't already have the dentry for its
inode, otherwise it simply returns the dentry we already have.
We may thus end up with several trees of dentries in the superblock, and if at
some later point one of anonymous tree roots is discovered by normal filesystem
activity to be located in another tree within the superblock, the anonymous
root is named and materialises attached to the second tree at the appropriate
point.
Why do it this way? Why not pass an extra argument to the mount() syscall to
indicate the subpath and then pathwalk from the server root to the desired
directory? You can't guarantee this will work for two reasons:
(1) The root and intervening nodes may not be accessible to the client.
With NFS2 and NFS3, for instance, mountd is called on the server to get
the filehandle for the tip of a path. mountd won't give us handles for
anything we don't have permission to access, and so we can't set up NFS
inodes for such nodes, and so can't easily set up dentries (we'd have to
have ghost inodes or something).
With this patch we don't actually create dentries until we get handles
from the server that we can use to set up their inodes, and we don't
actually bind them into the tree until we know for sure where they go.
(2) Inaccessible symbolic links.
If we're asked to mount two exports from the server, eg:
mount warthog:/warthog/aaa/xxx /mmm
mount warthog:/warthog/bbb/yyy /nnn
We may not be able to access anything nearer the root than xxx and yyy,
but we may find out later that /mmm/www/yyy, say, is actually the same
directory as the one mounted on /nnn. What we might then find out, for
example, is that /warthog/bbb was actually a symbolic link to
/warthog/aaa/xxx/www, but we can't actually determine that by talking to
the server until /warthog is made available by NFS.
This would lead to having constructed an errneous dentry tree which we
can't easily fix. We can end up with a dentry marked as a directory when
it should actually be a symlink, or we could end up with an apparently
hardlinked directory.
With this patch we need not make assumptions about the type of a dentry
for which we can't retrieve information, nor need we assume we know its
place in the grand scheme of things until we actually see that place.
This patch reduces the possibility of aliasing in the inode and page caches for
inodes that may be accessed by more than one NFS export. It also reduces the
number of superblocks required for NFS where there are many NFS exports being
used from a server (home directory server + autofs for example).
This in turn makes it simpler to do local caching of network filesystems, as it
can then be guaranteed that there won't be links from multiple inodes in
separate superblocks to the same cache file.
Obviously, cache aliasing between different levels of NFS protocol could still
be a problem, but at least that gives us another key to use when indexing the
cache.
This patch makes the following changes:
(1) The server record construction/destruction has been abstracted out into
its own set of functions to make things easier to get right. These have
been moved into fs/nfs/client.c.
All the code in fs/nfs/client.c has to do with the management of
connections to servers, and doesn't touch superblocks in any way; the
remaining code in fs/nfs/super.c has to do with VFS superblock management.
(2) The sequence of events undertaken by NFS mount is now reordered:
(a) A volume representation (struct nfs_server) is allocated.
(b) A server representation (struct nfs_client) is acquired. This may be
allocated or shared, and is keyed on server address, port and NFS
version.
(c) If allocated, the client representation is initialised. The state
member variable of nfs_client is used to prevent a race during
initialisation from two mounts.
(d) For NFS4 a simple pathwalk is performed, walking from FH to FH to find
the root filehandle for the mount (fs/nfs/getroot.c). For NFS2/3 we
are given the root FH in advance.
(e) The volume FSID is probed for on the root FH.
(f) The volume representation is initialised from the FSINFO record
retrieved on the root FH.
(g) sget() is called to acquire a superblock. This may be allocated or
shared, keyed on client pointer and FSID.
(h) If allocated, the superblock is initialised.
(i) If the superblock is shared, then the new nfs_server record is
discarded.
(j) The root dentry for this mount is looked up from the root FH.
(k) The root dentry for this mount is assigned to the vfsmount.
(3) nfs_readdir_lookup() creates dentries for each of the entries readdir()
returns; this function now attaches disconnected trees from alternate
roots that happen to be discovered attached to a directory being read (in
the same way nfs_lookup() is made to do for lookup ops).
The new d_materialise_unique() function is now used to do this, thus
permitting the whole thing to be done under one set of locks, and thus
avoiding any race between mount and lookup operations on the same
directory.
(4) The client management code uses a new debug facility: NFSDBG_CLIENT which
is set by echoing 1024 to /proc/net/sunrpc/nfs_debug.
(5) Clone mounts are now called xdev mounts.
(6) Use the dentry passed to the statfs() op as the handle for retrieving fs
statistics rather than the root dentry of the superblock (which is now a
dummy).
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2006-08-23 08:06:13 +08:00
|
|
|
void (*destroy)(struct nfs_server *);
|
2007-11-08 17:05:04 +08:00
|
|
|
|
|
|
|
atomic_t active; /* Keep trace of any activity to this server */
|
2008-03-15 02:10:30 +08:00
|
|
|
|
|
|
|
/* mountd-related mount options */
|
|
|
|
struct sockaddr_storage mountd_address;
|
|
|
|
size_t mountd_addrlen;
|
|
|
|
u32 mountd_version;
|
|
|
|
unsigned short mountd_port;
|
|
|
|
unsigned short mountd_protocol;
|
2017-04-12 00:50:10 +08:00
|
|
|
struct rpc_wait_queue uoc_rpcwaitq;
|
2018-03-06 01:03:00 +08:00
|
|
|
|
|
|
|
/* XDR related information */
|
|
|
|
unsigned int read_hdrsize;
|
2019-04-25 05:46:43 +08:00
|
|
|
|
|
|
|
/* User namespace info */
|
|
|
|
const struct cred *cred;
|
2005-04-17 06:20:36 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Server capabilities */
|
|
|
|
#define NFS_CAP_READDIRPLUS (1U << 0)
|
|
|
|
#define NFS_CAP_HARDLINKS (1U << 1)
|
|
|
|
#define NFS_CAP_SYMLINKS (1U << 2)
|
|
|
|
#define NFS_CAP_ACLS (1U << 3)
|
|
|
|
#define NFS_CAP_ATOMIC_OPEN (1U << 4)
|
2015-07-05 23:12:07 +08:00
|
|
|
/* #define NFS_CAP_CHANGE_ATTR (1U << 5) */
|
2016-10-05 03:26:41 +08:00
|
|
|
#define NFS_CAP_LGOPEN (1U << 5)
|
2009-08-10 03:06:19 +08:00
|
|
|
#define NFS_CAP_FILEID (1U << 6)
|
|
|
|
#define NFS_CAP_MODE (1U << 7)
|
|
|
|
#define NFS_CAP_NLINK (1U << 8)
|
|
|
|
#define NFS_CAP_OWNER (1U << 9)
|
|
|
|
#define NFS_CAP_OWNER_GROUP (1U << 10)
|
|
|
|
#define NFS_CAP_ATIME (1U << 11)
|
|
|
|
#define NFS_CAP_CTIME (1U << 12)
|
|
|
|
#define NFS_CAP_MTIME (1U << 13)
|
2010-04-12 04:48:44 +08:00
|
|
|
#define NFS_CAP_POSIX_LOCK (1U << 14)
|
2011-02-23 07:44:32 +08:00
|
|
|
#define NFS_CAP_UIDGID_NOMAP (1U << 15)
|
2013-03-18 03:31:15 +08:00
|
|
|
#define NFS_CAP_STATEID_NFSV41 (1U << 16)
|
2013-03-16 04:44:28 +08:00
|
|
|
#define NFS_CAP_ATOMIC_OPEN_V1 (1U << 17)
|
2013-05-23 00:50:39 +08:00
|
|
|
#define NFS_CAP_SECURITY_LABEL (1U << 18)
|
2014-09-27 01:58:48 +08:00
|
|
|
#define NFS_CAP_SEEK (1U << 19)
|
2014-11-26 02:18:15 +08:00
|
|
|
#define NFS_CAP_ALLOCATE (1U << 20)
|
2014-11-26 02:18:16 +08:00
|
|
|
#define NFS_CAP_DEALLOCATE (1U << 21)
|
2015-06-27 23:45:46 +08:00
|
|
|
#define NFS_CAP_LAYOUTSTATS (1U << 22)
|
2015-09-26 02:24:35 +08:00
|
|
|
#define NFS_CAP_CLONE (1U << 23)
|
2013-05-22 04:53:03 +08:00
|
|
|
#define NFS_CAP_COPY (1U << 24)
|
2018-07-10 03:13:29 +08:00
|
|
|
#define NFS_CAP_OFFLOAD_CANCEL (1U << 25)
|
2019-02-08 23:31:05 +08:00
|
|
|
#define NFS_CAP_LAYOUTERROR (1U << 26)
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
#endif
|