History

Merge tag 'nfs-for-4.13-1' of git://git.linux-nfs.org/projects/anna/linux-nfs

Pull NFS client updates from Anna Schumaker: "Stable bugfixes: - Fix -EACCESS on commit to DS handling - Fix initialization of nfs_page_array->npages - Only invalidate dentries that are actually invalid Features: - Enable NFSoRDMA transparent state migration - Add support for lookup-by-filehandle - Add support for nfs re-exporting Other bugfixes and cleanups: - Christoph cleaned up the way we declare NFS operations - Clean up various internal structures - Various cleanups to commits - Various improvements to error handling - Set the dt_type of . and .. entries in NFS v4 - Make slot allocation more reliable - Fix fscache stat printing - Fix uninitialized variable warnings - Fix potential list overrun in nfs_atomic_open() - Fix a race in NFSoRDMA RPC reply handler - Fix return size for nfs42_proc_copy() - Fix against MAC forgery timing attacks" * tag 'nfs-for-4.13-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (68 commits) NFS: Don't run wake_up_bit() when nobody is waiting... nfs: add export operations nfs4: add NFSv4 LOOKUPP handlers nfs: add a nfs_ilookup helper nfs: replace d_add with d_splice_alias in atomic_open sunrpc: use constant time memory comparison for mac NFSv4.2 fix size storage for nfs42_proc_copy xprtrdma: Fix documenting comments in frwr_ops.c xprtrdma: Replace PAGE_MASK with offset_in_page() xprtrdma: FMR does not need list_del_init() xprtrdma: Demote "connect" log messages NFSv4.1: Use seqid returned by EXCHANGE_ID after state migration NFSv4.1: Handle EXCHGID4_FLAG_CONFIRMED_R during NFSv4.1 migration xprtrdma: Don't defer MR recovery if ro_map fails xprtrdma: Fix FRWR invalidation error recovery xprtrdma: Fix client lock-up after application signal fires xprtrdma: Rename rpcrdma_req::rl_free xprtrdma: Pass only the list of registered MRs to ro_unmap_sync xprtrdma: Pre-mark remotely invalidated MRs xprtrdma: On invalidation failure, remove MWs from rl_registered ...

Linus Torvalds committed 9 years ago

Commit b86faee2 parents 48ea2ce b4f937c35 files · +777 −289Browse files

Unified · Split

35 files
  1. fs/nfs/Makefile +1 −1
  2. fs/nfs/dir.c +26 −16
  3. fs/nfs/export.c +177 −0
  4. fs/nfs/filelayout/filelayout.c +2 −29
  5. fs/nfs/flexfilelayout/flexfilelayout.c +0 −33
  6. fs/nfs/inode.c +32 −4
  7. fs/nfs/internal.h +5 −3
  8. fs/nfs/nfs2xdr.c +1 −1
  9. fs/nfs/nfs3proc.c +1 −1
  10. fs/nfs/nfs3xdr.c +1 −1
  11. fs/nfs/nfs42proc.c +1 −1
  12. fs/nfs/nfs4client.c +5 −0
  13. fs/nfs/nfs4idmap.c +2 −1
  14. fs/nfs/nfs4proc.c +80 −29
  15. fs/nfs/nfs4state.c +11 −5
  16. fs/nfs/nfs4trace.h +29 −0
  17. fs/nfs/nfs4xdr.c +76 −1
  18. fs/nfs/pagelist.c +20 −3
  19. fs/nfs/proc.c +1 −1
  20. fs/nfs/super.c +3 −1
  21. fs/nfs/unlink.c +13 −0
  22. fs/nfs/write.c +58 −1
  23. include/linux/nfs4.h +1 −0
  24. include/linux/nfs_fs.h +1 −0
  25. include/linux/nfs_fs_sb.h +2 −0
  26. include/linux/nfs_page.h +3 −1
  27. include/linux/nfs_xdr.h +24 −7
  28. net/sunrpc/auth_gss/gss_krb5_crypto.c +2 −1
  29. net/sunrpc/xprt.c +5 −3
  30. net/sunrpc/xprtrdma/fmr_ops.c +26 −21
  31. net/sunrpc/xprtrdma/frwr_ops.c +33 −36
  32. net/sunrpc/xprtrdma/rpc_rdma.c +81 −44
  33. net/sunrpc/xprtrdma/transport.c +2 −1
  34. net/sunrpc/xprtrdma/verbs.c +14 −41
  35. net/sunrpc/xprtrdma/xprt_rdma.h +38 −2
