License cleanup: add SPDX GPL-2.0 license identifier to files with no license
Many source files in the tree are missing licensing information, which
makes it harder for compliance tools to determine the correct license.
By default all files without license information are under the default
license of the kernel, which is GPL version 2.
Update the files which contain no license information with the 'GPL-2.0'
SPDX license identifier. The SPDX identifier is a legally binding
shorthand, which can be used instead of the full boiler plate text.
This patch is based on work done by Thomas Gleixner and Kate Stewart and
Philippe Ombredanne.
How this work was done:
Patches were generated and checked against linux-4.14-rc6 for a subset of
the use cases:
- file had no licensing information it it.
- file was a */uapi/* one with no licensing information in it,
- file was a */uapi/* one with existing licensing information,
Further patches will be generated in subsequent months to fix up cases
where non-standard license headers were used, and references to license
had to be inferred by heuristics based on keywords.
The analysis to determine which SPDX License Identifier to be applied to
a file was done in a spreadsheet of side by side results from of the
output of two independent scanners (ScanCode & Windriver) producing SPDX
tag:value files created by Philippe Ombredanne. Philippe prepared the
base worksheet, and did an initial spot review of a few 1000 files.
The 4.13 kernel was the starting point of the analysis with 60,537 files
assessed. Kate Stewart did a file by file comparison of the scanner
results in the spreadsheet to determine which SPDX license identifier(s)
to be applied to the file. She confirmed any determination that was not
immediately clear with lawyers working with the Linux Foundation.
Criteria used to select files for SPDX license identifier tagging was:
- Files considered eligible had to be source code files.
- Make and config files were included as candidates if they contained >5
lines of source
- File already had some variant of a license header in it (even if <5
lines).
All documentation files were explicitly excluded.
The following heuristics were used to determine which SPDX license
identifiers to apply.
- when both scanners couldn't find any license traces, file was
considered to have no license information in it, and the top level
COPYING file license applied.
For non */uapi/* files that summary was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 11139
and resulted in the first patch in this series.
If that file was a */uapi/* path one, it was "GPL-2.0 WITH
Linux-syscall-note" otherwise it was "GPL-2.0". Results of that was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 WITH Linux-syscall-note 930
and resulted in the second patch in this series.
- if a file had some form of licensing information in it, and was one
of the */uapi/* ones, it was denoted with the Linux-syscall-note if
any GPL family license was found in the file or had no licensing in
it (per prior point). Results summary:
SPDX license identifier # files
---------------------------------------------------|------
GPL-2.0 WITH Linux-syscall-note 270
GPL-2.0+ WITH Linux-syscall-note 169
((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) 21
((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 17
LGPL-2.1+ WITH Linux-syscall-note 15
GPL-1.0+ WITH Linux-syscall-note 14
((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) 5
LGPL-2.0+ WITH Linux-syscall-note 4
LGPL-2.1 WITH Linux-syscall-note 3
((GPL-2.0 WITH Linux-syscall-note) OR MIT) 3
((GPL-2.0 WITH Linux-syscall-note) AND MIT) 1
and that resulted in the third patch in this series.
- when the two scanners agreed on the detected license(s), that became
the concluded license(s).
- when there was disagreement between the two scanners (one detected a
license but the other didn't, or they both detected different
licenses) a manual inspection of the file occurred.
- In most cases a manual inspection of the information in the file
resulted in a clear resolution of the license that should apply (and
which scanner probably needed to revisit its heuristics).
- When it was not immediately clear, the license identifier was
confirmed with lawyers working with the Linux Foundation.
- If there was any question as to the appropriate license identifier,
the file was flagged for further research and to be revisited later
in time.
In total, over 70 hours of logged manual review was done on the
spreadsheet to determine the SPDX license identifiers to apply to the
source files by Kate, Philippe, Thomas and, in some cases, confirmation
by lawyers working with the Linux Foundation.
Kate also obtained a third independent scan of the 4.13 code base from
FOSSology, and compared selected files where the other two scanners
disagreed against that SPDX file, to see if there was new insights. The
Windriver scanner is based on an older version of FOSSology in part, so
they are related.
Thomas did random spot checks in about 500 files from the spreadsheets
for the uapi headers and agreed with SPDX license identifier in the
files he inspected. For the non-uapi files Thomas did random spot checks
in about 15000 files.
In initial set of patches against 4.14-rc6, 3 files were found to have
copy/paste license identifier errors, and have been fixed to reflect the
correct identifier.
Additionally Philippe spent 10 hours this week doing a detailed manual
inspection and review of the 12,461 patched files from the initial patch
version early this week with:
- a full scancode scan run, collecting the matched texts, detected
license ids and scores
- reviewing anything where there was a license detected (about 500+
files) to ensure that the applied SPDX license was correct
- reviewing anything where there was no detection but the patch license
was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied
SPDX license was correct
This produced a worksheet with 20 files needing minor correction. This
worksheet was then exported into 3 different .csv files for the
different types of files to be modified.
These .csv files were then reviewed by Greg. Thomas wrote a script to
parse the csv files and add the proper SPDX tag to the file, in the
format that the file expected. This script was further refined by Greg
based on the output to detect more types of files automatically and to
distinguish between header and source .c files (which need different
comment types.) Finally Greg ran the script using the .csv files to
generate the patches.
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-01 22:07:57 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
/*
|
|
|
|
* NFS internal definitions
|
|
|
|
*/
|
|
|
|
|
2009-04-01 21:22:41 +08:00
|
|
|
#include "nfs4_fs.h"
|
2019-12-10 20:31:13 +08:00
|
|
|
#include <linux/fs_context.h>
|
2008-03-06 03:20:18 +08:00
|
|
|
#include <linux/security.h>
|
2013-08-13 04:06:31 +08:00
|
|
|
#include <linux/crc32.h>
|
2019-12-10 20:31:04 +08:00
|
|
|
#include <linux/sunrpc/addr.h>
|
2014-11-10 08:35:34 +08:00
|
|
|
#include <linux/nfs_page.h>
|
2017-06-20 18:19:09 +08:00
|
|
|
#include <linux/wait_bit.h>
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
2019-12-10 20:31:14 +08:00
|
|
|
#define NFS_SB_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS)
|
2009-04-03 23:42:42 +08:00
|
|
|
|
2017-06-29 21:34:53 +08:00
|
|
|
extern const struct export_operations nfs_export_ops;
|
|
|
|
|
NFS: Share NFS superblocks per-protocol per-server per-FSID
The attached patch makes NFS share superblocks between mounts from the same
server and FSID over the same protocol.
It does this by creating each superblock with a false root and returning the
real root dentry in the vfsmount presented by get_sb(). The root dentry set
starts off as an anonymous dentry if we don't already have the dentry for its
inode, otherwise it simply returns the dentry we already have.
We may thus end up with several trees of dentries in the superblock, and if at
some later point one of anonymous tree roots is discovered by normal filesystem
activity to be located in another tree within the superblock, the anonymous
root is named and materialises attached to the second tree at the appropriate
point.
Why do it this way? Why not pass an extra argument to the mount() syscall to
indicate the subpath and then pathwalk from the server root to the desired
directory? You can't guarantee this will work for two reasons:
(1) The root and intervening nodes may not be accessible to the client.
With NFS2 and NFS3, for instance, mountd is called on the server to get
the filehandle for the tip of a path. mountd won't give us handles for
anything we don't have permission to access, and so we can't set up NFS
inodes for such nodes, and so can't easily set up dentries (we'd have to
have ghost inodes or something).
With this patch we don't actually create dentries until we get handles
from the server that we can use to set up their inodes, and we don't
actually bind them into the tree until we know for sure where they go.
(2) Inaccessible symbolic links.
If we're asked to mount two exports from the server, eg:
mount warthog:/warthog/aaa/xxx /mmm
mount warthog:/warthog/bbb/yyy /nnn
We may not be able to access anything nearer the root than xxx and yyy,
but we may find out later that /mmm/www/yyy, say, is actually the same
directory as the one mounted on /nnn. What we might then find out, for
example, is that /warthog/bbb was actually a symbolic link to
/warthog/aaa/xxx/www, but we can't actually determine that by talking to
the server until /warthog is made available by NFS.
This would lead to having constructed an errneous dentry tree which we
can't easily fix. We can end up with a dentry marked as a directory when
it should actually be a symlink, or we could end up with an apparently
hardlinked directory.
With this patch we need not make assumptions about the type of a dentry
for which we can't retrieve information, nor need we assume we know its
place in the grand scheme of things until we actually see that place.
This patch reduces the possibility of aliasing in the inode and page caches for
inodes that may be accessed by more than one NFS export. It also reduces the
number of superblocks required for NFS where there are many NFS exports being
used from a server (home directory server + autofs for example).
This in turn makes it simpler to do local caching of network filesystems, as it
can then be guaranteed that there won't be links from multiple inodes in
separate superblocks to the same cache file.
Obviously, cache aliasing between different levels of NFS protocol could still
be a problem, but at least that gives us another key to use when indexing the
cache.
This patch makes the following changes:
(1) The server record construction/destruction has been abstracted out into
its own set of functions to make things easier to get right. These have
been moved into fs/nfs/client.c.
All the code in fs/nfs/client.c has to do with the management of
connections to servers, and doesn't touch superblocks in any way; the
remaining code in fs/nfs/super.c has to do with VFS superblock management.
(2) The sequence of events undertaken by NFS mount is now reordered:
(a) A volume representation (struct nfs_server) is allocated.
(b) A server representation (struct nfs_client) is acquired. This may be
allocated or shared, and is keyed on server address, port and NFS
version.
(c) If allocated, the client representation is initialised. The state
member variable of nfs_client is used to prevent a race during
initialisation from two mounts.
(d) For NFS4 a simple pathwalk is performed, walking from FH to FH to find
the root filehandle for the mount (fs/nfs/getroot.c). For NFS2/3 we
are given the root FH in advance.
(e) The volume FSID is probed for on the root FH.
(f) The volume representation is initialised from the FSINFO record
retrieved on the root FH.
(g) sget() is called to acquire a superblock. This may be allocated or
shared, keyed on client pointer and FSID.
(h) If allocated, the superblock is initialised.
(i) If the superblock is shared, then the new nfs_server record is
discarded.
(j) The root dentry for this mount is looked up from the root FH.
(k) The root dentry for this mount is assigned to the vfsmount.
(3) nfs_readdir_lookup() creates dentries for each of the entries readdir()
returns; this function now attaches disconnected trees from alternate
roots that happen to be discovered attached to a directory being read (in
the same way nfs_lookup() is made to do for lookup ops).
The new d_materialise_unique() function is now used to do this, thus
permitting the whole thing to be done under one set of locks, and thus
avoiding any race between mount and lookup operations on the same
directory.
(4) The client management code uses a new debug facility: NFSDBG_CLIENT which
is set by echoing 1024 to /proc/net/sunrpc/nfs_debug.
(5) Clone mounts are now called xdev mounts.
(6) Use the dentry passed to the statfs() op as the handle for retrieving fs
statistics rather than the root dentry of the superblock (which is now a
dummy).
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2006-08-23 08:06:13 +08:00
|
|
|
struct nfs_string;
|
2019-12-10 20:31:13 +08:00
|
|
|
struct nfs_pageio_descriptor;
|
NFS: Share NFS superblocks per-protocol per-server per-FSID
The attached patch makes NFS share superblocks between mounts from the same
server and FSID over the same protocol.
It does this by creating each superblock with a false root and returning the
real root dentry in the vfsmount presented by get_sb(). The root dentry set
starts off as an anonymous dentry if we don't already have the dentry for its
inode, otherwise it simply returns the dentry we already have.
We may thus end up with several trees of dentries in the superblock, and if at
some later point one of anonymous tree roots is discovered by normal filesystem
activity to be located in another tree within the superblock, the anonymous
root is named and materialises attached to the second tree at the appropriate
point.
Why do it this way? Why not pass an extra argument to the mount() syscall to
indicate the subpath and then pathwalk from the server root to the desired
directory? You can't guarantee this will work for two reasons:
(1) The root and intervening nodes may not be accessible to the client.
With NFS2 and NFS3, for instance, mountd is called on the server to get
the filehandle for the tip of a path. mountd won't give us handles for
anything we don't have permission to access, and so we can't set up NFS
inodes for such nodes, and so can't easily set up dentries (we'd have to
have ghost inodes or something).
With this patch we don't actually create dentries until we get handles
from the server that we can use to set up their inodes, and we don't
actually bind them into the tree until we know for sure where they go.
(2) Inaccessible symbolic links.
If we're asked to mount two exports from the server, eg:
mount warthog:/warthog/aaa/xxx /mmm
mount warthog:/warthog/bbb/yyy /nnn
We may not be able to access anything nearer the root than xxx and yyy,
but we may find out later that /mmm/www/yyy, say, is actually the same
directory as the one mounted on /nnn. What we might then find out, for
example, is that /warthog/bbb was actually a symbolic link to
/warthog/aaa/xxx/www, but we can't actually determine that by talking to
the server until /warthog is made available by NFS.
This would lead to having constructed an errneous dentry tree which we
can't easily fix. We can end up with a dentry marked as a directory when
it should actually be a symlink, or we could end up with an apparently
hardlinked directory.
With this patch we need not make assumptions about the type of a dentry
for which we can't retrieve information, nor need we assume we know its
place in the grand scheme of things until we actually see that place.
This patch reduces the possibility of aliasing in the inode and page caches for
inodes that may be accessed by more than one NFS export. It also reduces the
number of superblocks required for NFS where there are many NFS exports being
used from a server (home directory server + autofs for example).
This in turn makes it simpler to do local caching of network filesystems, as it
can then be guaranteed that there won't be links from multiple inodes in
separate superblocks to the same cache file.
Obviously, cache aliasing between different levels of NFS protocol could still
be a problem, but at least that gives us another key to use when indexing the
cache.
This patch makes the following changes:
(1) The server record construction/destruction has been abstracted out into
its own set of functions to make things easier to get right. These have
been moved into fs/nfs/client.c.
All the code in fs/nfs/client.c has to do with the management of
connections to servers, and doesn't touch superblocks in any way; the
remaining code in fs/nfs/super.c has to do with VFS superblock management.
(2) The sequence of events undertaken by NFS mount is now reordered:
(a) A volume representation (struct nfs_server) is allocated.
(b) A server representation (struct nfs_client) is acquired. This may be
allocated or shared, and is keyed on server address, port and NFS
version.
(c) If allocated, the client representation is initialised. The state
member variable of nfs_client is used to prevent a race during
initialisation from two mounts.
(d) For NFS4 a simple pathwalk is performed, walking from FH to FH to find
the root filehandle for the mount (fs/nfs/getroot.c). For NFS2/3 we
are given the root FH in advance.
(e) The volume FSID is probed for on the root FH.
(f) The volume representation is initialised from the FSINFO record
retrieved on the root FH.
(g) sget() is called to acquire a superblock. This may be allocated or
shared, keyed on client pointer and FSID.
(h) If allocated, the superblock is initialised.
(i) If the superblock is shared, then the new nfs_server record is
discarded.
(j) The root dentry for this mount is looked up from the root FH.
(k) The root dentry for this mount is assigned to the vfsmount.
(3) nfs_readdir_lookup() creates dentries for each of the entries readdir()
returns; this function now attaches disconnected trees from alternate
roots that happen to be discovered attached to a directory being read (in
the same way nfs_lookup() is made to do for lookup ops).
The new d_materialise_unique() function is now used to do this, thus
permitting the whole thing to be done under one set of locks, and thus
avoiding any race between mount and lookup operations on the same
directory.
(4) The client management code uses a new debug facility: NFSDBG_CLIENT which
is set by echoing 1024 to /proc/net/sunrpc/nfs_debug.
(5) Clone mounts are now called xdev mounts.
(6) Use the dentry passed to the statfs() op as the handle for retrieving fs
statistics rather than the root dentry of the superblock (which is now a
dummy).
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2006-08-23 08:06:13 +08:00
|
|
|
|
2011-03-25 01:12:30 +08:00
|
|
|
static inline void nfs_attr_check_mountpoint(struct super_block *parent, struct nfs_fattr *fattr)
|
|
|
|
{
|
|
|
|
if (!nfs_fsid_equal(&NFS_SB(parent)->fsid, &fattr->fsid))
|
|
|
|
fattr->valid |= NFS_ATTR_FATTR_MOUNTPOINT;
|
|
|
|
}
|
|
|
|
|
2011-06-14 06:25:56 +08:00
|
|
|
static inline int nfs_attr_use_mounted_on_fileid(struct nfs_fattr *fattr)
|
|
|
|
{
|
|
|
|
if (((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) == 0) ||
|
|
|
|
(((fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0) &&
|
|
|
|
((fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) == 0)))
|
|
|
|
return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-01-15 01:06:34 +08:00
|
|
|
static inline bool nfs_lookup_is_soft_revalidate(const struct dentry *dentry)
|
|
|
|
{
|
|
|
|
if (!(NFS_SB(dentry->d_sb)->flags & NFS_MOUNT_SOFTREVAL))
|
|
|
|
return false;
|
|
|
|
if (!d_is_positive(dentry) || !NFS_FH(d_inode(dentry))->size)
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-06-18 09:02:12 +08:00
|
|
|
/*
|
|
|
|
* Note: RFC 1813 doesn't limit the number of auth flavors that
|
|
|
|
* a server can return, so make something up.
|
|
|
|
*/
|
|
|
|
#define NFS_MAX_SECFLAVORS (12)
|
|
|
|
|
2009-09-09 07:49:47 +08:00
|
|
|
/*
|
|
|
|
* Value used if the user did not specify a port value.
|
|
|
|
*/
|
|
|
|
#define NFS_UNSPEC_PORT (-1)
|
|
|
|
|
2016-08-16 22:26:47 +08:00
|
|
|
#define NFS_UNSPEC_RETRANS (UINT_MAX)
|
|
|
|
#define NFS_UNSPEC_TIMEO (UINT_MAX)
|
|
|
|
|
2010-10-21 03:44:37 +08:00
|
|
|
/*
|
|
|
|
* Maximum number of pages that readdir can use for creating
|
|
|
|
* a vmapped array of pages.
|
|
|
|
*/
|
Revert "NFS: readdirplus optimization by cache mechanism" (memleak)
This reverts commit be4c2d4723a4a637f0d1b4f7c66447141a4b3564.
That commit caused a severe memory leak in nfs_readdir_make_qstr().
When listing a directory with more than 100 files (this is how many
struct nfs_cache_array_entry elements fit in one 4kB page), all
allocated file name strings past those 100 leak.
The root of the leakage is that those string pointers are managed in
pages which are never linked into the page cache.
fs/nfs/dir.c puts pages into the page cache by calling
read_cache_page(); the callback function nfs_readdir_filler() will
then fill the given page struct which was passed to it, which is
already linked in the page cache (by do_read_cache_page() calling
add_to_page_cache_lru()).
Commit be4c2d4723a4 added another (local) array of allocated pages, to
be filled with more data, instead of discarding excess items received
from the NFS server. Those additional pages can be used by the next
nfs_readdir_filler() call (from within the same nfs_readdir() call).
The leak happens when some of those additional pages are never used
(copied to the page cache using copy_highpage()). The pages will be
freed by nfs_readdir_free_pages(), but their contents will not. The
commit did not invoke nfs_readdir_clear_array() (and doing so would
have been dangerous, because it did not track which of those pages
were already copied to the page cache, risking double free bugs).
How to reproduce the leak:
- Use a kernel with CONFIG_SLUB_DEBUG_ON.
- Create a directory on a NFS mount with more than 100 files with
names long enough to use the "kmalloc-32" slab (so we can easily
look up the allocation counts):
for i in `seq 110`; do touch ${i}_0123456789abcdef; done
- Drop all caches:
echo 3 >/proc/sys/vm/drop_caches
- Check the allocation counter:
grep nfs_readdir /sys/kernel/slab/kmalloc-32/alloc_calls
30564391 nfs_readdir_add_to_array+0x73/0xd0 age=534558/4791307/6540952 pid=370-1048386 cpus=0-47 nodes=0-1
- Request a directory listing and check the allocation counters again:
ls
[...]
grep nfs_readdir /sys/kernel/slab/kmalloc-32/alloc_calls
30564511 nfs_readdir_add_to_array+0x73/0xd0 age=207/4792999/6542663 pid=370-1048386 cpus=0-47 nodes=0-1
There are now 120 new allocations.
- Drop all caches and check the counters again:
echo 3 >/proc/sys/vm/drop_caches
grep nfs_readdir /sys/kernel/slab/kmalloc-32/alloc_calls
30564401 nfs_readdir_add_to_array+0x73/0xd0 age=735/4793524/6543176 pid=370-1048386 cpus=0-47 nodes=0-1
110 allocations are gone, but 10 have leaked and will never be freed.
Unhelpfully, those allocations are explicitly excluded from KMEMLEAK,
that's why my initial attempts with KMEMLEAK were not successful:
/*
* Avoid a kmemleak false positive. The pointer to the name is stored
* in a page cache page which kmemleak does not scan.
*/
kmemleak_not_leak(string->name);
It would be possible to solve this bug without reverting the whole
commit:
- keep track of which pages were not used, and call
nfs_readdir_clear_array() on them, or
- manually link those pages into the page cache
But for now I have decided to just revert the commit, because the real
fix would require complex considerations, risking more dangerous
(crash) bugs, which may seem unsuitable for the stable branches.
Signed-off-by: Max Kellermann <mk@cm4all.com>
Cc: stable@vger.kernel.org # v5.1+
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2019-07-12 22:18:06 +08:00
|
|
|
#define NFS_MAX_READDIR_PAGES 8
|
2010-10-21 03:44:37 +08:00
|
|
|
|
2012-07-17 04:39:18 +08:00
|
|
|
struct nfs_client_initdata {
|
|
|
|
unsigned long init_flags;
|
2016-06-23 02:13:12 +08:00
|
|
|
const char *hostname; /* Hostname of the server */
|
|
|
|
const struct sockaddr *addr; /* Address of the server */
|
|
|
|
const char *nodename; /* Hostname of the client */
|
|
|
|
const char *ip_addr; /* IP address of the client */
|
2012-07-17 04:39:18 +08:00
|
|
|
size_t addrlen;
|
2012-07-31 04:05:16 +08:00
|
|
|
struct nfs_subversion *nfs_mod;
|
2012-07-17 04:39:18 +08:00
|
|
|
int proto;
|
|
|
|
u32 minorversion;
|
2017-04-27 23:13:40 +08:00
|
|
|
unsigned int nconnect;
|
2012-07-17 04:39:18 +08:00
|
|
|
struct net *net;
|
2016-06-23 02:13:12 +08:00
|
|
|
const struct rpc_timeout *timeparms;
|
2019-04-25 05:46:43 +08:00
|
|
|
const struct cred *cred;
|
2012-07-17 04:39:18 +08:00
|
|
|
};
|
|
|
|
|
2007-09-11 01:43:29 +08:00
|
|
|
/*
|
|
|
|
* In-kernel mount arguments
|
|
|
|
*/
|
2019-12-10 20:31:06 +08:00
|
|
|
struct nfs_fs_context {
|
2019-12-10 20:31:13 +08:00
|
|
|
bool internal;
|
|
|
|
bool skip_reconfig_option_check;
|
|
|
|
bool need_mount;
|
|
|
|
bool sloppy;
|
2019-12-10 20:31:10 +08:00
|
|
|
unsigned int flags; /* NFS{,4}_MOUNT_* flags */
|
2012-09-15 05:23:14 +08:00
|
|
|
unsigned int rsize, wsize;
|
|
|
|
unsigned int timeo, retrans;
|
2019-12-10 20:31:10 +08:00
|
|
|
unsigned int acregmin, acregmax;
|
|
|
|
unsigned int acdirmin, acdirmax;
|
2012-09-15 05:23:14 +08:00
|
|
|
unsigned int namlen;
|
2009-04-03 23:42:48 +08:00
|
|
|
unsigned int options;
|
2007-09-11 01:43:29 +08:00
|
|
|
unsigned int bsize;
|
2013-10-19 03:15:16 +08:00
|
|
|
struct nfs_auth_info auth_info;
|
|
|
|
rpc_authflavor_t selected_flavor;
|
2007-09-11 01:43:29 +08:00
|
|
|
char *client_address;
|
2009-09-09 07:50:03 +08:00
|
|
|
unsigned int version;
|
2009-04-01 21:21:48 +08:00
|
|
|
unsigned int minorversion;
|
2009-04-03 23:42:42 +08:00
|
|
|
char *fscache_uniq;
|
2019-12-10 20:31:07 +08:00
|
|
|
unsigned short protofamily;
|
|
|
|
unsigned short mountfamily;
|
2007-09-11 01:43:29 +08:00
|
|
|
|
|
|
|
struct {
|
2019-12-10 20:31:10 +08:00
|
|
|
union {
|
|
|
|
struct sockaddr address;
|
|
|
|
struct sockaddr_storage _address;
|
|
|
|
};
|
2007-12-11 03:59:28 +08:00
|
|
|
size_t addrlen;
|
2007-09-11 01:43:29 +08:00
|
|
|
char *hostname;
|
2008-03-15 02:10:15 +08:00
|
|
|
u32 version;
|
2009-09-09 07:49:47 +08:00
|
|
|
int port;
|
2008-03-15 02:10:15 +08:00
|
|
|
unsigned short protocol;
|
2007-09-11 01:43:29 +08:00
|
|
|
} mount_server;
|
|
|
|
|
|
|
|
struct {
|
2019-12-10 20:31:10 +08:00
|
|
|
union {
|
|
|
|
struct sockaddr address;
|
|
|
|
struct sockaddr_storage _address;
|
|
|
|
};
|
2007-12-11 03:59:28 +08:00
|
|
|
size_t addrlen;
|
2007-09-11 01:43:29 +08:00
|
|
|
char *hostname;
|
|
|
|
char *export_path;
|
2009-09-09 07:49:47 +08:00
|
|
|
int port;
|
2008-03-15 02:10:15 +08:00
|
|
|
unsigned short protocol;
|
2017-04-27 11:30:48 +08:00
|
|
|
unsigned short nconnect;
|
2019-12-10 20:31:13 +08:00
|
|
|
unsigned short export_path_len;
|
2007-09-11 01:43:29 +08:00
|
|
|
} nfs_server;
|
2008-03-06 03:20:18 +08:00
|
|
|
|
2019-12-10 20:31:14 +08:00
|
|
|
struct nfs_fh *mntfh;
|
|
|
|
struct nfs_server *server;
|
|
|
|
struct nfs_subversion *nfs_mod;
|
|
|
|
|
|
|
|
/* Information for a cloned mount. */
|
|
|
|
struct nfs_clone_mount {
|
|
|
|
struct super_block *sb;
|
|
|
|
struct dentry *dentry;
|
|
|
|
struct nfs_fattr *fattr;
|
|
|
|
unsigned int inherited_bsize;
|
|
|
|
} clone_data;
|
2007-09-11 01:43:29 +08:00
|
|
|
};
|
|
|
|
|
2019-12-10 20:31:15 +08:00
|
|
|
#define nfs_errorf(fc, fmt, ...) errorf(fc, fmt, ## __VA_ARGS__)
|
|
|
|
#define nfs_invalf(fc, fmt, ...) invalf(fc, fmt, ## __VA_ARGS__)
|
|
|
|
#define nfs_warnf(fc, fmt, ...) warnf(fc, fmt, ## __VA_ARGS__)
|
|
|
|
|
2019-12-10 20:31:13 +08:00
|
|
|
static inline struct nfs_fs_context *nfs_fc2context(const struct fs_context *fc)
|
|
|
|
{
|
|
|
|
return fc->fs_private;
|
|
|
|
}
|
|
|
|
|
2008-12-24 04:21:34 +08:00
|
|
|
/* mount_clnt.c */
|
2008-12-24 04:21:35 +08:00
|
|
|
struct nfs_mount_request {
|
|
|
|
struct sockaddr *sap;
|
|
|
|
size_t salen;
|
|
|
|
char *hostname;
|
|
|
|
char *dirpath;
|
|
|
|
u32 version;
|
|
|
|
unsigned short protocol;
|
|
|
|
struct nfs_fh *fh;
|
2008-12-24 04:21:37 +08:00
|
|
|
int noresvport;
|
2009-06-18 09:02:13 +08:00
|
|
|
unsigned int *auth_flav_len;
|
|
|
|
rpc_authflavor_t *auth_flavs;
|
2012-01-10 20:12:54 +08:00
|
|
|
struct net *net;
|
2008-12-24 04:21:35 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
extern int nfs_mount(struct nfs_mount_request *info);
|
2009-08-10 03:09:30 +08:00
|
|
|
extern void nfs_umount(const struct nfs_mount_request *info);
|
2008-12-24 04:21:34 +08:00
|
|
|
|
2006-08-23 08:06:10 +08:00
|
|
|
/* client.c */
|
2012-01-21 02:53:56 +08:00
|
|
|
extern const struct rpc_program nfs_program;
|
2012-01-24 01:26:05 +08:00
|
|
|
extern void nfs_clients_init(struct net *net);
|
2019-02-06 22:32:50 +08:00
|
|
|
extern void nfs_clients_exit(struct net *net);
|
2012-06-21 03:53:46 +08:00
|
|
|
extern struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *);
|
2016-06-23 02:13:12 +08:00
|
|
|
int nfs_create_rpc_client(struct nfs_client *, const struct nfs_client_initdata *, rpc_authflavor_t);
|
2016-11-18 04:15:55 +08:00
|
|
|
struct nfs_client *nfs_get_client(const struct nfs_client_initdata *);
|
2012-07-17 04:39:18 +08:00
|
|
|
int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *, struct nfs_fattr *);
|
|
|
|
void nfs_server_insert_lists(struct nfs_server *);
|
2013-10-18 02:12:28 +08:00
|
|
|
void nfs_server_remove_lists(struct nfs_server *);
|
2016-08-16 22:26:47 +08:00
|
|
|
void nfs_init_timeout_values(struct rpc_timeout *to, int proto, int timeo, int retrans);
|
2012-07-17 04:39:18 +08:00
|
|
|
int nfs_init_server_rpcclient(struct nfs_server *, const struct rpc_timeout *t,
|
|
|
|
rpc_authflavor_t);
|
|
|
|
struct nfs_server *nfs_alloc_server(void);
|
|
|
|
void nfs_server_copy_userdata(struct nfs_server *, struct nfs_server *);
|
NFS: Share NFS superblocks per-protocol per-server per-FSID
The attached patch makes NFS share superblocks between mounts from the same
server and FSID over the same protocol.
It does this by creating each superblock with a false root and returning the
real root dentry in the vfsmount presented by get_sb(). The root dentry set
starts off as an anonymous dentry if we don't already have the dentry for its
inode, otherwise it simply returns the dentry we already have.
We may thus end up with several trees of dentries in the superblock, and if at
some later point one of anonymous tree roots is discovered by normal filesystem
activity to be located in another tree within the superblock, the anonymous
root is named and materialises attached to the second tree at the appropriate
point.
Why do it this way? Why not pass an extra argument to the mount() syscall to
indicate the subpath and then pathwalk from the server root to the desired
directory? You can't guarantee this will work for two reasons:
(1) The root and intervening nodes may not be accessible to the client.
With NFS2 and NFS3, for instance, mountd is called on the server to get
the filehandle for the tip of a path. mountd won't give us handles for
anything we don't have permission to access, and so we can't set up NFS
inodes for such nodes, and so can't easily set up dentries (we'd have to
have ghost inodes or something).
With this patch we don't actually create dentries until we get handles
from the server that we can use to set up their inodes, and we don't
actually bind them into the tree until we know for sure where they go.
(2) Inaccessible symbolic links.
If we're asked to mount two exports from the server, eg:
mount warthog:/warthog/aaa/xxx /mmm
mount warthog:/warthog/bbb/yyy /nnn
We may not be able to access anything nearer the root than xxx and yyy,
but we may find out later that /mmm/www/yyy, say, is actually the same
directory as the one mounted on /nnn. What we might then find out, for
example, is that /warthog/bbb was actually a symbolic link to
/warthog/aaa/xxx/www, but we can't actually determine that by talking to
the server until /warthog is made available by NFS.
This would lead to having constructed an errneous dentry tree which we
can't easily fix. We can end up with a dentry marked as a directory when
it should actually be a symlink, or we could end up with an apparently
hardlinked directory.
With this patch we need not make assumptions about the type of a dentry
for which we can't retrieve information, nor need we assume we know its
place in the grand scheme of things until we actually see that place.
This patch reduces the possibility of aliasing in the inode and page caches for
inodes that may be accessed by more than one NFS export. It also reduces the
number of superblocks required for NFS where there are many NFS exports being
used from a server (home directory server + autofs for example).
This in turn makes it simpler to do local caching of network filesystems, as it
can then be guaranteed that there won't be links from multiple inodes in
separate superblocks to the same cache file.
Obviously, cache aliasing between different levels of NFS protocol could still
be a problem, but at least that gives us another key to use when indexing the
cache.
This patch makes the following changes:
(1) The server record construction/destruction has been abstracted out into
its own set of functions to make things easier to get right. These have
been moved into fs/nfs/client.c.
All the code in fs/nfs/client.c has to do with the management of
connections to servers, and doesn't touch superblocks in any way; the
remaining code in fs/nfs/super.c has to do with VFS superblock management.
(2) The sequence of events undertaken by NFS mount is now reordered:
(a) A volume representation (struct nfs_server) is allocated.
(b) A server representation (struct nfs_client) is acquired. This may be
allocated or shared, and is keyed on server address, port and NFS
version.
(c) If allocated, the client representation is initialised. The state
member variable of nfs_client is used to prevent a race during
initialisation from two mounts.
(d) For NFS4 a simple pathwalk is performed, walking from FH to FH to find
the root filehandle for the mount (fs/nfs/getroot.c). For NFS2/3 we
are given the root FH in advance.
(e) The volume FSID is probed for on the root FH.
(f) The volume representation is initialised from the FSINFO record
retrieved on the root FH.
(g) sget() is called to acquire a superblock. This may be allocated or
shared, keyed on client pointer and FSID.
(h) If allocated, the superblock is initialised.
(i) If the superblock is shared, then the new nfs_server record is
discarded.
(j) The root dentry for this mount is looked up from the root FH.
(k) The root dentry for this mount is assigned to the vfsmount.
(3) nfs_readdir_lookup() creates dentries for each of the entries readdir()
returns; this function now attaches disconnected trees from alternate
roots that happen to be discovered attached to a directory being read (in
the same way nfs_lookup() is made to do for lookup ops).
The new d_materialise_unique() function is now used to do this, thus
permitting the whole thing to be done under one set of locks, and thus
avoiding any race between mount and lookup operations on the same
directory.
(4) The client management code uses a new debug facility: NFSDBG_CLIENT which
is set by echoing 1024 to /proc/net/sunrpc/nfs_debug.
(5) Clone mounts are now called xdev mounts.
(6) Use the dentry passed to the statfs() op as the handle for retrieving fs
statistics rather than the root dentry of the superblock (which is now a
dummy).
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2006-08-23 08:06:13 +08:00
|
|
|
|
2006-08-23 08:06:10 +08:00
|
|
|
extern void nfs_put_client(struct nfs_client *);
|
2012-06-21 03:53:45 +08:00
|
|
|
extern void nfs_free_client(struct nfs_client *);
|
2012-01-24 01:26:22 +08:00
|
|
|
extern struct nfs_client *nfs4_find_client_ident(struct net *, int);
|
2011-01-06 10:04:32 +08:00
|
|
|
extern struct nfs_client *
|
2012-01-26 19:11:49 +08:00
|
|
|
nfs4_find_client_sessionid(struct net *, const struct sockaddr *,
|
2013-06-05 23:15:01 +08:00
|
|
|
struct nfs4_sessionid *, u32);
|
2019-12-10 20:31:14 +08:00
|
|
|
extern struct nfs_server *nfs_create_server(struct fs_context *);
|
|
|
|
extern struct nfs_server *nfs4_create_server(struct fs_context *);
|
|
|
|
extern struct nfs_server *nfs4_create_referral_server(struct fs_context *);
|
2013-10-18 02:12:28 +08:00
|
|
|
extern int nfs4_update_server(struct nfs_server *server, const char *hostname,
|
2014-02-17 10:42:56 +08:00
|
|
|
struct sockaddr *sap, size_t salen,
|
|
|
|
struct net *net);
|
NFS: Share NFS superblocks per-protocol per-server per-FSID
The attached patch makes NFS share superblocks between mounts from the same
server and FSID over the same protocol.
It does this by creating each superblock with a false root and returning the
real root dentry in the vfsmount presented by get_sb(). The root dentry set
starts off as an anonymous dentry if we don't already have the dentry for its
inode, otherwise it simply returns the dentry we already have.
We may thus end up with several trees of dentries in the superblock, and if at
some later point one of anonymous tree roots is discovered by normal filesystem
activity to be located in another tree within the superblock, the anonymous
root is named and materialises attached to the second tree at the appropriate
point.
Why do it this way? Why not pass an extra argument to the mount() syscall to
indicate the subpath and then pathwalk from the server root to the desired
directory? You can't guarantee this will work for two reasons:
(1) The root and intervening nodes may not be accessible to the client.
With NFS2 and NFS3, for instance, mountd is called on the server to get
the filehandle for the tip of a path. mountd won't give us handles for
anything we don't have permission to access, and so we can't set up NFS
inodes for such nodes, and so can't easily set up dentries (we'd have to
have ghost inodes or something).
With this patch we don't actually create dentries until we get handles
from the server that we can use to set up their inodes, and we don't
actually bind them into the tree until we know for sure where they go.
(2) Inaccessible symbolic links.
If we're asked to mount two exports from the server, eg:
mount warthog:/warthog/aaa/xxx /mmm
mount warthog:/warthog/bbb/yyy /nnn
We may not be able to access anything nearer the root than xxx and yyy,
but we may find out later that /mmm/www/yyy, say, is actually the same
directory as the one mounted on /nnn. What we might then find out, for
example, is that /warthog/bbb was actually a symbolic link to
/warthog/aaa/xxx/www, but we can't actually determine that by talking to
the server until /warthog is made available by NFS.
This would lead to having constructed an errneous dentry tree which we
can't easily fix. We can end up with a dentry marked as a directory when
it should actually be a symlink, or we could end up with an apparently
hardlinked directory.
With this patch we need not make assumptions about the type of a dentry
for which we can't retrieve information, nor need we assume we know its
place in the grand scheme of things until we actually see that place.
This patch reduces the possibility of aliasing in the inode and page caches for
inodes that may be accessed by more than one NFS export. It also reduces the
number of superblocks required for NFS where there are many NFS exports being
used from a server (home directory server + autofs for example).
This in turn makes it simpler to do local caching of network filesystems, as it
can then be guaranteed that there won't be links from multiple inodes in
separate superblocks to the same cache file.
Obviously, cache aliasing between different levels of NFS protocol could still
be a problem, but at least that gives us another key to use when indexing the
cache.
This patch makes the following changes:
(1) The server record construction/destruction has been abstracted out into
its own set of functions to make things easier to get right. These have
been moved into fs/nfs/client.c.
All the code in fs/nfs/client.c has to do with the management of
connections to servers, and doesn't touch superblocks in any way; the
remaining code in fs/nfs/super.c has to do with VFS superblock management.
(2) The sequence of events undertaken by NFS mount is now reordered:
(a) A volume representation (struct nfs_server) is allocated.
(b) A server representation (struct nfs_client) is acquired. This may be
allocated or shared, and is keyed on server address, port and NFS
version.
(c) If allocated, the client representation is initialised. The state
member variable of nfs_client is used to prevent a race during
initialisation from two mounts.
(d) For NFS4 a simple pathwalk is performed, walking from FH to FH to find
the root filehandle for the mount (fs/nfs/getroot.c). For NFS2/3 we
are given the root FH in advance.
(e) The volume FSID is probed for on the root FH.
(f) The volume representation is initialised from the FSINFO record
retrieved on the root FH.
(g) sget() is called to acquire a superblock. This may be allocated or
shared, keyed on client pointer and FSID.
(h) If allocated, the superblock is initialised.
(i) If the superblock is shared, then the new nfs_server record is
discarded.
(j) The root dentry for this mount is looked up from the root FH.
(k) The root dentry for this mount is assigned to the vfsmount.
(3) nfs_readdir_lookup() creates dentries for each of the entries readdir()
returns; this function now attaches disconnected trees from alternate
roots that happen to be discovered attached to a directory being read (in
the same way nfs_lookup() is made to do for lookup ops).
The new d_materialise_unique() function is now used to do this, thus
permitting the whole thing to be done under one set of locks, and thus
avoiding any race between mount and lookup operations on the same
directory.
(4) The client management code uses a new debug facility: NFSDBG_CLIENT which
is set by echoing 1024 to /proc/net/sunrpc/nfs_debug.
(5) Clone mounts are now called xdev mounts.
(6) Use the dentry passed to the statfs() op as the handle for retrieving fs
statistics rather than the root dentry of the superblock (which is now a
dummy).
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2006-08-23 08:06:13 +08:00
|
|
|
extern void nfs_free_server(struct nfs_server *server);
|
|
|
|
extern struct nfs_server *nfs_clone_server(struct nfs_server *,
|
|
|
|
struct nfs_fh *,
|
2012-04-28 01:27:42 +08:00
|
|
|
struct nfs_fattr *,
|
|
|
|
rpc_authflavor_t);
|
2017-03-10 01:56:48 +08:00
|
|
|
extern bool nfs_client_init_is_complete(const struct nfs_client *clp);
|
|
|
|
extern int nfs_client_init_status(const struct nfs_client *clp);
|
2012-05-24 01:24:36 +08:00
|
|
|
extern int nfs_wait_client_init_complete(const struct nfs_client *clp);
|
2009-04-01 21:22:38 +08:00
|
|
|
extern void nfs_mark_client_ready(struct nfs_client *clp, int state);
|
2016-06-14 01:57:35 +08:00
|
|
|
extern struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
|
2011-03-01 09:34:17 +08:00
|
|
|
const struct sockaddr *ds_addr,
|
2012-04-28 05:53:45 +08:00
|
|
|
int ds_addrlen, int ds_proto,
|
|
|
|
unsigned int ds_timeo,
|
2014-05-29 21:07:00 +08:00
|
|
|
unsigned int ds_retrans,
|
2016-11-18 04:15:55 +08:00
|
|
|
u32 minor_version);
|
2013-09-07 02:14:00 +08:00
|
|
|
extern struct rpc_clnt *nfs4_find_or_create_ds_client(struct nfs_client *,
|
|
|
|
struct inode *);
|
2016-06-14 02:52:00 +08:00
|
|
|
extern struct nfs_client *nfs3_set_ds_client(struct nfs_server *mds_srv,
|
2014-05-30 18:15:57 +08:00
|
|
|
const struct sockaddr *ds_addr, int ds_addrlen,
|
|
|
|
int ds_proto, unsigned int ds_timeo,
|
2016-11-18 04:15:55 +08:00
|
|
|
unsigned int ds_retrans);
|
2006-08-23 08:06:13 +08:00
|
|
|
#ifdef CONFIG_PROC_FS
|
|
|
|
extern int __init nfs_fs_proc_init(void);
|
|
|
|
extern void nfs_fs_proc_exit(void);
|
2014-07-31 19:35:20 +08:00
|
|
|
extern int nfs_fs_proc_net_init(struct net *net);
|
|
|
|
extern void nfs_fs_proc_net_exit(struct net *net);
|
2006-08-23 08:06:13 +08:00
|
|
|
#else
|
2014-07-31 19:35:20 +08:00
|
|
|
static inline int nfs_fs_proc_net_init(struct net *net)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
static inline void nfs_fs_proc_net_exit(struct net *net)
|
|
|
|
{
|
|
|
|
}
|
2006-08-23 08:06:13 +08:00
|
|
|
static inline int nfs_fs_proc_init(void)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
static inline void nfs_fs_proc_exit(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
2006-08-23 08:06:10 +08:00
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
/* callback_xdr.c */
|
2017-05-12 22:21:37 +08:00
|
|
|
extern const struct svc_version nfs4_callback_version1;
|
|
|
|
extern const struct svc_version nfs4_callback_version4;
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
2019-12-10 20:31:13 +08:00
|
|
|
/* fs_context.c */
|
|
|
|
extern struct file_system_type nfs_fs_type;
|
2019-12-10 20:31:04 +08:00
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
/* pagelist.c */
|
|
|
|
extern int __init nfs_init_nfspagecache(void);
|
2006-06-28 03:59:15 +08:00
|
|
|
extern void nfs_destroy_nfspagecache(void);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
extern int __init nfs_init_readpagecache(void);
|
2006-06-28 03:59:15 +08:00
|
|
|
extern void nfs_destroy_readpagecache(void);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
extern int __init nfs_init_writepagecache(void);
|
2006-06-28 03:59:15 +08:00
|
|
|
extern void nfs_destroy_writepagecache(void);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
|
|
|
extern int __init nfs_init_directcache(void);
|
2006-06-28 03:59:15 +08:00
|
|
|
extern void nfs_destroy_directcache(void);
|
2012-04-21 02:47:46 +08:00
|
|
|
extern void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
|
|
|
|
struct nfs_pgio_header *hdr,
|
|
|
|
void (*release)(struct nfs_pgio_header *hdr));
|
|
|
|
void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos);
|
2016-01-06 23:40:18 +08:00
|
|
|
int nfs_iocounter_wait(struct nfs_lock_context *l_ctx);
|
2013-04-09 09:38:12 +08:00
|
|
|
|
2014-05-06 21:12:40 +08:00
|
|
|
extern const struct nfs_pageio_ops nfs_pgio_rw_ops;
|
2014-06-09 23:48:33 +08:00
|
|
|
struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *);
|
|
|
|
void nfs_pgio_header_free(struct nfs_pgio_header *);
|
2014-05-06 21:12:36 +08:00
|
|
|
int nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *);
|
2014-06-13 23:02:25 +08:00
|
|
|
int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
|
2018-12-03 08:30:31 +08:00
|
|
|
const struct cred *cred, const struct nfs_rpc_ops *rpc_ops,
|
2014-06-13 23:02:25 +08:00
|
|
|
const struct rpc_call_ops *call_ops, int how, int flags);
|
2014-07-11 22:20:48 +08:00
|
|
|
void nfs_free_request(struct nfs_page *req);
|
2014-11-10 08:35:35 +08:00
|
|
|
struct nfs_pgio_mirror *
|
|
|
|
nfs_pgio_current_mirror(struct nfs_pageio_descriptor *desc);
|
2014-05-06 21:12:29 +08:00
|
|
|
|
2014-11-10 08:35:34 +08:00
|
|
|
static inline bool nfs_pgio_has_mirroring(struct nfs_pageio_descriptor *desc)
|
|
|
|
{
|
|
|
|
WARN_ON_ONCE(desc->pg_mirror_count < 1);
|
|
|
|
return desc->pg_mirror_count > 1;
|
|
|
|
}
|
|
|
|
|
2015-10-02 05:17:06 +08:00
|
|
|
static inline bool nfs_match_open_context(const struct nfs_open_context *ctx1,
|
|
|
|
const struct nfs_open_context *ctx2)
|
|
|
|
{
|
2018-12-03 08:30:31 +08:00
|
|
|
return cred_fscmp(ctx1->cred, ctx2->cred) == 0 && ctx1->state == ctx2->state;
|
2015-10-02 05:17:06 +08:00
|
|
|
}
|
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
/* nfs2xdr.c */
|
2017-05-12 21:36:49 +08:00
|
|
|
extern const struct rpc_procinfo nfs_procedures[];
|
2010-12-14 22:58:11 +08:00
|
|
|
extern int nfs2_decode_dirent(struct xdr_stream *,
|
2017-06-20 20:33:44 +08:00
|
|
|
struct nfs_entry *, bool);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
|
|
|
/* nfs3xdr.c */
|
2017-05-12 21:36:49 +08:00
|
|
|
extern const struct rpc_procinfo nfs3_procedures[];
|
2010-12-14 22:58:11 +08:00
|
|
|
extern int nfs3_decode_dirent(struct xdr_stream *,
|
2017-06-20 20:33:44 +08:00
|
|
|
struct nfs_entry *, bool);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
|
|
|
/* nfs4xdr.c */
|
2012-07-31 04:05:25 +08:00
|
|
|
#if IS_ENABLED(CONFIG_NFS_V4)
|
2010-12-14 22:58:11 +08:00
|
|
|
extern int nfs4_decode_dirent(struct xdr_stream *,
|
2017-06-20 20:33:44 +08:00
|
|
|
struct nfs_entry *, bool);
|
2006-08-23 08:06:07 +08:00
|
|
|
#endif
|
2009-12-06 02:36:55 +08:00
|
|
|
#ifdef CONFIG_NFS_V4_1
|
|
|
|
extern const u32 nfs41_maxread_overhead;
|
|
|
|
extern const u32 nfs41_maxwrite_overhead;
|
2013-06-26 07:02:53 +08:00
|
|
|
extern const u32 nfs41_maxgetdevinfo_overhead;
|
2009-12-06 02:36:55 +08:00
|
|
|
#endif
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
|
|
|
/* nfs4proc.c */
|
2012-07-31 04:05:25 +08:00
|
|
|
#if IS_ENABLED(CONFIG_NFS_V4)
|
2017-05-12 21:36:49 +08:00
|
|
|
extern const struct rpc_procinfo nfs4_procedures[];
|
2006-06-25 17:41:26 +08:00
|
|
|
#endif
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
2013-11-14 01:29:08 +08:00
|
|
|
#ifdef CONFIG_NFS_V4_SECURITY_LABEL
|
|
|
|
extern struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags);
|
2015-07-27 15:31:38 +08:00
|
|
|
static inline struct nfs4_label *
|
|
|
|
nfs4_label_copy(struct nfs4_label *dst, struct nfs4_label *src)
|
|
|
|
{
|
|
|
|
if (!dst || !src)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (src->len > NFS4_MAXLABELLEN)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
dst->lfs = src->lfs;
|
|
|
|
dst->pi = src->pi;
|
|
|
|
dst->len = src->len;
|
|
|
|
memcpy(dst->label, src->label, src->len);
|
|
|
|
|
|
|
|
return dst;
|
|
|
|
}
|
2013-11-14 01:29:08 +08:00
|
|
|
static inline void nfs4_label_free(struct nfs4_label *label)
|
|
|
|
{
|
|
|
|
if (label) {
|
|
|
|
kfree(label->label);
|
|
|
|
kfree(label);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2014-02-07 03:38:53 +08:00
|
|
|
|
|
|
|
static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
|
|
|
|
{
|
|
|
|
if (nfs_server_capable(&nfsi->vfs_inode, NFS_CAP_SECURITY_LABEL))
|
|
|
|
nfsi->cache_validity |= NFS_INO_INVALID_LABEL;
|
|
|
|
}
|
2013-11-14 01:29:08 +08:00
|
|
|
#else
|
|
|
|
static inline struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) { return NULL; }
|
|
|
|
static inline void nfs4_label_free(void *label) {}
|
2014-02-07 03:38:53 +08:00
|
|
|
static inline void nfs_zap_label_cache_locked(struct nfs_inode *nfsi)
|
|
|
|
{
|
|
|
|
}
|
2015-07-27 15:31:38 +08:00
|
|
|
static inline struct nfs4_label *
|
|
|
|
nfs4_label_copy(struct nfs4_label *dst, struct nfs4_label *src)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2013-11-14 01:29:08 +08:00
|
|
|
#endif /* CONFIG_NFS_V4_SECURITY_LABEL */
|
|
|
|
|
2009-03-20 03:35:50 +08:00
|
|
|
/* proc.c */
|
|
|
|
void nfs_close_context(struct nfs_open_context *ctx, int is_sync);
|
2012-05-22 10:45:59 +08:00
|
|
|
extern struct nfs_client *nfs_init_client(struct nfs_client *clp,
|
2016-06-23 02:13:12 +08:00
|
|
|
const struct nfs_client_initdata *);
|
2009-03-20 03:35:50 +08:00
|
|
|
|
2006-07-25 23:28:19 +08:00
|
|
|
/* dir.c */
|
2016-12-02 22:15:37 +08:00
|
|
|
extern void nfs_advise_use_readdirplus(struct inode *dir);
|
2014-02-08 06:02:08 +08:00
|
|
|
extern void nfs_force_use_readdirplus(struct inode *dir);
|
2013-08-28 08:18:09 +08:00
|
|
|
extern unsigned long nfs_access_cache_count(struct shrinker *shrink,
|
|
|
|
struct shrink_control *sc);
|
|
|
|
extern unsigned long nfs_access_cache_scan(struct shrinker *shrink,
|
|
|
|
struct shrink_control *sc);
|
2012-07-17 04:39:10 +08:00
|
|
|
struct dentry *nfs_lookup(struct inode *, struct dentry *, unsigned int);
|
|
|
|
int nfs_create(struct inode *, struct dentry *, umode_t, bool);
|
|
|
|
int nfs_mkdir(struct inode *, struct dentry *, umode_t);
|
|
|
|
int nfs_rmdir(struct inode *, struct dentry *);
|
|
|
|
int nfs_unlink(struct inode *, struct dentry *);
|
|
|
|
int nfs_symlink(struct inode *, struct dentry *, const char *);
|
|
|
|
int nfs_link(struct dentry *, struct inode *, struct dentry *);
|
|
|
|
int nfs_mknod(struct inode *, struct dentry *, umode_t, dev_t);
|
fs: make remaining filesystems use .rename2
This is trivial to do:
- add flags argument to foo_rename()
- check if flags is zero
- assign foo_rename() to .rename2 instead of .rename
This doesn't mean it's impossible to support RENAME_NOREPLACE for these
filesystems, but it is not trivial, like for local filesystems.
RENAME_NOREPLACE must guarantee atomicity (i.e. it shouldn't be possible
for a file to be created on one host while it is overwritten by rename on
another host).
Filesystems converted:
9p, afs, ceph, coda, ecryptfs, kernfs, lustre, ncpfs, nfs, ocfs2, orangefs.
After this, we can get rid of the duplicate interfaces for rename.
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: David Howells <dhowells@redhat.com> [AFS]
Acked-by: Mike Marshall <hubcap@omnibond.com>
Cc: Eric Van Hensbergen <ericvh@gmail.com>
Cc: Ilya Dryomov <idryomov@gmail.com>
Cc: Jan Harkes <jaharkes@cs.cmu.edu>
Cc: Tyler Hicks <tyhicks@canonical.com>
Cc: Oleg Drokin <oleg.drokin@intel.com>
Cc: Trond Myklebust <trond.myklebust@primarydata.com>
Cc: Mark Fasheh <mfasheh@suse.com>
2016-09-27 17:03:58 +08:00
|
|
|
int nfs_rename(struct inode *, struct dentry *,
|
|
|
|
struct inode *, struct dentry *, unsigned int);
|
2006-07-25 23:28:19 +08:00
|
|
|
|
2012-07-17 04:39:15 +08:00
|
|
|
/* file.c */
|
2016-03-03 00:35:54 +08:00
|
|
|
int nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync);
|
2012-07-17 04:39:15 +08:00
|
|
|
loff_t nfs_file_llseek(struct file *, loff_t, int);
|
2014-04-03 08:14:12 +08:00
|
|
|
ssize_t nfs_file_read(struct kiocb *, struct iov_iter *);
|
2012-07-17 04:39:15 +08:00
|
|
|
int nfs_file_mmap(struct file *, struct vm_area_struct *);
|
2014-04-04 02:07:25 +08:00
|
|
|
ssize_t nfs_file_write(struct kiocb *, struct iov_iter *);
|
2012-07-17 04:39:15 +08:00
|
|
|
int nfs_file_release(struct inode *, struct file *);
|
|
|
|
int nfs_lock(struct file *, int, struct file_lock *);
|
|
|
|
int nfs_flock(struct file *, int, struct file_lock *);
|
|
|
|
int nfs_check_flags(int);
|
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
/* inode.c */
|
2008-02-20 09:04:22 +08:00
|
|
|
extern struct workqueue_struct *nfsiod_workqueue;
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
extern struct inode *nfs_alloc_inode(struct super_block *sb);
|
2019-04-16 08:19:40 +08:00
|
|
|
extern void nfs_free_inode(struct inode *);
|
2010-03-05 16:21:37 +08:00
|
|
|
extern int nfs_write_inode(struct inode *, struct writeback_control *);
|
2012-12-15 03:36:36 +08:00
|
|
|
extern int nfs_drop_inode(struct inode *);
|
2012-07-31 04:05:21 +08:00
|
|
|
extern void nfs_clear_inode(struct inode *);
|
2010-06-08 02:34:48 +08:00
|
|
|
extern void nfs_evict_inode(struct inode *);
|
2008-06-12 05:39:04 +08:00
|
|
|
void nfs_zap_acl_cache(struct inode *inode);
|
2016-12-09 07:18:38 +08:00
|
|
|
extern bool nfs_check_cache_invalid(struct inode *, unsigned long);
|
2015-12-14 05:11:16 +08:00
|
|
|
extern int nfs_wait_bit_killable(struct wait_bit_key *key, int mode);
|
2017-11-02 23:27:44 +08:00
|
|
|
extern int nfs_wait_atomic_killable(atomic_t *p, unsigned int mode);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
|
|
|
/* super.c */
|
2012-07-31 04:05:20 +08:00
|
|
|
extern const struct super_operations nfs_sops;
|
2013-10-19 03:15:19 +08:00
|
|
|
bool nfs_auth_info_match(const struct nfs_auth_info *, rpc_authflavor_t);
|
2019-12-10 20:31:13 +08:00
|
|
|
int nfs_try_get_tree(struct fs_context *);
|
|
|
|
int nfs_get_tree_common(struct fs_context *);
|
2012-07-17 04:39:20 +08:00
|
|
|
void nfs_kill_super(struct super_block *);
|
2006-07-02 23:29:26 +08:00
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
extern struct rpc_stat nfs_rpcstat;
|
2006-07-02 23:29:26 +08:00
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
extern int __init register_nfs_fs(void);
|
|
|
|
extern void __exit unregister_nfs_fs(void);
|
2015-02-06 04:13:24 +08:00
|
|
|
extern bool nfs_sb_active(struct super_block *sb);
|
2008-07-28 06:19:01 +08:00
|
|
|
extern void nfs_sb_deactive(struct super_block *sb);
|
2020-02-27 08:16:09 +08:00
|
|
|
extern int nfs_client_for_each_server(struct nfs_client *clp,
|
|
|
|
int (*fn)(struct nfs_server *, void *),
|
|
|
|
void *data);
|
2016-06-04 05:07:19 +08:00
|
|
|
/* io.c */
|
|
|
|
extern void nfs_start_io_read(struct inode *inode);
|
|
|
|
extern void nfs_end_io_read(struct inode *inode);
|
|
|
|
extern void nfs_start_io_write(struct inode *inode);
|
|
|
|
extern void nfs_end_io_write(struct inode *inode);
|
|
|
|
extern void nfs_start_io_direct(struct inode *inode);
|
|
|
|
extern void nfs_end_io_direct(struct inode *inode);
|
|
|
|
|
2016-06-26 05:24:46 +08:00
|
|
|
static inline bool nfs_file_io_is_buffered(struct nfs_inode *nfsi)
|
|
|
|
{
|
|
|
|
return test_bit(NFS_INO_ODIRECT, &nfsi->flags) == 0;
|
|
|
|
}
|
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
/* namespace.c */
|
2012-10-22 02:23:52 +08:00
|
|
|
#define NFS_PATH_CANONICAL 1
|
2011-03-16 18:26:11 +08:00
|
|
|
extern char *nfs_path(char **p, struct dentry *dentry,
|
2012-10-22 02:23:52 +08:00
|
|
|
char *buffer, ssize_t buflen, unsigned flags);
|
2011-01-15 02:45:42 +08:00
|
|
|
extern struct vfsmount *nfs_d_automount(struct path *path);
|
2019-12-10 20:31:13 +08:00
|
|
|
int nfs_submount(struct fs_context *, struct nfs_server *);
|
|
|
|
int nfs_do_submount(struct fs_context *);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
NFS: Share NFS superblocks per-protocol per-server per-FSID
The attached patch makes NFS share superblocks between mounts from the same
server and FSID over the same protocol.
It does this by creating each superblock with a false root and returning the
real root dentry in the vfsmount presented by get_sb(). The root dentry set
starts off as an anonymous dentry if we don't already have the dentry for its
inode, otherwise it simply returns the dentry we already have.
We may thus end up with several trees of dentries in the superblock, and if at
some later point one of anonymous tree roots is discovered by normal filesystem
activity to be located in another tree within the superblock, the anonymous
root is named and materialises attached to the second tree at the appropriate
point.
Why do it this way? Why not pass an extra argument to the mount() syscall to
indicate the subpath and then pathwalk from the server root to the desired
directory? You can't guarantee this will work for two reasons:
(1) The root and intervening nodes may not be accessible to the client.
With NFS2 and NFS3, for instance, mountd is called on the server to get
the filehandle for the tip of a path. mountd won't give us handles for
anything we don't have permission to access, and so we can't set up NFS
inodes for such nodes, and so can't easily set up dentries (we'd have to
have ghost inodes or something).
With this patch we don't actually create dentries until we get handles
from the server that we can use to set up their inodes, and we don't
actually bind them into the tree until we know for sure where they go.
(2) Inaccessible symbolic links.
If we're asked to mount two exports from the server, eg:
mount warthog:/warthog/aaa/xxx /mmm
mount warthog:/warthog/bbb/yyy /nnn
We may not be able to access anything nearer the root than xxx and yyy,
but we may find out later that /mmm/www/yyy, say, is actually the same
directory as the one mounted on /nnn. What we might then find out, for
example, is that /warthog/bbb was actually a symbolic link to
/warthog/aaa/xxx/www, but we can't actually determine that by talking to
the server until /warthog is made available by NFS.
This would lead to having constructed an errneous dentry tree which we
can't easily fix. We can end up with a dentry marked as a directory when
it should actually be a symlink, or we could end up with an apparently
hardlinked directory.
With this patch we need not make assumptions about the type of a dentry
for which we can't retrieve information, nor need we assume we know its
place in the grand scheme of things until we actually see that place.
This patch reduces the possibility of aliasing in the inode and page caches for
inodes that may be accessed by more than one NFS export. It also reduces the
number of superblocks required for NFS where there are many NFS exports being
used from a server (home directory server + autofs for example).
This in turn makes it simpler to do local caching of network filesystems, as it
can then be guaranteed that there won't be links from multiple inodes in
separate superblocks to the same cache file.
Obviously, cache aliasing between different levels of NFS protocol could still
be a problem, but at least that gives us another key to use when indexing the
cache.
This patch makes the following changes:
(1) The server record construction/destruction has been abstracted out into
its own set of functions to make things easier to get right. These have
been moved into fs/nfs/client.c.
All the code in fs/nfs/client.c has to do with the management of
connections to servers, and doesn't touch superblocks in any way; the
remaining code in fs/nfs/super.c has to do with VFS superblock management.
(2) The sequence of events undertaken by NFS mount is now reordered:
(a) A volume representation (struct nfs_server) is allocated.
(b) A server representation (struct nfs_client) is acquired. This may be
allocated or shared, and is keyed on server address, port and NFS
version.
(c) If allocated, the client representation is initialised. The state
member variable of nfs_client is used to prevent a race during
initialisation from two mounts.
(d) For NFS4 a simple pathwalk is performed, walking from FH to FH to find
the root filehandle for the mount (fs/nfs/getroot.c). For NFS2/3 we
are given the root FH in advance.
(e) The volume FSID is probed for on the root FH.
(f) The volume representation is initialised from the FSINFO record
retrieved on the root FH.
(g) sget() is called to acquire a superblock. This may be allocated or
shared, keyed on client pointer and FSID.
(h) If allocated, the superblock is initialised.
(i) If the superblock is shared, then the new nfs_server record is
discarded.
(j) The root dentry for this mount is looked up from the root FH.
(k) The root dentry for this mount is assigned to the vfsmount.
(3) nfs_readdir_lookup() creates dentries for each of the entries readdir()
returns; this function now attaches disconnected trees from alternate
roots that happen to be discovered attached to a directory being read (in
the same way nfs_lookup() is made to do for lookup ops).
The new d_materialise_unique() function is now used to do this, thus
permitting the whole thing to be done under one set of locks, and thus
avoiding any race between mount and lookup operations on the same
directory.
(4) The client management code uses a new debug facility: NFSDBG_CLIENT which
is set by echoing 1024 to /proc/net/sunrpc/nfs_debug.
(5) Clone mounts are now called xdev mounts.
(6) Use the dentry passed to the statfs() op as the handle for retrieving fs
statistics rather than the root dentry of the superblock (which is now a
dummy).
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2006-08-23 08:06:13 +08:00
|
|
|
/* getroot.c */
|
2019-12-10 20:31:14 +08:00
|
|
|
extern int nfs_get_root(struct super_block *s, struct fs_context *fc);
|
2012-07-31 04:05:25 +08:00
|
|
|
#if IS_ENABLED(CONFIG_NFS_V4)
|
2013-09-08 00:58:57 +08:00
|
|
|
extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh, bool);
|
2006-08-23 08:06:07 +08:00
|
|
|
#endif
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
|
2012-04-21 02:47:48 +08:00
|
|
|
struct nfs_pgio_completion_ops;
|
2009-04-01 21:22:25 +08:00
|
|
|
/* read.c */
|
2012-04-21 02:47:51 +08:00
|
|
|
extern void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
|
2014-04-16 21:07:22 +08:00
|
|
|
struct inode *inode, bool force_mds,
|
2012-04-21 02:47:51 +08:00
|
|
|
const struct nfs_pgio_completion_ops *compl_ops);
|
2009-04-01 21:22:25 +08:00
|
|
|
extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
|
2011-07-14 03:58:28 +08:00
|
|
|
extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio);
|
2011-06-11 01:30:23 +08:00
|
|
|
|
2012-07-17 04:39:20 +08:00
|
|
|
/* super.c */
|
|
|
|
void nfs_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 *);
|
2019-12-10 20:31:13 +08:00
|
|
|
int nfs_reconfigure(struct fs_context *);
|
2012-07-17 04:39:20 +08:00
|
|
|
|
2009-04-01 21:22:26 +08:00
|
|
|
/* write.c */
|
2012-04-21 02:47:57 +08:00
|
|
|
extern void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
|
2014-04-16 21:07:21 +08:00
|
|
|
struct inode *inode, int ioflags, bool force_mds,
|
2012-04-21 02:47:57 +08:00
|
|
|
const struct nfs_pgio_completion_ops *compl_ops);
|
2011-07-14 03:59:19 +08:00
|
|
|
extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
|
2012-04-21 02:47:39 +08:00
|
|
|
extern void nfs_commit_free(struct nfs_commit_data *p);
|
2009-04-01 21:22:26 +08:00
|
|
|
extern void nfs_write_prepare(struct rpc_task *task, void *calldata);
|
2012-04-21 02:47:39 +08:00
|
|
|
extern void nfs_commit_prepare(struct rpc_task *task, void *calldata);
|
|
|
|
extern int nfs_initiate_commit(struct rpc_clnt *clnt,
|
|
|
|
struct nfs_commit_data *data,
|
2014-06-09 07:10:14 +08:00
|
|
|
const struct nfs_rpc_ops *nfs_ops,
|
2011-03-23 21:27:53 +08:00
|
|
|
const struct rpc_call_ops *call_ops,
|
2012-04-28 05:53:44 +08:00
|
|
|
int how, int flags);
|
2012-04-21 02:47:39 +08:00
|
|
|
extern void nfs_init_commit(struct nfs_commit_data *data,
|
2011-03-23 21:27:53 +08:00
|
|
|
struct list_head *head,
|
2012-04-21 02:47:54 +08:00
|
|
|
struct pnfs_layout_segment *lseg,
|
|
|
|
struct nfs_commit_info *cinfo);
|
2012-04-21 02:47:57 +08:00
|
|
|
int nfs_scan_commit_list(struct list_head *src, struct list_head *dst,
|
|
|
|
struct nfs_commit_info *cinfo, int max);
|
2014-05-06 21:12:34 +08:00
|
|
|
unsigned long nfs_reqs_to_commit(struct nfs_commit_info *);
|
2012-04-21 02:47:57 +08:00
|
|
|
int nfs_scan_commit(struct inode *inode, struct list_head *dst,
|
|
|
|
struct nfs_commit_info *cinfo);
|
|
|
|
void nfs_mark_request_commit(struct nfs_page *req,
|
|
|
|
struct pnfs_layout_segment *lseg,
|
2014-09-06 06:20:21 +08:00
|
|
|
struct nfs_commit_info *cinfo,
|
|
|
|
u32 ds_commit_idx);
|
2014-06-09 23:48:36 +08:00
|
|
|
int nfs_write_need_commit(struct nfs_pgio_header *);
|
2015-02-27 06:36:09 +08:00
|
|
|
void nfs_writeback_update_inode(struct nfs_pgio_header *hdr);
|
2012-04-21 02:47:57 +08:00
|
|
|
int nfs_generic_commit_list(struct inode *inode, struct list_head *head,
|
|
|
|
int how, struct nfs_commit_info *cinfo);
|
2011-03-23 21:27:53 +08:00
|
|
|
void nfs_retry_commit(struct list_head *page_list,
|
2012-04-21 02:47:53 +08:00
|
|
|
struct pnfs_layout_segment *lseg,
|
2014-09-06 06:20:21 +08:00
|
|
|
struct nfs_commit_info *cinfo,
|
|
|
|
u32 ds_commit_idx);
|
2012-04-21 02:47:39 +08:00
|
|
|
void nfs_commitdata_release(struct nfs_commit_data *data);
|
2016-01-16 05:54:15 +08:00
|
|
|
void nfs_request_add_commit_list(struct nfs_page *req,
|
2012-04-21 02:47:53 +08:00
|
|
|
struct nfs_commit_info *cinfo);
|
2015-08-01 04:24:30 +08:00
|
|
|
void nfs_request_add_commit_list_locked(struct nfs_page *req,
|
|
|
|
struct list_head *dst,
|
|
|
|
struct nfs_commit_info *cinfo);
|
2012-04-21 02:47:53 +08:00
|
|
|
void nfs_request_remove_commit_list(struct nfs_page *req,
|
|
|
|
struct nfs_commit_info *cinfo);
|
|
|
|
void nfs_init_cinfo(struct nfs_commit_info *cinfo,
|
|
|
|
struct inode *inode,
|
|
|
|
struct nfs_direct_req *dreq);
|
2013-08-14 23:59:16 +08:00
|
|
|
int nfs_key_timeout_notify(struct file *filp, struct inode *inode);
|
sunrpc: move NO_CRKEY_TIMEOUT to the auth->au_flags
A generic_cred can be used to look up a unx_cred or a gss_cred, so it's
not really safe to use the the generic_cred->acred->ac_flags to store
the NO_CRKEY_TIMEOUT flag. A lookup for a unx_cred triggered while the
KEY_EXPIRE_SOON flag is already set will cause both NO_CRKEY_TIMEOUT and
KEY_EXPIRE_SOON to be set in the ac_flags, leaving the user associated
with the auth_cred to be in a state where they're perpetually doing 4K
NFS_FILE_SYNC writes.
This can be reproduced as follows:
1. Mount two NFS filesystems, one with sec=krb5 and one with sec=sys.
They do not need to be the same export, nor do they even need to be from
the same NFS server. Also, v3 is fine.
$ sudo mount -o v3,sec=krb5 server1:/export /mnt/krb5
$ sudo mount -o v3,sec=sys server2:/export /mnt/sys
2. As the normal user, before accessing the kerberized mount, kinit with
a short lifetime (but not so short that renewing the ticket would leave
you within the 4-minute window again by the time the original ticket
expires), e.g.
$ kinit -l 10m -r 60m
3. Do some I/O to the kerberized mount and verify that the writes are
wsize, UNSTABLE:
$ dd if=/dev/zero of=/mnt/krb5/file bs=1M count=1
4. Wait until you're within 4 minutes of key expiry, then do some more
I/O to the kerberized mount to ensure that RPC_CRED_KEY_EXPIRE_SOON gets
set. Verify that the writes are 4K, FILE_SYNC:
$ dd if=/dev/zero of=/mnt/krb5/file bs=1M count=1
5. Now do some I/O to the sec=sys mount. This will cause
RPC_CRED_NO_CRKEY_TIMEOUT to be set:
$ dd if=/dev/zero of=/mnt/sys/file bs=1M count=1
6. Writes for that user will now be permanently 4K, FILE_SYNC for that
user, regardless of which mount is being written to, until you reboot
the client. Renewing the kerberos ticket (assuming it hasn't already
expired) will have no effect. Grabbing a new kerberos ticket at this
point will have no effect either.
Move the flag to the auth->au_flags field (which is currently unused)
and rename it slightly to reflect that it's no longer associated with
the auth_cred->ac_flags. Add the rpc_auth to the arg list of
rpcauth_cred_key_to_expire and check the au_flags there too. Finally,
add the inode to the arg list of nfs_ctx_key_to_expire so we can
determine the rpc_auth to pass to rpcauth_cred_key_to_expire.
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
2016-06-08 03:14:48 +08:00
|
|
|
bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx, struct inode *inode);
|
2014-09-19 22:55:07 +08:00
|
|
|
void nfs_pageio_stop_mirroring(struct nfs_pageio_descriptor *pgio);
|
2011-03-23 21:27:53 +08:00
|
|
|
|
2016-06-26 06:12:03 +08:00
|
|
|
int nfs_filemap_write_and_wait_range(struct address_space *mapping,
|
|
|
|
loff_t lstart, loff_t lend);
|
|
|
|
|
2016-06-02 09:42:32 +08:00
|
|
|
#ifdef CONFIG_NFS_V4_1
|
|
|
|
static inline
|
|
|
|
void nfs_clear_pnfs_ds_commit_verifiers(struct pnfs_ds_commit_info *cinfo)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < cinfo->nbuckets; i++)
|
|
|
|
cinfo->buckets[i].direct_verf.committed = NFS_INVALID_STABLE_HOW;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
static inline
|
|
|
|
void nfs_clear_pnfs_ds_commit_verifiers(struct pnfs_ds_commit_info *cinfo)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-08-10 20:54:13 +08:00
|
|
|
#ifdef CONFIG_MIGRATION
|
|
|
|
extern int nfs_migrate_page(struct address_space *,
|
2012-01-13 09:19:43 +08:00
|
|
|
struct page *, struct page *, enum migrate_mode);
|
2009-08-10 20:54:13 +08:00
|
|
|
#endif
|
2009-04-01 21:22:26 +08:00
|
|
|
|
2016-06-02 09:32:24 +08:00
|
|
|
static inline int
|
|
|
|
nfs_write_verifier_cmp(const struct nfs_write_verifier *v1,
|
|
|
|
const struct nfs_write_verifier *v2)
|
|
|
|
{
|
|
|
|
return memcmp(v1->data, v2->data, sizeof(v1->data));
|
|
|
|
}
|
|
|
|
|
2020-03-21 21:27:46 +08:00
|
|
|
static inline bool
|
|
|
|
nfs_write_match_verf(const struct nfs_writeverf *verf,
|
|
|
|
struct nfs_page *req)
|
|
|
|
{
|
|
|
|
return verf->committed > NFS_UNSTABLE &&
|
|
|
|
!nfs_write_verifier_cmp(&req->wb_verf, &verf->verifier);
|
|
|
|
}
|
|
|
|
|
2014-03-17 19:06:55 +08:00
|
|
|
/* unlink.c */
|
|
|
|
extern struct rpc_task *
|
|
|
|
nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
|
|
|
|
struct dentry *old_dentry, struct dentry *new_dentry,
|
|
|
|
void (*complete)(struct rpc_task *, struct nfs_renamedata *));
|
|
|
|
extern int nfs_sillyrename(struct inode *dir, struct dentry *dentry);
|
|
|
|
|
2012-04-21 02:47:57 +08:00
|
|
|
/* direct.c */
|
|
|
|
void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo,
|
|
|
|
struct nfs_direct_req *dreq);
|
2012-09-25 14:55:57 +08:00
|
|
|
extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq);
|
2012-04-21 02:47:57 +08:00
|
|
|
|
2009-04-01 21:22:03 +08:00
|
|
|
/* nfs4proc.c */
|
2012-05-22 10:45:59 +08:00
|
|
|
extern struct nfs_client *nfs4_init_client(struct nfs_client *clp,
|
2016-06-23 02:13:12 +08:00
|
|
|
const struct nfs_client_initdata *);
|
2012-09-15 05:24:32 +08:00
|
|
|
extern int nfs40_walk_client_list(struct nfs_client *clp,
|
|
|
|
struct nfs_client **result,
|
2018-12-03 08:30:31 +08:00
|
|
|
const struct cred *cred);
|
2012-09-15 05:24:32 +08:00
|
|
|
extern int nfs41_walk_client_list(struct nfs_client *clp,
|
|
|
|
struct nfs_client **result,
|
2018-12-03 08:30:31 +08:00
|
|
|
const struct cred *cred);
|
2018-12-19 14:59:57 +08:00
|
|
|
extern void nfs4_test_session_trunk(struct rpc_clnt *clnt,
|
|
|
|
struct rpc_xprt *xprt,
|
|
|
|
void *data);
|
2009-04-01 21:22:03 +08:00
|
|
|
|
2015-02-06 04:13:24 +08:00
|
|
|
static inline struct inode *nfs_igrab_and_active(struct inode *inode)
|
|
|
|
{
|
|
|
|
inode = igrab(inode);
|
|
|
|
if (inode != NULL && !nfs_sb_active(inode->i_sb)) {
|
|
|
|
iput(inode);
|
|
|
|
inode = NULL;
|
|
|
|
}
|
|
|
|
return inode;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void nfs_iput_and_deactive(struct inode *inode)
|
|
|
|
{
|
|
|
|
if (inode != NULL) {
|
|
|
|
struct super_block *sb = inode->i_sb;
|
|
|
|
|
|
|
|
iput(inode);
|
|
|
|
nfs_sb_deactive(sb);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
/*
|
|
|
|
* Determine the device name as a string
|
|
|
|
*/
|
2011-03-16 18:26:11 +08:00
|
|
|
static inline char *nfs_devname(struct dentry *dentry,
|
NFS: Share NFS superblocks per-protocol per-server per-FSID
The attached patch makes NFS share superblocks between mounts from the same
server and FSID over the same protocol.
It does this by creating each superblock with a false root and returning the
real root dentry in the vfsmount presented by get_sb(). The root dentry set
starts off as an anonymous dentry if we don't already have the dentry for its
inode, otherwise it simply returns the dentry we already have.
We may thus end up with several trees of dentries in the superblock, and if at
some later point one of anonymous tree roots is discovered by normal filesystem
activity to be located in another tree within the superblock, the anonymous
root is named and materialises attached to the second tree at the appropriate
point.
Why do it this way? Why not pass an extra argument to the mount() syscall to
indicate the subpath and then pathwalk from the server root to the desired
directory? You can't guarantee this will work for two reasons:
(1) The root and intervening nodes may not be accessible to the client.
With NFS2 and NFS3, for instance, mountd is called on the server to get
the filehandle for the tip of a path. mountd won't give us handles for
anything we don't have permission to access, and so we can't set up NFS
inodes for such nodes, and so can't easily set up dentries (we'd have to
have ghost inodes or something).
With this patch we don't actually create dentries until we get handles
from the server that we can use to set up their inodes, and we don't
actually bind them into the tree until we know for sure where they go.
(2) Inaccessible symbolic links.
If we're asked to mount two exports from the server, eg:
mount warthog:/warthog/aaa/xxx /mmm
mount warthog:/warthog/bbb/yyy /nnn
We may not be able to access anything nearer the root than xxx and yyy,
but we may find out later that /mmm/www/yyy, say, is actually the same
directory as the one mounted on /nnn. What we might then find out, for
example, is that /warthog/bbb was actually a symbolic link to
/warthog/aaa/xxx/www, but we can't actually determine that by talking to
the server until /warthog is made available by NFS.
This would lead to having constructed an errneous dentry tree which we
can't easily fix. We can end up with a dentry marked as a directory when
it should actually be a symlink, or we could end up with an apparently
hardlinked directory.
With this patch we need not make assumptions about the type of a dentry
for which we can't retrieve information, nor need we assume we know its
place in the grand scheme of things until we actually see that place.
This patch reduces the possibility of aliasing in the inode and page caches for
inodes that may be accessed by more than one NFS export. It also reduces the
number of superblocks required for NFS where there are many NFS exports being
used from a server (home directory server + autofs for example).
This in turn makes it simpler to do local caching of network filesystems, as it
can then be guaranteed that there won't be links from multiple inodes in
separate superblocks to the same cache file.
Obviously, cache aliasing between different levels of NFS protocol could still
be a problem, but at least that gives us another key to use when indexing the
cache.
This patch makes the following changes:
(1) The server record construction/destruction has been abstracted out into
its own set of functions to make things easier to get right. These have
been moved into fs/nfs/client.c.
All the code in fs/nfs/client.c has to do with the management of
connections to servers, and doesn't touch superblocks in any way; the
remaining code in fs/nfs/super.c has to do with VFS superblock management.
(2) The sequence of events undertaken by NFS mount is now reordered:
(a) A volume representation (struct nfs_server) is allocated.
(b) A server representation (struct nfs_client) is acquired. This may be
allocated or shared, and is keyed on server address, port and NFS
version.
(c) If allocated, the client representation is initialised. The state
member variable of nfs_client is used to prevent a race during
initialisation from two mounts.
(d) For NFS4 a simple pathwalk is performed, walking from FH to FH to find
the root filehandle for the mount (fs/nfs/getroot.c). For NFS2/3 we
are given the root FH in advance.
(e) The volume FSID is probed for on the root FH.
(f) The volume representation is initialised from the FSINFO record
retrieved on the root FH.
(g) sget() is called to acquire a superblock. This may be allocated or
shared, keyed on client pointer and FSID.
(h) If allocated, the superblock is initialised.
(i) If the superblock is shared, then the new nfs_server record is
discarded.
(j) The root dentry for this mount is looked up from the root FH.
(k) The root dentry for this mount is assigned to the vfsmount.
(3) nfs_readdir_lookup() creates dentries for each of the entries readdir()
returns; this function now attaches disconnected trees from alternate
roots that happen to be discovered attached to a directory being read (in
the same way nfs_lookup() is made to do for lookup ops).
The new d_materialise_unique() function is now used to do this, thus
permitting the whole thing to be done under one set of locks, and thus
avoiding any race between mount and lookup operations on the same
directory.
(4) The client management code uses a new debug facility: NFSDBG_CLIENT which
is set by echoing 1024 to /proc/net/sunrpc/nfs_debug.
(5) Clone mounts are now called xdev mounts.
(6) Use the dentry passed to the statfs() op as the handle for retrieving fs
statistics rather than the root dentry of the superblock (which is now a
dummy).
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2006-08-23 08:06:13 +08:00
|
|
|
char *buffer, ssize_t buflen)
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
{
|
2011-03-16 18:26:11 +08:00
|
|
|
char *dummy;
|
2012-10-22 02:23:52 +08:00
|
|
|
return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL);
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine the actual block size (and log2 thereof)
|
|
|
|
*/
|
|
|
|
static inline
|
|
|
|
unsigned long nfs_block_bits(unsigned long bsize, unsigned char *nrbitsp)
|
|
|
|
{
|
|
|
|
/* make sure blocksize is a power of two */
|
|
|
|
if ((bsize & (bsize - 1)) || nrbitsp) {
|
|
|
|
unsigned char nrbits;
|
|
|
|
|
|
|
|
for (nrbits = 31; nrbits && !(bsize & (1 << nrbits)); nrbits--)
|
|
|
|
;
|
|
|
|
bsize = 1 << nrbits;
|
|
|
|
if (nrbitsp)
|
|
|
|
*nrbitsp = nrbits;
|
|
|
|
}
|
|
|
|
|
|
|
|
return bsize;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Calculate the number of 512byte blocks used.
|
|
|
|
*/
|
2007-07-02 00:12:19 +08:00
|
|
|
static inline blkcnt_t nfs_calc_block_size(u64 tsize)
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
{
|
2007-07-02 00:12:19 +08:00
|
|
|
blkcnt_t used = (tsize + 511) >> 9;
|
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached
patch splits it up into a number of files:
(*) fs/nfs/inode.c
Strictly inode specific functions.
(*) fs/nfs/super.c
Superblock management functions for NFS and NFS4, normal access, clones
and referrals. The NFS4 superblock functions _could_ move out into a
separate conditionally compiled file, but it's probably not worth it as
there're so many common bits.
(*) fs/nfs/namespace.c
Some namespace-specific functions have been moved here.
(*) fs/nfs/nfs4namespace.c
NFS4-specific namespace functions (this could be merged into the previous
file). This file is conditionally compiled.
(*) fs/nfs/internal.h
Inter-file declarations, plus a few simple utility functions moved from
fs/nfs/inode.c.
Additionally, all the in-.c-file externs have been moved here, and those
files they were moved from now includes this file.
For the most part, the functions have not been changed, only some multiplexor
functions have changed significantly.
I've also:
(*) Added some extra banner comments above some functions.
(*) Rearranged the function order within the files to be more logical and
better grouped (IMO), though someone may prefer a different order.
(*) Reduced the number of #ifdefs in .c files.
(*) Added missing __init and __exit directives.
Signed-Off-By: David Howells <dhowells@redhat.com>
2006-06-09 21:34:33 +08:00
|
|
|
return (used > ULONG_MAX) ? ULONG_MAX : used;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Compute and set NFS server blocksize
|
|
|
|
*/
|
|
|
|
static inline
|
|
|
|
unsigned long nfs_block_size(unsigned long bsize, unsigned char *nrbitsp)
|
|
|
|
{
|
|
|
|
if (bsize < NFS_MIN_FILE_IO_SIZE)
|
|
|
|
bsize = NFS_DEF_FILE_IO_SIZE;
|
|
|
|
else if (bsize >= NFS_MAX_FILE_IO_SIZE)
|
|
|
|
bsize = NFS_MAX_FILE_IO_SIZE;
|
|
|
|
|
|
|
|
return nfs_block_bits(bsize, nrbitsp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine the maximum file size for a superblock
|
|
|
|
*/
|
|
|
|
static inline
|
|
|
|
void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize)
|
|
|
|
{
|
|
|
|
sb->s_maxbytes = (loff_t)maxfilesize;
|
|
|
|
if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0)
|
|
|
|
sb->s_maxbytes = MAX_LFS_FILESIZE;
|
|
|
|
}
|
2006-12-05 13:35:38 +08:00
|
|
|
|
2015-02-14 05:19:53 +08:00
|
|
|
/*
|
|
|
|
* Record the page as unstable and mark its inode as dirty.
|
|
|
|
*/
|
|
|
|
static inline
|
2015-08-01 04:24:30 +08:00
|
|
|
void nfs_mark_page_unstable(struct page *page, struct nfs_commit_info *cinfo)
|
2015-02-14 05:19:53 +08:00
|
|
|
{
|
2015-08-01 04:24:30 +08:00
|
|
|
if (!cinfo->dreq) {
|
|
|
|
struct inode *inode = page_file_mapping(page)->host;
|
2015-02-14 05:19:53 +08:00
|
|
|
|
2016-07-29 06:46:20 +08:00
|
|
|
inc_node_page_state(page, NR_UNSTABLE_NFS);
|
2015-08-01 04:24:30 +08:00
|
|
|
inc_wb_stat(&inode_to_bdi(inode)->wb, WB_RECLAIMABLE);
|
|
|
|
__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
|
|
|
|
}
|
2015-02-14 05:19:53 +08:00
|
|
|
}
|
|
|
|
|
2006-12-05 13:35:38 +08:00
|
|
|
/*
|
|
|
|
* Determine the number of bytes of data the page contains
|
|
|
|
*/
|
|
|
|
static inline
|
|
|
|
unsigned int nfs_page_length(struct page *page)
|
|
|
|
{
|
2012-08-01 07:45:06 +08:00
|
|
|
loff_t i_size = i_size_read(page_file_mapping(page)->host);
|
2006-12-05 13:35:38 +08:00
|
|
|
|
|
|
|
if (i_size > 0) {
|
2016-10-08 08:00:24 +08:00
|
|
|
pgoff_t index = page_index(page);
|
mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros
PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
ago with promise that one day it will be possible to implement page
cache with bigger chunks than PAGE_SIZE.
This promise never materialized. And unlikely will.
We have many places where PAGE_CACHE_SIZE assumed to be equal to
PAGE_SIZE. And it's constant source of confusion on whether
PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
especially on the border between fs and mm.
Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
breakage to be doable.
Let's stop pretending that pages in page cache are special. They are
not.
The changes are pretty straight-forward:
- <foo> << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- <foo> >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};
- page_cache_get() -> get_page();
- page_cache_release() -> put_page();
This patch contains automated changes generated with coccinelle using
script below. For some reason, coccinelle doesn't patch header files.
I've called spatch for them manually.
The only adjustment after coccinelle is revert of changes to
PAGE_CAHCE_ALIGN definition: we are going to drop it later.
There are few places in the code where coccinelle didn't reach. I'll
fix them manually in a separate patch. Comments and documentation also
will be addressed with the separate patch.
virtual patch
@@
expression E;
@@
- E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
expression E;
@@
- E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
@@
- PAGE_CACHE_SHIFT
+ PAGE_SHIFT
@@
@@
- PAGE_CACHE_SIZE
+ PAGE_SIZE
@@
@@
- PAGE_CACHE_MASK
+ PAGE_MASK
@@
expression E;
@@
- PAGE_CACHE_ALIGN(E)
+ PAGE_ALIGN(E)
@@
expression E;
@@
- page_cache_get(E)
+ get_page(E)
@@
expression E;
@@
- page_cache_release(E)
+ put_page(E)
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-04-01 20:29:47 +08:00
|
|
|
pgoff_t end_index = (i_size - 1) >> PAGE_SHIFT;
|
2016-10-08 08:00:24 +08:00
|
|
|
if (index < end_index)
|
mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros
PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
ago with promise that one day it will be possible to implement page
cache with bigger chunks than PAGE_SIZE.
This promise never materialized. And unlikely will.
We have many places where PAGE_CACHE_SIZE assumed to be equal to
PAGE_SIZE. And it's constant source of confusion on whether
PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
especially on the border between fs and mm.
Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
breakage to be doable.
Let's stop pretending that pages in page cache are special. They are
not.
The changes are pretty straight-forward:
- <foo> << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- <foo> >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};
- page_cache_get() -> get_page();
- page_cache_release() -> put_page();
This patch contains automated changes generated with coccinelle using
script below. For some reason, coccinelle doesn't patch header files.
I've called spatch for them manually.
The only adjustment after coccinelle is revert of changes to
PAGE_CAHCE_ALIGN definition: we are going to drop it later.
There are few places in the code where coccinelle didn't reach. I'll
fix them manually in a separate patch. Comments and documentation also
will be addressed with the separate patch.
virtual patch
@@
expression E;
@@
- E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
expression E;
@@
- E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
@@
- PAGE_CACHE_SHIFT
+ PAGE_SHIFT
@@
@@
- PAGE_CACHE_SIZE
+ PAGE_SIZE
@@
@@
- PAGE_CACHE_MASK
+ PAGE_MASK
@@
expression E;
@@
- PAGE_CACHE_ALIGN(E)
+ PAGE_ALIGN(E)
@@
expression E;
@@
- page_cache_get(E)
+ get_page(E)
@@
expression E;
@@
- page_cache_release(E)
+ put_page(E)
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-04-01 20:29:47 +08:00
|
|
|
return PAGE_SIZE;
|
2016-10-08 08:00:24 +08:00
|
|
|
if (index == end_index)
|
mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros
PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
ago with promise that one day it will be possible to implement page
cache with bigger chunks than PAGE_SIZE.
This promise never materialized. And unlikely will.
We have many places where PAGE_CACHE_SIZE assumed to be equal to
PAGE_SIZE. And it's constant source of confusion on whether
PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
especially on the border between fs and mm.
Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
breakage to be doable.
Let's stop pretending that pages in page cache are special. They are
not.
The changes are pretty straight-forward:
- <foo> << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- <foo> >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};
- page_cache_get() -> get_page();
- page_cache_release() -> put_page();
This patch contains automated changes generated with coccinelle using
script below. For some reason, coccinelle doesn't patch header files.
I've called spatch for them manually.
The only adjustment after coccinelle is revert of changes to
PAGE_CAHCE_ALIGN definition: we are going to drop it later.
There are few places in the code where coccinelle didn't reach. I'll
fix them manually in a separate patch. Comments and documentation also
will be addressed with the separate patch.
virtual patch
@@
expression E;
@@
- E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
expression E;
@@
- E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
@@
- PAGE_CACHE_SHIFT
+ PAGE_SHIFT
@@
@@
- PAGE_CACHE_SIZE
+ PAGE_SIZE
@@
@@
- PAGE_CACHE_MASK
+ PAGE_MASK
@@
expression E;
@@
- PAGE_CACHE_ALIGN(E)
+ PAGE_ALIGN(E)
@@
expression E;
@@
- page_cache_get(E)
+ get_page(E)
@@
expression E;
@@
- page_cache_release(E)
+ put_page(E)
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-04-01 20:29:47 +08:00
|
|
|
return ((i_size - 1) & ~PAGE_MASK) + 1;
|
2006-12-05 13:35:38 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2007-04-10 21:26:35 +08:00
|
|
|
|
2010-11-21 03:26:44 +08:00
|
|
|
/*
|
|
|
|
* Convert a umode to a dirent->d_type
|
|
|
|
*/
|
|
|
|
static inline
|
|
|
|
unsigned char nfs_umode_to_dtype(umode_t mode)
|
|
|
|
{
|
|
|
|
return (mode >> 12) & 15;
|
|
|
|
}
|
|
|
|
|
2007-04-10 21:26:35 +08:00
|
|
|
/*
|
|
|
|
* Determine the number of pages in an array of length 'len' and
|
|
|
|
* with a base offset of 'base'
|
|
|
|
*/
|
|
|
|
static inline
|
|
|
|
unsigned int nfs_page_array_len(unsigned int base, size_t len)
|
|
|
|
{
|
|
|
|
return ((unsigned long)len + (unsigned long)base +
|
|
|
|
PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
|
|
}
|
2009-12-07 22:00:24 +08:00
|
|
|
|
2012-04-28 01:48:18 +08:00
|
|
|
/*
|
2019-11-12 04:16:23 +08:00
|
|
|
* Convert a struct timespec64 into a 64-bit change attribute
|
2012-04-28 01:48:18 +08:00
|
|
|
*
|
2019-11-12 04:16:23 +08:00
|
|
|
* This does approximately the same thing as timespec64_to_ns(),
|
2012-04-28 01:48:18 +08:00
|
|
|
* but for calculation efficiency, we multiply the seconds by
|
|
|
|
* 1024*1024*1024.
|
|
|
|
*/
|
|
|
|
static inline
|
2019-10-05 04:38:56 +08:00
|
|
|
u64 nfs_timespec_to_change_attr(const struct timespec64 *ts)
|
2012-04-28 01:48:18 +08:00
|
|
|
{
|
|
|
|
return ((u64)ts->tv_sec << 30) + ts->tv_nsec;
|
|
|
|
}
|
2013-08-13 04:06:31 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_CRC32
|
|
|
|
/**
|
|
|
|
* nfs_fhandle_hash - calculate the crc32 hash for the filehandle
|
|
|
|
* @fh - pointer to filehandle
|
|
|
|
*
|
|
|
|
* returns a crc32 hash for the filehandle that is compatible with
|
|
|
|
* the one displayed by "wireshark".
|
|
|
|
*/
|
|
|
|
static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
|
|
|
|
{
|
|
|
|
return ~crc32_le(0xFFFFFFFF, &fh->data[0], fh->size);
|
|
|
|
}
|
Adding stateid information to tracepoints
Operations to which stateid information is added:
close, delegreturn, open, read, setattr, layoutget, layoutcommit, test_stateid,
write, lock, locku, lockt
Format is "stateid=<seqid>:<crc32 hash stateid.other>", also "openstateid=",
"layoutstateid=", and "lockstateid=" for open_file, layoutget, set_lock
tracepoints.
New function is added to internal.h, nfs_stateid_hash(), to compute the hash
trace_nfs4_setattr() is moved from nfs4_do_setattr() to _nfs4_do_setattr()
to get access to stateid.
trace_nfs4_setattr and trace_nfs4_delegreturn are changed from INODE_EVENT
to new event type, INODE_STATEID_EVENT which is same as INODE_EVENT but adds
stateid information
for locking tracepoints, moved trace_nfs4_set_lock() into _nfs4_do_setlk()
to get access to stateid information, and removed trace_nfs4_lock_reclaim(),
trace_nfs4_lock_expired() as they call into _nfs4_do_setlk() and both were
previously same LOCK_EVENT type.
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
2015-11-25 02:29:41 +08:00
|
|
|
static inline u32 nfs_stateid_hash(const nfs4_stateid *stateid)
|
|
|
|
{
|
|
|
|
return ~crc32_le(0xFFFFFFFF, &stateid->other[0],
|
|
|
|
NFS4_STATEID_OTHER_SIZE);
|
|
|
|
}
|
2013-08-13 04:06:31 +08:00
|
|
|
#else
|
|
|
|
static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
Adding stateid information to tracepoints
Operations to which stateid information is added:
close, delegreturn, open, read, setattr, layoutget, layoutcommit, test_stateid,
write, lock, locku, lockt
Format is "stateid=<seqid>:<crc32 hash stateid.other>", also "openstateid=",
"layoutstateid=", and "lockstateid=" for open_file, layoutget, set_lock
tracepoints.
New function is added to internal.h, nfs_stateid_hash(), to compute the hash
trace_nfs4_setattr() is moved from nfs4_do_setattr() to _nfs4_do_setattr()
to get access to stateid.
trace_nfs4_setattr and trace_nfs4_delegreturn are changed from INODE_EVENT
to new event type, INODE_STATEID_EVENT which is same as INODE_EVENT but adds
stateid information
for locking tracepoints, moved trace_nfs4_set_lock() into _nfs4_do_setlk()
to get access to stateid information, and removed trace_nfs4_lock_reclaim(),
trace_nfs4_lock_expired() as they call into _nfs4_do_setlk() and both were
previously same LOCK_EVENT type.
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
2015-11-25 02:29:41 +08:00
|
|
|
static inline u32 nfs_stateid_hash(nfs4_stateid *stateid)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2013-08-13 04:06:31 +08:00
|
|
|
#endif
|
2015-12-05 15:57:31 +08:00
|
|
|
|
|
|
|
static inline bool nfs_error_is_fatal(int err)
|
|
|
|
{
|
|
|
|
switch (err) {
|
|
|
|
case -ERESTARTSYS:
|
2019-01-22 20:39:09 +08:00
|
|
|
case -EINTR:
|
2017-04-27 00:21:49 +08:00
|
|
|
case -EACCES:
|
|
|
|
case -EDQUOT:
|
|
|
|
case -EFBIG:
|
2015-12-05 15:57:31 +08:00
|
|
|
case -EIO:
|
|
|
|
case -ENOSPC:
|
|
|
|
case -EROFS:
|
2017-04-27 00:21:49 +08:00
|
|
|
case -ESTALE:
|
2015-12-05 15:57:31 +08:00
|
|
|
case -E2BIG:
|
2019-02-13 21:29:27 +08:00
|
|
|
case -ENOMEM:
|
2019-04-08 01:58:59 +08:00
|
|
|
case -ETIMEDOUT:
|
2015-12-05 15:57:31 +08:00
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2017-09-11 11:15:50 +08:00
|
|
|
|
2019-08-16 00:26:05 +08:00
|
|
|
static inline bool nfs_error_is_fatal_on_server(int err)
|
|
|
|
{
|
|
|
|
switch (err) {
|
|
|
|
case 0:
|
|
|
|
case -ERESTARTSYS:
|
|
|
|
case -EINTR:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return nfs_error_is_fatal(err);
|
|
|
|
}
|
2019-12-10 20:31:04 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Select between a default port value and a user-specified port value.
|
|
|
|
* If a zero value is set, then autobind will be used.
|
|
|
|
*/
|
|
|
|
static inline void nfs_set_port(struct sockaddr *sap, int *port,
|
|
|
|
const unsigned short default_port)
|
|
|
|
{
|
|
|
|
if (*port == NFS_UNSPEC_PORT)
|
|
|
|
*port = default_port;
|
|
|
|
|
|
|
|
rpc_set_port(sap, *port);
|
|
|
|
}
|