History

Merge tag 'nfs-for-6.19-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client updates from Trond Myklebust: "Bugfixes: - Fix 'nlink' attribute update races when unlinking a file - Add missing initialisers for the directory verifier in various places - Don't regress the NFSv4 open state due to misordered racing replies - Ensure the NFSv4.x callback server uses the correct transport connection - Fix potential use-after-free races when shutting down the NFSv4.x callback server - Fix a pNFS layout commit crash - Assorted fixes to ensure correct propagation of mount options when the client crosses a filesystem boundary and triggers the VFS automount code - More localio fixes Features and cleanups: - Add initial support for basic directory delegations - SunRPC back channel code cleanups" * tag 'nfs-for-6.19-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (24 commits) NFSv4: Handle NFS4ERR_NOTSUPP errors for directory delegations nfs/localio: remove 61 byte hole from needless ____cacheline_aligned nfs/localio: remove alignment size checking in nfs_is_local_dio_possible NFS: Fix up the automount fs_context to use the correct cred NFS: Fix inheritance of the block sizes when automounting NFS: Automounted filesystems should inherit ro,noexec,nodev,sync flags Revert "nfs: ignore SB_RDONLY when mounting nfs" Revert "nfs: clear SB_RDONLY before getting superblock" Revert "nfs: ignore SB_RDONLY when remounting nfs" NFS: Add a module option to disable directory delegations NFS: Shortcut lookup revalidations if we have a directory delegation NFS: Request a directory delegation during RENAME NFS: Request a directory delegation on ACCESS, CREATE, and UNLINK NFS: Add support for sending GDD_GETATTR NFSv4/pNFS: Clear NFS_INO_LAYOUTCOMMIT in pnfs_mark_layout_stateid_invalid NFSv4.1: protect destroying and nullifying bc_serv structure SUNRPC: new helper function for stopping backchannel server SUNRPC: cleanup common code in backchannel request NFSv4.1: pass transport for callback shutdown NFSv4: ensure the open stateid seqid doesn't go backwards ...

Linus Torvalds committed 11 months ago

Commit 6bb34af2 parents d358e52 bd3b04b25 files · +385 −91Browse files

Unified · Split

25 files
  1. fs/nfs/callback.c +2 −2
  2. fs/nfs/callback.h +2 −1
  3. fs/nfs/client.c +17 −4
  4. fs/nfs/delegation.c +8 −0
  5. fs/nfs/delegation.h +13 −0
  6. fs/nfs/dir.c +37 −9
  7. fs/nfs/inode.c +3 −0
  8. fs/nfs/internal.h +1 −2
  9. fs/nfs/localio.c +1 −3
  10. fs/nfs/namespace.c +15 −1
  11. fs/nfs/nfs3proc.c +2 −1
  12. fs/nfs/nfs4client.c +21 −6
  13. fs/nfs/nfs4proc.c +91 −20
  14. fs/nfs/nfs4trace.h +1 −0
  15. fs/nfs/nfs4xdr.c +106 −0
  16. fs/nfs/pnfs.c +1 −0
  17. fs/nfs/proc.c +2 −1
  18. fs/nfs/super.c +3 −30
  19. fs/nfs/unlink.c +2 −1
  20. include/linux/nfs_fs.h +1 −0
  21. include/linux/nfs_fs_sb.h +6 −0
  22. include/linux/nfs_xdr.h +9 −1
  23. include/linux/sunrpc/bc_xprt.h +7 −0
  24. net/sunrpc/backchannel_rqst.c +32 −3
  25. net/sunrpc/xprtrdma/backchannel.c +2 −6