fs/nfs/Makefile+1−1
@@ -7,7 +7,7 @@ obj-$(CONFIG_NFS_FS) += nfs.o · 6 unmodified lines
7CFLAGS_nfstrace.o += -I$(src)7CFLAGS_nfstrace.o += -I$(src)
8nfs-y := client.o dir.o file.o getroot.o inode.o super.o \8nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
9 io.o direct.o pagelist.o read.o symlink.o unlink.o \9 io.o direct.o pagelist.o read.o symlink.o unlink.o \
10 write.o namespace.o mount_clnt.o nfstrace.o10 write.o namespace.o mount_clnt.o nfstrace.o export.o
11nfs-$(CONFIG_ROOT_NFS) += nfsroot.o11nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
12nfs-$(CONFIG_SYSCTL) += sysctl.o12nfs-$(CONFIG_SYSCTL) += sysctl.o
13nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o13nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
fs/nfs/dir.c+26−16
@@ -151,7 +151,7 @@ struct nfs_cache_array { · 150 unmodified lines
151 struct nfs_cache_array_entry array[0];151 struct nfs_cache_array_entry array[0];
152};152};
153 153
154typedef int (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, int);154typedef int (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, bool);
155typedef struct {155typedef struct {
156 struct file *file;156 struct file *file;
157 struct page *page;157 struct page *page;
@@ -165,8 +165,8 @@ typedef struct { · 7 unmodified lines
165 unsigned long timestamp;165 unsigned long timestamp;
166 unsigned long gencount;166 unsigned long gencount;
167 unsigned int cache_entry_index;167 unsigned int cache_entry_index;
168 unsigned int plus:1;168 bool plus;
169 unsigned int eof:1;169 bool eof;
170} nfs_readdir_descriptor_t;170} nfs_readdir_descriptor_t;
171 171
172/*172/*
@@ -355,7 +355,7 @@ int nfs_readdir_xdr_filler(struct page **pages, nfs_readdir_descriptor_t *desc, · 182 unmodified lines
355 if (error == -ENOTSUPP && desc->plus) {355 if (error == -ENOTSUPP && desc->plus) {
356 NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS;356 NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS;
357 clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);357 clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
358 desc->plus = 0;358 desc->plus = false;
359 goto again;359 goto again;
360 }360 }
361 goto error;361 goto error;
@@ -557,7 +557,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en · 195 unmodified lines
557 557
558 count++;558 count++;
559 559
560 if (desc->plus != 0)560 if (desc->plus)
561 nfs_prime_dcache(file_dentry(desc->file), entry);561 nfs_prime_dcache(file_dentry(desc->file), entry);
562 562
563 status = nfs_readdir_add_to_array(entry, page);563 status = nfs_readdir_add_to_array(entry, page);
@@ -860,7 +860,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx) · 296 unmodified lines
860 desc->ctx = ctx;860 desc->ctx = ctx;
861 desc->dir_cookie = &dir_ctx->dir_cookie;861 desc->dir_cookie = &dir_ctx->dir_cookie;
862 desc->decode = NFS_PROTO(inode)->decode_dirent;862 desc->decode = NFS_PROTO(inode)->decode_dirent;
863 desc->plus = nfs_use_readdirplus(inode, ctx) ? 1 : 0;863 desc->plus = nfs_use_readdirplus(inode, ctx);
864 864
865 if (ctx->pos == 0 || nfs_attribute_cache_expired(inode))865 if (ctx->pos == 0 || nfs_attribute_cache_expired(inode))
866 res = nfs_revalidate_mapping(inode, file->f_mapping);866 res = nfs_revalidate_mapping(inode, file->f_mapping);
@@ -885,8 +885,8 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx) · 18 unmodified lines
885 clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);885 clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
886 nfs_zap_caches(inode);886 nfs_zap_caches(inode);
887 desc->page_index = 0;887 desc->page_index = 0;
888 desc->plus = 0;888 desc->plus = false;
889 desc->eof = 0;889 desc->eof = false;
890 continue;890 continue;
891 }891 }
892 if (res < 0)892 if (res < 0)
@@ -1115,11 +1115,13 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags) · 222 unmodified lines
1115 /* Force a full look up iff the parent directory has changed */1115 /* Force a full look up iff the parent directory has changed */
1116 if (!nfs_is_exclusive_create(dir, flags) &&1116 if (!nfs_is_exclusive_create(dir, flags) &&
1117 nfs_check_verifier(dir, dentry, flags & LOOKUP_RCU)) {1117 nfs_check_verifier(dir, dentry, flags & LOOKUP_RCU)) {
1118 1118 error = nfs_lookup_verify_inode(inode, flags);
1119 if (nfs_lookup_verify_inode(inode, flags)) {1119 if (error) {
1120 if (flags & LOOKUP_RCU)1120 if (flags & LOOKUP_RCU)
1121 return -ECHILD;1121 return -ECHILD;
1122 goto out_zap_parent;1122 if (error == -ESTALE)
1123 goto out_zap_parent;
1124 goto out_error;
1123 }1125 }
1124 nfs_advise_use_readdirplus(dir);1126 nfs_advise_use_readdirplus(dir);
1125 goto out_valid;1127 goto out_valid;
@@ -1144,8 +1146,10 @@ static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags) · 18 unmodified lines
1144 trace_nfs_lookup_revalidate_enter(dir, dentry, flags);1146 trace_nfs_lookup_revalidate_enter(dir, dentry, flags);
1145 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label);1147 error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label);
1146 trace_nfs_lookup_revalidate_exit(dir, dentry, flags, error);1148 trace_nfs_lookup_revalidate_exit(dir, dentry, flags, error);
1147 if (error)1149 if (error == -ESTALE || error == -ENOENT)
1148 goto out_bad;1150 goto out_bad;
1151 if (error)
1152 goto out_error;
1149 if (nfs_compare_fh(NFS_FH(inode), fhandle))1153 if (nfs_compare_fh(NFS_FH(inode), fhandle))
1150 goto out_bad;1154 goto out_bad;
1151 if ((error = nfs_refresh_inode(inode, fattr)) != 0)1155 if ((error = nfs_refresh_inode(inode, fattr)) != 0)
@@ -1427,8 +1431,10 @@ static int nfs_finish_open(struct nfs_open_context *ctx, · 275 unmodified lines
1427 err = finish_open(file, dentry, do_open, opened);1431 err = finish_open(file, dentry, do_open, opened);
1428 if (err)1432 if (err)
1429 goto out;1433 goto out;
1430 nfs_file_set_open_context(file, ctx);1434 if (S_ISREG(file->f_path.dentry->d_inode->i_mode))
1431 1435 nfs_file_set_open_context(file, ctx);
1436 else
1437 err = -ESTALE;
1432out:1438out:
1433 return err;1439 return err;
1434}1440}
@@ -1512,7 +1518,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, · 77 unmodified lines
1512 d_drop(dentry);1518 d_drop(dentry);
1513 switch (err) {1519 switch (err) {
1514 case -ENOENT:1520 case -ENOENT:
1515 d_add(dentry, NULL);1521 d_splice_alias(NULL, dentry);
1516 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));1522 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1517 break;1523 break;
1518 case -EISDIR:1524 case -EISDIR:
@@ -2035,7 +2041,11 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, · 516 unmodified lines
2035 }2041 }
2036 2042
2037 error = rpc_wait_for_completion_task(task);2043 error = rpc_wait_for_completion_task(task);
2038 if (error == 0)2044 if (error != 0) {
2045 ((struct nfs_renamedata *)task->tk_calldata)->cancelled = 1;
2046 /* Paired with the atomic_dec_and_test() barrier in rpc_do_put_task() */
2047 smp_wmb();
2048 } else
2039 error = task->tk_status;2049 error = task->tk_status;
2040 rpc_put_task(task);2050 rpc_put_task(task);
2041 nfs_mark_for_revalidate(old_inode);2051 nfs_mark_for_revalidate(old_inode);
fs/nfs/export.c+177−0
@@ -0,0 +1,177 @@
1/*
2 * Copyright (c) 2015, Primary Data, Inc. All rights reserved.
3 *
4 * Tao Peng <bergwolf@primarydata.com>
5 */
6#include <linux/dcache.h>
7#include <linux/exportfs.h>
8#include <linux/nfs.h>
9#include <linux/nfs_fs.h>
10
11#include "internal.h"
12#include "nfstrace.h"
13
14#define NFSDBG_FACILITY NFSDBG_VFS
15
16enum {
17 FILEID_HIGH_OFF = 0, /* inode fileid high */
18 FILEID_LOW_OFF, /* inode fileid low */
19 FILE_I_TYPE_OFF, /* inode type */
20 EMBED_FH_OFF /* embeded server fh */
21};
22
23
24static struct nfs_fh *nfs_exp_embedfh(__u32 *p)
25{
26 return (struct nfs_fh *)(p + EMBED_FH_OFF);
27}
28
29/*
30 * Let's break subtree checking for now... otherwise we'll have to embed parent fh
31 * but there might not be enough space.
32 */
33static int
34nfs_encode_fh(struct inode *inode, __u32 *p, int *max_len, struct inode *parent)
35{
36 struct nfs_fh *server_fh = NFS_FH(inode);
37 struct nfs_fh *clnt_fh = nfs_exp_embedfh(p);
38 size_t fh_size = offsetof(struct nfs_fh, data) + server_fh->size;
39 int len = EMBED_FH_OFF + XDR_QUADLEN(fh_size);
40
41 dprintk("%s: max fh len %d inode %p parent %p",
42 __func__, *max_len, inode, parent);
43
44 if (*max_len < len || IS_AUTOMOUNT(inode)) {
45 dprintk("%s: fh len %d too small, required %d\n",
46 __func__, *max_len, len);
47 *max_len = len;
48 return FILEID_INVALID;
49 }
50 if (IS_AUTOMOUNT(inode)) {
51 *max_len = FILEID_INVALID;
52 goto out;
53 }
54
55 p[FILEID_HIGH_OFF] = NFS_FILEID(inode) >> 32;
56 p[FILEID_LOW_OFF] = NFS_FILEID(inode);
57 p[FILE_I_TYPE_OFF] = inode->i_mode & S_IFMT;
58 p[len - 1] = 0; /* Padding */
59 nfs_copy_fh(clnt_fh, server_fh);
60 *max_len = len;
61out:
62 dprintk("%s: result fh fileid %llu mode %u size %d\n",
63 __func__, NFS_FILEID(inode), inode->i_mode, *max_len);
64 return *max_len;
65}
66
67static struct dentry *
68nfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
69 int fh_len, int fh_type)
70{
71 struct nfs4_label *label = NULL;
72 struct nfs_fattr *fattr = NULL;
73 struct nfs_fh *server_fh = nfs_exp_embedfh(fid->raw);
74 size_t fh_size = offsetof(struct nfs_fh, data) + server_fh->size;
75 const struct nfs_rpc_ops *rpc_ops;
76 struct dentry *dentry;
77 struct inode *inode;
78 int len = EMBED_FH_OFF + XDR_QUADLEN(fh_size);
79 u32 *p = fid->raw;
80 int ret;
81
82 /* NULL translates to ESTALE */
83 if (fh_len < len || fh_type != len)
84 return NULL;
85
86 fattr = nfs_alloc_fattr();
87 if (fattr == NULL) {
88 dentry = ERR_PTR(-ENOMEM);
89 goto out;
90 }
91
92 fattr->fileid = ((u64)p[FILEID_HIGH_OFF] << 32) + p[FILEID_LOW_OFF];
93 fattr->mode = p[FILE_I_TYPE_OFF];
94 fattr->valid |= NFS_ATTR_FATTR_FILEID | NFS_ATTR_FATTR_TYPE;
95
96 dprintk("%s: fileid %llu mode %d\n", __func__, fattr->fileid, fattr->mode);
97
98 inode = nfs_ilookup(sb, fattr, server_fh);
99 if (inode)
100 goto out_found;
101
102 label = nfs4_label_alloc(NFS_SB(sb), GFP_KERNEL);
103 if (IS_ERR(label)) {
104 dentry = ERR_CAST(label);
105 goto out_free_fattr;
106 }
107
108 rpc_ops = NFS_SB(sb)->nfs_client->rpc_ops;
109 ret = rpc_ops->getattr(NFS_SB(sb), server_fh, fattr, label);
110 if (ret) {
111 dprintk("%s: getattr failed %d\n", __func__, ret);
112 dentry = ERR_PTR(ret);
113 goto out_free_label;
114 }
115
116 inode = nfs_fhget(sb, server_fh, fattr, label);
117
118out_found:
119 dentry = d_obtain_alias(inode);
120
121out_free_label:
122 nfs4_label_free(label);
123out_free_fattr:
124 nfs_free_fattr(fattr);
125out:
126 return dentry;
127}
128
129static struct dentry *
130nfs_get_parent(struct dentry *dentry)
131{
132 int ret;
133 struct inode *inode = d_inode(dentry), *pinode;
134 struct super_block *sb = inode->i_sb;
135 struct nfs_server *server = NFS_SB(sb);
136 struct nfs_fattr *fattr = NULL;
137 struct nfs4_label *label = NULL;
138 struct dentry *parent;
139 struct nfs_rpc_ops const *ops = server->nfs_client->rpc_ops;
140 struct nfs_fh fh;
141
142 if (!ops->lookupp)
143 return ERR_PTR(-EACCES);
144
145 fattr = nfs_alloc_fattr();
146 if (fattr == NULL) {
147 parent = ERR_PTR(-ENOMEM);
148 goto out;
149 }
150
151 label = nfs4_label_alloc(server, GFP_KERNEL);
152 if (IS_ERR(label)) {
153 parent = ERR_CAST(label);
154 goto out_free_fattr;
155 }
156
157 ret = ops->lookupp(inode, &fh, fattr, label);
158 if (ret) {
159 parent = ERR_PTR(ret);
160 goto out_free_label;
161 }
162
163 pinode = nfs_fhget(sb, &fh, fattr, label);
164 parent = d_obtain_alias(pinode);
165out_free_label:
166 nfs4_label_free(label);
167out_free_fattr:
168 nfs_free_fattr(fattr);
169out:
170 return parent;
171}
172
173const struct export_operations nfs_export_ops = {
174 .encode_fh = nfs_encode_fh,
175 .fh_to_dentry = nfs_fh_to_dentry,
176 .get_parent = nfs_get_parent,
177};
fs/nfs/filelayout/filelayout.c+2−29
@@ -126,32 +126,13 @@ static int filelayout_async_handle_error(struct rpc_task *task, · 125 unmodified lines
126{126{
127 struct pnfs_layout_hdr *lo = lseg->pls_layout;127 struct pnfs_layout_hdr *lo = lseg->pls_layout;
128 struct inode *inode = lo->plh_inode;128 struct inode *inode = lo->plh_inode;
129 struct nfs_server *mds_server = NFS_SERVER(inode);
130 struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);129 struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
131 struct nfs_client *mds_client = mds_server->nfs_client;
132 struct nfs4_slot_table *tbl = &clp->cl_session->fc_slot_table;130 struct nfs4_slot_table *tbl = &clp->cl_session->fc_slot_table;
133 131
134 if (task->tk_status >= 0)132 if (task->tk_status >= 0)
135 return 0;133 return 0;
136 134
137 switch (task->tk_status) {135 switch (task->tk_status) {
138 /* MDS state errors */
139 case -NFS4ERR_DELEG_REVOKED:
140 case -NFS4ERR_ADMIN_REVOKED:
141 case -NFS4ERR_BAD_STATEID:
142 case -NFS4ERR_OPENMODE:
143 if (state == NULL)
144 break;
145 if (nfs4_schedule_stateid_recovery(mds_server, state) < 0)
146 goto out_bad_stateid;
147 goto wait_on_recovery;
148 case -NFS4ERR_EXPIRED:
149 if (state != NULL) {
150 if (nfs4_schedule_stateid_recovery(mds_server, state) < 0)
151 goto out_bad_stateid;
152 }
153 nfs4_schedule_lease_recovery(mds_client);
154 goto wait_on_recovery;
155 /* DS session errors */136 /* DS session errors */
156 case -NFS4ERR_BADSESSION:137 case -NFS4ERR_BADSESSION:
157 case -NFS4ERR_BADSLOT:138 case -NFS4ERR_BADSLOT:
@@ -172,6 +153,7 @@ static int filelayout_async_handle_error(struct rpc_task *task, · 14 unmodified lines
172 case -NFS4ERR_RETRY_UNCACHED_REP:153 case -NFS4ERR_RETRY_UNCACHED_REP:
173 break;154 break;
174 /* Invalidate Layout errors */155 /* Invalidate Layout errors */
156 case -NFS4ERR_ACCESS:
175 case -NFS4ERR_PNFS_NO_LAYOUT:157 case -NFS4ERR_PNFS_NO_LAYOUT:
176 case -ESTALE: /* mapped NFS4ERR_STALE */158 case -ESTALE: /* mapped NFS4ERR_STALE */
177 case -EBADHANDLE: /* mapped NFS4ERR_BADHANDLE */159 case -EBADHANDLE: /* mapped NFS4ERR_BADHANDLE */
@@ -202,26 +184,17 @@ static int filelayout_async_handle_error(struct rpc_task *task, · 24 unmodified lines
202 task->tk_status);184 task->tk_status);
203 nfs4_mark_deviceid_unavailable(devid);185 nfs4_mark_deviceid_unavailable(devid);
204 pnfs_error_mark_layout_for_return(inode, lseg);186 pnfs_error_mark_layout_for_return(inode, lseg);
187 pnfs_set_lo_fail(lseg);
205 rpc_wake_up(&tbl->slot_tbl_waitq);188 rpc_wake_up(&tbl->slot_tbl_waitq);
206 /* fall through */189 /* fall through */
207 default:190 default:
208 pnfs_set_lo_fail(lseg);
209reset:191reset:
210 dprintk("%s Retry through MDS. Error %d\n", __func__,192 dprintk("%s Retry through MDS. Error %d\n", __func__,
211 task->tk_status);193 task->tk_status);
212 return -NFS4ERR_RESET_TO_MDS;194 return -NFS4ERR_RESET_TO_MDS;
213 }195 }
214out:
215 task->tk_status = 0;196 task->tk_status = 0;
216 return -EAGAIN;197 return -EAGAIN;
217out_bad_stateid:
218 task->tk_status = -EIO;
219 return 0;
220wait_on_recovery:
221 rpc_sleep_on(&mds_client->cl_rpcwaitq, task, NULL);
222 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &mds_client->cl_state) == 0)
223 rpc_wake_up_queued_task(&mds_client->cl_rpcwaitq, task);
224 goto out;
225}198}
226 199
227/* NFS_PROTO call done callback routines */200/* NFS_PROTO call done callback routines */
fs/nfs/flexfilelayout/flexfilelayout.c+0−33
@@ -1050,34 +1050,10 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task, · 1049 unmodified lines
1050{1050{
1051 struct pnfs_layout_hdr *lo = lseg->pls_layout;1051 struct pnfs_layout_hdr *lo = lseg->pls_layout;
1052 struct inode *inode = lo->plh_inode;1052 struct inode *inode = lo->plh_inode;
1053 struct nfs_server *mds_server = NFS_SERVER(inode);
1054
1055 struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx);1053 struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx);
1056 struct nfs_client *mds_client = mds_server->nfs_client;
1057 struct nfs4_slot_table *tbl = &clp->cl_session->fc_slot_table;1054 struct nfs4_slot_table *tbl = &clp->cl_session->fc_slot_table;
1058 1055
1059 switch (task->tk_status) {1056 switch (task->tk_status) {
1060 /* MDS state errors */
1061 case -NFS4ERR_DELEG_REVOKED:
1062 case -NFS4ERR_ADMIN_REVOKED:
1063 case -NFS4ERR_BAD_STATEID:
1064 if (state == NULL)
1065 break;
1066 nfs_remove_bad_delegation(state->inode, NULL);
1067 case -NFS4ERR_OPENMODE:
1068 if (state == NULL)
1069 break;
1070 if (nfs4_schedule_stateid_recovery(mds_server, state) < 0)
1071 goto out_bad_stateid;
1072 goto wait_on_recovery;
1073 case -NFS4ERR_EXPIRED:
1074 if (state != NULL) {
1075 if (nfs4_schedule_stateid_recovery(mds_server, state) < 0)
1076 goto out_bad_stateid;
1077 }
1078 nfs4_schedule_lease_recovery(mds_client);
1079 goto wait_on_recovery;
1080 /* DS session errors */
1081 case -NFS4ERR_BADSESSION:1057 case -NFS4ERR_BADSESSION:
1082 case -NFS4ERR_BADSLOT:1058 case -NFS4ERR_BADSLOT:
1083 case -NFS4ERR_BAD_HIGH_SLOT:1059 case -NFS4ERR_BAD_HIGH_SLOT:
@@ -1137,17 +1113,8 @@ reset: · 53 unmodified lines
1137 task->tk_status);1113 task->tk_status);
1138 return -NFS4ERR_RESET_TO_MDS;1114 return -NFS4ERR_RESET_TO_MDS;
1139 }1115 }
1140out:
1141 task->tk_status = 0;1116 task->tk_status = 0;
1142 return -EAGAIN;1117 return -EAGAIN;
1143out_bad_stateid:
1144 task->tk_status = -EIO;
1145 return 0;
1146wait_on_recovery:
1147 rpc_sleep_on(&mds_client->cl_rpcwaitq, task, NULL);
1148 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &mds_client->cl_state) == 0)
1149 rpc_wake_up_queued_task(&mds_client->cl_rpcwaitq, task);
1150 goto out;
1151}1118}
1152 1119
1153/* Retry all errors through either pNFS or MDS except for -EJUKEBOX */1120/* Retry all errors through either pNFS or MDS except for -EJUKEBOX */
fs/nfs/inode.c+32−4
@@ -386,6 +386,28 @@ void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr, · 385 unmodified lines
386#endif386#endif
387EXPORT_SYMBOL_GPL(nfs_setsecurity);387EXPORT_SYMBOL_GPL(nfs_setsecurity);
388 388
389/* Search for inode identified by fh, fileid and i_mode in inode cache. */
390struct inode *
391nfs_ilookup(struct super_block *sb, struct nfs_fattr *fattr, struct nfs_fh *fh)
392{
393 struct nfs_find_desc desc = {
394 .fh = fh,
395 .fattr = fattr,
396 };
397 struct inode *inode;
398 unsigned long hash;
399
400 if (!(fattr->valid & NFS_ATTR_FATTR_FILEID) ||
401 !(fattr->valid & NFS_ATTR_FATTR_TYPE))
402 return NULL;
403
404 hash = nfs_fattr_to_ino_t(fattr);
405 inode = ilookup5(sb, hash, nfs_find_actor, &desc);
406
407 dprintk("%s: returning %p\n", __func__, inode);
408 return inode;
409}
410
389/*411/*
390 * This is our front-end to iget that looks up inodes by file handle412 * This is our front-end to iget that looks up inodes by file handle
391 * instead of inode number.413 * instead of inode number.
@@ -525,8 +547,14 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st · 133 unmodified lines
525 nfs_fscache_init_inode(inode);547 nfs_fscache_init_inode(inode);
526 548
527 unlock_new_inode(inode);549 unlock_new_inode(inode);
528 } else550 } else {
529 nfs_refresh_inode(inode, fattr);551 int err = nfs_refresh_inode(inode, fattr);
552 if (err < 0) {
553 iput(inode);
554 inode = ERR_PTR(err);
555 goto out_no_inode;
556 }
557 }
530 dprintk("NFS: nfs_fhget(%s/%Lu fh_crc=0x%08x ct=%d)\n",558 dprintk("NFS: nfs_fhget(%s/%Lu fh_crc=0x%08x ct=%d)\n",
531 inode->i_sb->s_id,559 inode->i_sb->s_id,
532 (unsigned long long)NFS_FILEID(inode),560 (unsigned long long)NFS_FILEID(inode),
@@ -1315,9 +1343,9 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat · 782 unmodified lines
1315 return 0;1343 return 0;
1316 /* Has the inode gone and changed behind our back? */1344 /* Has the inode gone and changed behind our back? */
1317 if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid)1345 if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid)
1318 return -EIO;1346 return -ESTALE;
1319 if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))1347 if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
1320 return -EIO;1348 return -ESTALE;
1321 1349
1322 if (!nfs_file_has_buffered_writers(nfsi)) {1350 if (!nfs_file_has_buffered_writers(nfsi)) {
1323 /* Verify a few of the more important attributes */1351 /* Verify a few of the more important attributes */
fs/nfs/internal.h+5−3
@@ -11,6 +11,8 @@ · 10 unmodified lines
11 11
12#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)12#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
13 13
14extern const struct export_operations nfs_export_ops;
15
14struct nfs_string;16struct nfs_string;
15 17
16/* Maximum number of readahead requests18/* Maximum number of readahead requests
@@ -273,17 +275,17 @@ static inline bool nfs_match_open_context(const struct nfs_open_context *ctx1, · 256 unmodified lines
273/* nfs2xdr.c */275/* nfs2xdr.c */
274extern const struct rpc_procinfo nfs_procedures[];276extern const struct rpc_procinfo nfs_procedures[];
275extern int nfs2_decode_dirent(struct xdr_stream *,277extern int nfs2_decode_dirent(struct xdr_stream *,
276 struct nfs_entry *, int);278 struct nfs_entry *, bool);
277 279
278/* nfs3xdr.c */280/* nfs3xdr.c */
279extern const struct rpc_procinfo nfs3_procedures[];281extern const struct rpc_procinfo nfs3_procedures[];
280extern int nfs3_decode_dirent(struct xdr_stream *,282extern int nfs3_decode_dirent(struct xdr_stream *,
281 struct nfs_entry *, int);283 struct nfs_entry *, bool);
282 284
283/* nfs4xdr.c */285/* nfs4xdr.c */
284#if IS_ENABLED(CONFIG_NFS_V4)286#if IS_ENABLED(CONFIG_NFS_V4)
285extern int nfs4_decode_dirent(struct xdr_stream *,287extern int nfs4_decode_dirent(struct xdr_stream *,
286 struct nfs_entry *, int);288 struct nfs_entry *, bool);
287#endif289#endif
288#ifdef CONFIG_NFS_V4_1290#ifdef CONFIG_NFS_V4_1
289extern const u32 nfs41_maxread_overhead;291extern const u32 nfs41_maxread_overhead;
fs/nfs/nfs2xdr.c+1−1
@@ -939,7 +939,7 @@ static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr, · 938 unmodified lines
939 * };939 * };
940 */940 */
941int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,941int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
942 int plus)942 bool plus)
943{943{
944 __be32 *p;944 __be32 *p;
945 int error;945 int error;
fs/nfs/nfs3proc.c+1−1
@@ -621,7 +621,7 @@ out: · 620 unmodified lines
621 */621 */
622static int622static int
623nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,623nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
624 u64 cookie, struct page **pages, unsigned int count, int plus)624 u64 cookie, struct page **pages, unsigned int count, bool plus)
625{625{
626 struct inode *dir = d_inode(dentry);626 struct inode *dir = d_inode(dentry);
627 __be32 *verf = NFS_I(dir)->cookieverf;627 __be32 *verf = NFS_I(dir)->cookieverf;
fs/nfs/nfs3xdr.c+1−1
@@ -1991,7 +1991,7 @@ out_status: · 1990 unmodified lines
1991 * };1991 * };
1992 */1992 */
1993int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,1993int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
1994 int plus)1994 bool plus)
1995{1995{
1996 struct nfs_entry old = *entry;1996 struct nfs_entry old = *entry;
1997 __be32 *p;1997 __be32 *p;
fs/nfs/nfs42proc.c+1−1
@@ -146,7 +146,7 @@ static ssize_t _nfs42_proc_copy(struct file *src, · 145 unmodified lines
146 loff_t pos_src = args->src_pos;146 loff_t pos_src = args->src_pos;
147 loff_t pos_dst = args->dst_pos;147 loff_t pos_dst = args->dst_pos;
148 size_t count = args->count;148 size_t count = args->count;
149 int status;149 ssize_t status;
150 150
151 status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context,151 status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context,
152 src_lock, FMODE_READ);152 src_lock, FMODE_READ);
fs/nfs/nfs4client.c+5−0
@@ -414,6 +414,7 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp, · 413 unmodified lines
414 if (clp != old)414 if (clp != old)
415 clp->cl_preserve_clid = true;415 clp->cl_preserve_clid = true;
416 nfs_put_client(clp);416 nfs_put_client(clp);
417 clear_bit(NFS_CS_TSM_POSSIBLE, &clp->cl_flags);
417 return old;418 return old;
418 419
419error:420error:
@@ -852,6 +853,8 @@ static int nfs4_set_client(struct nfs_server *server, · 432 unmodified lines
852 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);853 set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
853 if (server->options & NFS_OPTION_MIGRATION)854 if (server->options & NFS_OPTION_MIGRATION)
854 set_bit(NFS_CS_MIGRATION, &cl_init.init_flags);855 set_bit(NFS_CS_MIGRATION, &cl_init.init_flags);
856 if (test_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status))
857 set_bit(NFS_CS_TSM_POSSIBLE, &cl_init.init_flags);
855 858
856 /* Allocate or find a client reference we can use */859 /* Allocate or find a client reference we can use */
857 clp = nfs_get_client(&cl_init);860 clp = nfs_get_client(&cl_init);
@@ -1212,9 +1215,11 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname, · 354 unmodified lines
1212 return -EAFNOSUPPORT;1215 return -EAFNOSUPPORT;
1213 1216
1214 nfs_server_remove_lists(server);1217 nfs_server_remove_lists(server);
1218 set_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status);
1215 error = nfs4_set_client(server, hostname, sap, salen, buf,1219 error = nfs4_set_client(server, hostname, sap, salen, buf,
1216 clp->cl_proto, clnt->cl_timeout,1220 clp->cl_proto, clnt->cl_timeout,
1217 clp->cl_minorversion, net);1221 clp->cl_minorversion, net);
1222 clear_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status);
1218 nfs_put_client(clp);1223 nfs_put_client(clp);
1219 if (error != 0) {1224 if (error != 0) {
1220 nfs_server_insert_lists(server);1225 nfs_server_insert_lists(server);
fs/nfs/nfs4idmap.c+2−1
@@ -364,7 +364,8 @@ static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *typ · 363 unmodified lines
364 ret = -EINVAL;364 ret = -EINVAL;
365 } else {365 } else {
366 ret = kstrtol(id_str, 10, &id_long);366 ret = kstrtol(id_str, 10, &id_long);
367 *id = (__u32)id_long;367 if (!ret)
368 *id = (__u32)id_long;
368 }369 }
369 return ret;370 return ret;
370}371}
fs/nfs/nfs4proc.c+80−29
@@ -275,6 +275,7 @@ const u32 nfs4_fs_locations_bitmap[3] = { · 274 unmodified lines
275static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dentry,275static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dentry,
276 struct nfs4_readdir_arg *readdir)276 struct nfs4_readdir_arg *readdir)
277{277{
278 unsigned int attrs = FATTR4_WORD0_FILEID | FATTR4_WORD0_TYPE;
278 __be32 *start, *p;279 __be32 *start, *p;
279 280
280 if (cookie > 2) {281 if (cookie > 2) {
@@ -305,8 +306,9 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent · 24 unmodified lines
305 memcpy(p, ".\0\0\0", 4); /* entry */306 memcpy(p, ".\0\0\0", 4); /* entry */
306 p++;307 p++;
307 *p++ = xdr_one; /* bitmap length */308 *p++ = xdr_one; /* bitmap length */
308 *p++ = htonl(FATTR4_WORD0_FILEID); /* bitmap */309 *p++ = htonl(attrs); /* bitmap */
309 *p++ = htonl(8); /* attribute buffer length */310 *p++ = htonl(12); /* attribute buffer length */
311 *p++ = htonl(NF4DIR);
310 p = xdr_encode_hyper(p, NFS_FILEID(d_inode(dentry)));312 p = xdr_encode_hyper(p, NFS_FILEID(d_inode(dentry)));
311 }313 }
312 314
@@ -317,8 +319,9 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent · 4 unmodified lines
317 memcpy(p, "..\0\0", 4); /* entry */319 memcpy(p, "..\0\0", 4); /* entry */
318 p++;320 p++;
319 *p++ = xdr_one; /* bitmap length */321 *p++ = xdr_one; /* bitmap length */
320 *p++ = htonl(FATTR4_WORD0_FILEID); /* bitmap */322 *p++ = htonl(attrs); /* bitmap */
321 *p++ = htonl(8); /* attribute buffer length */323 *p++ = htonl(12); /* attribute buffer length */
324 *p++ = htonl(NF4DIR);
322 p = xdr_encode_hyper(p, NFS_FILEID(d_inode(dentry->d_parent)));325 p = xdr_encode_hyper(p, NFS_FILEID(d_inode(dentry->d_parent)));
323 326
324 readdir->pgbase = (char *)p - (char *)start;327 readdir->pgbase = (char *)p - (char *)start;
@@ -1034,11 +1037,11 @@ struct nfs4_opendata { · 709 unmodified lines
1034 struct nfs4_state *state;1037 struct nfs4_state *state;
1035 struct iattr attrs;1038 struct iattr attrs;
1036 unsigned long timestamp;1039 unsigned long timestamp;
1037 unsigned int rpc_done : 1;1040 bool rpc_done;
1038 unsigned int file_created : 1;1041 bool file_created;
1039 unsigned int is_recover : 1;1042 bool is_recover;
1043 bool cancelled;
1040 int rpc_status;1044 int rpc_status;
1041 int cancelled;
1042};1045};
1043 1046
1044static bool nfs4_clear_cap_atomic_open_v1(struct nfs_server *server,1047static bool nfs4_clear_cap_atomic_open_v1(struct nfs_server *server,
@@ -1962,7 +1965,7 @@ static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) · 917 unmodified lines
1962 nfs4_stateid_copy(&data->o_res.stateid, &data->c_res.stateid);1965 nfs4_stateid_copy(&data->o_res.stateid, &data->c_res.stateid);
1963 nfs_confirm_seqid(&data->owner->so_seqid, 0);1966 nfs_confirm_seqid(&data->owner->so_seqid, 0);
1964 renew_lease(data->o_res.server, data->timestamp);1967 renew_lease(data->o_res.server, data->timestamp);
1965 data->rpc_done = 1;1968 data->rpc_done = true;
1966 }1969 }
1967}1970}
1968 1971
@@ -1972,7 +1975,7 @@ static void nfs4_open_confirm_release(void *calldata) · 3 unmodified lines
1972 struct nfs4_state *state = NULL;1975 struct nfs4_state *state = NULL;
1973 1976
1974 /* If this request hasn't been cancelled, do nothing */1977 /* If this request hasn't been cancelled, do nothing */
1975 if (data->cancelled == 0)1978 if (!data->cancelled)
1976 goto out_free;1979 goto out_free;
1977 /* In case of error, no cleanup! */1980 /* In case of error, no cleanup! */
1978 if (!data->rpc_done)1981 if (!data->rpc_done)
@@ -2015,7 +2018,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data) · 36 unmodified lines
2015 2018
2016 nfs4_init_sequence(&data->c_arg.seq_args, &data->c_res.seq_res, 1);2019 nfs4_init_sequence(&data->c_arg.seq_args, &data->c_res.seq_res, 1);
2017 kref_get(&data->kref);2020 kref_get(&data->kref);
2018 data->rpc_done = 0;2021 data->rpc_done = false;
2019 data->rpc_status = 0;2022 data->rpc_status = 0;
2020 data->timestamp = jiffies;2023 data->timestamp = jiffies;
2021 if (data->is_recover)2024 if (data->is_recover)
@@ -2025,7 +2028,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data) · 3 unmodified lines
2025 return PTR_ERR(task);2028 return PTR_ERR(task);
2026 status = rpc_wait_for_completion_task(task);2029 status = rpc_wait_for_completion_task(task);
2027 if (status != 0) {2030 if (status != 0) {
2028 data->cancelled = 1;2031 data->cancelled = true;
2029 smp_wmb();2032 smp_wmb();
2030 } else2033 } else
2031 status = data->rpc_status;2034 status = data->rpc_status;
@@ -2124,7 +2127,7 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata) · 92 unmodified lines
2124 if (!(data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM))2127 if (!(data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM))
2125 nfs_confirm_seqid(&data->owner->so_seqid, 0);2128 nfs_confirm_seqid(&data->owner->so_seqid, 0);
2126 }2129 }
2127 data->rpc_done = 1;2130 data->rpc_done = true;
2128}2131}
2129 2132
2130static void nfs4_open_release(void *calldata)2133static void nfs4_open_release(void *calldata)
@@ -2133,7 +2136,7 @@ static void nfs4_open_release(void *calldata) · 2 unmodified lines
2133 struct nfs4_state *state = NULL;2136 struct nfs4_state *state = NULL;
2134 2137
2135 /* If this request hasn't been cancelled, do nothing */2138 /* If this request hasn't been cancelled, do nothing */
2136 if (data->cancelled == 0)2139 if (!data->cancelled)
2137 goto out_free;2140 goto out_free;
2138 /* In case of error, no cleanup! */2141 /* In case of error, no cleanup! */
2139 if (data->rpc_status != 0 || !data->rpc_done)2142 if (data->rpc_status != 0 || !data->rpc_done)
@@ -2179,20 +2182,20 @@ static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover) · 39 unmodified lines
2179 2182
2180 nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1);2183 nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1);
2181 kref_get(&data->kref);2184 kref_get(&data->kref);
2182 data->rpc_done = 0;2185 data->rpc_done = false;
2183 data->rpc_status = 0;2186 data->rpc_status = 0;
2184 data->cancelled = 0;2187 data->cancelled = false;
2185 data->is_recover = 0;2188 data->is_recover = false;
2186 if (isrecover) {2189 if (isrecover) {
2187 nfs4_set_sequence_privileged(&o_arg->seq_args);2190 nfs4_set_sequence_privileged(&o_arg->seq_args);
2188 data->is_recover = 1;2191 data->is_recover = true;
2189 }2192 }
2190 task = rpc_run_task(&task_setup_data);2193 task = rpc_run_task(&task_setup_data);
2191 if (IS_ERR(task))2194 if (IS_ERR(task))
2192 return PTR_ERR(task);2195 return PTR_ERR(task);
2193 status = rpc_wait_for_completion_task(task);2196 status = rpc_wait_for_completion_task(task);
2194 if (status != 0) {2197 if (status != 0) {
2195 data->cancelled = 1;2198 data->cancelled = true;
2196 smp_wmb();2199 smp_wmb();
2197 } else2200 } else
2198 status = data->rpc_status;2201 status = data->rpc_status;
@@ -2287,9 +2290,9 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) · 88 unmodified lines
2287 2290
2288 if (o_arg->open_flags & O_CREAT) {2291 if (o_arg->open_flags & O_CREAT) {
2289 if (o_arg->open_flags & O_EXCL)2292 if (o_arg->open_flags & O_EXCL)
2290 data->file_created = 1;2293 data->file_created = true;
2291 else if (o_res->cinfo.before != o_res->cinfo.after)2294 else if (o_res->cinfo.before != o_res->cinfo.after)
2292 data->file_created = 1;2295 data->file_created = true;
2293 if (data->file_created || dir->i_version != o_res->cinfo.after)2296 if (data->file_created || dir->i_version != o_res->cinfo.after)
2294 update_changeattr(dir, &o_res->cinfo,2297 update_changeattr(dir, &o_res->cinfo,
2295 o_res->f_attr->time_start);2298 o_res->f_attr->time_start);
@@ -3803,6 +3806,54 @@ nfs4_proc_lookup_mountpoint(struct inode *dir, const struct qstr *name, · 1507 unmodified lines
3803 return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client;3806 return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client;
3804}3807}
3805 3808
3809static int _nfs4_proc_lookupp(struct inode *inode,
3810 struct nfs_fh *fhandle, struct nfs_fattr *fattr,
3811 struct nfs4_label *label)
3812{
3813 struct rpc_clnt *clnt = NFS_CLIENT(inode);
3814 struct nfs_server *server = NFS_SERVER(inode);
3815 int status;
3816 struct nfs4_lookupp_arg args = {
3817 .bitmask = server->attr_bitmask,
3818 .fh = NFS_FH(inode),
3819 };
3820 struct nfs4_lookupp_res res = {
3821 .server = server,
3822 .fattr = fattr,
3823 .label = label,
3824 .fh = fhandle,
3825 };
3826 struct rpc_message msg = {
3827 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUPP],
3828 .rpc_argp = &args,
3829 .rpc_resp = &res,
3830 };
3831
3832 args.bitmask = nfs4_bitmask(server, label);
3833
3834 nfs_fattr_init(fattr);
3835
3836 dprintk("NFS call lookupp ino=0x%lx\n", inode->i_ino);
3837 status = nfs4_call_sync(clnt, server, &msg, &args.seq_args,
3838 &res.seq_res, 0);
3839 dprintk("NFS reply lookupp: %d\n", status);
3840 return status;
3841}
3842
3843static int nfs4_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle,
3844 struct nfs_fattr *fattr, struct nfs4_label *label)
3845{
3846 struct nfs4_exception exception = { };
3847 int err;
3848 do {
3849 err = _nfs4_proc_lookupp(inode, fhandle, fattr, label);
3850 trace_nfs4_lookupp(inode, err);
3851 err = nfs4_handle_exception(NFS_SERVER(inode), err,
3852 &exception);
3853 } while (exception.retry);
3854 return err;
3855}
3856
3806static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)3857static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
3807{3858{
3808 struct nfs_server *server = NFS_SERVER(inode);3859 struct nfs_server *server = NFS_SERVER(inode);
@@ -4273,7 +4324,7 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, · 464 unmodified lines
4273}4324}
4274 4325
4275static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,4326static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
4276 u64 cookie, struct page **pages, unsigned int count, int plus)4327 u64 cookie, struct page **pages, unsigned int count, bool plus)
4277{4328{
4278 struct inode *dir = d_inode(dentry);4329 struct inode *dir = d_inode(dentry);
4279 struct nfs4_readdir_arg args = {4330 struct nfs4_readdir_arg args = {
@@ -4311,7 +4362,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, · 31 unmodified lines
4311}4362}
4312 4363
4313static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,4364static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
4314 u64 cookie, struct page **pages, unsigned int count, int plus)4365 u64 cookie, struct page **pages, unsigned int count, bool plus)
4315{4366{
4316 struct nfs4_exception exception = { };4367 struct nfs4_exception exception = { };
4317 int err;4368 int err;
@@ -6135,7 +6186,7 @@ static void nfs4_lock_release(void *calldata) · 1817 unmodified lines
6135 6186
6136 dprintk("%s: begin!\n", __func__);6187 dprintk("%s: begin!\n", __func__);
6137 nfs_free_seqid(data->arg.open_seqid);6188 nfs_free_seqid(data->arg.open_seqid);
6138 if (data->cancelled != 0) {6189 if (data->cancelled) {
6139 struct rpc_task *task;6190 struct rpc_task *task;
6140 task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp,6191 task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp,
6141 data->arg.lock_seqid);6192 data->arg.lock_seqid);
@@ -6218,7 +6269,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f · 76 unmodified lines
6218 nfs4_handle_setlk_error(data->server, data->lsp,6269 nfs4_handle_setlk_error(data->server, data->lsp,
6219 data->arg.new_lock_owner, ret);6270 data->arg.new_lock_owner, ret);
6220 } else6271 } else
6221 data->cancelled = 1;6272 data->cancelled = true;
6222 rpc_put_task(task);6273 rpc_put_task(task);
6223 dprintk("%s: done, ret = %d!\n", __func__, ret);6274 dprintk("%s: done, ret = %d!\n", __func__, ret);
6224 trace_nfs4_set_lock(fl, state, &data->res.stateid, cmd, ret);6275 trace_nfs4_set_lock(fl, state, &data->res.stateid, cmd, ret);
@@ -7376,12 +7427,11 @@ static void nfs4_exchange_id_done(struct rpc_task *task, void *data) · 1151 unmodified lines
7376 if (status == 0) {7427 if (status == 0) {
7377 clp->cl_clientid = cdata->res.clientid;7428 clp->cl_clientid = cdata->res.clientid;
7378 clp->cl_exchange_flags = cdata->res.flags;7429 clp->cl_exchange_flags = cdata->res.flags;
7430 clp->cl_seqid = cdata->res.seqid;
7379 /* Client ID is not confirmed */7431 /* Client ID is not confirmed */
7380 if (!(cdata->res.flags & EXCHGID4_FLAG_CONFIRMED_R)) {7432 if (!(cdata->res.flags & EXCHGID4_FLAG_CONFIRMED_R))
7381 clear_bit(NFS4_SESSION_ESTABLISHED,7433 clear_bit(NFS4_SESSION_ESTABLISHED,
7382 &clp->cl_session->session_state);7434 &clp->cl_session->session_state);
7383 clp->cl_seqid = cdata->res.seqid;
7384 }
7385 7435
7386 kfree(clp->cl_serverowner);7436 kfree(clp->cl_serverowner);
7387 clp->cl_serverowner = cdata->res.server_owner;7437 clp->cl_serverowner = cdata->res.server_owner;
@@ -9313,6 +9363,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = { · 1925 unmodified lines
9313 .getattr = nfs4_proc_getattr,9363 .getattr = nfs4_proc_getattr,
9314 .setattr = nfs4_proc_setattr,9364 .setattr = nfs4_proc_setattr,
9315 .lookup = nfs4_proc_lookup,9365 .lookup = nfs4_proc_lookup,
9366 .lookupp = nfs4_proc_lookupp,
9316 .access = nfs4_proc_access,9367 .access = nfs4_proc_access,
9317 .readlink = nfs4_proc_readlink,9368 .readlink = nfs4_proc_readlink,
9318 .create = nfs4_proc_create,9369 .create = nfs4_proc_create,
fs/nfs/nfs4state.c+11−5
@@ -352,11 +352,17 @@ int nfs41_discover_server_trunking(struct nfs_client *clp, · 351 unmodified lines
352 if (clp != *result)352 if (clp != *result)
353 return 0;353 return 0;
354 354
355 /* Purge state if the client id was established in a prior instance */355 /*
356 if (clp->cl_exchange_flags & EXCHGID4_FLAG_CONFIRMED_R)356 * Purge state if the client id was established in a prior
357 set_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state);357 * instance and the client id could not have arrived on the
358 else358 * server via Transparent State Migration.
359 set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);359 */
360 if (clp->cl_exchange_flags & EXCHGID4_FLAG_CONFIRMED_R) {
361 if (!test_bit(NFS_CS_TSM_POSSIBLE, &clp->cl_flags))
362 set_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state);
363 else
364 set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
365 }
360 nfs4_schedule_state_manager(clp);366 nfs4_schedule_state_manager(clp);
361 status = nfs_wait_client_init_complete(clp);367 status = nfs_wait_client_init_complete(clp);
362 if (status < 0)368 if (status < 0)
fs/nfs/nfs4trace.h+29−0
@@ -891,6 +891,35 @@ DEFINE_NFS4_LOOKUP_EVENT(nfs4_remove); · 890 unmodified lines
891DEFINE_NFS4_LOOKUP_EVENT(nfs4_get_fs_locations);891DEFINE_NFS4_LOOKUP_EVENT(nfs4_get_fs_locations);
892DEFINE_NFS4_LOOKUP_EVENT(nfs4_secinfo);892DEFINE_NFS4_LOOKUP_EVENT(nfs4_secinfo);
893 893
894TRACE_EVENT(nfs4_lookupp,
895 TP_PROTO(
896 const struct inode *inode,
897 int error
898 ),
899
900 TP_ARGS(inode, error),
901
902 TP_STRUCT__entry(
903 __field(dev_t, dev)
904 __field(u64, ino)
905 __field(int, error)
906 ),
907
908 TP_fast_assign(
909 __entry->dev = inode->i_sb->s_dev;
910 __entry->ino = NFS_FILEID(inode);
911 __entry->error = error;
912 ),
913
914 TP_printk(
915 "error=%d (%s) inode=%02x:%02x:%llu",
916 __entry->error,
917 show_nfsv4_errors(__entry->error),
918 MAJOR(__entry->dev), MINOR(__entry->dev),
919 (unsigned long long)__entry->ino
920 )
921);
922
894TRACE_EVENT(nfs4_rename,923TRACE_EVENT(nfs4_rename,
895 TP_PROTO(924 TP_PROTO(
896 const struct inode *olddir,925 const struct inode *olddir,
fs/nfs/nfs4xdr.c+76−1
@@ -159,6 +159,8 @@ static int nfs4_stat_to_errno(int); · 158 unmodified lines
159 (op_decode_hdr_maxsz)159 (op_decode_hdr_maxsz)
160#define encode_lookup_maxsz (op_encode_hdr_maxsz + nfs4_name_maxsz)160#define encode_lookup_maxsz (op_encode_hdr_maxsz + nfs4_name_maxsz)
161#define decode_lookup_maxsz (op_decode_hdr_maxsz)161#define decode_lookup_maxsz (op_decode_hdr_maxsz)
162#define encode_lookupp_maxsz (op_encode_hdr_maxsz)
163#define decode_lookupp_maxsz (op_decode_hdr_maxsz)
162#define encode_share_access_maxsz \164#define encode_share_access_maxsz \
163 (2)165 (2)
164#define encode_createmode_maxsz (1 + encode_attrs_maxsz + encode_verifier_maxsz)166#define encode_createmode_maxsz (1 + encode_attrs_maxsz + encode_verifier_maxsz)
@@ -618,6 +620,18 @@ static int nfs4_stat_to_errno(int); · 453 unmodified lines
618 decode_lookup_maxsz + \620 decode_lookup_maxsz + \
619 decode_getattr_maxsz + \621 decode_getattr_maxsz + \
620 decode_getfh_maxsz)622 decode_getfh_maxsz)
623#define NFS4_enc_lookupp_sz (compound_encode_hdr_maxsz + \
624 encode_sequence_maxsz + \
625 encode_putfh_maxsz + \
626 encode_lookupp_maxsz + \
627 encode_getattr_maxsz + \
628 encode_getfh_maxsz)
629#define NFS4_dec_lookupp_sz (compound_decode_hdr_maxsz + \
630 decode_sequence_maxsz + \
631 decode_putfh_maxsz + \
632 decode_lookupp_maxsz + \
633 decode_getattr_maxsz + \
634 decode_getfh_maxsz)
621#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \635#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \
622 encode_sequence_maxsz + \636 encode_sequence_maxsz + \
623 encode_putrootfh_maxsz + \637 encode_putrootfh_maxsz + \
@@ -1368,6 +1382,11 @@ static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struc · 744 unmodified lines
1368 encode_string(xdr, name->len, name->name);1382 encode_string(xdr, name->len, name->name);
1369}1383}
1370 1384
1385static void encode_lookupp(struct xdr_stream *xdr, struct compound_hdr *hdr)
1386{
1387 encode_op_hdr(xdr, OP_LOOKUPP, decode_lookupp_maxsz, hdr);
1388}
1389
1371static void encode_share_access(struct xdr_stream *xdr, u32 share_access)1390static void encode_share_access(struct xdr_stream *xdr, u32 share_access)
1372{1391{
1373 __be32 *p;1392 __be32 *p;
@@ -2122,6 +2141,26 @@ static void nfs4_xdr_enc_lookup(struct rpc_rqst *req, struct xdr_stream *xdr, · 748 unmodified lines
2122 encode_nops(&hdr);2141 encode_nops(&hdr);
2123}2142}
2124 2143
2144/*
2145 * Encode LOOKUPP request
2146 */
2147static void nfs4_xdr_enc_lookupp(struct rpc_rqst *req, struct xdr_stream *xdr,
2148 const void *data)
2149{
2150 const struct nfs4_lookupp_arg *args = data;
2151 struct compound_hdr hdr = {
2152 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
2153 };
2154
2155 encode_compound_hdr(xdr, req, &hdr);
2156 encode_sequence(xdr, &args->seq_args, &hdr);
2157 encode_putfh(xdr, args->fh, &hdr);
2158 encode_lookupp(xdr, &hdr);
2159 encode_getfh(xdr, &hdr);
2160 encode_getfattr(xdr, args->bitmask, &hdr);
2161 encode_nops(&hdr);
2162}
2163
2125/*2164/*
2126 * Encode LOOKUP_ROOT request2165 * Encode LOOKUP_ROOT request
2127 */2166 */
@@ -5058,6 +5097,11 @@ static int decode_lookup(struct xdr_stream *xdr) · 2930 unmodified lines
5058 return decode_op_hdr(xdr, OP_LOOKUP);5097 return decode_op_hdr(xdr, OP_LOOKUP);
5059}5098}
5060 5099
5100static int decode_lookupp(struct xdr_stream *xdr)
5101{
5102 return decode_op_hdr(xdr, OP_LOOKUPP);
5103}
5104
5061/* This is too sick! */5105/* This is too sick! */
5062static int decode_space_limit(struct xdr_stream *xdr,5106static int decode_space_limit(struct xdr_stream *xdr,
5063 unsigned long *pagemod_limit)5107 unsigned long *pagemod_limit)
@@ -6237,6 +6281,36 @@ out: · 1173 unmodified lines
6237 return status;6281 return status;
6238}6282}
6239 6283
6284/*
6285 * Decode LOOKUPP response
6286 */
6287static int nfs4_xdr_dec_lookupp(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6288 void *data)
6289{
6290 struct nfs4_lookupp_res *res = data;
6291 struct compound_hdr hdr;
6292 int status;
6293
6294 status = decode_compound_hdr(xdr, &hdr);
6295 if (status)
6296 goto out;
6297 status = decode_sequence(xdr, &res->seq_res, rqstp);
6298 if (status)
6299 goto out;
6300 status = decode_putfh(xdr);
6301 if (status)
6302 goto out;
6303 status = decode_lookupp(xdr);
6304 if (status)
6305 goto out;
6306 status = decode_getfh(xdr, res->fh);
6307 if (status)
6308 goto out;
6309 status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
6310out:
6311 return status;
6312}
6313
6240/*6314/*
6241 * Decode LOOKUP_ROOT response6315 * Decode LOOKUP_ROOT response
6242 */6316 */
@@ -7447,7 +7521,7 @@ out: · 1204 unmodified lines
7447 * on a directory already in our cache.7521 * on a directory already in our cache.
7448 */7522 */
7449int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,7523int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
7450 int plus)7524 bool plus)
7451{7525{
7452 unsigned int savep;7526 unsigned int savep;
7453 uint32_t bitmap[3] = {0};7527 uint32_t bitmap[3] = {0};
@@ -7614,6 +7688,7 @@ const struct rpc_procinfo nfs4_procedures[] = { · 160 unmodified lines
7614 PROC(ACCESS, enc_access, dec_access),7688 PROC(ACCESS, enc_access, dec_access),
7615 PROC(GETATTR, enc_getattr, dec_getattr),7689 PROC(GETATTR, enc_getattr, dec_getattr),
7616 PROC(LOOKUP, enc_lookup, dec_lookup),7690 PROC(LOOKUP, enc_lookup, dec_lookup),
7691 PROC(LOOKUPP, enc_lookupp, dec_lookupp),
7617 PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root),7692 PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root),
7618 PROC(REMOVE, enc_remove, dec_remove),7693 PROC(REMOVE, enc_remove, dec_remove),
7619 PROC(RENAME, enc_rename, dec_rename),7694 PROC(RENAME, enc_rename, dec_rename),
fs/nfs/pagelist.c+20−3
@@ -50,8 +50,8 @@ void nfs_pgheader_init(struct nfs_pageio_descriptor *desc, · 49 unmodified lines
50 hdr->cred = hdr->req->wb_context->cred;50 hdr->cred = hdr->req->wb_context->cred;
51 hdr->io_start = req_offset(hdr->req);51 hdr->io_start = req_offset(hdr->req);
52 hdr->good_bytes = mirror->pg_count;52 hdr->good_bytes = mirror->pg_count;
53 hdr->io_completion = desc->pg_io_completion;
53 hdr->dreq = desc->pg_dreq;54 hdr->dreq = desc->pg_dreq;
54 hdr->layout_private = desc->pg_layout_private;
55 hdr->release = release;55 hdr->release = release;
56 hdr->completion_ops = desc->pg_completion_ops;56 hdr->completion_ops = desc->pg_completion_ops;
57 if (hdr->completion_ops->init_hdr)57 if (hdr->completion_ops->init_hdr)
@@ -155,9 +155,12 @@ nfs_page_group_lock(struct nfs_page *req, bool nonblock) · 97 unmodified lines
155 if (!test_and_set_bit(PG_HEADLOCK, &head->wb_flags))155 if (!test_and_set_bit(PG_HEADLOCK, &head->wb_flags))
156 return 0;156 return 0;
157 157
158 if (!nonblock)158 if (!nonblock) {
159 set_bit(PG_CONTENDED1, &head->wb_flags);
160 smp_mb__after_atomic();
159 return wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK,161 return wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK,
160 TASK_UNINTERRUPTIBLE);162 TASK_UNINTERRUPTIBLE);
163 }
161 164
162 return -EAGAIN;165 return -EAGAIN;
163}166}
@@ -175,6 +178,10 @@ nfs_page_group_lock_wait(struct nfs_page *req) · 11 unmodified lines
175 178
176 WARN_ON_ONCE(head != head->wb_head);179 WARN_ON_ONCE(head != head->wb_head);
177 180
181 if (!test_bit(PG_HEADLOCK, &head->wb_flags))
182 return;
183 set_bit(PG_CONTENDED1, &head->wb_flags);
184 smp_mb__after_atomic();
178 wait_on_bit(&head->wb_flags, PG_HEADLOCK,185 wait_on_bit(&head->wb_flags, PG_HEADLOCK,
179 TASK_UNINTERRUPTIBLE);186 TASK_UNINTERRUPTIBLE);
180}187}
@@ -193,6 +200,8 @@ nfs_page_group_unlock(struct nfs_page *req) · 12 unmodified lines
193 smp_mb__before_atomic();200 smp_mb__before_atomic();
194 clear_bit(PG_HEADLOCK, &head->wb_flags);201 clear_bit(PG_HEADLOCK, &head->wb_flags);
195 smp_mb__after_atomic();202 smp_mb__after_atomic();
203 if (!test_bit(PG_CONTENDED1, &head->wb_flags))
204 return;
196 wake_up_bit(&head->wb_flags, PG_HEADLOCK);205 wake_up_bit(&head->wb_flags, PG_HEADLOCK);
197}206}
198 207
@@ -383,6 +392,8 @@ void nfs_unlock_request(struct nfs_page *req) · 184 unmodified lines
383 smp_mb__before_atomic();392 smp_mb__before_atomic();
384 clear_bit(PG_BUSY, &req->wb_flags);393 clear_bit(PG_BUSY, &req->wb_flags);
385 smp_mb__after_atomic();394 smp_mb__after_atomic();
395 if (!test_bit(PG_CONTENDED2, &req->wb_flags))
396 return;
386 wake_up_bit(&req->wb_flags, PG_BUSY);397 wake_up_bit(&req->wb_flags, PG_BUSY);
387}398}
388 399
@@ -465,6 +476,10 @@ void nfs_release_request(struct nfs_page *req) · 76 unmodified lines
465int476int
466nfs_wait_on_request(struct nfs_page *req)477nfs_wait_on_request(struct nfs_page *req)
467{478{
479 if (!test_bit(PG_BUSY, &req->wb_flags))
480 return 0;
481 set_bit(PG_CONTENDED2, &req->wb_flags);
482 smp_mb__after_atomic();
468 return wait_on_bit_io(&req->wb_flags, PG_BUSY,483 return wait_on_bit_io(&req->wb_flags, PG_BUSY,
469 TASK_UNINTERRUPTIBLE);484 TASK_UNINTERRUPTIBLE);
470}485}
@@ -710,8 +725,8 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, · 239 unmodified lines
710 desc->pg_ioflags = io_flags;725 desc->pg_ioflags = io_flags;
711 desc->pg_error = 0;726 desc->pg_error = 0;
712 desc->pg_lseg = NULL;727 desc->pg_lseg = NULL;
728 desc->pg_io_completion = NULL;
713 desc->pg_dreq = NULL;729 desc->pg_dreq = NULL;
714 desc->pg_layout_private = NULL;
715 desc->pg_bsize = bsize;730 desc->pg_bsize = bsize;
716 731
717 desc->pg_mirror_count = 1;732 desc->pg_mirror_count = 1;
@@ -779,6 +794,7 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc, · 61 unmodified lines
779 gfp_t gfp_flags = GFP_KERNEL;794 gfp_t gfp_flags = GFP_KERNEL;
780 795
781 pagecount = nfs_page_array_len(mirror->pg_base, mirror->pg_count);796 pagecount = nfs_page_array_len(mirror->pg_base, mirror->pg_count);
797 pg_array->npages = pagecount;
782 798
783 if (pagecount <= ARRAY_SIZE(pg_array->page_array))799 if (pagecount <= ARRAY_SIZE(pg_array->page_array))
784 pg_array->pagevec = pg_array->page_array;800 pg_array->pagevec = pg_array->page_array;
@@ -1233,6 +1249,7 @@ int nfs_pageio_resend(struct nfs_pageio_descriptor *desc, · 448 unmodified lines
1233{1249{
1234 LIST_HEAD(failed);1250 LIST_HEAD(failed);
1235 1251
1252 desc->pg_io_completion = hdr->io_completion;
1236 desc->pg_dreq = hdr->dreq;1253 desc->pg_dreq = hdr->dreq;
1237 while (!list_empty(&hdr->pages)) {1254 while (!list_empty(&hdr->pages)) {
1238 struct nfs_page *req = nfs_list_entry(hdr->pages.next);1255 struct nfs_page *req = nfs_list_entry(hdr->pages.next);
fs/nfs/proc.c+1−1
@@ -485,7 +485,7 @@ nfs_proc_rmdir(struct inode *dir, const struct qstr *name) · 484 unmodified lines
485 */485 */
486static int486static int
487nfs_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,487nfs_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
488 u64 cookie, struct page **pages, unsigned int count, int plus)488 u64 cookie, struct page **pages, unsigned int count, bool plus)
489{489{
490 struct inode *dir = d_inode(dentry);490 struct inode *dir = d_inode(dentry);
491 struct nfs_readdirargs arg = {491 struct nfs_readdirargs arg = {
fs/nfs/super.c+3−1
@@ -879,7 +879,7 @@ int nfs_show_stats(struct seq_file *m, struct dentry *root) · 878 unmodified lines
879 if (nfss->options & NFS_OPTION_FSCACHE) {879 if (nfss->options & NFS_OPTION_FSCACHE) {
880 seq_printf(m, "\n\tfsc:\t");880 seq_printf(m, "\n\tfsc:\t");
881 for (i = 0; i < __NFSIOS_FSCACHEMAX; i++)881 for (i = 0; i < __NFSIOS_FSCACHEMAX; i++)
882 seq_printf(m, "%Lu ", totals.bytes[i]);882 seq_printf(m, "%Lu ", totals.fscache[i]);
883 }883 }
884#endif884#endif
885 seq_printf(m, "\n");885 seq_printf(m, "\n");
@@ -2339,6 +2339,7 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info) · 1453 unmodified lines
2339 */2339 */
2340 sb->s_flags |= MS_POSIXACL;2340 sb->s_flags |= MS_POSIXACL;
2341 sb->s_time_gran = 1;2341 sb->s_time_gran = 1;
2342 sb->s_export_op = &nfs_export_ops;
2342 }2343 }
2343 2344
2344 nfs_initialise_sb(sb);2345 nfs_initialise_sb(sb);
@@ -2360,6 +2361,7 @@ static void nfs_clone_super(struct super_block *sb, · 15 unmodified lines
2360 sb->s_xattr = old_sb->s_xattr;2361 sb->s_xattr = old_sb->s_xattr;
2361 sb->s_op = old_sb->s_op;2362 sb->s_op = old_sb->s_op;
2362 sb->s_time_gran = 1;2363 sb->s_time_gran = 1;
2364 sb->s_export_op = old_sb->s_export_op;
2363 2365
2364 if (server->nfs_client->rpc_ops->version != 2) {2366 if (server->nfs_client->rpc_ops->version != 2) {
2365 /* The VFS shouldn't apply the umask to mode bits. We will do2367 /* The VFS shouldn't apply the umask to mode bits. We will do
fs/nfs/unlink.c+13−0
@@ -288,6 +288,19 @@ static void nfs_async_rename_release(void *calldata) · 287 unmodified lines
288 if (d_really_is_positive(data->old_dentry))288 if (d_really_is_positive(data->old_dentry))
289 nfs_mark_for_revalidate(d_inode(data->old_dentry));289 nfs_mark_for_revalidate(d_inode(data->old_dentry));
290 290
291 /* The result of the rename is unknown. Play it safe by
292 * forcing a new lookup */
293 if (data->cancelled) {
294 spin_lock(&data->old_dir->i_lock);
295 nfs_force_lookup_revalidate(data->old_dir);
296 spin_unlock(&data->old_dir->i_lock);
297 if (data->new_dir != data->old_dir) {
298 spin_lock(&data->new_dir->i_lock);
299 nfs_force_lookup_revalidate(data->new_dir);
300 spin_unlock(&data->new_dir->i_lock);
301 }
302 }
303
291 dput(data->old_dentry);304 dput(data->old_dentry);
292 dput(data->new_dentry);305 dput(data->new_dentry);
293 iput(data->old_dir);306 iput(data->old_dir);
fs/nfs/write.c+58−1
@@ -40,6 +40,12 @@ · 39 unmodified lines
40#define MIN_POOL_WRITE (32)40#define MIN_POOL_WRITE (32)
41#define MIN_POOL_COMMIT (4)41#define MIN_POOL_COMMIT (4)
42 42
43struct nfs_io_completion {
44 void (*complete)(void *data);
45 void *data;
46 struct kref refcount;
47};
48
43/*49/*
44 * Local function declarations50 * Local function declarations
45 */51 */
@@ -108,6 +114,39 @@ static void nfs_writehdr_free(struct nfs_pgio_header *hdr) · 62 unmodified lines
108 mempool_free(hdr, nfs_wdata_mempool);114 mempool_free(hdr, nfs_wdata_mempool);
109}115}
110 116
117static struct nfs_io_completion *nfs_io_completion_alloc(gfp_t gfp_flags)
118{
119 return kmalloc(sizeof(struct nfs_io_completion), gfp_flags);
120}
121
122static void nfs_io_completion_init(struct nfs_io_completion *ioc,
123 void (*complete)(void *), void *data)
124{
125 ioc->complete = complete;
126 ioc->data = data;
127 kref_init(&ioc->refcount);
128}
129
130static void nfs_io_completion_release(struct kref *kref)
131{
132 struct nfs_io_completion *ioc = container_of(kref,
133 struct nfs_io_completion, refcount);
134 ioc->complete(ioc->data);
135 kfree(ioc);
136}
137
138static void nfs_io_completion_get(struct nfs_io_completion *ioc)
139{
140 if (ioc != NULL)
141 kref_get(&ioc->refcount);
142}
143
144static void nfs_io_completion_put(struct nfs_io_completion *ioc)
145{
146 if (ioc != NULL)
147 kref_put(&ioc->refcount, nfs_io_completion_release);
148}
149
111static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)150static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
112{151{
113 ctx->error = error;152 ctx->error = error;
@@ -681,18 +720,29 @@ static int nfs_writepages_callback(struct page *page, struct writeback_control * · 567 unmodified lines
681 return ret;720 return ret;
682}721}
683 722
723static void nfs_io_completion_commit(void *inode)
724{
725 nfs_commit_inode(inode, 0);
726}
727
684int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)728int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
685{729{
686 struct inode *inode = mapping->host;730 struct inode *inode = mapping->host;
687 struct nfs_pageio_descriptor pgio;731 struct nfs_pageio_descriptor pgio;
732 struct nfs_io_completion *ioc = nfs_io_completion_alloc(GFP_NOFS);
688 int err;733 int err;
689 734
690 nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES);735 nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES);
691 736
737 if (ioc)
738 nfs_io_completion_init(ioc, nfs_io_completion_commit, inode);
739
692 nfs_pageio_init_write(&pgio, inode, wb_priority(wbc), false,740 nfs_pageio_init_write(&pgio, inode, wb_priority(wbc), false,
693 &nfs_async_write_completion_ops);741 &nfs_async_write_completion_ops);
742 pgio.pg_io_completion = ioc;
694 err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio);743 err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio);
695 nfs_pageio_complete(&pgio);744 nfs_pageio_complete(&pgio);
745 nfs_io_completion_put(ioc);
696 746
697 if (err < 0)747 if (err < 0)
698 goto out_err;748 goto out_err;
@@ -940,6 +990,11 @@ int nfs_write_need_commit(struct nfs_pgio_header *hdr) · 241 unmodified lines
940 return hdr->verf.committed != NFS_FILE_SYNC;990 return hdr->verf.committed != NFS_FILE_SYNC;
941}991}
942 992
993static void nfs_async_write_init(struct nfs_pgio_header *hdr)
994{
995 nfs_io_completion_get(hdr->io_completion);
996}
997
943static void nfs_write_completion(struct nfs_pgio_header *hdr)998static void nfs_write_completion(struct nfs_pgio_header *hdr)
944{999{
945 struct nfs_commit_info cinfo;1000 struct nfs_commit_info cinfo;
@@ -973,6 +1028,7 @@ next: · 27 unmodified lines
973 nfs_release_request(req);1028 nfs_release_request(req);
974 }1029 }
975out:1030out:
1031 nfs_io_completion_put(hdr->io_completion);
976 hdr->release(hdr);1032 hdr->release(hdr);
977}1033}
978 1034
@@ -1378,6 +1434,7 @@ static void nfs_async_write_reschedule_io(struct nfs_pgio_header *hdr) · 399 unmodified lines
1378}1434}
1379 1435
1380static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops = {1436static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops = {
1437 .init_hdr = nfs_async_write_init,
1381 .error_cleanup = nfs_async_write_error,1438 .error_cleanup = nfs_async_write_error,
1382 .completion = nfs_write_completion,1439 .completion = nfs_write_completion,
1383 .reschedule_io = nfs_async_write_reschedule_io,1440 .reschedule_io = nfs_async_write_reschedule_io,
@@ -1884,7 +1941,7 @@ int nfs_write_inode(struct inode *inode, struct writeback_control *wbc) · 500 unmodified lines
1884 /* Don't commit yet if this is a non-blocking flush and there1941 /* Don't commit yet if this is a non-blocking flush and there
1885 * are a lot of outstanding writes for this mapping.1942 * are a lot of outstanding writes for this mapping.
1886 */1943 */
1887 if (nfsi->commit_info.ncommit <= (nfsi->nrequests >> 1))1944 if (mapping_tagged(inode->i_mapping, PAGECACHE_TAG_WRITEBACK))
1888 goto out_mark_dirty;1945 goto out_mark_dirty;
1889 1946
1890 /* don't wait for the COMMIT response */1947 /* don't wait for the COMMIT response */
include/linux/nfs4.h+1−0
@@ -479,6 +479,7 @@ enum { · 478 unmodified lines
479 NFSPROC4_CLNT_ACCESS,479 NFSPROC4_CLNT_ACCESS,
480 NFSPROC4_CLNT_GETATTR,480 NFSPROC4_CLNT_GETATTR,
481 NFSPROC4_CLNT_LOOKUP,481 NFSPROC4_CLNT_LOOKUP,
482 NFSPROC4_CLNT_LOOKUPP,
482 NFSPROC4_CLNT_LOOKUP_ROOT,483 NFSPROC4_CLNT_LOOKUP_ROOT,
483 NFSPROC4_CLNT_REMOVE,484 NFSPROC4_CLNT_REMOVE,
484 NFSPROC4_CLNT_RENAME,485 NFSPROC4_CLNT_RENAME,
include/linux/nfs_fs.h+1−0
@@ -332,6 +332,7 @@ extern void nfs_zap_caches(struct inode *); · 331 unmodified lines
332extern void nfs_invalidate_atime(struct inode *);332extern void nfs_invalidate_atime(struct inode *);
333extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,333extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,
334 struct nfs_fattr *, struct nfs4_label *);334 struct nfs_fattr *, struct nfs4_label *);
335struct inode *nfs_ilookup(struct super_block *sb, struct nfs_fattr *, struct nfs_fh *);
335extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);336extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
336extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);337extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
337extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);338extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);
include/linux/nfs_fs_sb.h+2−0
@@ -42,6 +42,7 @@ struct nfs_client { · 41 unmodified lines
42#define NFS_CS_MIGRATION 2 /* - transparent state migr */42#define NFS_CS_MIGRATION 2 /* - transparent state migr */
43#define NFS_CS_INFINITE_SLOTS 3 /* - don't limit TCP slots */43#define NFS_CS_INFINITE_SLOTS 3 /* - don't limit TCP slots */
44#define NFS_CS_NO_RETRANS_TIMEOUT 4 /* - Disable retransmit timeouts */44#define NFS_CS_NO_RETRANS_TIMEOUT 4 /* - Disable retransmit timeouts */
45#define NFS_CS_TSM_POSSIBLE 5 /* - Maybe state migration */
45 struct sockaddr_storage cl_addr; /* server identifier */46 struct sockaddr_storage cl_addr; /* server identifier */
46 size_t cl_addrlen;47 size_t cl_addrlen;
47 char * cl_hostname; /* hostname of server */48 char * cl_hostname; /* hostname of server */
@@ -210,6 +211,7 @@ struct nfs_server { · 162 unmodified lines
210 unsigned long mig_status;211 unsigned long mig_status;
211#define NFS_MIG_IN_TRANSITION (1)212#define NFS_MIG_IN_TRANSITION (1)
212#define NFS_MIG_FAILED (2)213#define NFS_MIG_FAILED (2)
214#define NFS_MIG_TSM_POSSIBLE (3)
213 215
214 void (*destroy)(struct nfs_server *);216 void (*destroy)(struct nfs_server *);
215 217
include/linux/nfs_page.h+3−1
@@ -33,6 +33,8 @@ enum { · 32 unmodified lines
33 PG_UPTODATE, /* page group sync bit in read path */33 PG_UPTODATE, /* page group sync bit in read path */
34 PG_WB_END, /* page group sync bit in write path */34 PG_WB_END, /* page group sync bit in write path */
35 PG_REMOVE, /* page group sync bit in write path */35 PG_REMOVE, /* page group sync bit in write path */
36 PG_CONTENDED1, /* Is someone waiting for a lock? */
37 PG_CONTENDED2, /* Is someone waiting for a lock? */
36};38};
37 39
38struct nfs_inode;40struct nfs_inode;
@@ -93,8 +95,8 @@ struct nfs_pageio_descriptor { · 54 unmodified lines
93 const struct rpc_call_ops *pg_rpc_callops;95 const struct rpc_call_ops *pg_rpc_callops;
94 const struct nfs_pgio_completion_ops *pg_completion_ops;96 const struct nfs_pgio_completion_ops *pg_completion_ops;
95 struct pnfs_layout_segment *pg_lseg;97 struct pnfs_layout_segment *pg_lseg;
98 struct nfs_io_completion *pg_io_completion;
96 struct nfs_direct_req *pg_dreq;99 struct nfs_direct_req *pg_dreq;
97 void *pg_layout_private;
98 unsigned int pg_bsize; /* default bsize for mirrors */100 unsigned int pg_bsize; /* default bsize for mirrors */
99 101
100 u32 pg_mirror_count;102 u32 pg_mirror_count;
include/linux/nfs_xdr.h+24−7
@@ -878,7 +878,7 @@ struct nfs3_readdirargs { · 877 unmodified lines
878 struct nfs_fh * fh;878 struct nfs_fh * fh;
879 __u64 cookie;879 __u64 cookie;
880 __be32 verf[2];880 __be32 verf[2];
881 int plus;881 bool plus;
882 unsigned int count;882 unsigned int count;
883 struct page ** pages;883 struct page ** pages;
884};884};
@@ -909,7 +909,7 @@ struct nfs3_linkres { · 24 unmodified lines
909struct nfs3_readdirres {909struct nfs3_readdirres {
910 struct nfs_fattr * dir_attr;910 struct nfs_fattr * dir_attr;
911 __be32 * verf;911 __be32 * verf;
912 int plus;912 bool plus;
913};913};
914 914
915struct nfs3_getaclres {915struct nfs3_getaclres {
@@ -1012,7 +1012,6 @@ struct nfs4_link_res { · 96 unmodified lines
1012 struct nfs_fattr * dir_attr;1012 struct nfs_fattr * dir_attr;
1013};1013};
1014 1014
1015
1016struct nfs4_lookup_arg {1015struct nfs4_lookup_arg {
1017 struct nfs4_sequence_args seq_args;1016 struct nfs4_sequence_args seq_args;
1018 const struct nfs_fh * dir_fh;1017 const struct nfs_fh * dir_fh;
@@ -1028,6 +1027,20 @@ struct nfs4_lookup_res { · 9 unmodified lines
1028 struct nfs4_label *label;1027 struct nfs4_label *label;
1029};1028};
1030 1029
1030struct nfs4_lookupp_arg {
1031 struct nfs4_sequence_args seq_args;
1032 const struct nfs_fh *fh;
1033 const u32 *bitmask;
1034};
1035
1036struct nfs4_lookupp_res {
1037 struct nfs4_sequence_res seq_res;
1038 const struct nfs_server *server;
1039 struct nfs_fattr *fattr;
1040 struct nfs_fh *fh;
1041 struct nfs4_label *label;
1042};
1043
1031struct nfs4_lookup_root_arg {1044struct nfs4_lookup_root_arg {
1032 struct nfs4_sequence_args seq_args;1045 struct nfs4_sequence_args seq_args;
1033 const u32 * bitmask;1046 const u32 * bitmask;
@@ -1053,7 +1066,7 @@ struct nfs4_readdir_arg { · 19 unmodified lines
1053 struct page ** pages; /* zero-copy data */1066 struct page ** pages; /* zero-copy data */
1054 unsigned int pgbase; /* zero-copy data */1067 unsigned int pgbase; /* zero-copy data */
1055 const u32 * bitmask;1068 const u32 * bitmask;
1056 int plus;1069 bool plus;
1057};1070};
1058 1071
1059struct nfs4_readdir_res {1072struct nfs4_readdir_res {
@@ -1422,6 +1435,7 @@ enum { · 362 unmodified lines
1422 NFS_IOHDR_STAT,1435 NFS_IOHDR_STAT,
1423};1436};
1424 1437
1438struct nfs_io_completion;
1425struct nfs_pgio_header {1439struct nfs_pgio_header {
1426 struct inode *inode;1440 struct inode *inode;
1427 struct rpc_cred *cred;1441 struct rpc_cred *cred;
@@ -1435,8 +1449,8 @@ struct nfs_pgio_header { · 7 unmodified lines
1435 void (*release) (struct nfs_pgio_header *hdr);1449 void (*release) (struct nfs_pgio_header *hdr);
1436 const struct nfs_pgio_completion_ops *completion_ops;1450 const struct nfs_pgio_completion_ops *completion_ops;
1437 const struct nfs_rw_ops *rw_ops;1451 const struct nfs_rw_ops *rw_ops;
1452 struct nfs_io_completion *io_completion;
1438 struct nfs_direct_req *dreq;1453 struct nfs_direct_req *dreq;
1439 void *layout_private;
1440 spinlock_t lock;1454 spinlock_t lock;
1441 /* fields protected by lock */1455 /* fields protected by lock */
1442 int pnfs_error;1456 int pnfs_error;
@@ -1533,6 +1547,7 @@ struct nfs_renamedata { · 90 unmodified lines
1533 struct nfs_fattr new_fattr;1547 struct nfs_fattr new_fattr;
1534 void (*complete)(struct rpc_task *, struct nfs_renamedata *);1548 void (*complete)(struct rpc_task *, struct nfs_renamedata *);
1535 long timeout;1549 long timeout;
1550 bool cancelled;
1536};1551};
1537 1552
1538struct nfs_access_entry;1553struct nfs_access_entry;
@@ -1567,6 +1582,8 @@ struct nfs_rpc_ops { · 28 unmodified lines
1567 int (*lookup) (struct inode *, const struct qstr *,1582 int (*lookup) (struct inode *, const struct qstr *,
1568 struct nfs_fh *, struct nfs_fattr *,1583 struct nfs_fh *, struct nfs_fattr *,
1569 struct nfs4_label *);1584 struct nfs4_label *);
1585 int (*lookupp) (struct inode *, struct nfs_fh *,
1586 struct nfs_fattr *, struct nfs4_label *);
1570 int (*access) (struct inode *, struct nfs_access_entry *);1587 int (*access) (struct inode *, struct nfs_access_entry *);
1571 int (*readlink)(struct inode *, struct page *, unsigned int,1588 int (*readlink)(struct inode *, struct page *, unsigned int,
1572 unsigned int);1589 unsigned int);
@@ -1585,7 +1602,7 @@ struct nfs_rpc_ops { · 12 unmodified lines
1585 int (*mkdir) (struct inode *, struct dentry *, struct iattr *);1602 int (*mkdir) (struct inode *, struct dentry *, struct iattr *);
1586 int (*rmdir) (struct inode *, const struct qstr *);1603 int (*rmdir) (struct inode *, const struct qstr *);
1587 int (*readdir) (struct dentry *, struct rpc_cred *,1604 int (*readdir) (struct dentry *, struct rpc_cred *,
1588 u64, struct page **, unsigned int, int);1605 u64, struct page **, unsigned int, bool);
1589 int (*mknod) (struct inode *, struct dentry *, struct iattr *,1606 int (*mknod) (struct inode *, struct dentry *, struct iattr *,
1590 dev_t);1607 dev_t);
1591 int (*statfs) (struct nfs_server *, struct nfs_fh *,1608 int (*statfs) (struct nfs_server *, struct nfs_fh *,
@@ -1595,7 +1612,7 @@ struct nfs_rpc_ops { · 3 unmodified lines
1595 int (*pathconf) (struct nfs_server *, struct nfs_fh *,1612 int (*pathconf) (struct nfs_server *, struct nfs_fh *,
1596 struct nfs_pathconf *);1613 struct nfs_pathconf *);
1597 int (*set_capabilities)(struct nfs_server *, struct nfs_fh *);1614 int (*set_capabilities)(struct nfs_server *, struct nfs_fh *);
1598 int (*decode_dirent)(struct xdr_stream *, struct nfs_entry *, int);1615 int (*decode_dirent)(struct xdr_stream *, struct nfs_entry *, bool);
1599 int (*pgio_rpc_prepare)(struct rpc_task *,1616 int (*pgio_rpc_prepare)(struct rpc_task *,
1600 struct nfs_pgio_header *);1617 struct nfs_pgio_header *);
1601 void (*read_setup)(struct nfs_pgio_header *, struct rpc_message *);1618 void (*read_setup)(struct nfs_pgio_header *, struct rpc_message *);
net/sunrpc/auth_gss/gss_krb5_crypto.c+2−1
@@ -34,6 +34,7 @@ · 33 unmodified lines
34 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.34 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
35 */35 */
36 36
37#include <crypto/algapi.h>
37#include <crypto/hash.h>38#include <crypto/hash.h>
38#include <crypto/skcipher.h>39#include <crypto/skcipher.h>
39#include <linux/err.h>40#include <linux/err.h>
@@ -927,7 +928,7 @@ gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, · 887 unmodified lines
927 if (ret)928 if (ret)
928 goto out_err;929 goto out_err;
929 930
930 if (memcmp(pkt_hmac, our_hmac, kctx->gk5e->cksumlength) != 0) {931 if (crypto_memneq(pkt_hmac, our_hmac, kctx->gk5e->cksumlength) != 0) {
931 ret = GSS_S_BAD_SIG;932 ret = GSS_S_BAD_SIG;
932 goto out_err;933 goto out_err;
933 }934 }
net/sunrpc/xprt.c+5−3
@@ -1047,13 +1047,15 @@ out: · 1046 unmodified lines
1047 return ret;1047 return ret;
1048}1048}
1049 1049
1050static struct rpc_rqst *xprt_dynamic_alloc_slot(struct rpc_xprt *xprt, gfp_t gfp_flags)1050static struct rpc_rqst *xprt_dynamic_alloc_slot(struct rpc_xprt *xprt)
1051{1051{
1052 struct rpc_rqst *req = ERR_PTR(-EAGAIN);1052 struct rpc_rqst *req = ERR_PTR(-EAGAIN);
1053 1053
1054 if (!atomic_add_unless(&xprt->num_reqs, 1, xprt->max_reqs))1054 if (!atomic_add_unless(&xprt->num_reqs, 1, xprt->max_reqs))
1055 goto out;1055 goto out;
1056 req = kzalloc(sizeof(struct rpc_rqst), gfp_flags);1056 spin_unlock(&xprt->reserve_lock);
1057 req = kzalloc(sizeof(struct rpc_rqst), GFP_NOFS);
1058 spin_lock(&xprt->reserve_lock);
1057 if (req != NULL)1059 if (req != NULL)
1058 goto out;1060 goto out;
1059 atomic_dec(&xprt->num_reqs);1061 atomic_dec(&xprt->num_reqs);
@@ -1081,7 +1083,7 @@ void xprt_alloc_slot(struct rpc_xprt *xprt, struct rpc_task *task) · 21 unmodified lines
1081 list_del(&req->rq_list);1083 list_del(&req->rq_list);
1082 goto out_init_req;1084 goto out_init_req;
1083 }1085 }
1084 req = xprt_dynamic_alloc_slot(xprt, GFP_NOWAIT|__GFP_NOWARN);1086 req = xprt_dynamic_alloc_slot(xprt);
1085 if (!IS_ERR(req))1087 if (!IS_ERR(req))
1086 goto out_init_req;1088 goto out_init_req;
1087 switch (PTR_ERR(req)) {1089 switch (PTR_ERR(req)) {
net/sunrpc/xprtrdma/fmr_ops.c+26−21
@@ -91,7 +91,7 @@ __fmr_unmap(struct rpcrdma_mw *mw) · 90 unmodified lines
91 91
92 list_add(&mw->fmr.fm_mr->list, &l);92 list_add(&mw->fmr.fm_mr->list, &l);
93 rc = ib_unmap_fmr(&l);93 rc = ib_unmap_fmr(&l);
94 list_del_init(&mw->fmr.fm_mr->list);94 list_del(&mw->fmr.fm_mr->list);
95 return rc;95 return rc;
96}96}
97 97
@@ -213,13 +213,11 @@ fmr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, · 115 unmodified lines
213 offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))213 offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))
214 break;214 break;
215 }215 }
216 mw->mw_nents = i;
217 mw->mw_dir = rpcrdma_data_dir(writing);216 mw->mw_dir = rpcrdma_data_dir(writing);
218 if (i == 0)
219 goto out_dmamap_err;
220 217
221 if (!ib_dma_map_sg(r_xprt->rx_ia.ri_device,218 mw->mw_nents = ib_dma_map_sg(r_xprt->rx_ia.ri_device,
222 mw->mw_sg, mw->mw_nents, mw->mw_dir))219 mw->mw_sg, i, mw->mw_dir);
220 if (!mw->mw_nents)
223 goto out_dmamap_err;221 goto out_dmamap_err;
224 222
225 for (i = 0, dma_pages = mw->fmr.fm_physaddrs; i < mw->mw_nents; i++)223 for (i = 0, dma_pages = mw->fmr.fm_physaddrs; i < mw->mw_nents; i++)
@@ -237,16 +235,18 @@ fmr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, · 11 unmodified lines
237 return mw->mw_nents;235 return mw->mw_nents;
238 236
239out_dmamap_err:237out_dmamap_err:
240 pr_err("rpcrdma: failed to dma map sg %p sg_nents %u\n",238 pr_err("rpcrdma: failed to DMA map sg %p sg_nents %d\n",
241 mw->mw_sg, mw->mw_nents);239 mw->mw_sg, i);
242 rpcrdma_defer_mr_recovery(mw);240 rpcrdma_put_mw(r_xprt, mw);
243 return -EIO;241 return -EIO;
244 242
245out_maperr:243out_maperr:
246 pr_err("rpcrdma: ib_map_phys_fmr %u@0x%llx+%i (%d) status %i\n",244 pr_err("rpcrdma: ib_map_phys_fmr %u@0x%llx+%i (%d) status %i\n",
247 len, (unsigned long long)dma_pages[0],245 len, (unsigned long long)dma_pages[0],
248 pageoff, mw->mw_nents, rc);246 pageoff, mw->mw_nents, rc);
249 rpcrdma_defer_mr_recovery(mw);247 ib_dma_unmap_sg(r_xprt->rx_ia.ri_device,
248 mw->mw_sg, mw->mw_nents, mw->mw_dir);
249 rpcrdma_put_mw(r_xprt, mw);
250 return -EIO;250 return -EIO;
251}251}
252 252
@@ -255,24 +255,26 @@ out_maperr: · 2 unmodified lines
255 * Sleeps until it is safe for the host CPU to access the255 * Sleeps until it is safe for the host CPU to access the
256 * previously mapped memory regions.256 * previously mapped memory regions.
257 *257 *
258 * Caller ensures that req->rl_registered is not empty.258 * Caller ensures that @mws is not empty before the call. This
259 * function empties the list.
259 */260 */
260static void261static void
261fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)262fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mws)
262{263{
263 struct rpcrdma_mw *mw, *tmp;264 struct rpcrdma_mw *mw;
264 LIST_HEAD(unmap_list);265 LIST_HEAD(unmap_list);
265 int rc;266 int rc;
266 267
267 dprintk("RPC: %s: req %p\n", __func__, req);
268
269 /* ORDER: Invalidate all of the req's MRs first268 /* ORDER: Invalidate all of the req's MRs first
270 *269 *
271 * ib_unmap_fmr() is slow, so use a single call instead270 * ib_unmap_fmr() is slow, so use a single call instead
272 * of one call per mapped FMR.271 * of one call per mapped FMR.
273 */272 */
274 list_for_each_entry(mw, &req->rl_registered, mw_list)273 list_for_each_entry(mw, mws, mw_list) {
274 dprintk("RPC: %s: unmapping fmr %p\n",
275 __func__, &mw->fmr);
275 list_add_tail(&mw->fmr.fm_mr->list, &unmap_list);276 list_add_tail(&mw->fmr.fm_mr->list, &unmap_list);
277 }
276 r_xprt->rx_stats.local_inv_needed++;278 r_xprt->rx_stats.local_inv_needed++;
277 rc = ib_unmap_fmr(&unmap_list);279 rc = ib_unmap_fmr(&unmap_list);
278 if (rc)280 if (rc)
@@ -281,9 +283,11 @@ fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) · 2 unmodified lines
281 /* ORDER: Now DMA unmap all of the req's MRs, and return283 /* ORDER: Now DMA unmap all of the req's MRs, and return
282 * them to the free MW list.284 * them to the free MW list.
283 */285 */
284 list_for_each_entry_safe(mw, tmp, &req->rl_registered, mw_list) {286 while (!list_empty(mws)) {
285 list_del_init(&mw->mw_list);287 mw = rpcrdma_pop_mw(mws);
286 list_del_init(&mw->fmr.fm_mr->list);288 dprintk("RPC: %s: DMA unmapping fmr %p\n",
289 __func__, &mw->fmr);
290 list_del(&mw->fmr.fm_mr->list);
287 ib_dma_unmap_sg(r_xprt->rx_ia.ri_device,291 ib_dma_unmap_sg(r_xprt->rx_ia.ri_device,
288 mw->mw_sg, mw->mw_nents, mw->mw_dir);292 mw->mw_sg, mw->mw_nents, mw->mw_dir);
289 rpcrdma_put_mw(r_xprt, mw);293 rpcrdma_put_mw(r_xprt, mw);
@@ -294,8 +298,9 @@ fmr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) · 4 unmodified lines
294out_reset:298out_reset:
295 pr_err("rpcrdma: ib_unmap_fmr failed (%i)\n", rc);299 pr_err("rpcrdma: ib_unmap_fmr failed (%i)\n", rc);
296 300
297 list_for_each_entry_safe(mw, tmp, &req->rl_registered, mw_list) {301 while (!list_empty(mws)) {
298 list_del_init(&mw->fmr.fm_mr->list);302 mw = rpcrdma_pop_mw(mws);
303 list_del(&mw->fmr.fm_mr->list);
299 fmr_op_recover_mr(mw);304 fmr_op_recover_mr(mw);
300 }305 }
301}306}
net/sunrpc/xprtrdma/frwr_ops.c+33−36
@@ -277,7 +277,7 @@ __frwr_sendcompletion_flush(struct ib_wc *wc, const char *wr) · 276 unmodified lines
277}277}
278 278
279/**279/**
280 * frwr_wc_fastreg - Invoked by RDMA provider for each polled FastReg WC280 * frwr_wc_fastreg - Invoked by RDMA provider for a flushed FastReg WC
281 * @cq: completion queue (ignored)281 * @cq: completion queue (ignored)
282 * @wc: completed WR282 * @wc: completed WR
283 *283 *
@@ -298,7 +298,7 @@ frwr_wc_fastreg(struct ib_cq *cq, struct ib_wc *wc) · 14 unmodified lines
298}298}
299 299
300/**300/**
301 * frwr_wc_localinv - Invoked by RDMA provider for each polled LocalInv WC301 * frwr_wc_localinv - Invoked by RDMA provider for a flushed LocalInv WC
302 * @cq: completion queue (ignored)302 * @cq: completion queue (ignored)
303 * @wc: completed WR303 * @wc: completed WR
304 *304 *
@@ -319,7 +319,7 @@ frwr_wc_localinv(struct ib_cq *cq, struct ib_wc *wc) · 14 unmodified lines
319}319}
320 320
321/**321/**
322 * frwr_wc_localinv - Invoked by RDMA provider for each polled LocalInv WC322 * frwr_wc_localinv_wake - Invoked by RDMA provider for a signaled LocalInv WC
323 * @cq: completion queue (ignored)323 * @cq: completion queue (ignored)
324 * @wc: completed WR324 * @wc: completed WR
325 *325 *
@@ -355,7 +355,7 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, · 29 unmodified lines
355 struct ib_mr *mr;355 struct ib_mr *mr;
356 struct ib_reg_wr *reg_wr;356 struct ib_reg_wr *reg_wr;
357 struct ib_send_wr *bad_wr;357 struct ib_send_wr *bad_wr;
358 int rc, i, n, dma_nents;358 int rc, i, n;
359 u8 key;359 u8 key;
360 360
361 mw = NULL;361 mw = NULL;
@@ -391,14 +391,10 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, · 29 unmodified lines
391 offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))391 offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))
392 break;392 break;
393 }393 }
394 mw->mw_nents = i;
395 mw->mw_dir = rpcrdma_data_dir(writing);394 mw->mw_dir = rpcrdma_data_dir(writing);
396 if (i == 0)
397 goto out_dmamap_err;
398 395
399 dma_nents = ib_dma_map_sg(ia->ri_device,396 mw->mw_nents = ib_dma_map_sg(ia->ri_device, mw->mw_sg, i, mw->mw_dir);
400 mw->mw_sg, mw->mw_nents, mw->mw_dir);397 if (!mw->mw_nents)
401 if (!dma_nents)
402 goto out_dmamap_err;398 goto out_dmamap_err;
403 399
404 n = ib_map_mr_sg(mr, mw->mw_sg, mw->mw_nents, NULL, PAGE_SIZE);400 n = ib_map_mr_sg(mr, mw->mw_sg, mw->mw_nents, NULL, PAGE_SIZE);
@@ -436,13 +432,14 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, · 31 unmodified lines
436 return mw->mw_nents;432 return mw->mw_nents;
437 433
438out_dmamap_err:434out_dmamap_err:
439 pr_err("rpcrdma: failed to dma map sg %p sg_nents %u\n",435 pr_err("rpcrdma: failed to DMA map sg %p sg_nents %d\n",
440 mw->mw_sg, mw->mw_nents);436 mw->mw_sg, i);
441 rpcrdma_defer_mr_recovery(mw);437 frmr->fr_state = FRMR_IS_INVALID;
438 rpcrdma_put_mw(r_xprt, mw);
442 return -EIO;439 return -EIO;
443 440
444out_mapmr_err:441out_mapmr_err:
445 pr_err("rpcrdma: failed to map mr %p (%u/%u)\n",442 pr_err("rpcrdma: failed to map mr %p (%d/%d)\n",
446 frmr->fr_mr, n, mw->mw_nents);443 frmr->fr_mr, n, mw->mw_nents);
447 rpcrdma_defer_mr_recovery(mw);444 rpcrdma_defer_mr_recovery(mw);
448 return -EIO;445 return -EIO;
@@ -458,21 +455,19 @@ out_senderr: · 9 unmodified lines
458 * Sleeps until it is safe for the host CPU to access the455 * Sleeps until it is safe for the host CPU to access the
459 * previously mapped memory regions.456 * previously mapped memory regions.
460 *457 *
461 * Caller ensures that req->rl_registered is not empty.458 * Caller ensures that @mws is not empty before the call. This
459 * function empties the list.
462 */460 */
463static void461static void
464frwr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)462frwr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct list_head *mws)
465{463{
466 struct ib_send_wr *first, **prev, *last, *bad_wr;464 struct ib_send_wr *first, **prev, *last, *bad_wr;
467 struct rpcrdma_rep *rep = req->rl_reply;
468 struct rpcrdma_ia *ia = &r_xprt->rx_ia;465 struct rpcrdma_ia *ia = &r_xprt->rx_ia;
469 struct rpcrdma_frmr *f;466 struct rpcrdma_frmr *f;
470 struct rpcrdma_mw *mw;467 struct rpcrdma_mw *mw;
471 int count, rc;468 int count, rc;
472 469
473 dprintk("RPC: %s: req %p\n", __func__, req);470 /* ORDER: Invalidate all of the MRs first
474
475 /* ORDER: Invalidate all of the req's MRs first
476 *471 *
477 * Chain the LOCAL_INV Work Requests and post them with472 * Chain the LOCAL_INV Work Requests and post them with
478 * a single ib_post_send() call.473 * a single ib_post_send() call.
@@ -480,11 +475,10 @@ frwr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) · 1 unmodified line
480 f = NULL;475 f = NULL;
481 count = 0;476 count = 0;
482 prev = &first;477 prev = &first;
483 list_for_each_entry(mw, &req->rl_registered, mw_list) {478 list_for_each_entry(mw, mws, mw_list) {
484 mw->frmr.fr_state = FRMR_IS_INVALID;479 mw->frmr.fr_state = FRMR_IS_INVALID;
485 480
486 if ((rep->rr_wc_flags & IB_WC_WITH_INVALIDATE) &&481 if (mw->mw_flags & RPCRDMA_MW_F_RI)
487 (mw->mw_handle == rep->rr_inv_rkey))
488 continue;482 continue;
489 483
490 f = &mw->frmr;484 f = &mw->frmr;
@@ -524,18 +518,19 @@ frwr_op_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) · 33 unmodified lines
524 * unless ri_id->qp is a valid pointer.518 * unless ri_id->qp is a valid pointer.
525 */519 */
526 r_xprt->rx_stats.local_inv_needed++;520 r_xprt->rx_stats.local_inv_needed++;
521 bad_wr = NULL;
527 rc = ib_post_send(ia->ri_id->qp, first, &bad_wr);522 rc = ib_post_send(ia->ri_id->qp, first, &bad_wr);
523 if (bad_wr != first)
524 wait_for_completion(&f->fr_linv_done);
528 if (rc)525 if (rc)
529 goto reset_mrs;526 goto reset_mrs;
530 527
531 wait_for_completion(&f->fr_linv_done);528 /* ORDER: Now DMA unmap all of the MRs, and return
532
533 /* ORDER: Now DMA unmap all of the req's MRs, and return
534 * them to the free MW list.529 * them to the free MW list.
535 */530 */
536unmap:531unmap:
537 while (!list_empty(&req->rl_registered)) {532 while (!list_empty(mws)) {
538 mw = rpcrdma_pop_mw(&req->rl_registered);533 mw = rpcrdma_pop_mw(mws);
539 dprintk("RPC: %s: DMA unmapping frmr %p\n",534 dprintk("RPC: %s: DMA unmapping frmr %p\n",
540 __func__, &mw->frmr);535 __func__, &mw->frmr);
541 ib_dma_unmap_sg(ia->ri_device,536 ib_dma_unmap_sg(ia->ri_device,
@@ -546,17 +541,19 @@ unmap: · 4 unmodified lines
546 541
547reset_mrs:542reset_mrs:
548 pr_err("rpcrdma: FRMR invalidate ib_post_send returned %i\n", rc);543 pr_err("rpcrdma: FRMR invalidate ib_post_send returned %i\n", rc);
549 rdma_disconnect(ia->ri_id);
550 544
551 /* Find and reset the MRs in the LOCAL_INV WRs that did not545 /* Find and reset the MRs in the LOCAL_INV WRs that did not
552 * get posted. This is synchronous, and slow.546 * get posted.
553 */547 */
554 list_for_each_entry(mw, &req->rl_registered, mw_list) {548 rpcrdma_init_cqcount(&r_xprt->rx_ep, -count);
555 f = &mw->frmr;549 while (bad_wr) {
556 if (mw->mw_handle == bad_wr->ex.invalidate_rkey) {550 f = container_of(bad_wr, struct rpcrdma_frmr,
557 __frwr_reset_mr(ia, mw);551 fr_invwr);
558 bad_wr = bad_wr->next;552 mw = container_of(f, struct rpcrdma_mw, frmr);
559 }553
554 __frwr_reset_mr(ia, mw);
555
556 bad_wr = bad_wr->next;
560 }557 }
561 goto unmap;558 goto unmap;
562}559}
net/sunrpc/xprtrdma/rpc_rdma.c+81−44
@@ -141,7 +141,7 @@ static bool rpcrdma_args_inline(struct rpcrdma_xprt *r_xprt, · 140 unmodified lines
141 141
142 if (xdr->page_len) {142 if (xdr->page_len) {
143 remaining = xdr->page_len;143 remaining = xdr->page_len;
144 offset = xdr->page_base & ~PAGE_MASK;144 offset = offset_in_page(xdr->page_base);
145 count = 0;145 count = 0;
146 while (remaining) {146 while (remaining) {
147 remaining -= min_t(unsigned int,147 remaining -= min_t(unsigned int,
@@ -222,7 +222,7 @@ rpcrdma_convert_iovs(struct rpcrdma_xprt *r_xprt, struct xdr_buf *xdrbuf, · 74 unmodified lines
222 222
223 len = xdrbuf->page_len;223 len = xdrbuf->page_len;
224 ppages = xdrbuf->pages + (xdrbuf->page_base >> PAGE_SHIFT);224 ppages = xdrbuf->pages + (xdrbuf->page_base >> PAGE_SHIFT);
225 page_base = xdrbuf->page_base & ~PAGE_MASK;225 page_base = offset_in_page(xdrbuf->page_base);
226 p = 0;226 p = 0;
227 while (len && n < RPCRDMA_MAX_SEGS) {227 while (len && n < RPCRDMA_MAX_SEGS) {
228 if (!ppages[p]) {228 if (!ppages[p]) {
@@ -540,7 +540,7 @@ rpcrdma_prepare_msg_sges(struct rpcrdma_ia *ia, struct rpcrdma_req *req, · 311 unmodified lines
540 goto out;540 goto out;
541 541
542 page = virt_to_page(xdr->tail[0].iov_base);542 page = virt_to_page(xdr->tail[0].iov_base);
543 page_base = (unsigned long)xdr->tail[0].iov_base & ~PAGE_MASK;543 page_base = offset_in_page(xdr->tail[0].iov_base);
544 544
545 /* If the content in the page list is an odd length,545 /* If the content in the page list is an odd length,
546 * xdr_write_pages() has added a pad at the beginning546 * xdr_write_pages() has added a pad at the beginning
@@ -557,7 +557,7 @@ rpcrdma_prepare_msg_sges(struct rpcrdma_ia *ia, struct rpcrdma_req *req, · 10 unmodified lines
557 */557 */
558 if (xdr->page_len) {558 if (xdr->page_len) {
559 ppages = xdr->pages + (xdr->page_base >> PAGE_SHIFT);559 ppages = xdr->pages + (xdr->page_base >> PAGE_SHIFT);
560 page_base = xdr->page_base & ~PAGE_MASK;560 page_base = offset_in_page(xdr->page_base);
561 remaining = xdr->page_len;561 remaining = xdr->page_len;
562 while (remaining) {562 while (remaining) {
563 sge_no++;563 sge_no++;
@@ -587,7 +587,7 @@ rpcrdma_prepare_msg_sges(struct rpcrdma_ia *ia, struct rpcrdma_req *req, · 23 unmodified lines
587 */587 */
588 if (xdr->tail[0].iov_len) {588 if (xdr->tail[0].iov_len) {
589 page = virt_to_page(xdr->tail[0].iov_base);589 page = virt_to_page(xdr->tail[0].iov_base);
590 page_base = (unsigned long)xdr->tail[0].iov_base & ~PAGE_MASK;590 page_base = offset_in_page(xdr->tail[0].iov_base);
591 len = xdr->tail[0].iov_len;591 len = xdr->tail[0].iov_len;
592 592
593map_tail:593map_tail:
@@ -734,6 +734,9 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst) · 140 unmodified lines
734 rpclen = 0;734 rpclen = 0;
735 }735 }
736 736
737 req->rl_xid = rqst->rq_xid;
738 rpcrdma_insert_req(&r_xprt->rx_buf, req);
739
737 /* This implementation supports the following combinations740 /* This implementation supports the following combinations
738 * of chunk lists in one RPC-over-RDMA Call message:741 * of chunk lists in one RPC-over-RDMA Call message:
739 *742 *
@@ -875,9 +878,9 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad) · 135 unmodified lines
875 srcp += curlen;878 srcp += curlen;
876 copy_len -= curlen;879 copy_len -= curlen;
877 880
878 page_base = rqst->rq_rcv_buf.page_base;881 ppages = rqst->rq_rcv_buf.pages +
879 ppages = rqst->rq_rcv_buf.pages + (page_base >> PAGE_SHIFT);882 (rqst->rq_rcv_buf.page_base >> PAGE_SHIFT);
880 page_base &= ~PAGE_MASK;883 page_base = offset_in_page(rqst->rq_rcv_buf.page_base);
881 fixup_copy_count = 0;884 fixup_copy_count = 0;
882 if (copy_len && rqst->rq_rcv_buf.page_len) {885 if (copy_len && rqst->rq_rcv_buf.page_len) {
883 int pagelist_len;886 int pagelist_len;
@@ -928,6 +931,24 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad) · 44 unmodified lines
928 return fixup_copy_count;931 return fixup_copy_count;
929}932}
930 933
934/* Caller must guarantee @rep remains stable during this call.
935 */
936static void
937rpcrdma_mark_remote_invalidation(struct list_head *mws,
938 struct rpcrdma_rep *rep)
939{
940 struct rpcrdma_mw *mw;
941
942 if (!(rep->rr_wc_flags & IB_WC_WITH_INVALIDATE))
943 return;
944
945 list_for_each_entry(mw, mws, mw_list)
946 if (mw->mw_handle == rep->rr_inv_rkey) {
947 mw->mw_flags = RPCRDMA_MW_F_RI;
948 break; /* only one invalidated MR per RPC */
949 }
950}
951
931#if defined(CONFIG_SUNRPC_BACKCHANNEL)952#if defined(CONFIG_SUNRPC_BACKCHANNEL)
932/* By convention, backchannel calls arrive via rdma_msg type953/* By convention, backchannel calls arrive via rdma_msg type
933 * messages, and never populate the chunk lists. This makes954 * messages, and never populate the chunk lists. This makes
@@ -969,14 +990,16 @@ rpcrdma_reply_handler(struct work_struct *work) · 35 unmodified lines
969{990{
970 struct rpcrdma_rep *rep =991 struct rpcrdma_rep *rep =
971 container_of(work, struct rpcrdma_rep, rr_work);992 container_of(work, struct rpcrdma_rep, rr_work);
993 struct rpcrdma_xprt *r_xprt = rep->rr_rxprt;
994 struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
995 struct rpc_xprt *xprt = &r_xprt->rx_xprt;
972 struct rpcrdma_msg *headerp;996 struct rpcrdma_msg *headerp;
973 struct rpcrdma_req *req;997 struct rpcrdma_req *req;
974 struct rpc_rqst *rqst;998 struct rpc_rqst *rqst;
975 struct rpcrdma_xprt *r_xprt = rep->rr_rxprt;
976 struct rpc_xprt *xprt = &r_xprt->rx_xprt;
977 __be32 *iptr;999 __be32 *iptr;
978 int rdmalen, status, rmerr;1000 int rdmalen, status, rmerr;
979 unsigned long cwnd;1001 unsigned long cwnd;
1002 struct list_head mws;
980 1003
981 dprintk("RPC: %s: incoming rep %p\n", __func__, rep);1004 dprintk("RPC: %s: incoming rep %p\n", __func__, rep);
982 1005
@@ -994,27 +1017,45 @@ rpcrdma_reply_handler(struct work_struct *work) · 11 unmodified lines
994 /* Match incoming rpcrdma_rep to an rpcrdma_req to1017 /* Match incoming rpcrdma_rep to an rpcrdma_req to
995 * get context for handling any incoming chunks.1018 * get context for handling any incoming chunks.
996 */1019 */
997 spin_lock_bh(&xprt->transport_lock);1020 spin_lock(&buf->rb_lock);
998 rqst = xprt_lookup_rqst(xprt, headerp->rm_xid);1021 req = rpcrdma_lookup_req_locked(&r_xprt->rx_buf,
999 if (!rqst)1022 headerp->rm_xid);
1023 if (!req)
1000 goto out_nomatch;1024 goto out_nomatch;
1001
1002 req = rpcr_to_rdmar(rqst);
1003 if (req->rl_reply)1025 if (req->rl_reply)
1004 goto out_duplicate;1026 goto out_duplicate;
1005 1027
1006 /* Sanity checking has passed. We are now committed1028 list_replace_init(&req->rl_registered, &mws);
1007 * to complete this transaction.1029 rpcrdma_mark_remote_invalidation(&mws, rep);
1030
1031 /* Avoid races with signals and duplicate replies
1032 * by marking this req as matched.
1008 */1033 */
1009 list_del_init(&rqst->rq_list);1034 req->rl_reply = rep;
1010 spin_unlock_bh(&xprt->transport_lock);1035 spin_unlock(&buf->rb_lock);
1036
1011 dprintk("RPC: %s: reply %p completes request %p (xid 0x%08x)\n",1037 dprintk("RPC: %s: reply %p completes request %p (xid 0x%08x)\n",
1012 __func__, rep, req, be32_to_cpu(headerp->rm_xid));1038 __func__, rep, req, be32_to_cpu(headerp->rm_xid));
1013 1039
1014 /* from here on, the reply is no longer an orphan */1040 /* Invalidate and unmap the data payloads before waking the
1015 req->rl_reply = rep;1041 * waiting application. This guarantees the memory regions
1016 xprt->reestablish_timeout = 0;1042 * are properly fenced from the server before the application
1043 * accesses the data. It also ensures proper send flow control:
1044 * waking the next RPC waits until this RPC has relinquished
1045 * all its Send Queue entries.
1046 */
1047 if (!list_empty(&mws))
1048 r_xprt->rx_ia.ri_ops->ro_unmap_sync(r_xprt, &mws);
1017 1049
1050 /* Perform XID lookup, reconstruction of the RPC reply, and
1051 * RPC completion while holding the transport lock to ensure
1052 * the rep, rqst, and rq_task pointers remain stable.
1053 */
1054 spin_lock_bh(&xprt->transport_lock);
1055 rqst = xprt_lookup_rqst(xprt, headerp->rm_xid);
1056 if (!rqst)
1057 goto out_norqst;
1058 xprt->reestablish_timeout = 0;
1018 if (headerp->rm_vers != rpcrdma_version)1059 if (headerp->rm_vers != rpcrdma_version)
1019 goto out_badversion;1060 goto out_badversion;
1020 1061
@@ -1024,12 +1065,9 @@ rpcrdma_reply_handler(struct work_struct *work) · 3 unmodified lines
1024 case rdma_msg:1065 case rdma_msg:
1025 /* never expect read chunks */1066 /* never expect read chunks */
1026 /* never expect reply chunks (two ways to check) */1067 /* never expect reply chunks (two ways to check) */
1027 /* never expect write chunks without having offered RDMA */
1028 if (headerp->rm_body.rm_chunks[0] != xdr_zero ||1068 if (headerp->rm_body.rm_chunks[0] != xdr_zero ||
1029 (headerp->rm_body.rm_chunks[1] == xdr_zero &&1069 (headerp->rm_body.rm_chunks[1] == xdr_zero &&
1030 headerp->rm_body.rm_chunks[2] != xdr_zero) ||1070 headerp->rm_body.rm_chunks[2] != xdr_zero))
1031 (headerp->rm_body.rm_chunks[1] != xdr_zero &&
1032 list_empty(&req->rl_registered)))
1033 goto badheader;1071 goto badheader;
1034 if (headerp->rm_body.rm_chunks[1] != xdr_zero) {1072 if (headerp->rm_body.rm_chunks[1] != xdr_zero) {
1035 /* count any expected write chunks in read reply */1073 /* count any expected write chunks in read reply */
@@ -1066,8 +1104,7 @@ rpcrdma_reply_handler(struct work_struct *work) · 30 unmodified lines
1066 /* never expect read or write chunks, always reply chunks */1104 /* never expect read or write chunks, always reply chunks */
1067 if (headerp->rm_body.rm_chunks[0] != xdr_zero ||1105 if (headerp->rm_body.rm_chunks[0] != xdr_zero ||
1068 headerp->rm_body.rm_chunks[1] != xdr_zero ||1106 headerp->rm_body.rm_chunks[1] != xdr_zero ||
1069 headerp->rm_body.rm_chunks[2] != xdr_one ||1107 headerp->rm_body.rm_chunks[2] != xdr_one)
1070 list_empty(&req->rl_registered))
1071 goto badheader;1108 goto badheader;
1072 iptr = (__be32 *)((unsigned char *)headerp +1109 iptr = (__be32 *)((unsigned char *)headerp +
1073 RPCRDMA_HDRLEN_MIN);1110 RPCRDMA_HDRLEN_MIN);
@@ -1093,17 +1130,6 @@ badheader: · 19 unmodified lines
1093 }1130 }
1094 1131
1095out:1132out:
1096 /* Invalidate and flush the data payloads before waking the
1097 * waiting application. This guarantees the memory region is
1098 * properly fenced from the server before the application
1099 * accesses the data. It also ensures proper send flow
1100 * control: waking the next RPC waits until this RPC has
1101 * relinquished all its Send Queue entries.
1102 */
1103 if (!list_empty(&req->rl_registered))
1104 r_xprt->rx_ia.ri_ops->ro_unmap_sync(r_xprt, req);
1105
1106 spin_lock_bh(&xprt->transport_lock);
1107 cwnd = xprt->cwnd;1133 cwnd = xprt->cwnd;
1108 xprt->cwnd = atomic_read(&r_xprt->rx_buf.rb_credits) << RPC_CWNDSHIFT;1134 xprt->cwnd = atomic_read(&r_xprt->rx_buf.rb_credits) << RPC_CWNDSHIFT;
1109 if (xprt->cwnd > cwnd)1135 if (xprt->cwnd > cwnd)
@@ -1112,7 +1138,7 @@ out: · 2 unmodified lines
1112 xprt_complete_rqst(rqst->rq_task, status);1138 xprt_complete_rqst(rqst->rq_task, status);
1113 spin_unlock_bh(&xprt->transport_lock);1139 spin_unlock_bh(&xprt->transport_lock);
1114 dprintk("RPC: %s: xprt_complete_rqst(0x%p, 0x%p, %d)\n",1140 dprintk("RPC: %s: xprt_complete_rqst(0x%p, 0x%p, %d)\n",
1115 __func__, xprt, rqst, status);1141 __func__, xprt, rqst, status);
1116 return;1142 return;
1117 1143
1118out_badstatus:1144out_badstatus:
@@ -1161,26 +1187,37 @@ out_rdmaerr: · 42 unmodified lines
1161 r_xprt->rx_stats.bad_reply_count++;1187 r_xprt->rx_stats.bad_reply_count++;
1162 goto out;1188 goto out;
1163 1189
1164/* If no pending RPC transaction was matched, post a replacement1190/* The req was still available, but by the time the transport_lock
1165 * receive buffer before returning.1191 * was acquired, the rqst and task had been released. Thus the RPC
1192 * has already been terminated.
1166 */1193 */
1194out_norqst:
1195 spin_unlock_bh(&xprt->transport_lock);
1196 rpcrdma_buffer_put(req);
1197 dprintk("RPC: %s: race, no rqst left for req %p\n",
1198 __func__, req);
1199 return;
1200
1167out_shortreply:1201out_shortreply:
1168 dprintk("RPC: %s: short/invalid reply\n", __func__);1202 dprintk("RPC: %s: short/invalid reply\n", __func__);
1169 goto repost;1203 goto repost;
1170 1204
1171out_nomatch:1205out_nomatch:
1172 spin_unlock_bh(&xprt->transport_lock);1206 spin_unlock(&buf->rb_lock);
1173 dprintk("RPC: %s: no match for incoming xid 0x%08x len %d\n",1207 dprintk("RPC: %s: no match for incoming xid 0x%08x len %d\n",
1174 __func__, be32_to_cpu(headerp->rm_xid),1208 __func__, be32_to_cpu(headerp->rm_xid),
1175 rep->rr_len);1209 rep->rr_len);
1176 goto repost;1210 goto repost;
1177 1211
1178out_duplicate:1212out_duplicate:
1179 spin_unlock_bh(&xprt->transport_lock);1213 spin_unlock(&buf->rb_lock);
1180 dprintk("RPC: %s: "1214 dprintk("RPC: %s: "
1181 "duplicate reply %p to RPC request %p: xid 0x%08x\n",1215 "duplicate reply %p to RPC request %p: xid 0x%08x\n",
1182 __func__, rep, req, be32_to_cpu(headerp->rm_xid));1216 __func__, rep, req, be32_to_cpu(headerp->rm_xid));
1183 1217
1218/* If no pending RPC transaction was matched, post a replacement
1219 * receive buffer before returning.
1220 */
1184repost:1221repost:
1185 r_xprt->rx_stats.bad_reply_count++;1222 r_xprt->rx_stats.bad_reply_count++;
1186 if (rpcrdma_ep_post_recv(&r_xprt->rx_ia, rep))1223 if (rpcrdma_ep_post_recv(&r_xprt->rx_ia, rep))
net/sunrpc/xprtrdma/transport.c+2−1
@@ -684,7 +684,8 @@ xprt_rdma_free(struct rpc_task *task) · 683 unmodified lines
684 684
685 dprintk("RPC: %s: called on 0x%p\n", __func__, req->rl_reply);685 dprintk("RPC: %s: called on 0x%p\n", __func__, req->rl_reply);
686 686
687 if (unlikely(!list_empty(&req->rl_registered)))687 rpcrdma_remove_req(&r_xprt->rx_buf, req);
688 if (!list_empty(&req->rl_registered))
688 ia->ri_ops->ro_unmap_safe(r_xprt, req, !RPC_IS_ASYNC(task));689 ia->ri_ops->ro_unmap_safe(r_xprt, req, !RPC_IS_ASYNC(task));
689 rpcrdma_unmap_sges(ia, req);690 rpcrdma_unmap_sges(ia, req);
690 rpcrdma_buffer_put(req);691 rpcrdma_buffer_put(req);
net/sunrpc/xprtrdma/verbs.c+14−41
@@ -243,8 +243,6 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event) · 242 unmodified lines
243#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)243#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
244 struct sockaddr *sap = (struct sockaddr *)&ep->rep_remote_addr;244 struct sockaddr *sap = (struct sockaddr *)&ep->rep_remote_addr;
245#endif245#endif
246 struct ib_qp_attr *attr = &ia->ri_qp_attr;
247 struct ib_qp_init_attr *iattr = &ia->ri_qp_init_attr;
248 int connstate = 0;246 int connstate = 0;
249 247
250 switch (event->event) {248 switch (event->event) {
@@ -267,7 +265,8 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event) · 16 unmodified lines
267 break;265 break;
268 case RDMA_CM_EVENT_DEVICE_REMOVAL:266 case RDMA_CM_EVENT_DEVICE_REMOVAL:
269#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)267#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
270 pr_info("rpcrdma: removing device for %pIS:%u\n",268 pr_info("rpcrdma: removing device %s for %pIS:%u\n",
269 ia->ri_device->name,
271 sap, rpc_get_port(sap));270 sap, rpc_get_port(sap));
272#endif271#endif
273 set_bit(RPCRDMA_IAF_REMOVING, &ia->ri_flags);272 set_bit(RPCRDMA_IAF_REMOVING, &ia->ri_flags);
@@ -282,13 +281,6 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event) · 8 unmodified lines
282 return 1;281 return 1;
283 case RDMA_CM_EVENT_ESTABLISHED:282 case RDMA_CM_EVENT_ESTABLISHED:
284 connstate = 1;283 connstate = 1;
285 ib_query_qp(ia->ri_id->qp, attr,
286 IB_QP_MAX_QP_RD_ATOMIC | IB_QP_MAX_DEST_RD_ATOMIC,
287 iattr);
288 dprintk("RPC: %s: %d responder resources"
289 " (%d initiator)\n",
290 __func__, attr->max_dest_rd_atomic,
291 attr->max_rd_atomic);
292 rpcrdma_update_connect_private(xprt, &event->param.conn);284 rpcrdma_update_connect_private(xprt, &event->param.conn);
293 goto connected;285 goto connected;
294 case RDMA_CM_EVENT_CONNECT_ERROR:286 case RDMA_CM_EVENT_CONNECT_ERROR:
@@ -298,11 +290,9 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event) · 3 unmodified lines
298 connstate = -ENETDOWN;290 connstate = -ENETDOWN;
299 goto connected;291 goto connected;
300 case RDMA_CM_EVENT_REJECTED:292 case RDMA_CM_EVENT_REJECTED:
301#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)293 dprintk("rpcrdma: connection to %pIS:%u rejected: %s\n",
302 pr_info("rpcrdma: connection to %pIS:%u on %s rejected: %s\n",294 sap, rpc_get_port(sap),
303 sap, rpc_get_port(sap), ia->ri_device->name,
304 rdma_reject_msg(id, event->status));295 rdma_reject_msg(id, event->status));
305#endif
306 connstate = -ECONNREFUSED;296 connstate = -ECONNREFUSED;
307 if (event->status == IB_CM_REJ_STALE_CONN)297 if (event->status == IB_CM_REJ_STALE_CONN)
308 connstate = -EAGAIN;298 connstate = -EAGAIN;
@@ -310,37 +300,19 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event) · 1 unmodified line
310 case RDMA_CM_EVENT_DISCONNECTED:300 case RDMA_CM_EVENT_DISCONNECTED:
311 connstate = -ECONNABORTED;301 connstate = -ECONNABORTED;
312connected:302connected:
313 dprintk("RPC: %s: %sconnected\n",
314 __func__, connstate > 0 ? "" : "dis");
315 atomic_set(&xprt->rx_buf.rb_credits, 1);303 atomic_set(&xprt->rx_buf.rb_credits, 1);
316 ep->rep_connected = connstate;304 ep->rep_connected = connstate;
317 rpcrdma_conn_func(ep);305 rpcrdma_conn_func(ep);
318 wake_up_all(&ep->rep_connect_wait);306 wake_up_all(&ep->rep_connect_wait);
319 /*FALLTHROUGH*/307 /*FALLTHROUGH*/
320 default:308 default:
321 dprintk("RPC: %s: %pIS:%u (ep 0x%p): %s\n",309 dprintk("RPC: %s: %pIS:%u on %s/%s (ep 0x%p): %s\n",
322 __func__, sap, rpc_get_port(sap), ep,310 __func__, sap, rpc_get_port(sap),
323 rdma_event_msg(event->event));311 ia->ri_device->name, ia->ri_ops->ro_displayname,
312 ep, rdma_event_msg(event->event));
324 break;313 break;
325 }314 }
326 315
327#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
328 if (connstate == 1) {
329 int ird = attr->max_dest_rd_atomic;
330 int tird = ep->rep_remote_cma.responder_resources;
331
332 pr_info("rpcrdma: connection to %pIS:%u on %s, memreg '%s', %d credits, %d responders%s\n",
333 sap, rpc_get_port(sap),
334 ia->ri_device->name,
335 ia->ri_ops->ro_displayname,
336 xprt->rx_buf.rb_max_requests,
337 ird, ird < 4 && ird < tird / 2 ? " (low!)" : "");
338 } else if (connstate < 0) {
339 pr_info("rpcrdma: connection to %pIS:%u closed (%d)\n",
340 sap, rpc_get_port(sap), connstate);
341 }
342#endif
343
344 return 0;316 return 0;
345}317}
346 318
@@ -971,7 +943,6 @@ rpcrdma_create_req(struct rpcrdma_xprt *r_xprt) · 624 unmodified lines
971 if (req == NULL)943 if (req == NULL)
972 return ERR_PTR(-ENOMEM);944 return ERR_PTR(-ENOMEM);
973 945
974 INIT_LIST_HEAD(&req->rl_free);
975 spin_lock(&buffer->rb_reqslock);946 spin_lock(&buffer->rb_reqslock);
976 list_add(&req->rl_all, &buffer->rb_allreqs);947 list_add(&req->rl_all, &buffer->rb_allreqs);
977 spin_unlock(&buffer->rb_reqslock);948 spin_unlock(&buffer->rb_reqslock);
@@ -1033,6 +1004,7 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt) · 55 unmodified lines
1033 spin_lock_init(&buf->rb_recovery_lock);1004 spin_lock_init(&buf->rb_recovery_lock);
1034 INIT_LIST_HEAD(&buf->rb_mws);1005 INIT_LIST_HEAD(&buf->rb_mws);
1035 INIT_LIST_HEAD(&buf->rb_all);1006 INIT_LIST_HEAD(&buf->rb_all);
1007 INIT_LIST_HEAD(&buf->rb_pending);
1036 INIT_LIST_HEAD(&buf->rb_stale_mrs);1008 INIT_LIST_HEAD(&buf->rb_stale_mrs);
1037 INIT_DELAYED_WORK(&buf->rb_refresh_worker,1009 INIT_DELAYED_WORK(&buf->rb_refresh_worker,
1038 rpcrdma_mr_refresh_worker);1010 rpcrdma_mr_refresh_worker);
@@ -1055,7 +1027,7 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt) · 16 unmodified lines
1055 goto out;1027 goto out;
1056 }1028 }
1057 req->rl_backchannel = false;1029 req->rl_backchannel = false;
1058 list_add(&req->rl_free, &buf->rb_send_bufs);1030 list_add(&req->rl_list, &buf->rb_send_bufs);
1059 }1031 }
1060 1032
1061 INIT_LIST_HEAD(&buf->rb_recv_bufs);1033 INIT_LIST_HEAD(&buf->rb_recv_bufs);
@@ -1084,8 +1056,8 @@ rpcrdma_buffer_get_req_locked(struct rpcrdma_buffer *buf) · 22 unmodified lines
1084 struct rpcrdma_req *req;1056 struct rpcrdma_req *req;
1085 1057
1086 req = list_first_entry(&buf->rb_send_bufs,1058 req = list_first_entry(&buf->rb_send_bufs,
1087 struct rpcrdma_req, rl_free);1059 struct rpcrdma_req, rl_list);
1088 list_del(&req->rl_free);1060 list_del_init(&req->rl_list);
1089 return req;1061 return req;
1090}1062}
1091 1063
@@ -1187,6 +1159,7 @@ rpcrdma_get_mw(struct rpcrdma_xprt *r_xprt) · 95 unmodified lines
1187 1159
1188 if (!mw)1160 if (!mw)
1189 goto out_nomws;1161 goto out_nomws;
1162 mw->mw_flags = 0;
1190 return mw;1163 return mw;
1191 1164
1192out_nomws:1165out_nomws:
@@ -1267,7 +1240,7 @@ rpcrdma_buffer_put(struct rpcrdma_req *req) · 74 unmodified lines
1267 1240
1268 spin_lock(&buffers->rb_lock);1241 spin_lock(&buffers->rb_lock);
1269 buffers->rb_send_count--;1242 buffers->rb_send_count--;
1270 list_add_tail(&req->rl_free, &buffers->rb_send_bufs);1243 list_add_tail(&req->rl_list, &buffers->rb_send_bufs);
1271 if (rep) {1244 if (rep) {
1272 buffers->rb_recv_count--;1245 buffers->rb_recv_count--;
1273 list_add_tail(&rep->rr_list, &buffers->rb_recv_bufs);1246 list_add_tail(&rep->rr_list, &buffers->rb_recv_bufs);
net/sunrpc/xprtrdma/xprt_rdma.h+38−2
@@ -271,6 +271,7 @@ struct rpcrdma_mw { · 270 unmodified lines
271 struct scatterlist *mw_sg;271 struct scatterlist *mw_sg;
272 int mw_nents;272 int mw_nents;
273 enum dma_data_direction mw_dir;273 enum dma_data_direction mw_dir;
274 unsigned long mw_flags;
274 union {275 union {
275 struct rpcrdma_fmr fmr;276 struct rpcrdma_fmr fmr;
276 struct rpcrdma_frmr frmr;277 struct rpcrdma_frmr frmr;
@@ -282,6 +283,11 @@ struct rpcrdma_mw { · 5 unmodified lines
282 struct list_head mw_all;283 struct list_head mw_all;
283};284};
284 285
286/* mw_flags */
287enum {
288 RPCRDMA_MW_F_RI = 1,
289};
290
285/*291/*
286 * struct rpcrdma_req -- structure central to the request/reply sequence.292 * struct rpcrdma_req -- structure central to the request/reply sequence.
287 *293 *
@@ -334,7 +340,8 @@ enum { · 46 unmodified lines
334 340
335struct rpcrdma_buffer;341struct rpcrdma_buffer;
336struct rpcrdma_req {342struct rpcrdma_req {
337 struct list_head rl_free;343 struct list_head rl_list;
344 __be32 rl_xid;
338 unsigned int rl_mapped_sges;345 unsigned int rl_mapped_sges;
339 unsigned int rl_connect_cookie;346 unsigned int rl_connect_cookie;
340 struct rpcrdma_buffer *rl_buffer;347 struct rpcrdma_buffer *rl_buffer;
@@ -396,6 +403,7 @@ struct rpcrdma_buffer { · 55 unmodified lines
396 int rb_send_count, rb_recv_count;403 int rb_send_count, rb_recv_count;
397 struct list_head rb_send_bufs;404 struct list_head rb_send_bufs;
398 struct list_head rb_recv_bufs;405 struct list_head rb_recv_bufs;
406 struct list_head rb_pending;
399 u32 rb_max_requests;407 u32 rb_max_requests;
400 atomic_t rb_credits; /* most recent credit grant */408 atomic_t rb_credits; /* most recent credit grant */
401 409
@@ -461,7 +469,7 @@ struct rpcrdma_memreg_ops { · 59 unmodified lines
461 struct rpcrdma_mr_seg *, int, bool,469 struct rpcrdma_mr_seg *, int, bool,
462 struct rpcrdma_mw **);470 struct rpcrdma_mw **);
463 void (*ro_unmap_sync)(struct rpcrdma_xprt *,471 void (*ro_unmap_sync)(struct rpcrdma_xprt *,
464 struct rpcrdma_req *);472 struct list_head *);
465 void (*ro_unmap_safe)(struct rpcrdma_xprt *,473 void (*ro_unmap_safe)(struct rpcrdma_xprt *,
466 struct rpcrdma_req *, bool);474 struct rpcrdma_req *, bool);
467 void (*ro_recover_mr)(struct rpcrdma_mw *);475 void (*ro_recover_mr)(struct rpcrdma_mw *);
@@ -544,6 +552,34 @@ void rpcrdma_destroy_req(struct rpcrdma_req *); · 76 unmodified lines
544int rpcrdma_buffer_create(struct rpcrdma_xprt *);552int rpcrdma_buffer_create(struct rpcrdma_xprt *);
545void rpcrdma_buffer_destroy(struct rpcrdma_buffer *);553void rpcrdma_buffer_destroy(struct rpcrdma_buffer *);
546 554
555static inline void
556rpcrdma_insert_req(struct rpcrdma_buffer *buffers, struct rpcrdma_req *req)
557{
558 spin_lock(&buffers->rb_lock);
559 if (list_empty(&req->rl_list))
560 list_add_tail(&req->rl_list, &buffers->rb_pending);
561 spin_unlock(&buffers->rb_lock);
562}
563
564static inline struct rpcrdma_req *
565rpcrdma_lookup_req_locked(struct rpcrdma_buffer *buffers, __be32 xid)
566{
567 struct rpcrdma_req *pos;
568
569 list_for_each_entry(pos, &buffers->rb_pending, rl_list)
570 if (pos->rl_xid == xid)
571 return pos;
572 return NULL;
573}
574
575static inline void
576rpcrdma_remove_req(struct rpcrdma_buffer *buffers, struct rpcrdma_req *req)
577{
578 spin_lock(&buffers->rb_lock);
579 list_del(&req->rl_list);
580 spin_unlock(&buffers->rb_lock);
581}
582
547struct rpcrdma_mw *rpcrdma_get_mw(struct rpcrdma_xprt *);583struct rpcrdma_mw *rpcrdma_get_mw(struct rpcrdma_xprt *);
548void rpcrdma_put_mw(struct rpcrdma_xprt *, struct rpcrdma_mw *);584void rpcrdma_put_mw(struct rpcrdma_xprt *, struct rpcrdma_mw *);
549struct rpcrdma_req *rpcrdma_buffer_get(struct rpcrdma_buffer *);585struct rpcrdma_req *rpcrdma_buffer_get(struct rpcrdma_buffer *);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t