NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
/*
|
|
|
|
* NFS internal definitions
|
|
|
|
*/
|
|
|
|
|
2009-04-01 21:22:41 +08:00
|
|
|
#include "nfs4_fs.h"
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
#include <linux/mount.h>
|
2008-03-06 03:20:18 +08:00
|
|
|
#include <linux/security.h>
|
2013-08-13 04:06:31 +08:00
|
|
|
#include <linux/crc32.h>
|
2014-11-10 08:35:34 +08:00
|
|
|
#include <linux/nfs_page.h>
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
2009-04-03 23:42:42 +08:00
|
|
|
#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
|
|
|
|
|
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 nfs_string;
|
|
|
|
|
|
|
|
/* Maximum number of readahead requests
|
|
|
|
* FIXME: this should really be a sysctl so that users may tune it to suit
|
|
|
|
* their needs. People that do NFS over a slow network, might for
|
|
|
|
* instance want to reduce it to something closer to 1 for improved
|
|
|
|
* interactive response.
|
|
|
|
*/
|
|
|
|
#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1)
|
|
|
|
|
2011-03-25 01:12:30 +08:00
|
|
|
static inline void nfs_attr_check_mountpoint(struct super_block *parent, struct nfs_fattr *fattr)
|
|
|
|
{
|
|
|
|
if (!nfs_fsid_equal(&NFS_SB(parent)->fsid, &fattr->fsid))
|
|
|
|
fattr->valid |= NFS_ATTR_FATTR_MOUNTPOINT;
|
|
|
|
}
|
|
|
|
|
2011-06-14 06:25:56 +08:00
|
|
|
static inline int nfs_attr_use_mounted_on_fileid(struct nfs_fattr *fattr)
|
|
|
|
{
|
|
|
|
if (((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) == 0) ||
|
|
|
|
(((fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0) &&
|
|
|
|
((fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) == 0)))
|
|
|
|
return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
struct nfs_clone_mount {
|
|
|
|
const struct super_block *sb;
|
|
|
|
const struct dentry *dentry;
|
|
|
|
struct nfs_fh *fh;
|
|
|
|
struct nfs_fattr *fattr;
|
|
|
|
char *hostname;
|
|
|
|
char *mnt_path;
|
2007-12-11 03:59:06 +08:00
|
|
|
struct sockaddr *addr;
|
|
|
|
size_t addrlen;
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
rpc_authflavor_t authflavor;
|
|
|
|
};
|
|
|
|
|
2009-06-18 09:02:12 +08:00
|
|
|
/*
|
|
|
|
* Note: RFC 1813 doesn't limit the number of auth flavors that
|
|
|
|
* a server can return, so make something up.
|
|
|
|
*/
|
|
|
|
#define NFS_MAX_SECFLAVORS (12)
|
|
|
|
|
2009-09-09 07:49:47 +08:00
|
|
|
/*
|
|
|
|
* Value used if the user did not specify a port value.
|
|
|
|
*/
|
|
|
|
#define NFS_UNSPEC_PORT (-1)
|
|
|
|
|
2016-08-16 22:26:47 +08:00
|
|
|
#define NFS_UNSPEC_RETRANS (UINT_MAX)
|
|
|
|
#define NFS_UNSPEC_TIMEO (UINT_MAX)
|
|
|
|
|
2010-10-21 03:44:37 +08:00
|
|
|
/*
|
|
|
|
* Maximum number of pages that readdir can use for creating
|
|
|
|
* a vmapped array of pages.
|
|
|
|
*/
|
|
|
|
#define NFS_MAX_READDIR_PAGES 8
|
|
|
|
|
2012-07-17 04:39:18 +08:00
|
|
|
struct nfs_client_initdata {
|
|
|
|
unsigned long init_flags;
|
2016-06-23 02:13:12 +08:00
|
|
|
const char *hostname; /* Hostname of the server */
|
|
|
|
const struct sockaddr *addr; /* Address of the server */
|
|
|
|
const char *nodename; /* Hostname of the client */
|
|
|
|
const char *ip_addr; /* IP address of the client */
|
2012-07-17 04:39:18 +08:00
|
|
|
size_t addrlen;
|
2012-07-31 04:05:16 +08:00
|
|
|
struct nfs_subversion *nfs_mod;
|
2012-07-17 04:39:18 +08:00
|
|
|
int proto;
|
|
|
|
u32 minorversion;
|
|
|
|
struct net *net;
|
2016-06-23 02:13:12 +08:00
|
|
|
const struct rpc_timeout *timeparms;
|
2012-07-17 04:39:18 +08:00
|
|
|
};
|
|
|
|
|
2007-09-11 01:43:29 +08:00
|
|
|
/*
|
|
|
|
* In-kernel mount arguments
|
|
|
|
*/
|
|
|
|
struct nfs_parsed_mount_data {
|
|
|
|
int flags;
|
2012-09-15 05:23:14 +08:00
|
|
|
unsigned int rsize, wsize;
|
|
|
|
unsigned int timeo, retrans;
|
|
|
|
unsigned int acregmin, acregmax,
|
2007-09-11 01:43:29 +08:00
|
|
|
acdirmin, acdirmax;
|
2012-09-15 05:23:14 +08:00
|
|
|
unsigned int namlen;
|
2009-04-03 23:42:48 +08:00
|
|
|
unsigned int options;
|
2007-09-11 01:43:29 +08:00
|
|
|
unsigned int bsize;
|
2013-10-19 03:15:16 +08:00
|
|
|
struct nfs_auth_info auth_info;
|
|
|
|
rpc_authflavor_t selected_flavor;
|
2007-09-11 01:43:29 +08:00
|
|
|
char *client_address;
|
2009-09-09 07:50:03 +08:00
|
|
|
unsigned int version;
|
2009-04-01 21:21:48 +08:00
|
|
|
unsigned int minorversion;
|
2009-04-03 23:42:42 +08:00
|
|
|
char *fscache_uniq;
|
2012-05-11 03:07:40 +08:00
|
|
|
bool need_mount;
|
2007-09-11 01:43:29 +08:00
|
|
|
|
|
|
|
struct {
|
2007-12-11 03:59:28 +08:00
|
|
|
struct sockaddr_storage address;
|
|
|
|
size_t addrlen;
|
2007-09-11 01:43:29 +08:00
|
|
|
char *hostname;
|
2008-03-15 02:10:15 +08:00
|
|
|
u32 version;
|
2009-09-09 07:49:47 +08:00
|
|
|
int port;
|
2008-03-15 02:10:15 +08:00
|
|
|
unsigned short protocol;
|
2007-09-11 01:43:29 +08:00
|
|
|
} mount_server;
|
|
|
|
|
|
|
|
struct {
|
2007-12-11 03:59:28 +08:00
|
|
|
struct sockaddr_storage address;
|
|
|
|
size_t addrlen;
|
2007-09-11 01:43:29 +08:00
|
|
|
char *hostname;
|
|
|
|
char *export_path;
|
2009-09-09 07:49:47 +08:00
|
|
|
int port;
|
2008-03-15 02:10:15 +08:00
|
|
|
unsigned short protocol;
|
2007-09-11 01:43:29 +08:00
|
|
|
} nfs_server;
|
2008-03-06 03:20:18 +08:00
|
|
|
|
|
|
|
struct security_mnt_opts lsm_opts;
|
2012-01-10 20:12:46 +08:00
|
|
|
struct net *net;
|
2007-09-11 01:43:29 +08:00
|
|
|
};
|
|
|
|
|
2008-12-24 04:21:34 +08:00
|
|
|
/* mount_clnt.c */
|
2008-12-24 04:21:35 +08:00
|
|
|
struct nfs_mount_request {
|
|
|
|
struct sockaddr *sap;
|
|
|
|
size_t salen;
|
|
|
|
char *hostname;
|
|
|
|
char *dirpath;
|
|
|
|
u32 version;
|
|
|
|
unsigned short protocol;
|
|
|
|
struct nfs_fh *fh;
|
2008-12-24 04:21:37 +08:00
|
|
|
int noresvport;
|
2009-06-18 09:02:13 +08:00
|
|
|
unsigned int *auth_flav_len;
|
|
|
|
rpc_authflavor_t *auth_flavs;
|
2012-01-10 20:12:54 +08:00
|
|
|
struct net *net;
|
2008-12-24 04:21:35 +08:00
|
|
|
};
|
|
|
|
|
2012-07-17 04:39:20 +08:00
|
|
|
struct nfs_mount_info {
|
|
|
|
void (*fill_super)(struct super_block *, struct nfs_mount_info *);
|
|
|
|
int (*set_security)(struct super_block *, struct dentry *, struct nfs_mount_info *);
|
|
|
|
struct nfs_parsed_mount_data *parsed;
|
|
|
|
struct nfs_clone_mount *cloned;
|
|
|
|
struct nfs_fh *mntfh;
|
|
|
|
};
|
|
|
|
|
2008-12-24 04:21:35 +08:00
|
|
|
extern int nfs_mount(struct nfs_mount_request *info);
|
2009-08-10 03:09:30 +08:00
|
|
|
extern void nfs_umount(const struct nfs_mount_request *info);
|
2008-12-24 04:21:34 +08:00
|
|
|
|
2006-08-23 08:06:10 +08:00
|
|
|
/* client.c */
|
2012-01-21 02:53:56 +08:00
|
|
|
extern const struct rpc_program nfs_program;
|
2012-01-24 01:26:05 +08:00
|
|
|
extern void nfs_clients_init(struct net *net);
|
2012-06-21 03:53:46 +08:00
|
|
|
extern struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *);
|
2016-06-23 02:13:12 +08:00
|
|
|
int nfs_create_rpc_client(struct nfs_client *, const struct nfs_client_initdata *, rpc_authflavor_t);
|
2016-11-18 04:15:55 +08:00
|
|
|
struct nfs_client *nfs_get_client(const struct nfs_client_initdata *);
|
2012-07-17 04:39:18 +08:00
|
|
|
int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *, struct nfs_fattr *);
|
|
|
|
void nfs_server_insert_lists(struct nfs_server *);
|
2013-10-18 02:12:28 +08:00
|
|
|
void nfs_server_remove_lists(struct nfs_server *);
|
2016-08-16 22:26:47 +08:00
|
|
|
void nfs_init_timeout_values(struct rpc_timeout *to, int proto, int timeo, int retrans);
|
2012-07-17 04:39:18 +08:00
|
|
|
int nfs_init_server_rpcclient(struct nfs_server *, const struct rpc_timeout *t,
|
|
|
|
rpc_authflavor_t);
|
|
|
|
struct nfs_server *nfs_alloc_server(void);
|
|
|
|
void nfs_server_copy_userdata(struct nfs_server *, struct nfs_server *);
|
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
|
|
|
|
2012-01-24 01:26:22 +08:00
|
|
|
extern void nfs_cleanup_cb_ident_idr(struct net *);
|
2006-08-23 08:06:10 +08:00
|
|
|
extern void nfs_put_client(struct nfs_client *);
|
2012-06-21 03:53:45 +08:00
|
|
|
extern void nfs_free_client(struct nfs_client *);
|
2012-01-24 01:26:22 +08:00
|
|
|
extern struct nfs_client *nfs4_find_client_ident(struct net *, int);
|
2011-01-06 10:04:32 +08:00
|
|
|
extern struct nfs_client *
|
2012-01-26 19:11:49 +08:00
|
|
|
nfs4_find_client_sessionid(struct net *, const struct sockaddr *,
|
2013-06-05 23:15:01 +08:00
|
|
|
struct nfs4_sessionid *, u32);
|
2012-07-31 04:05:19 +08:00
|
|
|
extern struct nfs_server *nfs_create_server(struct nfs_mount_info *,
|
2012-07-31 04:05:16 +08:00
|
|
|
struct nfs_subversion *);
|
2007-09-11 01:44:33 +08:00
|
|
|
extern struct nfs_server *nfs4_create_server(
|
2012-07-31 04:05:19 +08:00
|
|
|
struct nfs_mount_info *,
|
|
|
|
struct nfs_subversion *);
|
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
|
|
|
extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
|
|
|
|
struct nfs_fh *);
|
2013-10-18 02:12:28 +08:00
|
|
|
extern int nfs4_update_server(struct nfs_server *server, const char *hostname,
|
2014-02-17 10:42:56 +08:00
|
|
|
struct sockaddr *sap, size_t salen,
|
|
|
|
struct net *net);
|
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
|
|
|
extern void nfs_free_server(struct nfs_server *server);
|
|
|
|
extern struct nfs_server *nfs_clone_server(struct nfs_server *,
|
|
|
|
struct nfs_fh *,
|
2012-04-28 01:27:42 +08:00
|
|
|
struct nfs_fattr *,
|
|
|
|
rpc_authflavor_t);
|
2017-03-10 01:56:48 +08:00
|
|
|
extern bool nfs_client_init_is_complete(const struct nfs_client *clp);
|
|
|
|
extern int nfs_client_init_status(const struct nfs_client *clp);
|
2012-05-24 01:24:36 +08:00
|
|
|
extern int nfs_wait_client_init_complete(const struct nfs_client *clp);
|
2009-04-01 21:22:38 +08:00
|
|
|
extern void nfs_mark_client_ready(struct nfs_client *clp, int state);
|
2016-06-14 01:57:35 +08:00
|
|
|
extern struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
|
2011-03-01 09:34:17 +08:00
|
|
|
const struct sockaddr *ds_addr,
|
2012-04-28 05:53:45 +08:00
|
|
|
int ds_addrlen, int ds_proto,
|
|
|
|
unsigned int ds_timeo,
|
2014-05-29 21:07:00 +08:00
|
|
|
unsigned int ds_retrans,
|
2016-11-18 04:15:55 +08:00
|
|
|
u32 minor_version);
|
2013-09-07 02:14:00 +08:00
|
|
|
extern struct rpc_clnt *nfs4_find_or_create_ds_client(struct nfs_client *,
|
|
|
|
struct inode *);
|
2016-06-14 02:52:00 +08:00
|
|
|
extern struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv,
|
2014-05-30 18:15:57 +08:00
|
|
|
const struct sockaddr *ds_addr, int ds_addrlen,
|
|
|
|
int ds_proto, unsigned int ds_timeo,
|
2016-11-18 04:15:55 +08:00
|
|
|
unsigned int ds_retrans);
|
2006-08-23 08:06:13 +08:00
|
|
|
#ifdef CONFIG_PROC_FS
|
|
|
|
extern int __init nfs_fs_proc_init(void);
|
|
|
|
extern void nfs_fs_proc_exit(void);
|
2014-07-31 19:35:20 +08:00
|
|
|
extern int nfs_fs_proc_net_init(struct net *net);
|
|
|
|
extern void nfs_fs_proc_net_exit(struct net *net);
|
2006-08-23 08:06:13 +08:00
|
|
|
#else
|
2014-07-31 19:35:20 +08:00
|
|
|
static inline int nfs_fs_proc_net_init(struct net *net)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
static inline void nfs_fs_proc_net_exit(struct net *net)
|
|
|
|
{
|
|
|
|
}
|
2006-08-23 08:06:13 +08:00
|
|
|
static inline int nfs_fs_proc_init(void)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
static inline void nfs_fs_proc_exit(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
2006-08-23 08:06:10 +08:00
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
/* callback_xdr.c */
|
|
|
|
extern struct svc_version nfs4_callback_version1;
|
2009-12-06 02:19:01 +08:00
|
|
|
extern struct svc_version nfs4_callback_version4;
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
2012-04-21 02:47:46 +08:00
|
|
|
struct nfs_pageio_descriptor;
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
/* pagelist.c */
|
|
|
|
extern int __init nfs_init_nfspagecache(void);
|
2006-06-28 03:59:15 +08:00
|
|
|
extern void nfs_destroy_nfspagecache(void);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
extern int __init nfs_init_readpagecache(void);
|
2006-06-28 03:59:15 +08:00
|
|
|
extern void nfs_destroy_readpagecache(void);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
extern int __init nfs_init_writepagecache(void);
|
2006-06-28 03:59:15 +08:00
|
|
|
extern void nfs_destroy_writepagecache(void);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
|
|
|
extern int __init nfs_init_directcache(void);
|
2006-06-28 03:59:15 +08:00
|
|
|
extern void nfs_destroy_directcache(void);
|
2012-04-21 02:47:46 +08:00
|
|
|
extern void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
|
|
|
|
struct nfs_pgio_header *hdr,
|
|
|
|
void (*release)(struct nfs_pgio_header *hdr));
|
|
|
|
void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos);
|
2016-01-06 23:40:18 +08:00
|
|
|
int nfs_iocounter_wait(struct nfs_lock_context *l_ctx);
|
2013-04-09 09:38:12 +08:00
|
|
|
|
2014-05-06 21:12:40 +08:00
|
|
|
extern const struct nfs_pageio_ops nfs_pgio_rw_ops;
|
2014-06-09 23:48:33 +08:00
|
|
|
struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *);
|
|
|
|
void nfs_pgio_header_free(struct nfs_pgio_header *);
|
2014-06-09 23:48:35 +08:00
|
|
|
void nfs_pgio_data_destroy(struct nfs_pgio_header *);
|
2014-05-06 21:12:36 +08:00
|
|
|
int nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *);
|
2014-06-13 23:02:25 +08:00
|
|
|
int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
|
|
|
|
struct rpc_cred *cred, const struct nfs_rpc_ops *rpc_ops,
|
|
|
|
const struct rpc_call_ops *call_ops, int how, int flags);
|
2014-07-11 22:20:48 +08:00
|
|
|
void nfs_free_request(struct nfs_page *req);
|
2014-11-10 08:35:35 +08:00
|
|
|
struct nfs_pgio_mirror *
|
|
|
|
nfs_pgio_current_mirror(struct nfs_pageio_descriptor *desc);
|
2014-05-06 21:12:29 +08:00
|
|
|
|
2014-11-10 08:35:34 +08:00
|
|
|
static inline bool nfs_pgio_has_mirroring(struct nfs_pageio_descriptor *desc)
|
|
|
|
{
|
|
|
|
WARN_ON_ONCE(desc->pg_mirror_count < 1);
|
|
|
|
return desc->pg_mirror_count > 1;
|
|
|
|
}
|
|
|
|
|
2015-10-02 05:17:06 +08:00
|
|
|
static inline bool nfs_match_open_context(const struct nfs_open_context *ctx1,
|
|
|
|
const struct nfs_open_context *ctx2)
|
|
|
|
{
|
|
|
|
return ctx1->cred == ctx2->cred && ctx1->state == ctx2->state;
|
|
|
|
}
|
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
/* nfs2xdr.c */
|
|
|
|
extern struct rpc_procinfo nfs_procedures[];
|
2010-12-14 22:58:11 +08:00
|
|
|
extern int nfs2_decode_dirent(struct xdr_stream *,
|
|
|
|
struct nfs_entry *, int);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
|
|
|
/* nfs3xdr.c */
|
|
|
|
extern struct rpc_procinfo nfs3_procedures[];
|
2010-12-14 22:58:11 +08:00
|
|
|
extern int nfs3_decode_dirent(struct xdr_stream *,
|
|
|
|
struct nfs_entry *, int);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
|
|
|
/* nfs4xdr.c */
|
2012-07-31 04:05:25 +08:00
|
|
|
#if IS_ENABLED(CONFIG_NFS_V4)
|
2010-12-14 22:58:11 +08:00
|
|
|
extern int nfs4_decode_dirent(struct xdr_stream *,
|
|
|
|
struct nfs_entry *, int);
|
2006-08-23 08:06:07 +08:00
|
|
|
#endif
|
2009-12-06 02:36:55 +08:00
|
|
|
#ifdef CONFIG_NFS_V4_1
|
|
|
|
extern const u32 nfs41_maxread_overhead;
|
|
|
|
extern const u32 nfs41_maxwrite_overhead;
|
2013-06-26 07:02:53 +08:00
|
|
|
extern const u32 nfs41_maxgetdevinfo_overhead;
|
2009-12-06 02:36:55 +08:00
|
|
|
#endif
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
|
|
|
/* nfs4proc.c */
|
2012-07-31 04:05:25 +08:00
|
|
|
#if IS_ENABLED(CONFIG_NFS_V4)
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
extern struct rpc_procinfo nfs4_procedures[];
|
2006-06-25 17:41:26 +08:00
|
|
|
#endif
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
2013-11-14 01:29:08 +08:00
|
|
|
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
|
|
|
|
extern struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags);
|
2015-07-27 15:31:38 +08:00
|
|
|
static inline struct nfs4_label *
|
|
|
|
nfs4_label_copy(struct nfs4_label *dst, struct nfs4_label *src)
|
|
|
|
{
|
|
|
|
if (!dst || !src)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (src->len > NFS4_MAXLABELLEN)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
dst->lfs = src->lfs;
|
|
|
|
dst->pi = src->pi;
|
|
|
|
dst->len = src->len;
|
|
|
|
memcpy(dst->label, src->label, src->len);
|
|
|
|
|
|
|
|
return dst;
|
|
|
|
}
|
2013-11-14 01:29:08 +08:00
|
|
|
static inline void nfs4_label_free(struct nfs4_label *label)
|
|
|
|
{
|
|
|
|
if (label) {
|
|
|
|
kfree(label->label);
|
|
|
|
kfree(label);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2014-02-07 03:38:53 +08:00
|
|
|
|
|
|
|
static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
|
|
|
|
{
|
|
|
|
if (nfs_server_capable(&nfsi->vfs_inode, NFS_CAP_SECURITY_LABEL))
|
|
|
|
nfsi->cache_validity |= NFS_INO_INVALID_LABEL;
|
|
|
|
}
|
2013-11-14 01:29:08 +08:00
|
|
|
#else
|
|
|
|
static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; }
|
|
|
|
static inline void nfs4_label_free(void *label) {}
|
2014-02-07 03:38:53 +08:00
|
|
|
static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
|
|
|
|
{
|
|
|
|
}
|
2015-07-27 15:31:38 +08:00
|
|
|
static inline struct nfs4_label *
|
|
|
|
nfs4_label_copy(struct nfs4_label *dst, struct nfs4_label *src)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2013-11-14 01:29:08 +08:00
|
|
|
#endif /* CONFIG_NFS_V4_SECURITY_LABEL */
|
|
|
|
|
2009-03-20 03:35:50 +08:00
|
|
|
/* proc.c */
|
|
|
|
void nfs_close_context(struct nfs_open_context *ctx, int is_sync);
|
2012-05-22 10:45:59 +08:00
|
|
|
extern struct nfs_client *nfs_init_client(struct nfs_client *clp,
|
2016-06-23 02:13:12 +08:00
|
|
|
const struct nfs_client_initdata *);
|
2009-03-20 03:35:50 +08:00
|
|
|
|
2006-07-25 23:28:19 +08:00
|
|
|
/* dir.c */
|
2016-12-02 22:15:37 +08:00
|
|
|
extern void nfs_advise_use_readdirplus(struct inode *dir);
|
2014-02-08 06:02:08 +08:00
|
|
|
extern void nfs_force_use_readdirplus(struct inode *dir);
|
2013-08-28 08:18:09 +08:00
|
|
|
extern unsigned long nfs_access_cache_count(struct shrinker *shrink,
|
|
|
|
struct shrink_control *sc);
|
|
|
|
extern unsigned long nfs_access_cache_scan(struct shrinker *shrink,
|
|
|
|
struct shrink_control *sc);
|
2012-07-17 04:39:10 +08:00
|
|
|
struct dentry *nfs_lookup(struct inode *, struct dentry *, unsigned int);
|
|
|
|
int nfs_create(struct inode *, struct dentry *, umode_t, bool);
|
|
|
|
int nfs_mkdir(struct inode *, struct dentry *, umode_t);
|
|
|
|
int nfs_rmdir(struct inode *, struct dentry *);
|
|
|
|
int nfs_unlink(struct inode *, struct dentry *);
|
|
|
|
int nfs_symlink(struct inode *, struct dentry *, const char *);
|
|
|
|
int nfs_link(struct dentry *, struct inode *, struct dentry *);
|
|
|
|
int nfs_mknod(struct inode *, struct dentry *, umode_t, dev_t);
|
fs: make remaining filesystems use .rename2
This is trivial to do:
- add flags argument to foo_rename()
- check if flags is zero
- assign foo_rename() to .rename2 instead of .rename
This doesn't mean it's impossible to support RENAME_NOREPLACE for these
filesystems, but it is not trivial, like for local filesystems.
RENAME_NOREPLACE must guarantee atomicity (i.e. it shouldn't be possible
for a file to be created on one host while it is overwritten by rename on
another host).
Filesystems converted:
9p, afs, ceph, coda, ecryptfs, kernfs, lustre, ncpfs, nfs, ocfs2, orangefs.
After this, we can get rid of the duplicate interfaces for rename.
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: David Howells <dhowells@redhat.com> [AFS]
Acked-by: Mike Marshall <hubcap@omnibond.com>
Cc: Eric Van Hensbergen <ericvh@gmail.com>
Cc: Ilya Dryomov <idryomov@gmail.com>
Cc: Jan Harkes <jaharkes@cs.cmu.edu>
Cc: Tyler Hicks <tyhicks@canonical.com>
Cc: Oleg Drokin <oleg.drokin@intel.com>
Cc: Trond Myklebust <trond.myklebust@primarydata.com>
Cc: Mark Fasheh <mfasheh@suse.com>
2016-09-27 17:03:58 +08:00
|
|
|
int nfs_rename(struct inode *, struct dentry *,
|
|
|
|
struct inode *, struct dentry *, unsigned int);
|
2006-07-25 23:28:19 +08:00
|
|
|
|
2012-07-17 04:39:15 +08:00
|
|
|
/* file.c */
|
2016-03-03 00:35:54 +08:00
|
|
|
int nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync);
|
2012-07-17 04:39:15 +08:00
|
|
|
loff_t nfs_file_llseek(struct file *, loff_t, int);
|
2014-04-03 08:14:12 +08:00
|
|
|
ssize_t nfs_file_read(struct kiocb *, struct iov_iter *);
|
2012-07-17 04:39:15 +08:00
|
|
|
int nfs_file_mmap(struct file *, struct vm_area_struct *);
|
2014-04-04 02:07:25 +08:00
|
|
|
ssize_t nfs_file_write(struct kiocb *, struct iov_iter *);
|
2012-07-17 04:39:15 +08:00
|
|
|
int nfs_file_release(struct inode *, struct file *);
|
|
|
|
int nfs_lock(struct file *, int, struct file_lock *);
|
|
|
|
int nfs_flock(struct file *, int, struct file_lock *);
|
|
|
|
int nfs_check_flags(int);
|
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
/* inode.c */
|
2008-02-20 09:04:22 +08:00
|
|
|
extern struct workqueue_struct *nfsiod_workqueue;
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
extern struct inode *nfs_alloc_inode(struct super_block *sb);
|
|
|
|
extern void nfs_destroy_inode(struct inode *);
|
2010-03-05 16:21:37 +08:00
|
|
|
extern int nfs_write_inode(struct inode *, struct writeback_control *);
|
2012-12-15 03:36:36 +08:00
|
|
|
extern int nfs_drop_inode(struct inode *);
|
2012-07-31 04:05:21 +08:00
|
|
|
extern void nfs_clear_inode(struct inode *);
|
2010-06-08 02:34:48 +08:00
|
|
|
extern void nfs_evict_inode(struct inode *);
|
2008-06-12 05:39:04 +08:00
|
|
|
void nfs_zap_acl_cache(struct inode *inode);
|
2016-12-09 07:18:38 +08:00
|
|
|
extern bool nfs_check_cache_invalid(struct inode *, unsigned long);
|
2015-12-14 05:11:16 +08:00
|
|
|
extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode);
|
2016-01-06 23:40:18 +08:00
|
|
|
extern int nfs_wait_atomic_killable(atomic_t *p);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
|
|
|
/* super.c */
|
2012-07-31 04:05:20 +08:00
|
|
|
extern const struct super_operations nfs_sops;
|
2012-07-31 04:05:16 +08:00
|
|
|
extern struct file_system_type nfs_fs_type;
|
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
|
|
|
extern struct file_system_type nfs_xdev_fs_type;
|
2012-07-31 04:05:25 +08:00
|
|
|
#if IS_ENABLED(CONFIG_NFS_V4)
|
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
|
|
|
extern struct file_system_type nfs4_xdev_fs_type;
|
|
|
|
extern struct file_system_type nfs4_referral_fs_type;
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
#endif
|
2013-10-19 03:15:19 +08:00
|
|
|
bool nfs_auth_info_match(const struct nfs_auth_info *, rpc_authflavor_t);
|
2012-07-31 04:05:18 +08:00
|
|
|
struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *,
|
|
|
|
struct nfs_subversion *);
|
2012-07-17 04:39:20 +08:00
|
|
|
void nfs_initialise_sb(struct super_block *);
|
|
|
|
int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *);
|
|
|
|
int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *);
|
2012-07-31 04:05:16 +08:00
|
|
|
struct dentry *nfs_fs_mount_common(struct nfs_server *, int, const char *,
|
|
|
|
struct nfs_mount_info *, struct nfs_subversion *);
|
2012-07-17 04:39:20 +08:00
|
|
|
struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *);
|
|
|
|
struct dentry * nfs_xdev_mount_common(struct file_system_type *, int,
|
|
|
|
const char *, struct nfs_mount_info *);
|
|
|
|
void nfs_kill_super(struct super_block *);
|
|
|
|
void nfs_fill_super(struct super_block *, struct nfs_mount_info *);
|
2006-07-02 23:29:26 +08:00
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
extern struct rpc_stat nfs_rpcstat;
|
2006-07-02 23:29:26 +08:00
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
extern int __init register_nfs_fs(void);
|
|
|
|
extern void __exit unregister_nfs_fs(void);
|
2015-02-06 04:13:24 +08:00
|
|
|
extern bool nfs_sb_active(struct super_block *sb);
|
2008-07-28 06:19:01 +08:00
|
|
|
extern void nfs_sb_deactive(struct super_block *sb);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
2016-06-04 05:07:19 +08:00
|
|
|
/* io.c */
|
|
|
|
extern void nfs_start_io_read(struct inode *inode);
|
|
|
|
extern void nfs_end_io_read(struct inode *inode);
|
|
|
|
extern void nfs_start_io_write(struct inode *inode);
|
|
|
|
extern void nfs_end_io_write(struct inode *inode);
|
|
|
|
extern void nfs_start_io_direct(struct inode *inode);
|
|
|
|
extern void nfs_end_io_direct(struct inode *inode);
|
|
|
|
|
2016-06-26 05:24:46 +08:00
|
|
|
static inline bool nfs_file_io_is_buffered(struct nfs_inode *nfsi)
|
|
|
|
{
|
|
|
|
return test_bit(NFS_INO_ODIRECT, &nfsi->flags) == 0;
|
|
|
|
}
|
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
/* namespace.c */
|
2012-10-22 02:23:52 +08:00
|
|
|
#define NFS_PATH_CANONICAL 1
|
2011-03-16 18:26:11 +08:00
|
|
|
extern char *nfs_path(char **p, struct dentry *dentry,
|
2012-10-22 02:23:52 +08:00
|
|
|
char *buffer, ssize_t buflen, unsigned flags);
|
2011-01-15 02:45:42 +08:00
|
|
|
extern struct vfsmount *nfs_d_automount(struct path *path);
|
2012-04-28 01:27:45 +08:00
|
|
|
struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *,
|
|
|
|
struct nfs_fh *, struct nfs_fattr *);
|
|
|
|
struct vfsmount *nfs_do_submount(struct dentry *, struct nfs_fh *,
|
|
|
|
struct nfs_fattr *, rpc_authflavor_t);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +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
|
|
|
/* getroot.c */
|
2011-03-16 17:27:27 +08:00
|
|
|
extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *,
|
|
|
|
const char *);
|
2012-07-31 04:05:25 +08:00
|
|
|
#if IS_ENABLED(CONFIG_NFS_V4)
|
2011-03-16 17:27:27 +08:00
|
|
|
extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *,
|
|
|
|
const char *);
|
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
|
|
|
|
2013-09-08 00:58:57 +08:00
|
|
|
extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh, bool);
|
2006-08-23 08:06:07 +08:00
|
|
|
#endif
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
2012-04-21 02:47:48 +08:00
|
|
|
struct nfs_pgio_completion_ops;
|
2009-04-01 21:22:25 +08:00
|
|
|
/* read.c */
|
2012-04-21 02:47:51 +08:00
|
|
|
extern void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
|
2014-04-16 21:07:22 +08:00
|
|
|
struct inode *inode, bool force_mds,
|
2012-04-21 02:47:51 +08:00
|
|
|
const struct nfs_pgio_completion_ops *compl_ops);
|
2009-04-01 21:22:25 +08:00
|
|
|
extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
|
2011-07-14 03:58:28 +08:00
|
|
|
extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio);
|
2011-06-11 01:30:23 +08:00
|
|
|
|
2012-07-17 04:39:20 +08:00
|
|
|
/* super.c */
|
|
|
|
void nfs_clone_super(struct super_block *, struct nfs_mount_info *);
|
|
|
|
void nfs_umount_begin(struct super_block *);
|
|
|
|
int nfs_statfs(struct dentry *, struct kstatfs *);
|
|
|
|
int nfs_show_options(struct seq_file *, struct dentry *);
|
|
|
|
int nfs_show_devname(struct seq_file *, struct dentry *);
|
|
|
|
int nfs_show_path(struct seq_file *, struct dentry *);
|
|
|
|
int nfs_show_stats(struct seq_file *, struct dentry *);
|
|
|
|
int nfs_remount(struct super_block *sb, int *flags, char *raw_data);
|
|
|
|
|
2009-04-01 21:22:26 +08:00
|
|
|
/* write.c */
|
2012-04-21 02:47:57 +08:00
|
|
|
extern void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
|
2014-04-16 21:07:21 +08:00
|
|
|
struct inode *inode, int ioflags, bool force_mds,
|
2012-04-21 02:47:57 +08:00
|
|
|
const struct nfs_pgio_completion_ops *compl_ops);
|
2011-07-14 03:59:19 +08:00
|
|
|
extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
|
2012-04-21 02:47:39 +08:00
|
|
|
extern void nfs_commit_free(struct nfs_commit_data *p);
|
2009-04-01 21:22:26 +08:00
|
|
|
extern void nfs_write_prepare(struct rpc_task *task, void *calldata);
|
2012-04-21 02:47:39 +08:00
|
|
|
extern void nfs_commit_prepare(struct rpc_task *task, void *calldata);
|
|
|
|
extern int nfs_initiate_commit(struct rpc_clnt *clnt,
|
|
|
|
struct nfs_commit_data *data,
|
2014-06-09 07:10:14 +08:00
|
|
|
const struct nfs_rpc_ops *nfs_ops,
|
2011-03-23 21:27:53 +08:00
|
|
|
const struct rpc_call_ops *call_ops,
|
2012-04-28 05:53:44 +08:00
|
|
|
int how, int flags);
|
2012-04-21 02:47:39 +08:00
|
|
|
extern void nfs_init_commit(struct nfs_commit_data *data,
|
2011-03-23 21:27:53 +08:00
|
|
|
struct list_head *head,
|
2012-04-21 02:47:54 +08:00
|
|
|
struct pnfs_layout_segment *lseg,
|
|
|
|
struct nfs_commit_info *cinfo);
|
2012-04-21 02:47:57 +08:00
|
|
|
int nfs_scan_commit_list(struct list_head *src, struct list_head *dst,
|
|
|
|
struct nfs_commit_info *cinfo, int max);
|
2014-05-06 21:12:34 +08:00
|
|
|
unsigned long nfs_reqs_to_commit(struct nfs_commit_info *);
|
2012-04-21 02:47:57 +08:00
|
|
|
int nfs_scan_commit(struct inode *inode, struct list_head *dst,
|
|
|
|
struct nfs_commit_info *cinfo);
|
|
|
|
void nfs_mark_request_commit(struct nfs_page *req,
|
|
|
|
struct pnfs_layout_segment *lseg,
|
2014-09-06 06:20:21 +08:00
|
|
|
struct nfs_commit_info *cinfo,
|
|
|
|
u32 ds_commit_idx);
|
2014-06-09 23:48:36 +08:00
|
|
|
int nfs_write_need_commit(struct nfs_pgio_header *);
|
2015-02-27 06:36:09 +08:00
|
|
|
void nfs_writeback_update_inode(struct nfs_pgio_header *hdr);
|
2016-01-20 03:37:30 +08:00
|
|
|
int nfs_commit_file(struct file *file, struct nfs_write_verifier *verf);
|
2012-04-21 02:47:57 +08:00
|
|
|
int nfs_generic_commit_list(struct inode *inode, struct list_head *head,
|
|
|
|
int how, struct nfs_commit_info *cinfo);
|
2011-03-23 21:27:53 +08:00
|
|
|
void nfs_retry_commit(struct list_head *page_list,
|
2012-04-21 02:47:53 +08:00
|
|
|
struct pnfs_layout_segment *lseg,
|
2014-09-06 06:20:21 +08:00
|
|
|
struct nfs_commit_info *cinfo,
|
|
|
|
u32 ds_commit_idx);
|
2012-04-21 02:47:39 +08:00
|
|
|
void nfs_commitdata_release(struct nfs_commit_data *data);
|
2016-01-16 05:54:15 +08:00
|
|
|
void nfs_request_add_commit_list(struct nfs_page *req,
|
2012-04-21 02:47:53 +08:00
|
|
|
struct nfs_commit_info *cinfo);
|
2015-08-01 04:24:30 +08:00
|
|
|
void nfs_request_add_commit_list_locked(struct nfs_page *req,
|
|
|
|
struct list_head *dst,
|
|
|
|
struct nfs_commit_info *cinfo);
|
2012-04-21 02:47:53 +08:00
|
|
|
void nfs_request_remove_commit_list(struct nfs_page *req,
|
|
|
|
struct nfs_commit_info *cinfo);
|
|
|
|
void nfs_init_cinfo(struct nfs_commit_info *cinfo,
|
|
|
|
struct inode *inode,
|
|
|
|
struct nfs_direct_req *dreq);
|
2013-08-14 23:59:16 +08:00
|
|
|
int nfs_key_timeout_notify(struct file *filp, struct inode *inode);
|
sunrpc: move NO_CRKEY_TIMEOUT to the auth->au_flags
A generic_cred can be used to look up a unx_cred or a gss_cred, so it's
not really safe to use the the generic_cred->acred->ac_flags to store
the NO_CRKEY_TIMEOUT flag. A lookup for a unx_cred triggered while the
KEY_EXPIRE_SOON flag is already set will cause both NO_CRKEY_TIMEOUT and
KEY_EXPIRE_SOON to be set in the ac_flags, leaving the user associated
with the auth_cred to be in a state where they're perpetually doing 4K
NFS_FILE_SYNC writes.
This can be reproduced as follows:
1. Mount two NFS filesystems, one with sec=krb5 and one with sec=sys.
They do not need to be the same export, nor do they even need to be from
the same NFS server. Also, v3 is fine.
$ sudo mount -o v3,sec=krb5 server1:/export /mnt/krb5
$ sudo mount -o v3,sec=sys server2:/export /mnt/sys
2. As the normal user, before accessing the kerberized mount, kinit with
a short lifetime (but not so short that renewing the ticket would leave
you within the 4-minute window again by the time the original ticket
expires), e.g.
$ kinit -l 10m -r 60m
3. Do some I/O to the kerberized mount and verify that the writes are
wsize, UNSTABLE:
$ dd if=/dev/zero of=/mnt/krb5/file bs=1M count=1
4. Wait until you're within 4 minutes of key expiry, then do some more
I/O to the kerberized mount to ensure that RPC_CRED_KEY_EXPIRE_SOON gets
set. Verify that the writes are 4K, FILE_SYNC:
$ dd if=/dev/zero of=/mnt/krb5/file bs=1M count=1
5. Now do some I/O to the sec=sys mount. This will cause
RPC_CRED_NO_CRKEY_TIMEOUT to be set:
$ dd if=/dev/zero of=/mnt/sys/file bs=1M count=1
6. Writes for that user will now be permanently 4K, FILE_SYNC for that
user, regardless of which mount is being written to, until you reboot
the client. Renewing the kerberos ticket (assuming it hasn't already
expired) will have no effect. Grabbing a new kerberos ticket at this
point will have no effect either.
Move the flag to the auth->au_flags field (which is currently unused)
and rename it slightly to reflect that it's no longer associated with
the auth_cred->ac_flags. Add the rpc_auth to the arg list of
rpcauth_cred_key_to_expire and check the au_flags there too. Finally,
add the inode to the arg list of nfs_ctx_key_to_expire so we can
determine the rpc_auth to pass to rpcauth_cred_key_to_expire.
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
2016-06-08 03:14:48 +08:00
|
|
|
bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx, struct inode *inode);
|
2014-09-19 22:55:07 +08:00
|
|
|
void nfs_pageio_stop_mirroring(struct nfs_pageio_descriptor *pgio);
|
2011-03-23 21:27:53 +08:00
|
|
|
|
2016-06-26 06:12:03 +08:00
|
|
|
int nfs_filemap_write_and_wait_range(struct address_space *mapping,
|
|
|
|
loff_t lstart, loff_t lend);
|
|
|
|
|
2016-06-02 09:42:32 +08:00
|
|
|
#ifdef CONFIG_NFS_V4_1
|
|
|
|
static inline
|
|
|
|
void nfs_clear_pnfs_ds_commit_verifiers(struct pnfs_ds_commit_info *cinfo)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < cinfo->nbuckets; i++)
|
|
|
|
cinfo->buckets[i].direct_verf.committed = NFS_INVALID_STABLE_HOW;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static inline
|
|
|
|
void nfs_clear_pnfs_ds_commit_verifiers(struct pnfs_ds_commit_info *cinfo)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-08-10 20:54:13 +08:00
|
|
|
#ifdef CONFIG_MIGRATION
|
|
|
|
extern int nfs_migrate_page(struct address_space *,
|
2012-01-13 09:19:43 +08:00
|
|
|
struct page *, struct page *, enum migrate_mode);
|
2009-08-10 20:54:13 +08:00
|
|
|
#endif
|
2009-04-01 21:22:26 +08:00
|
|
|
|
2016-06-02 09:32:24 +08:00
|
|
|
static inline int
|
|
|
|
nfs_write_verifier_cmp(const struct nfs_write_verifier *v1,
|
|
|
|
const struct nfs_write_verifier *v2)
|
|
|
|
{
|
|
|
|
return memcmp(v1->data, v2->data, sizeof(v1->data));
|
|
|
|
}
|
|
|
|
|
2014-03-17 19:06:55 +08:00
|
|
|
/* unlink.c */
|
|
|
|
extern struct rpc_task *
|
|
|
|
nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
|
|
|
|
struct dentry *old_dentry, struct dentry *new_dentry,
|
|
|
|
void (*complete)(struct rpc_task *, struct nfs_renamedata *));
|
|
|
|
extern int nfs_sillyrename(struct inode *dir, struct dentry *dentry);
|
|
|
|
|
2012-04-21 02:47:57 +08:00
|
|
|
/* direct.c */
|
|
|
|
void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo,
|
|
|
|
struct nfs_direct_req *dreq);
|
2012-09-25 14:55:57 +08:00
|
|
|
extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq);
|
2012-04-21 02:47:57 +08:00
|
|
|
|
2009-04-01 21:22:03 +08:00
|
|
|
/* nfs4proc.c */
|
2012-05-22 10:45:59 +08:00
|
|
|
extern struct nfs_client *nfs4_init_client(struct nfs_client *clp,
|
2016-06-23 02:13:12 +08:00
|
|
|
const struct nfs_client_initdata *);
|
2012-09-15 05:24:32 +08:00
|
|
|
extern int nfs40_walk_client_list(struct nfs_client *clp,
|
|
|
|
struct nfs_client **result,
|
|
|
|
struct rpc_cred *cred);
|
|
|
|
extern int nfs41_walk_client_list(struct nfs_client *clp,
|
|
|
|
struct nfs_client **result,
|
|
|
|
struct rpc_cred *cred);
|
2016-09-09 21:22:29 +08:00
|
|
|
extern int nfs4_test_session_trunk(struct rpc_clnt *,
|
|
|
|
struct rpc_xprt *,
|
|
|
|
void *);
|
2009-04-01 21:22:03 +08:00
|
|
|
|
2015-02-06 04:13:24 +08:00
|
|
|
static inline struct inode *nfs_igrab_and_active(struct inode *inode)
|
|
|
|
{
|
|
|
|
inode = igrab(inode);
|
|
|
|
if (inode != NULL && !nfs_sb_active(inode->i_sb)) {
|
|
|
|
iput(inode);
|
|
|
|
inode = NULL;
|
|
|
|
}
|
|
|
|
return inode;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void nfs_iput_and_deactive(struct inode *inode)
|
|
|
|
{
|
|
|
|
if (inode != NULL) {
|
|
|
|
struct super_block *sb = inode->i_sb;
|
|
|
|
|
|
|
|
iput(inode);
|
|
|
|
nfs_sb_deactive(sb);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
/*
|
|
|
|
* Determine the device name as a string
|
|
|
|
*/
|
2011-03-16 18:26:11 +08:00
|
|
|
static inline char *nfs_devname(struct dentry *dentry,
|
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
|
|
|
char *buffer, ssize_t buflen)
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
{
|
2011-03-16 18:26:11 +08:00
|
|
|
char *dummy;
|
2012-10-22 02:23:52 +08:00
|
|
|
return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine the actual block size (and log2 thereof)
|
|
|
|
*/
|
|
|
|
static inline
|
|
|
|
unsigned long nfs_block_bits(unsigned long bsize, unsigned char *nrbitsp)
|
|
|
|
{
|
|
|
|
/* make sure blocksize is a power of two */
|
|
|
|
if ((bsize & (bsize - 1)) || nrbitsp) {
|
|
|
|
unsigned char nrbits;
|
|
|
|
|
|
|
|
for (nrbits = 31; nrbits && !(bsize & (1 << nrbits)); nrbits--)
|
|
|
|
;
|
|
|
|
bsize = 1 << nrbits;
|
|
|
|
if (nrbitsp)
|
|
|
|
*nrbitsp = nrbits;
|
|
|
|
}
|
|
|
|
|
|
|
|
return bsize;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Calculate the number of 512byte blocks used.
|
|
|
|
*/
|
2007-07-02 00:12:19 +08:00
|
|
|
static inline blkcnt_t nfs_calc_block_size(u64 tsize)
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
{
|
2007-07-02 00:12:19 +08:00
|
|
|
blkcnt_t used = (tsize + 511) >> 9;
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
return (used > ULONG_MAX) ? ULONG_MAX : used;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Compute and set NFS server blocksize
|
|
|
|
*/
|
|
|
|
static inline
|
|
|
|
unsigned long nfs_block_size(unsigned long bsize, unsigned char *nrbitsp)
|
|
|
|
{
|
|
|
|
if (bsize < NFS_MIN_FILE_IO_SIZE)
|
|
|
|
bsize = NFS_DEF_FILE_IO_SIZE;
|
|
|
|
else if (bsize >= NFS_MAX_FILE_IO_SIZE)
|
|
|
|
bsize = NFS_MAX_FILE_IO_SIZE;
|
|
|
|
|
|
|
|
return nfs_block_bits(bsize, nrbitsp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine the maximum file size for a superblock
|
|
|
|
*/
|
|
|
|
static inline
|
|
|
|
void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize)
|
|
|
|
{
|
|
|
|
sb->s_maxbytes = (loff_t)maxfilesize;
|
|
|
|
if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0)
|
|
|
|
sb->s_maxbytes = MAX_LFS_FILESIZE;
|
|
|
|
}
|
2006-12-05 13:35:38 +08:00
|
|
|
|
2015-02-14 05:19:53 +08:00
|
|
|
/*
|
|
|
|
* Record the page as unstable and mark its inode as dirty.
|
|
|
|
*/
|
|
|
|
static inline
|
2015-08-01 04:24:30 +08:00
|
|
|
void nfs_mark_page_unstable(struct page *page, struct nfs_commit_info *cinfo)
|
2015-02-14 05:19:53 +08:00
|
|
|
{
|
2015-08-01 04:24:30 +08:00
|
|
|
if (!cinfo->dreq) {
|
|
|
|
struct inode *inode = page_file_mapping(page)->host;
|
2015-02-14 05:19:53 +08:00
|
|
|
|
2016-07-29 06:46:20 +08:00
|
|
|
inc_node_page_state(page, NR_UNSTABLE_NFS);
|
2015-08-01 04:24:30 +08:00
|
|
|
inc_wb_stat(&inode_to_bdi(inode)->wb, WB_RECLAIMABLE);
|
|
|
|
__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
|
|
|
|
}
|
2015-02-14 05:19:53 +08:00
|
|
|
}
|
|
|
|
|
2006-12-05 13:35:38 +08:00
|
|
|
/*
|
|
|
|
* Determine the number of bytes of data the page contains
|
|
|
|
*/
|
|
|
|
static inline
|
|
|
|
unsigned int nfs_page_length(struct page *page)
|
|
|
|
{
|
2012-08-01 07:45:06 +08:00
|
|
|
loff_t i_size = i_size_read(page_file_mapping(page)->host);
|
2006-12-05 13:35:38 +08:00
|
|
|
|
|
|
|
if (i_size > 0) {
|
2016-10-08 08:00:24 +08:00
|
|
|
pgoff_t index = page_index(page);
|
mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros
PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
ago with promise that one day it will be possible to implement page
cache with bigger chunks than PAGE_SIZE.
This promise never materialized. And unlikely will.
We have many places where PAGE_CACHE_SIZE assumed to be equal to
PAGE_SIZE. And it's constant source of confusion on whether
PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
especially on the border between fs and mm.
Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
breakage to be doable.
Let's stop pretending that pages in page cache are special. They are
not.
The changes are pretty straight-forward:
- <foo> << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- <foo> >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};
- page_cache_get() -> get_page();
- page_cache_release() -> put_page();
This patch contains automated changes generated with coccinelle using
script below. For some reason, coccinelle doesn't patch header files.
I've called spatch for them manually.
The only adjustment after coccinelle is revert of changes to
PAGE_CAHCE_ALIGN definition: we are going to drop it later.
There are few places in the code where coccinelle didn't reach. I'll
fix them manually in a separate patch. Comments and documentation also
will be addressed with the separate patch.
virtual patch
@@
expression E;
@@
- E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
expression E;
@@
- E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
@@
- PAGE_CACHE_SHIFT
+ PAGE_SHIFT
@@
@@
- PAGE_CACHE_SIZE
+ PAGE_SIZE
@@
@@
- PAGE_CACHE_MASK
+ PAGE_MASK
@@
expression E;
@@
- PAGE_CACHE_ALIGN(E)
+ PAGE_ALIGN(E)
@@
expression E;
@@
- page_cache_get(E)
+ get_page(E)
@@
expression E;
@@
- page_cache_release(E)
+ put_page(E)
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-04-01 20:29:47 +08:00
|
|
|
pgoff_t end_index = (i_size - 1) >> PAGE_SHIFT;
|
2016-10-08 08:00:24 +08:00
|
|
|
if (index < end_index)
|
mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros
PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
ago with promise that one day it will be possible to implement page
cache with bigger chunks than PAGE_SIZE.
This promise never materialized. And unlikely will.
We have many places where PAGE_CACHE_SIZE assumed to be equal to
PAGE_SIZE. And it's constant source of confusion on whether
PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
especially on the border between fs and mm.
Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
breakage to be doable.
Let's stop pretending that pages in page cache are special. They are
not.
The changes are pretty straight-forward:
- <foo> << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- <foo> >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};
- page_cache_get() -> get_page();
- page_cache_release() -> put_page();
This patch contains automated changes generated with coccinelle using
script below. For some reason, coccinelle doesn't patch header files.
I've called spatch for them manually.
The only adjustment after coccinelle is revert of changes to
PAGE_CAHCE_ALIGN definition: we are going to drop it later.
There are few places in the code where coccinelle didn't reach. I'll
fix them manually in a separate patch. Comments and documentation also
will be addressed with the separate patch.
virtual patch
@@
expression E;
@@
- E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
expression E;
@@
- E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
@@
- PAGE_CACHE_SHIFT
+ PAGE_SHIFT
@@
@@
- PAGE_CACHE_SIZE
+ PAGE_SIZE
@@
@@
- PAGE_CACHE_MASK
+ PAGE_MASK
@@
expression E;
@@
- PAGE_CACHE_ALIGN(E)
+ PAGE_ALIGN(E)
@@
expression E;
@@
- page_cache_get(E)
+ get_page(E)
@@
expression E;
@@
- page_cache_release(E)
+ put_page(E)
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-04-01 20:29:47 +08:00
|
|
|
return PAGE_SIZE;
|
2016-10-08 08:00:24 +08:00
|
|
|
if (index == end_index)
|
mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros
PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
ago with promise that one day it will be possible to implement page
cache with bigger chunks than PAGE_SIZE.
This promise never materialized. And unlikely will.
We have many places where PAGE_CACHE_SIZE assumed to be equal to
PAGE_SIZE. And it's constant source of confusion on whether
PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
especially on the border between fs and mm.
Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
breakage to be doable.
Let's stop pretending that pages in page cache are special. They are
not.
The changes are pretty straight-forward:
- <foo> << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- <foo> >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};
- page_cache_get() -> get_page();
- page_cache_release() -> put_page();
This patch contains automated changes generated with coccinelle using
script below. For some reason, coccinelle doesn't patch header files.
I've called spatch for them manually.
The only adjustment after coccinelle is revert of changes to
PAGE_CAHCE_ALIGN definition: we are going to drop it later.
There are few places in the code where coccinelle didn't reach. I'll
fix them manually in a separate patch. Comments and documentation also
will be addressed with the separate patch.
virtual patch
@@
expression E;
@@
- E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
expression E;
@@
- E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
@@
- PAGE_CACHE_SHIFT
+ PAGE_SHIFT
@@
@@
- PAGE_CACHE_SIZE
+ PAGE_SIZE
@@
@@
- PAGE_CACHE_MASK
+ PAGE_MASK
@@
expression E;
@@
- PAGE_CACHE_ALIGN(E)
+ PAGE_ALIGN(E)
@@
expression E;
@@
- page_cache_get(E)
+ get_page(E)
@@
expression E;
@@
- page_cache_release(E)
+ put_page(E)
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-04-01 20:29:47 +08:00
|
|
|
return ((i_size - 1) & ~PAGE_MASK) + 1;
|
2006-12-05 13:35:38 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2007-04-10 21:26:35 +08:00
|
|
|
|
2010-11-21 03:26:44 +08:00
|
|
|
/*
|
|
|
|
* Convert a umode to a dirent->d_type
|
|
|
|
*/
|
|
|
|
static inline
|
|
|
|
unsigned char nfs_umode_to_dtype(umode_t mode)
|
|
|
|
{
|
|
|
|
return (mode >> 12) & 15;
|
|
|
|
}
|
|
|
|
|
2007-04-10 21:26:35 +08:00
|
|
|
/*
|
|
|
|
* Determine the number of pages in an array of length 'len' and
|
|
|
|
* with a base offset of 'base'
|
|
|
|
*/
|
|
|
|
static inline
|
|
|
|
unsigned int nfs_page_array_len(unsigned int base, size_t len)
|
|
|
|
{
|
|
|
|
return ((unsigned long)len + (unsigned long)base +
|
|
|
|
PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
|
|
}
|
2009-12-07 22:00:24 +08:00
|
|
|
|
2012-04-28 01:48:18 +08:00
|
|
|
/*
|
|
|
|
* Convert a struct timespec into a 64-bit change attribute
|
|
|
|
*
|
|
|
|
* This does approximately the same thing as timespec_to_ns(),
|
|
|
|
* but for calculation efficiency, we multiply the seconds by
|
|
|
|
* 1024*1024*1024.
|
|
|
|
*/
|
|
|
|
static inline
|
|
|
|
u64 nfs_timespec_to_change_attr(const struct timespec *ts)
|
|
|
|
{
|
|
|
|
return ((u64)ts->tv_sec << 30) + ts->tv_nsec;
|
|
|
|
}
|
2013-08-13 04:06:31 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_CRC32
|
|
|
|
/**
|
|
|
|
* nfs_fhandle_hash - calculate the crc32 hash for the filehandle
|
|
|
|
* @fh - pointer to filehandle
|
|
|
|
*
|
|
|
|
* returns a crc32 hash for the filehandle that is compatible with
|
|
|
|
* the one displayed by "wireshark".
|
|
|
|
*/
|
|
|
|
static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
|
|
|
|
{
|
|
|
|
return ~crc32_le(0xFFFFFFFF, &fh->data[0], fh->size);
|
|
|
|
}
|
Adding stateid information to tracepoints
Operations to which stateid information is added:
close, delegreturn, open, read, setattr, layoutget, layoutcommit, test_stateid,
write, lock, locku, lockt
Format is "stateid=<seqid>:<crc32 hash stateid.other>", also "openstateid=",
"layoutstateid=", and "lockstateid=" for open_file, layoutget, set_lock
tracepoints.
New function is added to internal.h, nfs_stateid_hash(), to compute the hash
trace_nfs4_setattr() is moved from nfs4_do_setattr() to _nfs4_do_setattr()
to get access to stateid.
trace_nfs4_setattr and trace_nfs4_delegreturn are changed from INODE_EVENT
to new event type, INODE_STATEID_EVENT which is same as INODE_EVENT but adds
stateid information
for locking tracepoints, moved trace_nfs4_set_lock() into _nfs4_do_setlk()
to get access to stateid information, and removed trace_nfs4_lock_reclaim(),
trace_nfs4_lock_expired() as they call into _nfs4_do_setlk() and both were
previously same LOCK_EVENT type.
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
2015-11-25 02:29:41 +08:00
|
|
|
static inline u32 nfs_stateid_hash(const nfs4_stateid *stateid)
|
|
|
|
{
|
|
|
|
return ~crc32_le(0xFFFFFFFF, &stateid->other[0],
|
|
|
|
NFS4_STATEID_OTHER_SIZE);
|
|
|
|
}
|
2013-08-13 04:06:31 +08:00
|
|
|
#else
|
|
|
|
static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
Adding stateid information to tracepoints
Operations to which stateid information is added:
close, delegreturn, open, read, setattr, layoutget, layoutcommit, test_stateid,
write, lock, locku, lockt
Format is "stateid=<seqid>:<crc32 hash stateid.other>", also "openstateid=",
"layoutstateid=", and "lockstateid=" for open_file, layoutget, set_lock
tracepoints.
New function is added to internal.h, nfs_stateid_hash(), to compute the hash
trace_nfs4_setattr() is moved from nfs4_do_setattr() to _nfs4_do_setattr()
to get access to stateid.
trace_nfs4_setattr and trace_nfs4_delegreturn are changed from INODE_EVENT
to new event type, INODE_STATEID_EVENT which is same as INODE_EVENT but adds
stateid information
for locking tracepoints, moved trace_nfs4_set_lock() into _nfs4_do_setlk()
to get access to stateid information, and removed trace_nfs4_lock_reclaim(),
trace_nfs4_lock_expired() as they call into _nfs4_do_setlk() and both were
previously same LOCK_EVENT type.
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
2015-11-25 02:29:41 +08:00
|
|
|
static inline u32 nfs_stateid_hash(nfs4_stateid *stateid)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2013-08-13 04:06:31 +08:00
|
|
|
#endif
|
2015-12-05 15:57:31 +08:00
|
|
|
|
|
|
|
static inline bool nfs_error_is_fatal(int err)
|
|
|
|
{
|
|
|
|
switch (err) {
|
|
|
|
case -ERESTARTSYS:
|
|
|
|
case -EIO:
|
|
|
|
case -ENOSPC:
|
|
|
|
case -EROFS:
|
|
|
|
case -E2BIG:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|