aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/client.c12
-rw-r--r--fs/nfs/filelayout/filelayout.c5
-rw-r--r--fs/nfs/nfs3acl.c5
-rw-r--r--fs/nfs/nfs4_fs.h13
-rw-r--r--fs/nfs/nfs4client.c38
-rw-r--r--fs/nfs/nfs4proc.c50
-rw-r--r--fs/nfs/nfs4state.c24
-rw-r--r--fs/nfs/pagelist.c84
-rw-r--r--fs/nfs/write.c21
9 files changed, 149 insertions, 103 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 1c5ff6d58385..6a4f3666e273 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -1412,24 +1412,18 @@ int nfs_fs_proc_net_init(struct net *net)
1412 p = proc_create("volumes", S_IFREG|S_IRUGO, 1412 p = proc_create("volumes", S_IFREG|S_IRUGO,
1413 nn->proc_nfsfs, &nfs_volume_list_fops); 1413 nn->proc_nfsfs, &nfs_volume_list_fops);
1414 if (!p) 1414 if (!p)
1415 goto error_2; 1415 goto error_1;
1416 return 0; 1416 return 0;
1417 1417
1418error_2:
1419 remove_proc_entry("servers", nn->proc_nfsfs);
1420error_1: 1418error_1:
1421 remove_proc_entry("fs/nfsfs", NULL); 1419 remove_proc_subtree("nfsfs", net->proc_net);
1422error_0: 1420error_0:
1423 return -ENOMEM; 1421 return -ENOMEM;
1424} 1422}
1425 1423
1426void nfs_fs_proc_net_exit(struct net *net) 1424void nfs_fs_proc_net_exit(struct net *net)
1427{ 1425{
1428 struct nfs_net *nn = net_generic(net, nfs_net_id); 1426 remove_proc_subtree("nfsfs", net->proc_net);
1429
1430 remove_proc_entry("volumes", nn->proc_nfsfs);
1431 remove_proc_entry("servers", nn->proc_nfsfs);
1432 remove_proc_entry("fs/nfsfs", NULL);
1433} 1427}
1434 1428
1435/* 1429/*
diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c
index 1359c4a27393..90978075f730 100644
--- a/fs/nfs/filelayout/filelayout.c
+++ b/fs/nfs/filelayout/filelayout.c
@@ -1269,11 +1269,12 @@ filelayout_search_commit_reqs(struct nfs_commit_info *cinfo, struct page *page)
1269static void filelayout_retry_commit(struct nfs_commit_info *cinfo, int idx) 1269static void filelayout_retry_commit(struct nfs_commit_info *cinfo, int idx)
1270{ 1270{
1271 struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds; 1271 struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
1272 struct pnfs_commit_bucket *bucket = fl_cinfo->buckets; 1272 struct pnfs_commit_bucket *bucket;
1273 struct pnfs_layout_segment *freeme; 1273 struct pnfs_layout_segment *freeme;
1274 int i; 1274 int i;
1275 1275
1276 for (i = idx; i < fl_cinfo->nbuckets; i++, bucket++) { 1276 for (i = idx; i < fl_cinfo->nbuckets; i++) {
1277 bucket = &fl_cinfo->buckets[i];
1277 if (list_empty(&bucket->committing)) 1278 if (list_empty(&bucket->committing))
1278 continue; 1279 continue;
1279 nfs_retry_commit(&bucket->committing, bucket->clseg, cinfo); 1280 nfs_retry_commit(&bucket->committing, bucket->clseg, cinfo);
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c
index d0fec260132a..24c6898159cc 100644
--- a/fs/nfs/nfs3acl.c
+++ b/fs/nfs/nfs3acl.c
@@ -129,7 +129,10 @@ static int __nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
129 .rpc_argp = &args, 129 .rpc_argp = &args,
130 .rpc_resp = &fattr, 130 .rpc_resp = &fattr,
131 }; 131 };
132 int status; 132 int status = 0;
133
134 if (acl == NULL && (!S_ISDIR(inode->i_mode) || dfacl == NULL))
135 goto out;
133 136
134 status = -EOPNOTSUPP; 137 status = -EOPNOTSUPP;
135 if (!nfs_server_capable(inode, NFS_CAP_ACLS)) 138 if (!nfs_server_capable(inode, NFS_CAP_ACLS))
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 92193eddb41d..a8b855ab4e22 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -130,16 +130,15 @@ enum {
130 */ 130 */
131 131
132struct nfs4_lock_state { 132struct nfs4_lock_state {
133 struct list_head ls_locks; /* Other lock stateids */ 133 struct list_head ls_locks; /* Other lock stateids */
134 struct nfs4_state * ls_state; /* Pointer to open state */ 134 struct nfs4_state * ls_state; /* Pointer to open state */
135#define NFS_LOCK_INITIALIZED 0 135#define NFS_LOCK_INITIALIZED 0
136#define NFS_LOCK_LOST 1 136#define NFS_LOCK_LOST 1
137 unsigned long ls_flags; 137 unsigned long ls_flags;
138 struct nfs_seqid_counter ls_seqid; 138 struct nfs_seqid_counter ls_seqid;
139 nfs4_stateid ls_stateid; 139 nfs4_stateid ls_stateid;
140 atomic_t ls_count; 140 atomic_t ls_count;
141 fl_owner_t ls_owner; 141 fl_owner_t ls_owner;
142 struct work_struct ls_release;
143}; 142};
144 143
145/* bits for nfs4_state->flags */ 144/* bits for nfs4_state->flags */
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 53e435a95260..ffdb28d86cf8 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -482,6 +482,16 @@ int nfs40_walk_client_list(struct nfs_client *new,
482 482
483 spin_lock(&nn->nfs_client_lock); 483 spin_lock(&nn->nfs_client_lock);
484 list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { 484 list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {
485
486 if (pos->rpc_ops != new->rpc_ops)
487 continue;
488
489 if (pos->cl_proto != new->cl_proto)
490 continue;
491
492 if (pos->cl_minorversion != new->cl_minorversion)
493 continue;
494
485 /* If "pos" isn't marked ready, we can't trust the 495 /* If "pos" isn't marked ready, we can't trust the
486 * remaining fields in "pos" */ 496 * remaining fields in "pos" */
487 if (pos->cl_cons_state > NFS_CS_READY) { 497 if (pos->cl_cons_state > NFS_CS_READY) {
@@ -501,15 +511,6 @@ int nfs40_walk_client_list(struct nfs_client *new,
501 if (pos->cl_cons_state != NFS_CS_READY) 511 if (pos->cl_cons_state != NFS_CS_READY)
502 continue; 512 continue;
503 513
504 if (pos->rpc_ops != new->rpc_ops)
505 continue;
506
507 if (pos->cl_proto != new->cl_proto)
508 continue;
509
510 if (pos->cl_minorversion != new->cl_minorversion)
511 continue;
512
513 if (pos->cl_clientid != new->cl_clientid) 514 if (pos->cl_clientid != new->cl_clientid)
514 continue; 515 continue;
515 516
@@ -622,6 +623,16 @@ int nfs41_walk_client_list(struct nfs_client *new,
622 623
623 spin_lock(&nn->nfs_client_lock); 624 spin_lock(&nn->nfs_client_lock);
624 list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) { 625 list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {
626
627 if (pos->rpc_ops != new->rpc_ops)
628 continue;
629
630 if (pos->cl_proto != new->cl_proto)
631 continue;
632
633 if (pos->cl_minorversion != new->cl_minorversion)
634 continue;
635
625 /* If "pos" isn't marked ready, we can't trust the 636 /* If "pos" isn't marked ready, we can't trust the
626 * remaining fields in "pos", especially the client 637 * remaining fields in "pos", especially the client
627 * ID and serverowner fields. Wait for CREATE_SESSION 638 * ID and serverowner fields. Wait for CREATE_SESSION
@@ -647,15 +658,6 @@ int nfs41_walk_client_list(struct nfs_client *new,
647 if (pos->cl_cons_state != NFS_CS_READY) 658 if (pos->cl_cons_state != NFS_CS_READY)
648 continue; 659 continue;
649 660
650 if (pos->rpc_ops != new->rpc_ops)
651 continue;
652
653 if (pos->cl_proto != new->cl_proto)
654 continue;
655
656 if (pos->cl_minorversion != new->cl_minorversion)
657 continue;
658
659 if (!nfs4_match_clientids(pos, new)) 661 if (!nfs4_match_clientids(pos, new))
660 continue; 662 continue;
661 663
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 75ae8d22f067..6ca0c8e7a945 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2226,9 +2226,13 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
2226 ret = _nfs4_proc_open(opendata); 2226 ret = _nfs4_proc_open(opendata);
2227 if (ret != 0) { 2227 if (ret != 0) {
2228 if (ret == -ENOENT) { 2228 if (ret == -ENOENT) {
2229 d_drop(opendata->dentry); 2229 dentry = opendata->dentry;
2230 d_add(opendata->dentry, NULL); 2230 if (dentry->d_inode)
2231 nfs_set_verifier(opendata->dentry, 2231 d_delete(dentry);
2232 else if (d_unhashed(dentry))
2233 d_add(dentry, NULL);
2234
2235 nfs_set_verifier(dentry,
2232 nfs_save_change_attribute(opendata->dir->d_inode)); 2236 nfs_save_change_attribute(opendata->dir->d_inode));
2233 } 2237 }
2234 goto out; 2238 goto out;
@@ -2560,6 +2564,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
2560 struct nfs4_closedata *calldata = data; 2564 struct nfs4_closedata *calldata = data;
2561 struct nfs4_state *state = calldata->state; 2565 struct nfs4_state *state = calldata->state;
2562 struct nfs_server *server = NFS_SERVER(calldata->inode); 2566 struct nfs_server *server = NFS_SERVER(calldata->inode);
2567 nfs4_stateid *res_stateid = NULL;
2563 2568
2564 dprintk("%s: begin!\n", __func__); 2569 dprintk("%s: begin!\n", __func__);
2565 if (!nfs4_sequence_done(task, &calldata->res.seq_res)) 2570 if (!nfs4_sequence_done(task, &calldata->res.seq_res))
@@ -2570,12 +2575,12 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
2570 */ 2575 */
2571 switch (task->tk_status) { 2576 switch (task->tk_status) {
2572 case 0: 2577 case 0:
2573 if (calldata->roc) 2578 res_stateid = &calldata->res.stateid;
2579 if (calldata->arg.fmode == 0 && calldata->roc)
2574 pnfs_roc_set_barrier(state->inode, 2580 pnfs_roc_set_barrier(state->inode,
2575 calldata->roc_barrier); 2581 calldata->roc_barrier);
2576 nfs_clear_open_stateid(state, &calldata->res.stateid, 0);
2577 renew_lease(server, calldata->timestamp); 2582 renew_lease(server, calldata->timestamp);
2578 goto out_release; 2583 break;
2579 case -NFS4ERR_ADMIN_REVOKED: 2584 case -NFS4ERR_ADMIN_REVOKED:
2580 case -NFS4ERR_STALE_STATEID: 2585 case -NFS4ERR_STALE_STATEID:
2581 case -NFS4ERR_OLD_STATEID: 2586 case -NFS4ERR_OLD_STATEID:
@@ -2589,7 +2594,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
2589 goto out_release; 2594 goto out_release;
2590 } 2595 }
2591 } 2596 }
2592 nfs_clear_open_stateid(state, NULL, calldata->arg.fmode); 2597 nfs_clear_open_stateid(state, res_stateid, calldata->arg.fmode);
2593out_release: 2598out_release:
2594 nfs_release_seqid(calldata->arg.seqid); 2599 nfs_release_seqid(calldata->arg.seqid);
2595 nfs_refresh_inode(calldata->inode, calldata->res.fattr); 2600 nfs_refresh_inode(calldata->inode, calldata->res.fattr);
@@ -2601,6 +2606,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
2601 struct nfs4_closedata *calldata = data; 2606 struct nfs4_closedata *calldata = data;
2602 struct nfs4_state *state = calldata->state; 2607 struct nfs4_state *state = calldata->state;
2603 struct inode *inode = calldata->inode; 2608 struct inode *inode = calldata->inode;
2609 bool is_rdonly, is_wronly, is_rdwr;
2604 int call_close = 0; 2610 int call_close = 0;
2605 2611
2606 dprintk("%s: begin!\n", __func__); 2612 dprintk("%s: begin!\n", __func__);
@@ -2608,21 +2614,27 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
2608 goto out_wait; 2614 goto out_wait;
2609 2615
2610 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; 2616 task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
2611 calldata->arg.fmode = FMODE_READ|FMODE_WRITE;
2612 spin_lock(&state->owner->so_lock); 2617 spin_lock(&state->owner->so_lock);
2618 is_rdwr = test_bit(NFS_O_RDWR_STATE, &state->flags);
2619 is_rdonly = test_bit(NFS_O_RDONLY_STATE, &state->flags);
2620 is_wronly = test_bit(NFS_O_WRONLY_STATE, &state->flags);
2613 /* Calculate the change in open mode */ 2621 /* Calculate the change in open mode */
2622 calldata->arg.fmode = 0;
2614 if (state->n_rdwr == 0) { 2623 if (state->n_rdwr == 0) {
2615 if (state->n_rdonly == 0) { 2624 if (state->n_rdonly == 0)
2616 call_close |= test_bit(NFS_O_RDONLY_STATE, &state->flags); 2625 call_close |= is_rdonly;
2617 call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags); 2626 else if (is_rdonly)
2618 calldata->arg.fmode &= ~FMODE_READ; 2627 calldata->arg.fmode |= FMODE_READ;
2619 } 2628 if (state->n_wronly == 0)
2620 if (state->n_wronly == 0) { 2629 call_close |= is_wronly;
2621 call_close |= test_bit(NFS_O_WRONLY_STATE, &state->flags); 2630 else if (is_wronly)
2622 call_close |= test_bit(NFS_O_RDWR_STATE, &state->flags); 2631 calldata->arg.fmode |= FMODE_WRITE;
2623 calldata->arg.fmode &= ~FMODE_WRITE; 2632 } else if (is_rdwr)
2624 } 2633 calldata->arg.fmode |= FMODE_READ|FMODE_WRITE;
2625 } 2634
2635 if (calldata->arg.fmode == 0)
2636 call_close |= is_rdwr;
2637
2626 if (!nfs4_valid_open_stateid(state)) 2638 if (!nfs4_valid_open_stateid(state))
2627 call_close = 0; 2639 call_close = 0;
2628 spin_unlock(&state->owner->so_lock); 2640 spin_unlock(&state->owner->so_lock);
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index a043f618cd5a..22fe35104c0c 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -799,18 +799,6 @@ __nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
799 return NULL; 799 return NULL;
800} 800}
801 801
802static void
803free_lock_state_work(struct work_struct *work)
804{
805 struct nfs4_lock_state *lsp = container_of(work,
806 struct nfs4_lock_state, ls_release);
807 struct nfs4_state *state = lsp->ls_state;
808 struct nfs_server *server = state->owner->so_server;
809 struct nfs_client *clp = server->nfs_client;
810
811 clp->cl_mvops->free_lock_state(server, lsp);
812}
813
814/* 802/*
815 * Return a compatible lock_state. If no initialized lock_state structure 803 * Return a compatible lock_state. If no initialized lock_state structure
816 * exists, return an uninitialized one. 804 * exists, return an uninitialized one.
@@ -832,7 +820,6 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
832 if (lsp->ls_seqid.owner_id < 0) 820 if (lsp->ls_seqid.owner_id < 0)
833 goto out_free; 821 goto out_free;
834 INIT_LIST_HEAD(&lsp->ls_locks); 822 INIT_LIST_HEAD(&lsp->ls_locks);
835 INIT_WORK(&lsp->ls_release, free_lock_state_work);
836 return lsp; 823 return lsp;
837out_free: 824out_free:
838 kfree(lsp); 825 kfree(lsp);
@@ -896,12 +883,13 @@ void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
896 if (list_empty(&state->lock_states)) 883 if (list_empty(&state->lock_states))
897 clear_bit(LK_STATE_IN_USE, &state->flags); 884 clear_bit(LK_STATE_IN_USE, &state->flags);
898 spin_unlock(&state->state_lock); 885 spin_unlock(&state->state_lock);
899 if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) 886 server = state->owner->so_server;
900 queue_work(nfsiod_workqueue, &lsp->ls_release); 887 if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
901 else { 888 struct nfs_client *clp = server->nfs_client;
902 server = state->owner->so_server; 889
890 clp->cl_mvops->free_lock_state(server, lsp);
891 } else
903 nfs4_free_lock_state(server, lsp); 892 nfs4_free_lock_state(server, lsp);
904 }
905} 893}
906 894
907static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src) 895static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index ba491926df5f..be7cbce6e4c7 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -116,7 +116,7 @@ __nfs_iocounter_wait(struct nfs_io_counter *c)
116 if (atomic_read(&c->io_count) == 0) 116 if (atomic_read(&c->io_count) == 0)
117 break; 117 break;
118 ret = nfs_wait_bit_killable(&q.key); 118 ret = nfs_wait_bit_killable(&q.key);
119 } while (atomic_read(&c->io_count) != 0); 119 } while (atomic_read(&c->io_count) != 0 && !ret);
120 finish_wait(wq, &q.wait); 120 finish_wait(wq, &q.wait);
121 return ret; 121 return ret;
122} 122}
@@ -139,26 +139,49 @@ nfs_iocounter_wait(struct nfs_io_counter *c)
139/* 139/*
140 * nfs_page_group_lock - lock the head of the page group 140 * nfs_page_group_lock - lock the head of the page group
141 * @req - request in group that is to be locked 141 * @req - request in group that is to be locked
142 * @nonblock - if true don't block waiting for lock
142 * 143 *
143 * this lock must be held if modifying the page group list 144 * this lock must be held if modifying the page group list
144 * 145 *
145 * returns result from wait_on_bit_lock: 0 on success, < 0 on error 146 * return 0 on success, < 0 on error: -EDELAY if nonblocking or the
147 * result from wait_on_bit_lock
148 *
149 * NOTE: calling with nonblock=false should always have set the
150 * lock bit (see fs/buffer.c and other uses of wait_on_bit_lock
151 * with TASK_UNINTERRUPTIBLE), so there is no need to check the result.
146 */ 152 */
147int 153int
148nfs_page_group_lock(struct nfs_page *req, bool wait) 154nfs_page_group_lock(struct nfs_page *req, bool nonblock)
149{ 155{
150 struct nfs_page *head = req->wb_head; 156 struct nfs_page *head = req->wb_head;
151 int ret;
152 157
153 WARN_ON_ONCE(head != head->wb_head); 158 WARN_ON_ONCE(head != head->wb_head);
154 159
155 do { 160 if (!test_and_set_bit(PG_HEADLOCK, &head->wb_flags))
156 ret = wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK, 161 return 0;
157 TASK_UNINTERRUPTIBLE);
158 } while (wait && ret != 0);
159 162
160 WARN_ON_ONCE(ret > 0); 163 if (!nonblock)
161 return ret; 164 return wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK,
165 TASK_UNINTERRUPTIBLE);
166
167 return -EAGAIN;
168}
169
170/*
171 * nfs_page_group_lock_wait - wait for the lock to clear, but don't grab it
172 * @req - a request in the group
173 *
174 * This is a blocking call to wait for the group lock to be cleared.
175 */
176void
177nfs_page_group_lock_wait(struct nfs_page *req)
178{
179 struct nfs_page *head = req->wb_head;
180
181 WARN_ON_ONCE(head != head->wb_head);
182
183 wait_on_bit(&head->wb_flags, PG_HEADLOCK,
184 TASK_UNINTERRUPTIBLE);
162} 185}
163 186
164/* 187/*
@@ -219,7 +242,7 @@ bool nfs_page_group_sync_on_bit(struct nfs_page *req, unsigned int bit)
219{ 242{
220 bool ret; 243 bool ret;
221 244
222 nfs_page_group_lock(req, true); 245 nfs_page_group_lock(req, false);
223 ret = nfs_page_group_sync_on_bit_locked(req, bit); 246 ret = nfs_page_group_sync_on_bit_locked(req, bit);
224 nfs_page_group_unlock(req); 247 nfs_page_group_unlock(req);
225 248
@@ -701,10 +724,11 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc,
701 struct nfs_pgio_header *hdr) 724 struct nfs_pgio_header *hdr)
702{ 725{
703 struct nfs_page *req; 726 struct nfs_page *req;
704 struct page **pages; 727 struct page **pages,
728 *last_page;
705 struct list_head *head = &desc->pg_list; 729 struct list_head *head = &desc->pg_list;
706 struct nfs_commit_info cinfo; 730 struct nfs_commit_info cinfo;
707 unsigned int pagecount; 731 unsigned int pagecount, pageused;
708 732
709 pagecount = nfs_page_array_len(desc->pg_base, desc->pg_count); 733 pagecount = nfs_page_array_len(desc->pg_base, desc->pg_count);
710 if (!nfs_pgarray_set(&hdr->page_array, pagecount)) 734 if (!nfs_pgarray_set(&hdr->page_array, pagecount))
@@ -712,12 +736,23 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc,
712 736
713 nfs_init_cinfo(&cinfo, desc->pg_inode, desc->pg_dreq); 737 nfs_init_cinfo(&cinfo, desc->pg_inode, desc->pg_dreq);
714 pages = hdr->page_array.pagevec; 738 pages = hdr->page_array.pagevec;
739 last_page = NULL;
740 pageused = 0;
715 while (!list_empty(head)) { 741 while (!list_empty(head)) {
716 req = nfs_list_entry(head->next); 742 req = nfs_list_entry(head->next);
717 nfs_list_remove_request(req); 743 nfs_list_remove_request(req);
718 nfs_list_add_request(req, &hdr->pages); 744 nfs_list_add_request(req, &hdr->pages);
719 *pages++ = req->wb_page; 745
746 if (WARN_ON_ONCE(pageused >= pagecount))
747 return nfs_pgio_error(desc, hdr);
748
749 if (!last_page || last_page != req->wb_page) {
750 *pages++ = last_page = req->wb_page;
751 pageused++;
752 }
720 } 753 }
754 if (WARN_ON_ONCE(pageused != pagecount))
755 return nfs_pgio_error(desc, hdr);
721 756
722 if ((desc->pg_ioflags & FLUSH_COND_STABLE) && 757 if ((desc->pg_ioflags & FLUSH_COND_STABLE) &&
723 (desc->pg_moreio || nfs_reqs_to_commit(&cinfo))) 758 (desc->pg_moreio || nfs_reqs_to_commit(&cinfo)))
@@ -788,6 +823,14 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev,
788 return false; 823 return false;
789 if (req_offset(req) != req_offset(prev) + prev->wb_bytes) 824 if (req_offset(req) != req_offset(prev) + prev->wb_bytes)
790 return false; 825 return false;
826 if (req->wb_page == prev->wb_page) {
827 if (req->wb_pgbase != prev->wb_pgbase + prev->wb_bytes)
828 return false;
829 } else {
830 if (req->wb_pgbase != 0 ||
831 prev->wb_pgbase + prev->wb_bytes != PAGE_CACHE_SIZE)
832 return false;
833 }
791 } 834 }
792 size = pgio->pg_ops->pg_test(pgio, prev, req); 835 size = pgio->pg_ops->pg_test(pgio, prev, req);
793 WARN_ON_ONCE(size > req->wb_bytes); 836 WARN_ON_ONCE(size > req->wb_bytes);
@@ -858,13 +901,8 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
858 struct nfs_page *subreq; 901 struct nfs_page *subreq;
859 unsigned int bytes_left = 0; 902 unsigned int bytes_left = 0;
860 unsigned int offset, pgbase; 903 unsigned int offset, pgbase;
861 int ret;
862 904
863 ret = nfs_page_group_lock(req, false); 905 nfs_page_group_lock(req, false);
864 if (ret < 0) {
865 desc->pg_error = ret;
866 return 0;
867 }
868 906
869 subreq = req; 907 subreq = req;
870 bytes_left = subreq->wb_bytes; 908 bytes_left = subreq->wb_bytes;
@@ -886,11 +924,7 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
886 if (desc->pg_recoalesce) 924 if (desc->pg_recoalesce)
887 return 0; 925 return 0;
888 /* retry add_request for this subreq */ 926 /* retry add_request for this subreq */
889 ret = nfs_page_group_lock(req, false); 927 nfs_page_group_lock(req, false);
890 if (ret < 0) {
891 desc->pg_error = ret;
892 return 0;
893 }
894 continue; 928 continue;
895 } 929 }
896 930
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index e3b5cf28bdc5..175d5d073ccf 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -241,7 +241,7 @@ static bool nfs_page_group_covers_page(struct nfs_page *req)
241 unsigned int pos = 0; 241 unsigned int pos = 0;
242 unsigned int len = nfs_page_length(req->wb_page); 242 unsigned int len = nfs_page_length(req->wb_page);
243 243
244 nfs_page_group_lock(req, true); 244 nfs_page_group_lock(req, false);
245 245
246 do { 246 do {
247 tmp = nfs_page_group_search_locked(req->wb_head, pos); 247 tmp = nfs_page_group_search_locked(req->wb_head, pos);
@@ -478,10 +478,23 @@ try_again:
478 return NULL; 478 return NULL;
479 } 479 }
480 480
481 /* lock each request in the page group */ 481 /* holding inode lock, so always make a non-blocking call to try the
482 ret = nfs_page_group_lock(head, false); 482 * page group lock */
483 if (ret < 0) 483 ret = nfs_page_group_lock(head, true);
484 if (ret < 0) {
485 spin_unlock(&inode->i_lock);
486
487 if (!nonblock && ret == -EAGAIN) {
488 nfs_page_group_lock_wait(head);
489 nfs_release_request(head);
490 goto try_again;
491 }
492
493 nfs_release_request(head);
484 return ERR_PTR(ret); 494 return ERR_PTR(ret);
495 }
496
497 /* lock each request in the page group */
485 subreq = head; 498 subreq = head;
486 do { 499 do {
487 /* 500 /*