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 20:34:33 +07:00
|
|
|
/*
|
|
|
|
* NFS internal definitions
|
|
|
|
*/
|
|
|
|
|
2009-04-01 20:22:41 +07: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 20:34:33 +07:00
|
|
|
#include <linux/mount.h>
|
2008-03-06 02:20:18 +07:00
|
|
|
#include <linux/security.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 20:34:33 +07:00
|
|
|
|
2009-04-03 22:42:42 +07: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 07:06:13 +07: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)
|
|
|
|
|
2009-04-01 20:22:41 +07:00
|
|
|
/*
|
|
|
|
* Determine if sessions are in use.
|
|
|
|
*/
|
|
|
|
static inline int nfs4_has_session(const struct nfs_client *clp)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_NFS_V4_1
|
|
|
|
if (clp->cl_session)
|
|
|
|
return 1;
|
|
|
|
#endif /* CONFIG_NFS_V4_1 */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-06 01:29:53 +07:00
|
|
|
static inline int nfs4_has_persistent_session(const struct nfs_client *clp)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_NFS_V4_1
|
|
|
|
if (nfs4_has_session(clp))
|
|
|
|
return (clp->cl_session->flags & SESSION4_PERSIST);
|
|
|
|
#endif /* CONFIG_NFS_V4_1 */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-03-25 00:12:30 +07: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 05:25:56 +07: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;
|
|
|
|
|
|
|
|
fattr->fileid = fattr->mounted_on_fileid;
|
|
|
|
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 20:34:33 +07: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 02:59:06 +07: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 20:34:33 +07:00
|
|
|
rpc_authflavor_t authflavor;
|
|
|
|
};
|
|
|
|
|
2009-06-18 08:02:12 +07: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 06:49:47 +07:00
|
|
|
/*
|
|
|
|
* Value used if the user did not specify a port value.
|
|
|
|
*/
|
|
|
|
#define NFS_UNSPEC_PORT (-1)
|
|
|
|
|
2010-10-21 02:44:37 +07: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 03:39:18 +07:00
|
|
|
struct nfs_client_initdata {
|
|
|
|
unsigned long init_flags;
|
|
|
|
const char *hostname;
|
|
|
|
const struct sockaddr *addr;
|
|
|
|
size_t addrlen;
|
2012-07-31 03:05:16 +07:00
|
|
|
struct nfs_subversion *nfs_mod;
|
2012-07-17 03:39:18 +07:00
|
|
|
int proto;
|
|
|
|
u32 minorversion;
|
|
|
|
struct net *net;
|
|
|
|
};
|
|
|
|
|
2007-09-11 00:43:29 +07:00
|
|
|
/*
|
|
|
|
* In-kernel mount arguments
|
|
|
|
*/
|
|
|
|
struct nfs_parsed_mount_data {
|
|
|
|
int flags;
|
|
|
|
int rsize, wsize;
|
|
|
|
int timeo, retrans;
|
|
|
|
int acregmin, acregmax,
|
|
|
|
acdirmin, acdirmax;
|
|
|
|
int namlen;
|
2009-04-03 22:42:48 +07:00
|
|
|
unsigned int options;
|
2007-09-11 00:43:29 +07:00
|
|
|
unsigned int bsize;
|
|
|
|
unsigned int auth_flavor_len;
|
|
|
|
rpc_authflavor_t auth_flavors[1];
|
|
|
|
char *client_address;
|
2009-09-09 06:50:03 +07:00
|
|
|
unsigned int version;
|
2009-04-01 20:21:48 +07:00
|
|
|
unsigned int minorversion;
|
2009-04-03 22:42:42 +07:00
|
|
|
char *fscache_uniq;
|
2012-05-11 02:07:40 +07:00
|
|
|
bool need_mount;
|
2007-09-11 00:43:29 +07:00
|
|
|
|
|
|
|
struct {
|
2007-12-11 02:59:28 +07:00
|
|
|
struct sockaddr_storage address;
|
|
|
|
size_t addrlen;
|
2007-09-11 00:43:29 +07:00
|
|
|
char *hostname;
|
2008-03-15 01:10:15 +07:00
|
|
|
u32 version;
|
2009-09-09 06:49:47 +07:00
|
|
|
int port;
|
2008-03-15 01:10:15 +07:00
|
|
|
unsigned short protocol;
|
2007-09-11 00:43:29 +07:00
|
|
|
} mount_server;
|
|
|
|
|
|
|
|
struct {
|
2007-12-11 02:59:28 +07:00
|
|
|
struct sockaddr_storage address;
|
|
|
|
size_t addrlen;
|
2007-09-11 00:43:29 +07:00
|
|
|
char *hostname;
|
|
|
|
char *export_path;
|
2009-09-09 06:49:47 +07:00
|
|
|
int port;
|
2008-03-15 01:10:15 +07:00
|
|
|
unsigned short protocol;
|
2007-09-11 00:43:29 +07:00
|
|
|
} nfs_server;
|
2008-03-06 02:20:18 +07:00
|
|
|
|
|
|
|
struct security_mnt_opts lsm_opts;
|
2012-01-10 19:12:46 +07:00
|
|
|
struct net *net;
|
2007-09-11 00:43:29 +07:00
|
|
|
};
|
|
|
|
|
2008-12-24 03:21:34 +07:00
|
|
|
/* mount_clnt.c */
|
2008-12-24 03:21:35 +07: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 03:21:37 +07:00
|
|
|
int noresvport;
|
2009-06-18 08:02:13 +07:00
|
|
|
unsigned int *auth_flav_len;
|
|
|
|
rpc_authflavor_t *auth_flavs;
|
2012-01-10 19:12:54 +07:00
|
|
|
struct net *net;
|
2008-12-24 03:21:35 +07:00
|
|
|
};
|
|
|
|
|
2012-07-17 03:39:20 +07: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 03:21:35 +07:00
|
|
|
extern int nfs_mount(struct nfs_mount_request *info);
|
2009-08-10 02:09:30 +07:00
|
|
|
extern void nfs_umount(const struct nfs_mount_request *info);
|
2008-12-24 03:21:34 +07:00
|
|
|
|
2006-08-23 07:06:10 +07:00
|
|
|
/* client.c */
|
2012-01-21 01:53:56 +07:00
|
|
|
extern const struct rpc_program nfs_program;
|
2012-01-24 00:26:05 +07:00
|
|
|
extern void nfs_clients_init(struct net *net);
|
2012-06-21 02:53:46 +07:00
|
|
|
extern struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *);
|
2012-07-17 03:39:17 +07:00
|
|
|
int nfs_create_rpc_client(struct nfs_client *, const struct rpc_timeout *, rpc_authflavor_t);
|
2012-07-17 03:39:18 +07:00
|
|
|
struct nfs_client *nfs_get_client(const struct nfs_client_initdata *,
|
|
|
|
const struct rpc_timeout *, const char *,
|
|
|
|
rpc_authflavor_t);
|
|
|
|
int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *, struct nfs_fattr *);
|
|
|
|
void nfs_server_insert_lists(struct nfs_server *);
|
|
|
|
void nfs_init_timeout_values(struct rpc_timeout *, int, unsigned int, unsigned int);
|
|
|
|
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 07:06:13 +07:00
|
|
|
|
2012-01-24 00:26:22 +07:00
|
|
|
extern void nfs_cleanup_cb_ident_idr(struct net *);
|
2006-08-23 07:06:10 +07:00
|
|
|
extern void nfs_put_client(struct nfs_client *);
|
2012-06-21 02:53:45 +07:00
|
|
|
extern void nfs_free_client(struct nfs_client *);
|
2012-01-24 00:26:22 +07:00
|
|
|
extern struct nfs_client *nfs4_find_client_ident(struct net *, int);
|
2011-01-06 09:04:32 +07:00
|
|
|
extern struct nfs_client *
|
2012-01-26 18:11:49 +07:00
|
|
|
nfs4_find_client_sessionid(struct net *, const struct sockaddr *,
|
|
|
|
struct nfs4_sessionid *);
|
2012-07-31 03:05:19 +07:00
|
|
|
extern struct nfs_server *nfs_create_server(struct nfs_mount_info *,
|
2012-07-31 03:05:16 +07:00
|
|
|
struct nfs_subversion *);
|
2007-09-11 00:44:33 +07:00
|
|
|
extern struct nfs_server *nfs4_create_server(
|
2012-07-31 03:05:19 +07: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 07:06:13 +07:00
|
|
|
extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
|
|
|
|
struct nfs_fh *);
|
|
|
|
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 00:27:42 +07:00
|
|
|
struct nfs_fattr *,
|
|
|
|
rpc_authflavor_t);
|
2012-05-24 00:24:36 +07:00
|
|
|
extern int nfs_wait_client_init_complete(const struct nfs_client *clp);
|
2009-04-01 20:22:38 +07:00
|
|
|
extern void nfs_mark_client_ready(struct nfs_client *clp, int state);
|
2011-03-01 08:34:17 +07:00
|
|
|
extern struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
|
|
|
|
const struct sockaddr *ds_addr,
|
2012-04-28 04:53:45 +07:00
|
|
|
int ds_addrlen, int ds_proto,
|
|
|
|
unsigned int ds_timeo,
|
|
|
|
unsigned int ds_retrans);
|
2006-08-23 07:06:13 +07:00
|
|
|
#ifdef CONFIG_PROC_FS
|
|
|
|
extern int __init nfs_fs_proc_init(void);
|
|
|
|
extern void nfs_fs_proc_exit(void);
|
|
|
|
#else
|
|
|
|
static inline int nfs_fs_proc_init(void)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
static inline void nfs_fs_proc_exit(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
2006-08-23 07:06:10 +07:00
|
|
|
|
2012-07-17 03:39:18 +07:00
|
|
|
#ifdef CONFIG_NFS_V4_1
|
|
|
|
int nfs_sockaddr_match_ipaddr(const struct sockaddr *, const struct sockaddr *);
|
|
|
|
#endif
|
|
|
|
|
2012-07-31 03:05:19 +07:00
|
|
|
/* nfs3client.c */
|
2012-07-31 03:05:24 +07:00
|
|
|
#if IS_ENABLED(CONFIG_NFS_V3)
|
2012-07-31 03:05:19 +07:00
|
|
|
struct nfs_server *nfs3_create_server(struct nfs_mount_info *, struct nfs_subversion *);
|
|
|
|
struct nfs_server *nfs3_clone_server(struct nfs_server *, struct nfs_fh *,
|
|
|
|
struct nfs_fattr *, rpc_authflavor_t);
|
|
|
|
#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 20:34:33 +07:00
|
|
|
/* callback_xdr.c */
|
|
|
|
extern struct svc_version nfs4_callback_version1;
|
2009-12-06 01:19:01 +07: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 20:34:33 +07:00
|
|
|
|
2012-04-21 01:47:46 +07: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 20:34:33 +07:00
|
|
|
/* pagelist.c */
|
|
|
|
extern int __init nfs_init_nfspagecache(void);
|
2006-06-28 02:59:15 +07: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 20:34:33 +07:00
|
|
|
extern int __init nfs_init_readpagecache(void);
|
2006-06-28 02:59:15 +07: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 20:34:33 +07:00
|
|
|
extern int __init nfs_init_writepagecache(void);
|
2006-06-28 02:59:15 +07: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 20:34:33 +07:00
|
|
|
|
|
|
|
extern int __init nfs_init_directcache(void);
|
2006-06-28 02:59:15 +07:00
|
|
|
extern void nfs_destroy_directcache(void);
|
2012-04-21 01:47:45 +07:00
|
|
|
extern bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount);
|
2012-04-21 01:47:46 +07: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);
|
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 20:34:33 +07:00
|
|
|
|
|
|
|
/* nfs2xdr.c */
|
|
|
|
extern struct rpc_procinfo nfs_procedures[];
|
2010-12-14 21:58:11 +07: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 20:34:33 +07:00
|
|
|
|
|
|
|
/* nfs3xdr.c */
|
|
|
|
extern struct rpc_procinfo nfs3_procedures[];
|
2010-12-14 21:58:11 +07: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 20:34:33 +07:00
|
|
|
|
|
|
|
/* nfs4xdr.c */
|
2012-07-31 03:05:25 +07:00
|
|
|
#if IS_ENABLED(CONFIG_NFS_V4)
|
2010-12-14 21:58:11 +07:00
|
|
|
extern int nfs4_decode_dirent(struct xdr_stream *,
|
|
|
|
struct nfs_entry *, int);
|
2006-08-23 07:06:07 +07:00
|
|
|
#endif
|
2009-12-06 01:36:55 +07:00
|
|
|
#ifdef CONFIG_NFS_V4_1
|
|
|
|
extern const u32 nfs41_maxread_overhead;
|
|
|
|
extern const u32 nfs41_maxwrite_overhead;
|
|
|
|
#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 20:34:33 +07:00
|
|
|
|
|
|
|
/* nfs4proc.c */
|
2012-07-31 03:05:25 +07: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 20:34:33 +07:00
|
|
|
extern struct rpc_procinfo nfs4_procedures[];
|
2006-06-25 16:41:26 +07: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 20:34:33 +07:00
|
|
|
|
2012-05-24 00:23:31 +07:00
|
|
|
extern int nfs4_init_ds_session(struct nfs_client *, unsigned long);
|
2011-03-01 08:34:17 +07:00
|
|
|
|
2009-03-20 02:35:50 +07:00
|
|
|
/* proc.c */
|
|
|
|
void nfs_close_context(struct nfs_open_context *ctx, int is_sync);
|
2012-05-22 09:45:59 +07:00
|
|
|
extern struct nfs_client *nfs_init_client(struct nfs_client *clp,
|
2011-03-01 08:34:08 +07:00
|
|
|
const struct rpc_timeout *timeparms,
|
2012-05-22 09:46:07 +07:00
|
|
|
const char *ip_addr, rpc_authflavor_t authflavour);
|
2009-03-20 02:35:50 +07:00
|
|
|
|
2006-07-25 22:28:19 +07:00
|
|
|
/* dir.c */
|
2010-07-19 11:56:17 +07:00
|
|
|
extern int nfs_access_cache_shrinker(struct shrinker *shrink,
|
2011-05-25 07:12:27 +07:00
|
|
|
struct shrink_control *sc);
|
2012-07-17 03:39:10 +07: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);
|
|
|
|
int nfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
|
2006-07-25 22:28:19 +07:00
|
|
|
|
2012-07-17 03:39:15 +07:00
|
|
|
/* file.c */
|
|
|
|
int nfs_file_fsync_commit(struct file *, loff_t, loff_t, int);
|
|
|
|
loff_t nfs_file_llseek(struct file *, loff_t, int);
|
|
|
|
int nfs_file_flush(struct file *, fl_owner_t);
|
|
|
|
ssize_t nfs_file_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
|
|
|
|
ssize_t nfs_file_splice_read(struct file *, loff_t *, struct pipe_inode_info *,
|
|
|
|
size_t, unsigned int);
|
|
|
|
int nfs_file_mmap(struct file *, struct vm_area_struct *);
|
|
|
|
ssize_t nfs_file_write(struct kiocb *, const struct iovec *, unsigned long, loff_t);
|
|
|
|
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 *);
|
|
|
|
ssize_t nfs_file_splice_write(struct pipe_inode_info *, struct file *, loff_t *,
|
|
|
|
size_t, unsigned int);
|
|
|
|
int nfs_check_flags(int);
|
|
|
|
int nfs_setlease(struct file *, long, struct file_lock **);
|
|
|
|
|
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 20:34:33 +07:00
|
|
|
/* inode.c */
|
2008-02-20 08:04:22 +07: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 20:34:33 +07:00
|
|
|
extern struct inode *nfs_alloc_inode(struct super_block *sb);
|
|
|
|
extern void nfs_destroy_inode(struct inode *);
|
2010-03-05 15:21:37 +07:00
|
|
|
extern int nfs_write_inode(struct inode *, struct writeback_control *);
|
2012-07-31 03:05:21 +07:00
|
|
|
extern void nfs_clear_inode(struct inode *);
|
2010-06-08 01:34:48 +07:00
|
|
|
extern void nfs_evict_inode(struct inode *);
|
2008-06-12 04:39:04 +07:00
|
|
|
void nfs_zap_acl_cache(struct inode *inode);
|
2009-03-12 01:10:30 +07:00
|
|
|
extern int nfs_wait_bit_killable(void *word);
|
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 20:34:33 +07:00
|
|
|
|
|
|
|
/* super.c */
|
2012-07-31 03:05:20 +07:00
|
|
|
extern const struct super_operations nfs_sops;
|
2012-07-31 03:05:16 +07: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 07:06:13 +07:00
|
|
|
extern struct file_system_type nfs_xdev_fs_type;
|
2012-07-31 03:05:25 +07: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 07:06:13 +07: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 20:34:33 +07:00
|
|
|
#endif
|
2012-07-31 03:05:18 +07:00
|
|
|
struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *,
|
|
|
|
struct nfs_subversion *);
|
2012-07-17 03:39:20 +07: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 03:05:16 +07:00
|
|
|
struct dentry *nfs_fs_mount_common(struct nfs_server *, int, const char *,
|
|
|
|
struct nfs_mount_info *, struct nfs_subversion *);
|
2012-07-17 03:39:20 +07: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 22:29:26 +07: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 20:34:33 +07:00
|
|
|
extern struct rpc_stat nfs_rpcstat;
|
2006-07-02 22:29:26 +07: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 20:34:33 +07:00
|
|
|
extern int __init register_nfs_fs(void);
|
|
|
|
extern void __exit unregister_nfs_fs(void);
|
2008-07-28 05:19:01 +07:00
|
|
|
extern void nfs_sb_active(struct super_block *sb);
|
|
|
|
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 20:34:33 +07:00
|
|
|
|
|
|
|
/* namespace.c */
|
2011-03-16 17:26:11 +07:00
|
|
|
extern char *nfs_path(char **p, struct dentry *dentry,
|
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 20:34:33 +07:00
|
|
|
char *buffer, ssize_t buflen);
|
2011-01-15 01:45:42 +07:00
|
|
|
extern struct vfsmount *nfs_d_automount(struct path *path);
|
2012-04-28 00:27:45 +07: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 20:34:33 +07: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 07:06:13 +07:00
|
|
|
/* getroot.c */
|
2011-03-16 16:27:27 +07:00
|
|
|
extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *,
|
|
|
|
const char *);
|
2012-07-31 03:05:25 +07:00
|
|
|
#if IS_ENABLED(CONFIG_NFS_V4)
|
2011-03-16 16:27:27 +07: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 07:06:13 +07:00
|
|
|
|
2010-04-17 03:22:46 +07:00
|
|
|
extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh);
|
2006-08-23 07:06:07 +07: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 20:34:33 +07:00
|
|
|
|
2012-04-21 01:47:48 +07:00
|
|
|
struct nfs_pgio_completion_ops;
|
2009-04-01 20:22:25 +07:00
|
|
|
/* read.c */
|
2012-04-21 01:47:46 +07:00
|
|
|
extern struct nfs_read_header *nfs_readhdr_alloc(void);
|
2012-04-21 01:47:44 +07:00
|
|
|
extern void nfs_readhdr_free(struct nfs_pgio_header *hdr);
|
2012-04-21 01:47:51 +07:00
|
|
|
extern void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
|
|
|
|
struct inode *inode,
|
|
|
|
const struct nfs_pgio_completion_ops *compl_ops);
|
2012-04-21 01:47:41 +07:00
|
|
|
extern int nfs_initiate_read(struct rpc_clnt *clnt,
|
|
|
|
struct nfs_read_data *data,
|
2012-04-28 04:53:44 +07:00
|
|
|
const struct rpc_call_ops *call_ops, int flags);
|
2009-04-01 20:22:25 +07:00
|
|
|
extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
|
2011-07-14 02:58:28 +07:00
|
|
|
extern int nfs_generic_pagein(struct nfs_pageio_descriptor *desc,
|
2012-04-21 01:47:46 +07:00
|
|
|
struct nfs_pgio_header *hdr);
|
2012-06-21 02:53:47 +07:00
|
|
|
extern void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
|
2012-04-21 01:47:48 +07:00
|
|
|
struct inode *inode,
|
|
|
|
const struct nfs_pgio_completion_ops *compl_ops);
|
2011-07-14 02:58:28 +07:00
|
|
|
extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio);
|
|
|
|
extern void nfs_readdata_release(struct nfs_read_data *rdata);
|
2011-06-11 00:30:23 +07:00
|
|
|
|
2012-07-17 03:39:20 +07: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 *);
|
|
|
|
void nfs_put_super(struct super_block *);
|
|
|
|
int nfs_remount(struct super_block *sb, int *flags, char *raw_data);
|
|
|
|
|
2009-04-01 20:22:26 +07:00
|
|
|
/* write.c */
|
2012-04-21 01:47:57 +07:00
|
|
|
extern void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
|
|
|
|
struct inode *inode, int ioflags,
|
|
|
|
const struct nfs_pgio_completion_ops *compl_ops);
|
2012-04-21 01:47:47 +07:00
|
|
|
extern struct nfs_write_header *nfs_writehdr_alloc(void);
|
2012-04-21 01:47:44 +07:00
|
|
|
extern void nfs_writehdr_free(struct nfs_pgio_header *hdr);
|
2011-07-14 02:59:19 +07:00
|
|
|
extern int nfs_generic_flush(struct nfs_pageio_descriptor *desc,
|
2012-04-21 01:47:47 +07:00
|
|
|
struct nfs_pgio_header *hdr);
|
2012-06-21 02:53:48 +07:00
|
|
|
extern void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
|
2012-04-21 01:47:48 +07:00
|
|
|
struct inode *inode, int ioflags,
|
|
|
|
const struct nfs_pgio_completion_ops *compl_ops);
|
2011-07-14 02:59:19 +07:00
|
|
|
extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
|
|
|
|
extern void nfs_writedata_release(struct nfs_write_data *wdata);
|
2012-04-21 01:47:39 +07:00
|
|
|
extern void nfs_commit_free(struct nfs_commit_data *p);
|
2012-04-21 01:47:41 +07:00
|
|
|
extern int nfs_initiate_write(struct rpc_clnt *clnt,
|
|
|
|
struct nfs_write_data *data,
|
2011-03-03 22:13:47 +07:00
|
|
|
const struct rpc_call_ops *call_ops,
|
2012-04-28 04:53:44 +07:00
|
|
|
int how, int flags);
|
2009-04-01 20:22:26 +07:00
|
|
|
extern void nfs_write_prepare(struct rpc_task *task, void *calldata);
|
2012-04-21 01:47:39 +07: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,
|
2011-03-23 20:27:53 +07:00
|
|
|
const struct rpc_call_ops *call_ops,
|
2012-04-28 04:53:44 +07:00
|
|
|
int how, int flags);
|
2012-04-21 01:47:39 +07:00
|
|
|
extern void nfs_init_commit(struct nfs_commit_data *data,
|
2011-03-23 20:27:53 +07:00
|
|
|
struct list_head *head,
|
2012-04-21 01:47:54 +07:00
|
|
|
struct pnfs_layout_segment *lseg,
|
|
|
|
struct nfs_commit_info *cinfo);
|
2012-04-21 01:47:57 +07:00
|
|
|
int nfs_scan_commit_list(struct list_head *src, struct list_head *dst,
|
|
|
|
struct nfs_commit_info *cinfo, int max);
|
|
|
|
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,
|
|
|
|
struct nfs_commit_info *cinfo);
|
|
|
|
int nfs_generic_commit_list(struct inode *inode, struct list_head *head,
|
|
|
|
int how, struct nfs_commit_info *cinfo);
|
2011-03-23 20:27:53 +07:00
|
|
|
void nfs_retry_commit(struct list_head *page_list,
|
2012-04-21 01:47:53 +07:00
|
|
|
struct pnfs_layout_segment *lseg,
|
|
|
|
struct nfs_commit_info *cinfo);
|
2012-04-21 01:47:39 +07:00
|
|
|
void nfs_commitdata_release(struct nfs_commit_data *data);
|
2012-04-21 01:47:53 +07:00
|
|
|
void nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst,
|
|
|
|
struct nfs_commit_info *cinfo);
|
|
|
|
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);
|
2011-03-23 20:27:53 +07:00
|
|
|
|
2009-08-10 19:54:13 +07:00
|
|
|
#ifdef CONFIG_MIGRATION
|
|
|
|
extern int nfs_migrate_page(struct address_space *,
|
2012-01-13 08:19:43 +07:00
|
|
|
struct page *, struct page *, enum migrate_mode);
|
2009-08-10 19:54:13 +07:00
|
|
|
#else
|
|
|
|
#define nfs_migrate_page NULL
|
|
|
|
#endif
|
2009-04-01 20:22:26 +07:00
|
|
|
|
2012-04-21 01:47:57 +07:00
|
|
|
/* direct.c */
|
|
|
|
void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo,
|
|
|
|
struct nfs_direct_req *dreq);
|
2012-05-31 23:22:33 +07:00
|
|
|
static inline void nfs_inode_dio_wait(struct inode *inode)
|
|
|
|
{
|
|
|
|
inode_dio_wait(inode);
|
|
|
|
}
|
2012-04-21 01:47:57 +07:00
|
|
|
|
2009-04-01 20:22:03 +07:00
|
|
|
/* nfs4proc.c */
|
2011-05-22 23:52:03 +07:00
|
|
|
extern void __nfs4_read_done_cb(struct nfs_read_data *);
|
2012-05-22 09:45:59 +07:00
|
|
|
extern struct nfs_client *nfs4_init_client(struct nfs_client *clp,
|
2011-03-01 08:34:08 +07:00
|
|
|
const struct rpc_timeout *timeparms,
|
|
|
|
const char *ip_addr,
|
2012-05-22 09:46:07 +07:00
|
|
|
rpc_authflavor_t authflavour);
|
2011-03-25 00:12:24 +07:00
|
|
|
extern int _nfs4_call_sync(struct rpc_clnt *clnt,
|
|
|
|
struct nfs_server *server,
|
2009-04-01 20:22:03 +07:00
|
|
|
struct rpc_message *msg,
|
|
|
|
struct nfs4_sequence_args *args,
|
|
|
|
struct nfs4_sequence_res *res,
|
|
|
|
int cache_reply);
|
2011-03-25 00:12:24 +07:00
|
|
|
extern int _nfs4_call_sync_session(struct rpc_clnt *clnt,
|
|
|
|
struct nfs_server *server,
|
2009-04-01 20:22:03 +07:00
|
|
|
struct rpc_message *msg,
|
|
|
|
struct nfs4_sequence_args *args,
|
|
|
|
struct nfs4_sequence_res *res,
|
|
|
|
int cache_reply);
|
|
|
|
|
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 20:34:33 +07:00
|
|
|
/*
|
|
|
|
* Determine the device name as a string
|
|
|
|
*/
|
2011-03-16 17:26:11 +07: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 07:06:13 +07: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 20:34:33 +07:00
|
|
|
{
|
2011-03-16 17:26:11 +07:00
|
|
|
char *dummy;
|
|
|
|
return nfs_path(&dummy, dentry, buffer, 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 20:34:33 +07: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-01 23:12:19 +07: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 20:34:33 +07:00
|
|
|
{
|
2007-07-01 23:12:19 +07: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 20:34:33 +07: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 12:35:38 +07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine the number of bytes of data the page contains
|
|
|
|
*/
|
|
|
|
static inline
|
|
|
|
unsigned int nfs_page_length(struct page *page)
|
|
|
|
{
|
2012-08-01 06:45:06 +07:00
|
|
|
loff_t i_size = i_size_read(page_file_mapping(page)->host);
|
2006-12-05 12:35:38 +07:00
|
|
|
|
|
|
|
if (i_size > 0) {
|
2012-08-01 06:45:06 +07:00
|
|
|
pgoff_t page_index = page_file_index(page);
|
2006-12-05 12:35:38 +07:00
|
|
|
pgoff_t end_index = (i_size - 1) >> PAGE_CACHE_SHIFT;
|
2012-08-01 06:45:06 +07:00
|
|
|
if (page_index < end_index)
|
2006-12-05 12:35:38 +07:00
|
|
|
return PAGE_CACHE_SIZE;
|
2012-08-01 06:45:06 +07:00
|
|
|
if (page_index == end_index)
|
2006-12-05 12:35:38 +07:00
|
|
|
return ((i_size - 1) & ~PAGE_CACHE_MASK) + 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2007-04-10 20:26:35 +07:00
|
|
|
|
2010-11-21 02:26:44 +07: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 20:26:35 +07: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 21:00:24 +07:00
|
|
|
|
2012-04-28 00:48:18 +07: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;
|
|
|
|
}
|