fs/nfs/callback.c+2−2
@@ -258,7 +258,7 @@ err_start: · 257 unmodified lines
258/*258/*
259 * Kill the callback thread if it's no longer being used.259 * Kill the callback thread if it's no longer being used.
260 */260 */
261void nfs_callback_down(int minorversion, struct net *net)261void nfs_callback_down(int minorversion, struct net *net, struct rpc_xprt *xprt)
262{262{
263 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];263 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
264 struct svc_serv *serv;264 struct svc_serv *serv;
@@ -270,7 +270,7 @@ void nfs_callback_down(int minorversion, struct net *net) · 5 unmodified lines
270 if (cb_info->users == 0) {270 if (cb_info->users == 0) {
271 svc_set_num_threads(serv, NULL, 0);271 svc_set_num_threads(serv, NULL, 0);
272 dprintk("nfs_callback_down: service destroyed\n");272 dprintk("nfs_callback_down: service destroyed\n");
273 svc_destroy(&cb_info->serv);273 xprt_svc_destroy_nullify_bc(xprt, &cb_info->serv);
274 }274 }
275 mutex_unlock(&nfs_callback_mutex);275 mutex_unlock(&nfs_callback_mutex);
276}276}
fs/nfs/callback.h+2−1
@@ -188,7 +188,8 @@ extern __be32 nfs4_callback_recall(void *argp, void *resp, · 187 unmodified lines
188 struct cb_process_state *cps);188 struct cb_process_state *cps);
189#if IS_ENABLED(CONFIG_NFS_V4)189#if IS_ENABLED(CONFIG_NFS_V4)
190extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt);190extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt);
191extern void nfs_callback_down(int minorversion, struct net *net);191extern void nfs_callback_down(int minorversion, struct net *net,
192 struct rpc_xprt *xprt);
192#endif /* CONFIG_NFS_V4 */193#endif /* CONFIG_NFS_V4 */
193/*194/*
194 * nfs41: Callbacks are expected to not cause substantial latency,195 * nfs41: Callbacks are expected to not cause substantial latency,
fs/nfs/client.c+17−4
@@ -784,10 +784,18 @@ static int nfs_init_server(struct nfs_server *server, · 783 unmodified lines
784 server->fattr_valid = NFS_ATTR_FATTR_V4;784 server->fattr_valid = NFS_ATTR_FATTR_V4;
785 }785 }
786 786
787 if (ctx->rsize)787 if (ctx->bsize) {
788 server->bsize = ctx->bsize;
789 server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_BSIZE;
790 }
791 if (ctx->rsize) {
788 server->rsize = nfs_io_size(ctx->rsize, clp->cl_proto);792 server->rsize = nfs_io_size(ctx->rsize, clp->cl_proto);
789 if (ctx->wsize)793 server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_RSIZE;
794 }
795 if (ctx->wsize) {
790 server->wsize = nfs_io_size(ctx->wsize, clp->cl_proto);796 server->wsize = nfs_io_size(ctx->wsize, clp->cl_proto);
797 server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_WSIZE;
798 }
791 799
792 server->acregmin = ctx->acregmin * HZ;800 server->acregmin = ctx->acregmin * HZ;
793 server->acregmax = ctx->acregmax * HZ;801 server->acregmax = ctx->acregmax * HZ;
@@ -977,8 +985,13 @@ EXPORT_SYMBOL_GPL(nfs_probe_server); · 183 unmodified lines
977void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)985void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)
978{986{
979 target->flags = source->flags;987 target->flags = source->flags;
980 target->rsize = source->rsize;988 target->automount_inherit = source->automount_inherit;
981 target->wsize = source->wsize;989 if (source->automount_inherit & NFS_AUTOMOUNT_INHERIT_BSIZE)
990 target->bsize = source->bsize;
991 if (source->automount_inherit & NFS_AUTOMOUNT_INHERIT_RSIZE)
992 target->rsize = source->rsize;
993 if (source->automount_inherit & NFS_AUTOMOUNT_INHERIT_WSIZE)
994 target->wsize = source->wsize;
982 target->acregmin = source->acregmin;995 target->acregmin = source->acregmin;
983 target->acregmax = source->acregmax;996 target->acregmax = source->acregmax;
984 target->acdirmin = source->acdirmin;997 target->acdirmin = source->acdirmin;
fs/nfs/delegation.c+8−0
@@ -30,6 +30,11 @@ · 29 unmodified lines
30static unsigned nfs_delegation_watermark = NFS_DEFAULT_DELEGATION_WATERMARK;30static unsigned nfs_delegation_watermark = NFS_DEFAULT_DELEGATION_WATERMARK;
31module_param_named(delegation_watermark, nfs_delegation_watermark, uint, 0644);31module_param_named(delegation_watermark, nfs_delegation_watermark, uint, 0644);
32 32
33bool directory_delegations = true;
34module_param(directory_delegations, bool, 0644);
35MODULE_PARM_DESC(directory_delegations,
36 "Enable the use of directory delegations, defaults to on.");
37
33static struct hlist_head *nfs_delegation_hash(struct nfs_server *server,38static struct hlist_head *nfs_delegation_hash(struct nfs_server *server,
34 const struct nfs_fh *fhandle)39 const struct nfs_fh *fhandle)
35{40{
@@ -143,6 +148,8 @@ static int nfs4_do_check_delegation(struct inode *inode, fmode_t type, · 107 unmodified lines
143 */148 */
144int nfs4_have_delegation(struct inode *inode, fmode_t type, int flags)149int nfs4_have_delegation(struct inode *inode, fmode_t type, int flags)
145{150{
151 if (S_ISDIR(inode->i_mode) && !directory_delegations)
152 nfs_inode_evict_delegation(inode);
146 return nfs4_do_check_delegation(inode, type, flags, true);153 return nfs4_do_check_delegation(inode, type, flags, true);
147}154}
148 155
@@ -379,6 +386,7 @@ nfs_detach_delegation_locked(struct nfs_inode *nfsi, · 230 unmodified lines
379 delegation->inode = NULL;386 delegation->inode = NULL;
380 rcu_assign_pointer(nfsi->delegation, NULL);387 rcu_assign_pointer(nfsi->delegation, NULL);
381 spin_unlock(&delegation->lock);388 spin_unlock(&delegation->lock);
389 clear_bit(NFS_INO_REQ_DIR_DELEG, &nfsi->flags);
382 return delegation;390 return delegation;
383}391}
384 392
fs/nfs/delegation.h+13−0
@@ -124,6 +124,19 @@ static inline int nfs_have_delegated_mtime(struct inode *inode) · 123 unmodified lines
124 NFS_DELEGATION_FLAG_TIME);124 NFS_DELEGATION_FLAG_TIME);
125}125}
126 126
127extern bool directory_delegations;
128
129static inline void nfs_request_directory_delegation(struct inode *inode)
130{
131 if (S_ISDIR(inode->i_mode))
132 set_bit(NFS_INO_REQ_DIR_DELEG, &NFS_I(inode)->flags);
133}
134
135static inline bool nfs_have_directory_delegation(struct inode *inode)
136{
137 return S_ISDIR(inode->i_mode) && nfs_have_delegated_attributes(inode);
138}
139
127int nfs4_delegation_hash_alloc(struct nfs_server *server);140int nfs4_delegation_hash_alloc(struct nfs_server *server);
128 141
129#endif142#endif
fs/nfs/dir.c+37−9
@@ -789,16 +789,17 @@ again: · 788 unmodified lines
789 goto out;789 goto out;
790 }790 }
791 791
792 nfs_set_verifier(dentry, dir_verifier);
792 inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr);793 inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr);
793 alias = d_splice_alias(inode, dentry);794 alias = d_splice_alias(inode, dentry);
794 d_lookup_done(dentry);795 d_lookup_done(dentry);
795 if (alias) {796 if (alias) {
796 if (IS_ERR(alias))797 if (IS_ERR(alias))
797 goto out;798 goto out;
799 nfs_set_verifier(alias, dir_verifier);
798 dput(dentry);800 dput(dentry);
799 dentry = alias;801 dentry = alias;
800 }802 }
801 nfs_set_verifier(dentry, dir_verifier);
802 trace_nfs_readdir_lookup(d_inode(parent), dentry, 0);803 trace_nfs_readdir_lookup(d_inode(parent), dentry, 0);
803out:804out:
804 dput(dentry);805 dput(dentry);
@@ -1514,6 +1515,15 @@ static int nfs_check_verifier(struct inode *dir, struct dentry *dentry, · 709 unmodified lines
1514 return 0;1515 return 0;
1515 if (!nfs_dentry_verify_change(dir, dentry))1516 if (!nfs_dentry_verify_change(dir, dentry))
1516 return 0;1517 return 0;
1518
1519 /*
1520 * If we have a directory delegation then we don't need to revalidate
1521 * the directory. The delegation will either get recalled or we will
1522 * receive a notification when it changes.
1523 */
1524 if (nfs_have_directory_delegation(dir))
1525 return 0;
1526
1517 /* Revalidate nfsi->cache_change_attribute before we declare a match */1527 /* Revalidate nfsi->cache_change_attribute before we declare a match */
1518 if (nfs_mapping_need_revalidate_inode(dir)) {1528 if (nfs_mapping_need_revalidate_inode(dir)) {
1519 if (rcu_walk)1529 if (rcu_walk)
@@ -1894,13 +1904,15 @@ static int nfs_dentry_delete(const struct dentry *dentry) · 374 unmodified lines
1894}1904}
1895 1905
1896/* Ensure that we revalidate inode->i_nlink */1906/* Ensure that we revalidate inode->i_nlink */
1897static void nfs_drop_nlink(struct inode *inode)1907static void nfs_drop_nlink(struct inode *inode, unsigned long gencount)
1898{1908{
1909 struct nfs_inode *nfsi = NFS_I(inode);
1910
1899 spin_lock(&inode->i_lock);1911 spin_lock(&inode->i_lock);
1900 /* drop the inode if we're reasonably sure this is the last link */1912 /* drop the inode if we're reasonably sure this is the last link */
1901 if (inode->i_nlink > 0)1913 if (inode->i_nlink > 0 && gencount == nfsi->attr_gencount)
1902 drop_nlink(inode);1914 drop_nlink(inode);
1903 NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter();1915 nfsi->attr_gencount = nfs_inc_attr_generation_counter();
1904 nfs_set_cache_invalid(1916 nfs_set_cache_invalid(
1905 inode, NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME |1917 inode, NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_CTIME |
1906 NFS_INO_INVALID_NLINK);1918 NFS_INO_INVALID_NLINK);
@@ -1914,8 +1926,9 @@ static void nfs_drop_nlink(struct inode *inode) · 7 unmodified lines
1914static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)1926static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
1915{1927{
1916 if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {1928 if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
1929 unsigned long gencount = READ_ONCE(NFS_I(inode)->attr_gencount);
1917 nfs_complete_unlink(dentry, inode);1930 nfs_complete_unlink(dentry, inode);
1918 nfs_drop_nlink(inode);1931 nfs_drop_nlink(inode, gencount);
1919 }1932 }
1920 iput(inode);1933 iput(inode);
1921}1934}
@@ -1991,13 +2004,14 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in · 69 unmodified lines
1991 nfs_lookup_advise_force_readdirplus(dir, flags);2004 nfs_lookup_advise_force_readdirplus(dir, flags);
1992 2005
1993no_entry:2006no_entry:
2007 nfs_set_verifier(dentry, dir_verifier);
1994 res = d_splice_alias(inode, dentry);2008 res = d_splice_alias(inode, dentry);
1995 if (res != NULL) {2009 if (res != NULL) {
1996 if (IS_ERR(res))2010 if (IS_ERR(res))
1997 goto out;2011 goto out;
2012 nfs_set_verifier(res, dir_verifier);
1998 dentry = res;2013 dentry = res;
1999 }2014 }
2000 nfs_set_verifier(dentry, dir_verifier);
2001out:2015out:
2002 trace_nfs_lookup_exit(dir, dentry, flags, PTR_ERR_OR_ZERO(res));2016 trace_nfs_lookup_exit(dir, dentry, flags, PTR_ERR_OR_ZERO(res));
2003 nfs_free_fattr(fattr);2017 nfs_free_fattr(fattr);
@@ -2139,12 +2153,12 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, · 135 unmodified lines
2139 d_drop(dentry);2153 d_drop(dentry);
2140 switch (err) {2154 switch (err) {
2141 case -ENOENT:2155 case -ENOENT:
2142 d_splice_alias(NULL, dentry);
2143 if (nfs_server_capable(dir, NFS_CAP_CASE_INSENSITIVE))2156 if (nfs_server_capable(dir, NFS_CAP_CASE_INSENSITIVE))
2144 dir_verifier = inode_peek_iversion_raw(dir);2157 dir_verifier = inode_peek_iversion_raw(dir);
2145 else2158 else
2146 dir_verifier = nfs_save_change_attribute(dir);2159 dir_verifier = nfs_save_change_attribute(dir);
2147 nfs_set_verifier(dentry, dir_verifier);2160 nfs_set_verifier(dentry, dir_verifier);
2161 d_splice_alias(NULL, dentry);
2148 break;2162 break;
2149 case -EISDIR:2163 case -EISDIR:
2150 case -ENOTDIR:2164 case -ENOTDIR:
@@ -2202,6 +2216,13 @@ no_open: · 51 unmodified lines
2202}2216}
2203EXPORT_SYMBOL_GPL(nfs_atomic_open);2217EXPORT_SYMBOL_GPL(nfs_atomic_open);
2204 2218
2219static int
2220nfs_lookup_revalidate_delegated_parent(struct inode *dir, struct dentry *dentry,
2221 struct inode *inode)
2222{
2223 return nfs_lookup_revalidate_done(dir, dentry, inode, 1);
2224}
2225
2205static int2226static int
2206nfs4_lookup_revalidate(struct inode *dir, const struct qstr *name,2227nfs4_lookup_revalidate(struct inode *dir, const struct qstr *name,
2207 struct dentry *dentry, unsigned int flags)2228 struct dentry *dentry, unsigned int flags)
@@ -2229,6 +2250,9 @@ nfs4_lookup_revalidate(struct inode *dir, const struct qstr *name, · 21 unmodified lines
2229 if (nfs_verifier_is_delegated(dentry))2250 if (nfs_verifier_is_delegated(dentry))
2230 return nfs_lookup_revalidate_delegated(dir, dentry, inode);2251 return nfs_lookup_revalidate_delegated(dir, dentry, inode);
2231 2252
2253 if (nfs_have_directory_delegation(dir))
2254 return nfs_lookup_revalidate_delegated_parent(dir, dentry, inode);
2255
2232 /* NFS only supports OPEN on regular files */2256 /* NFS only supports OPEN on regular files */
2233 if (!S_ISREG(inode->i_mode))2257 if (!S_ISREG(inode->i_mode))
2234 goto full_reval;2258 goto full_reval;
@@ -2507,9 +2531,11 @@ static int nfs_safe_remove(struct dentry *dentry) · 272 unmodified lines
2507 2531
2508 trace_nfs_remove_enter(dir, dentry);2532 trace_nfs_remove_enter(dir, dentry);
2509 if (inode != NULL) {2533 if (inode != NULL) {
2534 unsigned long gencount = READ_ONCE(NFS_I(inode)->attr_gencount);
2535
2510 error = NFS_PROTO(dir)->remove(dir, dentry);2536 error = NFS_PROTO(dir)->remove(dir, dentry);
2511 if (error == 0)2537 if (error == 0)
2512 nfs_drop_nlink(inode);2538 nfs_drop_nlink(inode, gencount);
2513 } else2539 } else
2514 error = NFS_PROTO(dir)->remove(dir, dentry);2540 error = NFS_PROTO(dir)->remove(dir, dentry);
2515 if (error == -ENOENT)2541 if (error == -ENOENT)
@@ -2709,6 +2735,7 @@ int nfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, · 193 unmodified lines
2709{2735{
2710 struct inode *old_inode = d_inode(old_dentry);2736 struct inode *old_inode = d_inode(old_dentry);
2711 struct inode *new_inode = d_inode(new_dentry);2737 struct inode *new_inode = d_inode(new_dentry);
2738 unsigned long new_gencount = 0;
2712 struct dentry *dentry = NULL;2739 struct dentry *dentry = NULL;
2713 struct rpc_task *task;2740 struct rpc_task *task;
2714 bool must_unblock = false;2741 bool must_unblock = false;
@@ -2761,6 +2788,7 @@ int nfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, · 46 unmodified lines
2761 } else {2788 } else {
2762 block_revalidate(new_dentry);2789 block_revalidate(new_dentry);
2763 must_unblock = true;2790 must_unblock = true;
2791 new_gencount = NFS_I(new_inode)->attr_gencount;
2764 spin_unlock(&new_dentry->d_lock);2792 spin_unlock(&new_dentry->d_lock);
2765 }2793 }
2766 2794
@@ -2800,7 +2828,7 @@ out: · 33 unmodified lines
2800 new_dir, new_dentry, error);2828 new_dir, new_dentry, error);
2801 if (!error) {2829 if (!error) {
2802 if (new_inode != NULL)2830 if (new_inode != NULL)
2803 nfs_drop_nlink(new_inode);2831 nfs_drop_nlink(new_inode, new_gencount);
2804 /*2832 /*
2805 * The d_move() should be here instead of in an async RPC completion2833 * The d_move() should be here instead of in an async RPC completion
2806 * handler because we need the proper locks to move the dentry. If2834 * handler because we need the proper locks to move the dentry. If
fs/nfs/inode.c+3−0
@@ -1389,6 +1389,9 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) · 1388 unmodified lines
1389 status = pnfs_sync_inode(inode, false);1389 status = pnfs_sync_inode(inode, false);
1390 if (status)1390 if (status)
1391 goto out;1391 goto out;
1392 } else if (nfs_have_directory_delegation(inode)) {
1393 status = 0;
1394 goto out;
1392 }1395 }
1393 1396
1394 status = -ENOMEM;1397 status = -ENOMEM;
fs/nfs/internal.h+1−2
@@ -13,7 +13,7 @@ · 12 unmodified lines
13#include <linux/nfslocalio.h>13#include <linux/nfslocalio.h>
14#include <linux/wait_bit.h>14#include <linux/wait_bit.h>
15 15
16#define NFS_SB_MASK (SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS)16#define NFS_SB_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS)
17 17
18extern const struct export_operations nfs_export_ops;18extern const struct export_operations nfs_export_ops;
19 19
@@ -152,7 +152,6 @@ struct nfs_fs_context { · 132 unmodified lines
152 struct super_block *sb;152 struct super_block *sb;
153 struct dentry *dentry;153 struct dentry *dentry;
154 struct nfs_fattr *fattr;154 struct nfs_fattr *fattr;
155 unsigned int inherited_bsize;
156 } clone_data;155 } clone_data;
157};156};
158 157
fs/nfs/localio.c+1−3
@@ -43,8 +43,8 @@ struct nfs_local_kiocb { · 42 unmodified lines
43 size_t end_len;43 size_t end_len;
44 short int end_iter_index;44 short int end_iter_index;
45 atomic_t n_iters;45 atomic_t n_iters;
46 struct iov_iter iters[NFSLOCAL_MAX_IOS];
46 bool iter_is_dio_aligned[NFSLOCAL_MAX_IOS];47 bool iter_is_dio_aligned[NFSLOCAL_MAX_IOS];
47 struct iov_iter iters[NFSLOCAL_MAX_IOS] ____cacheline_aligned;
48 /* End mostly DIO-specific members */48 /* End mostly DIO-specific members */
49};49};
50 50
@@ -339,8 +339,6 @@ nfs_is_local_dio_possible(struct nfs_local_kiocb *iocb, int rw, · 288 unmodified lines
339 339
340 if (unlikely(!nf_dio_mem_align || !nf_dio_offset_align))340 if (unlikely(!nf_dio_mem_align || !nf_dio_offset_align))
341 return false;341 return false;
342 if (unlikely(nf_dio_offset_align > PAGE_SIZE))
343 return false;
344 if (unlikely(len < nf_dio_offset_align))342 if (unlikely(len < nf_dio_offset_align))
345 return false;343 return false;
346 344
fs/nfs/namespace.c+15−1
@@ -149,6 +149,7 @@ struct vfsmount *nfs_d_automount(struct path *path) · 148 unmodified lines
149 struct vfsmount *mnt = ERR_PTR(-ENOMEM);149 struct vfsmount *mnt = ERR_PTR(-ENOMEM);
150 struct nfs_server *server = NFS_SB(path->dentry->d_sb);150 struct nfs_server *server = NFS_SB(path->dentry->d_sb);
151 struct nfs_client *client = server->nfs_client;151 struct nfs_client *client = server->nfs_client;
152 unsigned long s_flags = path->dentry->d_sb->s_flags;
152 int timeout = READ_ONCE(nfs_mountpoint_expiry_timeout);153 int timeout = READ_ONCE(nfs_mountpoint_expiry_timeout);
153 int ret;154 int ret;
154 155
@@ -169,11 +170,21 @@ struct vfsmount *nfs_d_automount(struct path *path) · 14 unmodified lines
169 if (!ctx->clone_data.fattr)170 if (!ctx->clone_data.fattr)
170 goto out_fc;171 goto out_fc;
171 172
173 if (fc->cred != server->cred) {
174 put_cred(fc->cred);
175 fc->cred = get_cred(server->cred);
176 }
177
172 if (fc->net_ns != client->cl_net) {178 if (fc->net_ns != client->cl_net) {
173 put_net(fc->net_ns);179 put_net(fc->net_ns);
174 fc->net_ns = get_net(client->cl_net);180 fc->net_ns = get_net(client->cl_net);
175 }181 }
176 182
183 /* Inherit the flags covered by NFS_SB_MASK */
184 fc->sb_flags_mask |= NFS_SB_MASK;
185 fc->sb_flags &= ~NFS_SB_MASK;
186 fc->sb_flags |= s_flags & NFS_SB_MASK;
187
177 /* for submounts we want the same server; referrals will reassign */188 /* for submounts we want the same server; referrals will reassign */
178 memcpy(&ctx->nfs_server._address, &client->cl_addr, client->cl_addrlen);189 memcpy(&ctx->nfs_server._address, &client->cl_addr, client->cl_addrlen);
179 ctx->nfs_server.addrlen = client->cl_addrlen;190 ctx->nfs_server.addrlen = client->cl_addrlen;
@@ -184,6 +195,10 @@ struct vfsmount *nfs_d_automount(struct path *path) · 4 unmodified lines
184 ctx->nfs_mod = client->cl_nfs_mod;195 ctx->nfs_mod = client->cl_nfs_mod;
185 get_nfs_version(ctx->nfs_mod);196 get_nfs_version(ctx->nfs_mod);
186 197
198 /* Inherit block sizes if they were specified as mount parameters */
199 if (server->automount_inherit & NFS_AUTOMOUNT_INHERIT_BSIZE)
200 ctx->bsize = server->bsize;
201
187 ret = client->rpc_ops->submount(fc, server);202 ret = client->rpc_ops->submount(fc, server);
188 if (ret < 0) {203 if (ret < 0) {
189 mnt = ERR_PTR(ret);204 mnt = ERR_PTR(ret);
@@ -283,7 +298,6 @@ int nfs_do_submount(struct fs_context *fc) · 93 unmodified lines
283 return -ENOMEM;298 return -ENOMEM;
284 299
285 ctx->internal = true;300 ctx->internal = true;
286 ctx->clone_data.inherited_bsize = ctx->clone_data.sb->s_blocksize_bits;
287 301
288 p = nfs_devname(dentry, buffer, 4096);302 p = nfs_devname(dentry, buffer, 4096);
289 if (IS_ERR(p)) {303 if (IS_ERR(p)) {
fs/nfs/nfs3proc.c+2−1
@@ -483,7 +483,8 @@ nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir) · 482 unmodified lines
483static void483static void
484nfs3_proc_rename_setup(struct rpc_message *msg,484nfs3_proc_rename_setup(struct rpc_message *msg,
485 struct dentry *old_dentry,485 struct dentry *old_dentry,
486 struct dentry *new_dentry)486 struct dentry *new_dentry,
487 struct inode *same_parent)
487{488{
488 msg->rpc_proc = &nfs3_procedures[NFS3PROC_RENAME];489 msg->rpc_proc = &nfs3_procedures[NFS3PROC_RENAME];
489}490}
fs/nfs/nfs4client.c+21−6
@@ -281,8 +281,13 @@ error: · 280 unmodified lines
281 */281 */
282static void nfs4_destroy_callback(struct nfs_client *clp)282static void nfs4_destroy_callback(struct nfs_client *clp)
283{283{
284 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))284 if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state)) {
285 nfs_callback_down(clp->cl_mvops->minor_version, clp->cl_net);285 struct rpc_xprt *xprt;
286
287 xprt = rcu_dereference_raw(clp->cl_rpcclient->cl_xprt);
288 nfs_callback_down(clp->cl_mvops->minor_version, clp->cl_net,
289 xprt);
290 }
286}291}
287 292
288static void nfs4_shutdown_client(struct nfs_client *clp)293static void nfs4_shutdown_client(struct nfs_client *clp)
@@ -1174,10 +1179,20 @@ static int nfs4_init_server(struct nfs_server *server, struct fs_context *fc) · 885 unmodified lines
1174 if (error < 0)1179 if (error < 0)
1175 return error;1180 return error;
1176 1181
1177 if (ctx->rsize)1182 if (ctx->bsize) {
1178 server->rsize = nfs_io_size(ctx->rsize, server->nfs_client->cl_proto);1183 server->bsize = ctx->bsize;
1179 if (ctx->wsize)1184 server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_BSIZE;
1180 server->wsize = nfs_io_size(ctx->wsize, server->nfs_client->cl_proto);1185 }
1186 if (ctx->rsize) {
1187 server->rsize =
1188 nfs_io_size(ctx->rsize, server->nfs_client->cl_proto);
1189 server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_RSIZE;
1190 }
1191 if (ctx->wsize) {
1192 server->wsize =
1193 nfs_io_size(ctx->wsize, server->nfs_client->cl_proto);
1194 server->automount_inherit |= NFS_AUTOMOUNT_INHERIT_WSIZE;
1195 }
1181 1196
1182 server->acregmin = ctx->acregmin * HZ;1197 server->acregmin = ctx->acregmin * HZ;
1183 server->acregmax = ctx->acregmax * HZ;1198 server->acregmax = ctx->acregmax * HZ;
fs/nfs/nfs4proc.c+91−20
@@ -1780,8 +1780,17 @@ static void nfs_set_open_stateid_locked(struct nfs4_state *state, · 1779 unmodified lines
1780 if (nfs_stateid_is_sequential(state, stateid))1780 if (nfs_stateid_is_sequential(state, stateid))
1781 break;1781 break;
1782 1782
1783 if (status)1783 if (status) {
1784 break;1784 if (nfs4_stateid_match_other(stateid, &state->open_stateid) &&
1785 !nfs4_stateid_is_newer(stateid, &state->open_stateid)) {
1786 trace_nfs4_open_stateid_update_skip(state->inode,
1787 stateid, status);
1788 return;
1789 } else {
1790 break;
1791 }
1792 }
1793
1785 /* Rely on seqids for serialisation with NFSv4.0 */1794 /* Rely on seqids for serialisation with NFSv4.0 */
1786 if (!nfs4_has_session(NFS_SERVER(state->inode)->nfs_client))1795 if (!nfs4_has_session(NFS_SERVER(state->inode)->nfs_client))
1787 break;1796 break;
@@ -3174,18 +3183,6 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, · 1386 unmodified lines
3174 if (opendata->o_res.rflags & NFS4_OPEN_RESULT_PRESERVE_UNLINKED)3183 if (opendata->o_res.rflags & NFS4_OPEN_RESULT_PRESERVE_UNLINKED)
3175 set_bit(NFS_INO_PRESERVE_UNLINKED, &NFS_I(state->inode)->flags);3184 set_bit(NFS_INO_PRESERVE_UNLINKED, &NFS_I(state->inode)->flags);
3176 3185
3177 dentry = opendata->dentry;
3178 if (d_really_is_negative(dentry)) {
3179 struct dentry *alias;
3180 d_drop(dentry);
3181 alias = d_splice_alias(igrab(state->inode), dentry);
3182 /* d_splice_alias() can't fail here - it's a non-directory */
3183 if (alias) {
3184 dput(ctx->dentry);
3185 ctx->dentry = dentry = alias;
3186 }
3187 }
3188
3189 switch(opendata->o_arg.claim) {3186 switch(opendata->o_arg.claim) {
3190 default:3187 default:
3191 break;3188 break;
@@ -3196,7 +3193,20 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, · 4 unmodified lines
3196 break;3193 break;
3197 if (opendata->o_res.delegation.type != 0)3194 if (opendata->o_res.delegation.type != 0)
3198 dir_verifier = nfs_save_change_attribute(dir);3195 dir_verifier = nfs_save_change_attribute(dir);
3199 nfs_set_verifier(dentry, dir_verifier);3196 }
3197
3198 dentry = opendata->dentry;
3199 nfs_set_verifier(dentry, dir_verifier);
3200 if (d_really_is_negative(dentry)) {
3201 struct dentry *alias;
3202 d_drop(dentry);
3203 alias = d_splice_alias(igrab(state->inode), dentry);
3204 /* d_splice_alias() can't fail here - it's a non-directory */
3205 if (alias) {
3206 dput(ctx->dentry);
3207 nfs_set_verifier(alias, dir_verifier);
3208 ctx->dentry = dentry = alias;
3209 }
3200 }3210 }
3201 3211
3202 /* Parse layoutget results before we check for access */3212 /* Parse layoutget results before we check for access */
@@ -4460,6 +4470,30 @@ out: · 1257 unmodified lines
4460 return status;4470 return status;
4461}4471}
4462 4472
4473#if IS_ENABLED(CONFIG_NFS_V4_1)
4474static bool should_request_dir_deleg(struct inode *inode)
4475{
4476 if (!directory_delegations)
4477 return false;
4478 if (!inode)
4479 return false;
4480 if (!S_ISDIR(inode->i_mode))
4481 return false;
4482 if (!nfs_server_capable(inode, NFS_CAP_DIR_DELEG))
4483 return false;
4484 if (!test_and_clear_bit(NFS_INO_REQ_DIR_DELEG, &(NFS_I(inode)->flags)))
4485 return false;
4486 if (nfs4_have_delegation(inode, FMODE_READ, 0))
4487 return false;
4488 return true;
4489}
4490#else
4491static bool should_request_dir_deleg(struct inode *inode)
4492{
4493 return false;
4494}
4495#endif /* CONFIG_NFS_V4_1 */
4496
4463static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,4497static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
4464 struct nfs_fattr *fattr, struct inode *inode)4498 struct nfs_fattr *fattr, struct inode *inode)
4465{4499{
@@ -4477,7 +4511,9 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, · 11 unmodified lines
4477 .rpc_argp = &args,4511 .rpc_argp = &args,
4478 .rpc_resp = &res,4512 .rpc_resp = &res,
4479 };4513 };
4514 struct nfs4_gdd_res gdd_res;
4480 unsigned short task_flags = 0;4515 unsigned short task_flags = 0;
4516 int status;
4481 4517
4482 if (nfs4_has_session(server->nfs_client))4518 if (nfs4_has_session(server->nfs_client))
4483 task_flags = RPC_TASK_MOVEABLE;4519 task_flags = RPC_TASK_MOVEABLE;
@@ -4486,11 +4522,31 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, · 2 unmodified lines
4486 if (inode && (server->flags & NFS_MOUNT_SOFTREVAL))4522 if (inode && (server->flags & NFS_MOUNT_SOFTREVAL))
4487 task_flags |= RPC_TASK_TIMEOUT;4523 task_flags |= RPC_TASK_TIMEOUT;
4488 4524
4525 args.get_dir_deleg = should_request_dir_deleg(inode);
4526 if (args.get_dir_deleg)
4527 res.gdd_res = &gdd_res;
4528
4489 nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, fattr->label), inode, 0);4529 nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, fattr->label), inode, 0);
4490 nfs_fattr_init(fattr);4530 nfs_fattr_init(fattr);
4491 nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);4531 nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
4492 return nfs4_do_call_sync(server->client, server, &msg,4532
4493 &args.seq_args, &res.seq_res, task_flags);4533 status = nfs4_do_call_sync(server->client, server, &msg,
4534 &args.seq_args, &res.seq_res, task_flags);
4535 if (args.get_dir_deleg) {
4536 switch (status) {
4537 case 0:
4538 if (gdd_res.status != GDD4_OK)
4539 break;
4540 status = nfs_inode_set_delegation(
4541 inode, current_cred(), FMODE_READ,
4542 &gdd_res.deleg, 0, NFS4_OPEN_DELEGATE_READ);
4543 break;
4544 case -ENOTSUPP:
4545 case -EOPNOTSUPP:
4546 server->caps &= ~NFS_CAP_DIR_DELEG;
4547 }
4548 }
4549 return status;
4494}4550}
4495 4551
4496int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,4552int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -4503,8 +4559,14 @@ int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, · 6 unmodified lines
4503 do {4559 do {
4504 err = _nfs4_proc_getattr(server, fhandle, fattr, inode);4560 err = _nfs4_proc_getattr(server, fhandle, fattr, inode);
4505 trace_nfs4_getattr(server, fhandle, fattr, err);4561 trace_nfs4_getattr(server, fhandle, fattr, err);
4506 err = nfs4_handle_exception(server, err,4562 switch (err) {
4507 &exception);4563 default:
4564 err = nfs4_handle_exception(server, err, &exception);
4565 break;
4566 case -ENOTSUPP:
4567 case -EOPNOTSUPP:
4568 exception.retry = true;
4569 }
4508 } while (exception.retry);4570 } while (exception.retry);
4509 return err;4571 return err;
4510}4572}
@@ -4768,6 +4830,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry · 257 unmodified lines
4768 int status = 0;4830 int status = 0;
4769 4831
4770 if (!nfs4_have_delegation(inode, FMODE_READ, 0)) {4832 if (!nfs4_have_delegation(inode, FMODE_READ, 0)) {
4833 nfs_request_directory_delegation(inode);
4771 res.fattr = nfs_alloc_fattr();4834 res.fattr = nfs_alloc_fattr();
4772 if (res.fattr == NULL)4835 if (res.fattr == NULL)
4773 return -ENOMEM;4836 return -ENOMEM;
@@ -4875,6 +4938,8 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, · 101 unmodified lines
4875 4938
4876 ilabel = nfs4_label_init_security(dir, dentry, sattr, &l);4939 ilabel = nfs4_label_init_security(dir, dentry, sattr, &l);
4877 4940
4941 nfs_request_directory_delegation(dir);
4942
4878 if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK))4943 if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK))
4879 sattr->ia_mode &= ~current_umask();4944 sattr->ia_mode &= ~current_umask();
4880 state = nfs4_do_open(dir, ctx, flags, sattr, ilabel, NULL);4945 state = nfs4_do_open(dir, ctx, flags, sattr, ilabel, NULL);
@@ -4971,6 +5036,7 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg, · 90 unmodified lines
4971 nfs4_init_sequence(&args->seq_args, &res->seq_res, 1, 0);5036 nfs4_init_sequence(&args->seq_args, &res->seq_res, 1, 0);
4972 5037
4973 nfs_fattr_init(res->dir_attr);5038 nfs_fattr_init(res->dir_attr);
5039 nfs_request_directory_delegation(d_inode(dentry->d_parent));
4974 5040
4975 if (inode) {5041 if (inode) {
4976 nfs4_inode_return_delegation(inode);5042 nfs4_inode_return_delegation(inode);
@@ -5005,7 +5071,8 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir) · 28 unmodified lines
5005 5071
5006static void nfs4_proc_rename_setup(struct rpc_message *msg,5072static void nfs4_proc_rename_setup(struct rpc_message *msg,
5007 struct dentry *old_dentry,5073 struct dentry *old_dentry,
5008 struct dentry *new_dentry)5074 struct dentry *new_dentry,
5075 struct inode *same_parent)
5009{5076{
5010 struct nfs_renameargs *arg = msg->rpc_argp;5077 struct nfs_renameargs *arg = msg->rpc_argp;
5011 struct nfs_renameres *res = msg->rpc_resp;5078 struct nfs_renameres *res = msg->rpc_resp;
@@ -5016,6 +5083,8 @@ static void nfs4_proc_rename_setup(struct rpc_message *msg, · 4 unmodified lines
5016 nfs4_inode_make_writeable(old_inode);5083 nfs4_inode_make_writeable(old_inode);
5017 if (new_inode)5084 if (new_inode)
5018 nfs4_inode_return_delegation(new_inode);5085 nfs4_inode_return_delegation(new_inode);
5086 if (same_parent)
5087 nfs_request_directory_delegation(same_parent);
5019 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME];5088 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME];
5020 res->server = NFS_SB(old_dentry->d_sb);5089 res->server = NFS_SB(old_dentry->d_sb);
5021 nfs4_init_sequence(&arg->seq_args, &res->seq_res, 1, 0);5090 nfs4_init_sequence(&arg->seq_args, &res->seq_res, 1, 0);
@@ -10822,6 +10891,7 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = { · 5800 unmodified lines
10822 .minor_version = 1,10891 .minor_version = 1,
10823 .init_caps = NFS_CAP_READDIRPLUS10892 .init_caps = NFS_CAP_READDIRPLUS
10824 | NFS_CAP_ATOMIC_OPEN10893 | NFS_CAP_ATOMIC_OPEN
10894 | NFS_CAP_DIR_DELEG
10825 | NFS_CAP_POSIX_LOCK10895 | NFS_CAP_POSIX_LOCK
10826 | NFS_CAP_STATEID_NFSV4110896 | NFS_CAP_STATEID_NFSV41
10827 | NFS_CAP_ATOMIC_OPEN_V110897 | NFS_CAP_ATOMIC_OPEN_V1
@@ -10848,6 +10918,7 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = { · 20 unmodified lines
10848 .minor_version = 2,10918 .minor_version = 2,
10849 .init_caps = NFS_CAP_READDIRPLUS10919 .init_caps = NFS_CAP_READDIRPLUS
10850 | NFS_CAP_ATOMIC_OPEN10920 | NFS_CAP_ATOMIC_OPEN
10921 | NFS_CAP_DIR_DELEG
10851 | NFS_CAP_POSIX_LOCK10922 | NFS_CAP_POSIX_LOCK
10852 | NFS_CAP_STATEID_NFSV4110923 | NFS_CAP_STATEID_NFSV41
10853 | NFS_CAP_ATOMIC_OPEN_V110924 | NFS_CAP_ATOMIC_OPEN_V1
fs/nfs/nfs4trace.h+1−0
@@ -1353,6 +1353,7 @@ DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_setattr); · 1352 unmodified lines
1353DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_delegreturn);1353DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_delegreturn);
1354DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_open_stateid_update);1354DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_open_stateid_update);
1355DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_open_stateid_update_wait);1355DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_open_stateid_update_wait);
1356DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_open_stateid_update_skip);
1356DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_close_stateid_update_wait);1357DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_close_stateid_update_wait);
1357 1358
1358DECLARE_EVENT_CLASS(nfs4_getattr_event,1359DECLARE_EVENT_CLASS(nfs4_getattr_event,
fs/nfs/nfs4xdr.c+106−0
@@ -393,6 +393,20 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, · 392 unmodified lines
393 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5)393 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5)
394#define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4)394#define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4)
395#define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4)395#define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4)
396#define encode_get_dir_deleg_maxsz (op_encode_hdr_maxsz + \
397 4 /* gdda_signal_deleg_avail */ + \
398 8 /* gdda_notification_types */ + \
399 nfstime4_maxsz /* gdda_child_attr_delay */ + \
400 nfstime4_maxsz /* gdda_dir_attr_delay */ + \
401 nfs4_fattr_bitmap_maxsz /* gdda_child_attributes */ + \
402 nfs4_fattr_bitmap_maxsz /* gdda_dir_attributes */)
403#define decode_get_dir_deleg_maxsz (op_decode_hdr_maxsz + \
404 4 /* gddrnf_status */ + \
405 encode_verifier_maxsz /* gddr_cookieverf */ + \
406 encode_stateid_maxsz /* gddr_stateid */ + \
407 8 /* gddr_notification */ + \
408 nfs4_fattr_maxsz /* gddr_child_attributes */ + \
409 nfs4_fattr_maxsz /* gddr_dir_attributes */)
396#define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + \410#define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + \
397 XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \411 XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \
398 1 /* layout type */ + \412 1 /* layout type */ + \
@@ -444,6 +458,8 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, · 45 unmodified lines
444#else /* CONFIG_NFS_V4_1 */458#else /* CONFIG_NFS_V4_1 */
445#define encode_sequence_maxsz 0459#define encode_sequence_maxsz 0
446#define decode_sequence_maxsz 0460#define decode_sequence_maxsz 0
461#define encode_get_dir_deleg_maxsz 0
462#define decode_get_dir_deleg_maxsz 0
447#define encode_layoutreturn_maxsz 0463#define encode_layoutreturn_maxsz 0
448#define decode_layoutreturn_maxsz 0464#define decode_layoutreturn_maxsz 0
449#define encode_layoutget_maxsz 0465#define encode_layoutget_maxsz 0
@@ -631,11 +647,13 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, · 181 unmodified lines
631#define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \647#define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \
632 encode_sequence_maxsz + \648 encode_sequence_maxsz + \
633 encode_putfh_maxsz + \649 encode_putfh_maxsz + \
650 encode_get_dir_deleg_maxsz + \
634 encode_getattr_maxsz + \651 encode_getattr_maxsz + \
635 encode_renew_maxsz)652 encode_renew_maxsz)
636#define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \653#define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \
637 decode_sequence_maxsz + \654 decode_sequence_maxsz + \
638 decode_putfh_maxsz + \655 decode_putfh_maxsz + \
656 decode_get_dir_deleg_maxsz + \
639 decode_getattr_maxsz + \657 decode_getattr_maxsz + \
640 decode_renew_maxsz)658 decode_renew_maxsz)
641#define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \659#define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \
@@ -2007,6 +2025,33 @@ static void encode_sequence(struct xdr_stream *xdr, · 1365 unmodified lines
2007}2025}
2008 2026
2009#ifdef CONFIG_NFS_V4_12027#ifdef CONFIG_NFS_V4_1
2028static void
2029encode_get_dir_delegation(struct xdr_stream *xdr, struct compound_hdr *hdr)
2030{
2031 struct timespec64 ts = { 0, 0 };
2032 u32 notifications[1] = { 0 };
2033 u32 attributes[1] = { 0 };
2034 __be32 *p;
2035
2036 encode_op_hdr(xdr, OP_GET_DIR_DELEGATION, decode_get_dir_deleg_maxsz, hdr);
2037
2038 /* We don't handle CB_RECALLABLE_OBJ_AVAIL yet. */
2039 xdr_stream_encode_bool(xdr, false);
2040
2041 xdr_encode_bitmap4(xdr, notifications, ARRAY_SIZE(notifications));
2042
2043 /* Request no delay on attribute updates */
2044 p = reserve_space(xdr, 12 + 12);
2045 p = xdr_encode_nfstime4(p, &ts);
2046 xdr_encode_nfstime4(p, &ts);
2047
2048 /* Requested child attributes */
2049 xdr_encode_bitmap4(xdr, attributes, ARRAY_SIZE(attributes));
2050
2051 /* Requested dir attributes */
2052 xdr_encode_bitmap4(xdr, attributes, ARRAY_SIZE(attributes));
2053}
2054
2010static void2055static void
2011encode_getdeviceinfo(struct xdr_stream *xdr,2056encode_getdeviceinfo(struct xdr_stream *xdr,
2012 const struct nfs4_getdeviceinfo_args *args,2057 const struct nfs4_getdeviceinfo_args *args,
@@ -2142,6 +2187,11 @@ static void encode_free_stateid(struct xdr_stream *xdr, · 129 unmodified lines
2142 encode_nfs4_stateid(xdr, &args->stateid);2187 encode_nfs4_stateid(xdr, &args->stateid);
2143}2188}
2144#else2189#else
2190static inline void
2191encode_get_dir_delegation(struct xdr_stream *xdr, struct compound_hdr *hdr)
2192{
2193}
2194
2145static inline void2195static inline void
2146encode_layoutreturn(struct xdr_stream *xdr,2196encode_layoutreturn(struct xdr_stream *xdr,
2147 const struct nfs4_layoutreturn_args *args,2197 const struct nfs4_layoutreturn_args *args,
@@ -2356,6 +2406,8 @@ static void nfs4_xdr_enc_getattr(struct rpc_rqst *req, struct xdr_stream *xdr, · 208 unmodified lines
2356 encode_compound_hdr(xdr, req, &hdr);2406 encode_compound_hdr(xdr, req, &hdr);
2357 encode_sequence(xdr, &args->seq_args, &hdr);2407 encode_sequence(xdr, &args->seq_args, &hdr);
2358 encode_putfh(xdr, args->fh, &hdr);2408 encode_putfh(xdr, args->fh, &hdr);
2409 if (args->get_dir_deleg)
2410 encode_get_dir_delegation(xdr, &hdr);
2359 encode_getfattr(xdr, args->bitmask, &hdr);2411 encode_getfattr(xdr, args->bitmask, &hdr);
2360 encode_nops(&hdr);2412 encode_nops(&hdr);
2361}2413}
@@ -5994,6 +6046,49 @@ static int decode_layout_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) · 3632 unmodified lines
5994 return decode_stateid(xdr, stateid);6046 return decode_stateid(xdr, stateid);
5995}6047}
5996 6048
6049static int decode_get_dir_delegation(struct xdr_stream *xdr,
6050 struct nfs4_getattr_res *res)
6051{
6052 struct nfs4_gdd_res *gdd_res = res->gdd_res;
6053 nfs4_verifier cookieverf;
6054 u32 bitmap[1];
6055 int status;
6056
6057 status = decode_op_hdr(xdr, OP_GET_DIR_DELEGATION);
6058 if (status)
6059 return status;
6060
6061 if (xdr_stream_decode_u32(xdr, &gdd_res->status))
6062 return -EIO;
6063
6064 if (gdd_res->status == GDD4_UNAVAIL)
6065 return xdr_inline_decode(xdr, 4) ? 0 : -EIO;
6066
6067 status = decode_verifier(xdr, &cookieverf);
6068 if (status)
6069 return status;
6070
6071 status = decode_delegation_stateid(xdr, &gdd_res->deleg);
6072 if (status)
6073 return status;
6074
6075 /* Decode supported notification types. */
6076 status = decode_bitmap4(xdr, bitmap, ARRAY_SIZE(bitmap));
6077 if (status < 0)
6078 return status;
6079
6080 /* Decode supported child attributes. */
6081 status = decode_bitmap4(xdr, bitmap, ARRAY_SIZE(bitmap));
6082 if (status < 0)
6083 return status;
6084
6085 /* Decode supported attributes. */
6086 status = decode_bitmap4(xdr, bitmap, ARRAY_SIZE(bitmap));
6087 if (status < 0)
6088 return status;
6089 return 0;
6090}
6091
5997static int decode_getdeviceinfo(struct xdr_stream *xdr,6092static int decode_getdeviceinfo(struct xdr_stream *xdr,
5998 struct nfs4_getdeviceinfo_res *res)6093 struct nfs4_getdeviceinfo_res *res)
5999{6094{
@@ -6208,6 +6303,12 @@ static int decode_free_stateid(struct xdr_stream *xdr, · 208 unmodified lines
6208 return res->status;6303 return res->status;
6209}6304}
6210#else6305#else
6306static int decode_get_dir_delegation(struct xdr_stream *xdr,
6307 struct nfs4_getattr_res *res)
6308{
6309 return 0;
6310}
6311
6211static inline6312static inline
6212int decode_layoutreturn(struct xdr_stream *xdr,6313int decode_layoutreturn(struct xdr_stream *xdr,
6213 struct nfs4_layoutreturn_res *res)6314 struct nfs4_layoutreturn_res *res)
@@ -6525,6 +6626,11 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr, · 311 unmodified lines
6525 status = decode_putfh(xdr);6626 status = decode_putfh(xdr);
6526 if (status)6627 if (status)
6527 goto out;6628 goto out;
6629 if (res->gdd_res) {
6630 status = decode_get_dir_delegation(xdr, res);
6631 if (status)
6632 goto out;
6633 }
6528 status = decode_getfattr(xdr, res->fattr, res->server);6634 status = decode_getfattr(xdr, res->fattr, res->server);
6529out:6635out:
6530 return status;6636 return status;
fs/nfs/pnfs.c+1−0
@@ -464,6 +464,7 @@ pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo, · 463 unmodified lines
464 struct pnfs_layout_segment *lseg, *next;464 struct pnfs_layout_segment *lseg, *next;
465 465
466 set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);466 set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);
467 clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(lo->plh_inode)->flags);
467 list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)468 list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
468 pnfs_clear_lseg_state(lseg, lseg_list);469 pnfs_clear_lseg_state(lseg, lseg_list);
469 pnfs_clear_layoutreturn_info(lo);470 pnfs_clear_layoutreturn_info(lo);
fs/nfs/proc.c+2−1
@@ -353,7 +353,8 @@ static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir) · 352 unmodified lines
353static void353static void
354nfs_proc_rename_setup(struct rpc_message *msg,354nfs_proc_rename_setup(struct rpc_message *msg,
355 struct dentry *old_dentry,355 struct dentry *old_dentry,
356 struct dentry *new_dentry)356 struct dentry *new_dentry,
357 struct inode *same_parent)
357{358{
358 msg->rpc_proc = &nfs_procedures[NFSPROC_RENAME];359 msg->rpc_proc = &nfs_procedures[NFSPROC_RENAME];
359}360}
fs/nfs/super.c+3−30
@@ -1051,16 +1051,6 @@ int nfs_reconfigure(struct fs_context *fc) · 1050 unmodified lines
1051 1051
1052 sync_filesystem(sb);1052 sync_filesystem(sb);
1053 1053
1054 /*
1055 * The SB_RDONLY flag has been removed from the superblock during
1056 * mounts to prevent interference between different filesystems.
1057 * Similarly, it is also necessary to ignore the SB_RDONLY flag
1058 * during reconfiguration; otherwise, it may also result in the
1059 * creation of redundant superblocks when mounting a directory with
1060 * different rw and ro flags multiple times.
1061 */
1062 fc->sb_flags_mask &= ~SB_RDONLY;
1063
1064 /*1054 /*
1065 * Userspace mount programs that send binary options generally send1055 * Userspace mount programs that send binary options generally send
1066 * them populated with default values. We have no way to know which1056 * them populated with default values. We have no way to know which
@@ -1101,8 +1091,9 @@ static void nfs_fill_super(struct super_block *sb, struct nfs_fs_context *ctx) · 34 unmodified lines
1101 sb->s_blocksize = 0;1091 sb->s_blocksize = 0;
1102 sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr;1092 sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr;
1103 sb->s_op = server->nfs_client->cl_nfs_mod->sops;1093 sb->s_op = server->nfs_client->cl_nfs_mod->sops;
1104 if (ctx->bsize)1094 if (server->bsize)
1105 sb->s_blocksize = nfs_block_size(ctx->bsize, &sb->s_blocksize_bits);1095 sb->s_blocksize =
1096 nfs_block_size(server->bsize, &sb->s_blocksize_bits);
1106 1097
1107 switch (server->nfs_client->rpc_ops->version) {1098 switch (server->nfs_client->rpc_ops->version) {
1108 case 2:1099 case 2:
@@ -1318,26 +1309,13 @@ int nfs_get_tree_common(struct fs_context *fc) · 209 unmodified lines
1318 if (IS_ERR(server))1309 if (IS_ERR(server))
1319 return PTR_ERR(server);1310 return PTR_ERR(server);
1320 1311
1321 /*
1322 * When NFS_MOUNT_UNSHARED is not set, NFS forces the sharing of a
1323 * superblock among each filesystem that mounts sub-directories
1324 * belonging to a single exported root path.
1325 * To prevent interference between different filesystems, the
1326 * SB_RDONLY flag should be removed from the superblock.
1327 */
1328 if (server->flags & NFS_MOUNT_UNSHARED)1312 if (server->flags & NFS_MOUNT_UNSHARED)
1329 compare_super = NULL;1313 compare_super = NULL;
1330 else
1331 fc->sb_flags &= ~SB_RDONLY;
1332 1314
1333 /* -o noac implies -o sync */1315 /* -o noac implies -o sync */
1334 if (server->flags & NFS_MOUNT_NOAC)1316 if (server->flags & NFS_MOUNT_NOAC)
1335 fc->sb_flags |= SB_SYNCHRONOUS;1317 fc->sb_flags |= SB_SYNCHRONOUS;
1336 1318
1337 if (ctx->clone_data.sb)
1338 if (ctx->clone_data.sb->s_flags & SB_SYNCHRONOUS)
1339 fc->sb_flags |= SB_SYNCHRONOUS;
1340
1341 /* Get a superblock - note that we may end up sharing one that already exists */1319 /* Get a superblock - note that we may end up sharing one that already exists */
1342 fc->s_fs_info = server;1320 fc->s_fs_info = server;
1343 s = sget_fc(fc, compare_super, nfs_set_super);1321 s = sget_fc(fc, compare_super, nfs_set_super);
@@ -1361,13 +1339,8 @@ int nfs_get_tree_common(struct fs_context *fc) · 17 unmodified lines
1361 }1339 }
1362 1340
1363 if (!s->s_root) {1341 if (!s->s_root) {
1364 unsigned bsize = ctx->clone_data.inherited_bsize;
1365 /* initial superblock/root creation */1342 /* initial superblock/root creation */
1366 nfs_fill_super(s, ctx);1343 nfs_fill_super(s, ctx);
1367 if (bsize) {
1368 s->s_blocksize_bits = bsize;
1369 s->s_blocksize = 1U << bsize;
1370 }
1371 error = nfs_get_cache_cookie(s, ctx);1344 error = nfs_get_cache_cookie(s, ctx);
1372 if (error < 0)1345 if (error < 0)
1373 goto error_splat_super;1346 goto error_splat_super;
fs/nfs/unlink.c+2−1
@@ -390,7 +390,8 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir, · 389 unmodified lines
390 390
391 nfs_sb_active(old_dir->i_sb);391 nfs_sb_active(old_dir->i_sb);
392 392
393 NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dentry, new_dentry);393 NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dentry, new_dentry,
394 old_dir == new_dir ? old_dir : NULL);
394 395
395 return rpc_run_task(&task_setup_data);396 return rpc_run_task(&task_setup_data);
396}397}
include/linux/nfs_fs.h+1−0
@@ -344,6 +344,7 @@ struct nfs4_copy_state { · 343 unmodified lines
344#define NFS_INO_LAYOUTCOMMITTING (10) /* layoutcommit inflight */344#define NFS_INO_LAYOUTCOMMITTING (10) /* layoutcommit inflight */
345#define NFS_INO_LAYOUTSTATS (11) /* layoutstats inflight */345#define NFS_INO_LAYOUTSTATS (11) /* layoutstats inflight */
346#define NFS_INO_ODIRECT (12) /* I/O setting is O_DIRECT */346#define NFS_INO_ODIRECT (12) /* I/O setting is O_DIRECT */
347#define NFS_INO_REQ_DIR_DELEG (13) /* Request a directory delegation */
347 348
348static inline struct nfs_inode *NFS_I(const struct inode *inode)349static inline struct nfs_inode *NFS_I(const struct inode *inode)
349{350{
include/linux/nfs_fs_sb.h+6−0
@@ -172,6 +172,11 @@ struct nfs_server { · 171 unmodified lines
172#define NFS_MOUNT_FORCE_RDIRPLUS 0x20000000172#define NFS_MOUNT_FORCE_RDIRPLUS 0x20000000
173#define NFS_MOUNT_NETUNREACH_FATAL 0x40000000173#define NFS_MOUNT_NETUNREACH_FATAL 0x40000000
174 174
175 unsigned int automount_inherit; /* Properties inherited by automount */
176#define NFS_AUTOMOUNT_INHERIT_BSIZE 0x0001
177#define NFS_AUTOMOUNT_INHERIT_RSIZE 0x0002
178#define NFS_AUTOMOUNT_INHERIT_WSIZE 0x0004
179
175 unsigned int caps; /* server capabilities */180 unsigned int caps; /* server capabilities */
176 __u64 fattr_valid; /* Valid attributes */181 __u64 fattr_valid; /* Valid attributes */
177 unsigned int rsize; /* read size */182 unsigned int rsize; /* read size */
@@ -305,6 +310,7 @@ struct nfs_server { · 127 unmodified lines
305#define NFS_CAP_REBOOT_LAYOUTRETURN (1U << 8)310#define NFS_CAP_REBOOT_LAYOUTRETURN (1U << 8)
306#define NFS_CAP_OFFLOAD_STATUS (1U << 9)311#define NFS_CAP_OFFLOAD_STATUS (1U << 9)
307#define NFS_CAP_ZERO_RANGE (1U << 10)312#define NFS_CAP_ZERO_RANGE (1U << 10)
313#define NFS_CAP_DIR_DELEG (1U << 11)
308#define NFS_CAP_OPEN_XOR (1U << 12)314#define NFS_CAP_OPEN_XOR (1U << 12)
309#define NFS_CAP_DELEGTIME (1U << 13)315#define NFS_CAP_DELEGTIME (1U << 13)
310#define NFS_CAP_POSIX_LOCK (1U << 14)316#define NFS_CAP_POSIX_LOCK (1U << 14)
include/linux/nfs_xdr.h+9−1
@@ -1092,12 +1092,19 @@ struct nfs4_getattr_arg { · 1091 unmodified lines
1092 struct nfs4_sequence_args seq_args;1092 struct nfs4_sequence_args seq_args;
1093 const struct nfs_fh * fh;1093 const struct nfs_fh * fh;
1094 const u32 * bitmask;1094 const u32 * bitmask;
1095 bool get_dir_deleg;
1096};
1097
1098struct nfs4_gdd_res {
1099 u32 status;
1100 nfs4_stateid deleg;
1095};1101};
1096 1102
1097struct nfs4_getattr_res {1103struct nfs4_getattr_res {
1098 struct nfs4_sequence_res seq_res;1104 struct nfs4_sequence_res seq_res;
1099 const struct nfs_server * server;1105 const struct nfs_server * server;
1100 struct nfs_fattr * fattr;1106 struct nfs_fattr * fattr;
1107 struct nfs4_gdd_res * gdd_res;
1101};1108};
1102 1109
1103struct nfs4_link_arg {1110struct nfs4_link_arg {
@@ -1801,7 +1808,8 @@ struct nfs_rpc_ops { · 697 unmodified lines
1801 int (*unlink_done) (struct rpc_task *, struct inode *);1808 int (*unlink_done) (struct rpc_task *, struct inode *);
1802 void (*rename_setup) (struct rpc_message *msg,1809 void (*rename_setup) (struct rpc_message *msg,
1803 struct dentry *old_dentry,1810 struct dentry *old_dentry,
1804 struct dentry *new_dentry);1811 struct dentry *new_dentry,
1812 struct inode *same_parent);
1805 void (*rename_rpc_prepare)(struct rpc_task *task, struct nfs_renamedata *);1813 void (*rename_rpc_prepare)(struct rpc_task *task, struct nfs_renamedata *);
1806 int (*rename_done) (struct rpc_task *task, struct inode *old_dir, struct inode *new_dir);1814 int (*rename_done) (struct rpc_task *task, struct inode *old_dir, struct inode *new_dir);
1807 int (*link) (struct inode *, struct inode *, const struct qstr *);1815 int (*link) (struct inode *, struct inode *, const struct qstr *);
include/linux/sunrpc/bc_xprt.h+7−0
@@ -25,12 +25,14 @@ void xprt_init_bc_request(struct rpc_rqst *req, struct rpc_task *task, · 24 unmodified lines
25void xprt_free_bc_request(struct rpc_rqst *req);25void xprt_free_bc_request(struct rpc_rqst *req);
26int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs);26int xprt_setup_backchannel(struct rpc_xprt *, unsigned int min_reqs);
27void xprt_destroy_backchannel(struct rpc_xprt *, unsigned int max_reqs);27void xprt_destroy_backchannel(struct rpc_xprt *, unsigned int max_reqs);
28void xprt_enqueue_bc_request(struct rpc_rqst *req);
28 29
29/* Socket backchannel transport methods */30/* Socket backchannel transport methods */
30int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs);31int xprt_setup_bc(struct rpc_xprt *xprt, unsigned int min_reqs);
31void xprt_destroy_bc(struct rpc_xprt *xprt, unsigned int max_reqs);32void xprt_destroy_bc(struct rpc_xprt *xprt, unsigned int max_reqs);
32void xprt_free_bc_rqst(struct rpc_rqst *req);33void xprt_free_bc_rqst(struct rpc_rqst *req);
33unsigned int xprt_bc_max_slots(struct rpc_xprt *xprt);34unsigned int xprt_bc_max_slots(struct rpc_xprt *xprt);
35void xprt_svc_destroy_nullify_bc(struct rpc_xprt *xprt, struct svc_serv **serv);
34 36
35/*37/*
36 * Determine if a shared backchannel is in use38 * Determine if a shared backchannel is in use
@@ -68,5 +70,10 @@ static inline void set_bc_enabled(struct svc_serv *serv) · 31 unmodified lines
68static inline void xprt_free_bc_request(struct rpc_rqst *req)70static inline void xprt_free_bc_request(struct rpc_rqst *req)
69{71{
70}72}
73
74static inline void xprt_svc_destroy_nullify_bc(struct rpc_xprt *xprt, struct svc_serv **serv)
75{
76 svc_destroy(serv);
77}
71#endif /* CONFIG_SUNRPC_BACKCHANNEL */78#endif /* CONFIG_SUNRPC_BACKCHANNEL */
72#endif /* _LINUX_SUNRPC_BC_XPRT_H */79#endif /* _LINUX_SUNRPC_BC_XPRT_H */
net/sunrpc/backchannel_rqst.c+32−3
@@ -24,6 +24,22 @@ unsigned int xprt_bc_max_slots(struct rpc_xprt *xprt) · 23 unmodified lines
24 return BC_MAX_SLOTS;24 return BC_MAX_SLOTS;
25}25}
26 26
27/*
28 * Helper function to nullify backchannel server pointer in transport.
29 * We need to synchronize setting the pointer to NULL (done so after
30 * the backchannel server is shutdown) with the usage of that pointer
31 * by the backchannel request processing routines
32 * xprt_complete_bc_request() and rpcrdma_bc_receive_call().
33 */
34void xprt_svc_destroy_nullify_bc(struct rpc_xprt *xprt, struct svc_serv **serv)
35{
36 spin_lock(&xprt->bc_pa_lock);
37 svc_destroy(serv);
38 xprt->bc_serv = NULL;
39 spin_unlock(&xprt->bc_pa_lock);
40}
41EXPORT_SYMBOL_GPL(xprt_svc_destroy_nullify_bc);
42
27/*43/*
28 * Helper routines that track the number of preallocation elements44 * Helper routines that track the number of preallocation elements
29 * on the transport.45 * on the transport.
@@ -354,7 +370,6 @@ found: · 324 unmodified lines
354void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied)370void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied)
355{371{
356 struct rpc_xprt *xprt = req->rq_xprt;372 struct rpc_xprt *xprt = req->rq_xprt;
357 struct svc_serv *bc_serv = xprt->bc_serv;
358 373
359 spin_lock(&xprt->bc_pa_lock);374 spin_lock(&xprt->bc_pa_lock);
360 list_del(&req->rq_bc_pa_list);375 list_del(&req->rq_bc_pa_list);
@@ -365,7 +380,21 @@ void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied) · 4 unmodified lines
365 set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state);380 set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state);
366 381
367 dprintk("RPC: add callback request to list\n");382 dprintk("RPC: add callback request to list\n");
383 xprt_enqueue_bc_request(req);
384}
385
386void xprt_enqueue_bc_request(struct rpc_rqst *req)
387{
388 struct rpc_xprt *xprt = req->rq_xprt;
389 struct svc_serv *bc_serv;
390
368 xprt_get(xprt);391 xprt_get(xprt);
369 lwq_enqueue(&req->rq_bc_list, &bc_serv->sv_cb_list);392 spin_lock(&xprt->bc_pa_lock);
370 svc_pool_wake_idle_thread(&bc_serv->sv_pools[0]);393 bc_serv = xprt->bc_serv;
394 if (bc_serv) {
395 lwq_enqueue(&req->rq_bc_list, &bc_serv->sv_cb_list);
396 svc_pool_wake_idle_thread(&bc_serv->sv_pools[0]);
397 }
398 spin_unlock(&xprt->bc_pa_lock);
371}399}
400EXPORT_SYMBOL_GPL(xprt_enqueue_bc_request);
net/sunrpc/xprtrdma/backchannel.c+2−6
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#include <linux/sunrpc/svc.h>9#include <linux/sunrpc/svc.h>
10#include <linux/sunrpc/svc_xprt.h>10#include <linux/sunrpc/svc_xprt.h>
11#include <linux/sunrpc/svc_rdma.h>11#include <linux/sunrpc/svc_rdma.h>
12#include <linux/sunrpc/bc_xprt.h>
12 13
13#include "xprt_rdma.h"14#include "xprt_rdma.h"
14#include <trace/events/rpcrdma.h>15#include <trace/events/rpcrdma.h>
@@ -220,7 +221,6 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt, · 205 unmodified lines
220 struct rpcrdma_rep *rep)221 struct rpcrdma_rep *rep)
221{222{
222 struct rpc_xprt *xprt = &r_xprt->rx_xprt;223 struct rpc_xprt *xprt = &r_xprt->rx_xprt;
223 struct svc_serv *bc_serv;
224 struct rpcrdma_req *req;224 struct rpcrdma_req *req;
225 struct rpc_rqst *rqst;225 struct rpc_rqst *rqst;
226 struct xdr_buf *buf;226 struct xdr_buf *buf;
@@ -261,11 +261,7 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt, · 34 unmodified lines
261 trace_xprtrdma_cb_call(r_xprt, rqst);261 trace_xprtrdma_cb_call(r_xprt, rqst);
262 262
263 /* Queue rqst for ULP's callback service */263 /* Queue rqst for ULP's callback service */
264 bc_serv = xprt->bc_serv;264 xprt_enqueue_bc_request(rqst);
265 xprt_get(xprt);
266 lwq_enqueue(&rqst->rq_bc_list, &bc_serv->sv_cb_list);
267
268 svc_pool_wake_idle_thread(&bc_serv->sv_pools[0]);
269 265
270 r_xprt->rx_stats.bcall_count++;266 r_xprt->rx_stats.bcall_count++;
271 return;267 return;