aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4filelayout.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4filelayout.c')
-rw-r--r--fs/nfs/nfs4filelayout.c272
1 files changed, 215 insertions, 57 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 71ec08617e23..634c0bcb4fd6 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -33,7 +33,10 @@
33#include <linux/nfs_page.h> 33#include <linux/nfs_page.h>
34#include <linux/module.h> 34#include <linux/module.h>
35 35
36#include <linux/sunrpc/metrics.h>
37
36#include "internal.h" 38#include "internal.h"
39#include "delegation.h"
37#include "nfs4filelayout.h" 40#include "nfs4filelayout.h"
38 41
39#define NFSDBG_FACILITY NFSDBG_PNFS_LD 42#define NFSDBG_FACILITY NFSDBG_PNFS_LD
@@ -84,12 +87,27 @@ static int filelayout_async_handle_error(struct rpc_task *task,
84 struct nfs_client *clp, 87 struct nfs_client *clp,
85 int *reset) 88 int *reset)
86{ 89{
90 struct nfs_server *mds_server = NFS_SERVER(state->inode);
91 struct nfs_client *mds_client = mds_server->nfs_client;
92
87 if (task->tk_status >= 0) 93 if (task->tk_status >= 0)
88 return 0; 94 return 0;
89
90 *reset = 0; 95 *reset = 0;
91 96
92 switch (task->tk_status) { 97 switch (task->tk_status) {
98 /* MDS state errors */
99 case -NFS4ERR_DELEG_REVOKED:
100 case -NFS4ERR_ADMIN_REVOKED:
101 case -NFS4ERR_BAD_STATEID:
102 nfs_remove_bad_delegation(state->inode);
103 case -NFS4ERR_OPENMODE:
104 nfs4_schedule_stateid_recovery(mds_server, state);
105 goto wait_on_recovery;
106 case -NFS4ERR_EXPIRED:
107 nfs4_schedule_stateid_recovery(mds_server, state);
108 nfs4_schedule_lease_recovery(mds_client);
109 goto wait_on_recovery;
110 /* DS session errors */
93 case -NFS4ERR_BADSESSION: 111 case -NFS4ERR_BADSESSION:
94 case -NFS4ERR_BADSLOT: 112 case -NFS4ERR_BADSLOT:
95 case -NFS4ERR_BAD_HIGH_SLOT: 113 case -NFS4ERR_BAD_HIGH_SLOT:
@@ -115,8 +133,14 @@ static int filelayout_async_handle_error(struct rpc_task *task,
115 *reset = 1; 133 *reset = 1;
116 break; 134 break;
117 } 135 }
136out:
118 task->tk_status = 0; 137 task->tk_status = 0;
119 return -EAGAIN; 138 return -EAGAIN;
139wait_on_recovery:
140 rpc_sleep_on(&mds_client->cl_rpcwaitq, task, NULL);
141 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &mds_client->cl_state) == 0)
142 rpc_wake_up_queued_task(&mds_client->cl_rpcwaitq, task);
143 goto out;
120} 144}
121 145
122/* NFS_PROTO call done callback routines */ 146/* NFS_PROTO call done callback routines */
@@ -173,7 +197,7 @@ static void filelayout_read_prepare(struct rpc_task *task, void *data)
173 197
174 if (nfs41_setup_sequence(rdata->ds_clp->cl_session, 198 if (nfs41_setup_sequence(rdata->ds_clp->cl_session,
175 &rdata->args.seq_args, &rdata->res.seq_res, 199 &rdata->args.seq_args, &rdata->res.seq_res,
176 0, task)) 200 task))
177 return; 201 return;
178 202
179 rpc_call_start(task); 203 rpc_call_start(task);
@@ -189,10 +213,18 @@ static void filelayout_read_call_done(struct rpc_task *task, void *data)
189 rdata->mds_ops->rpc_call_done(task, data); 213 rdata->mds_ops->rpc_call_done(task, data);
190} 214}
191 215
216static void filelayout_read_count_stats(struct rpc_task *task, void *data)
217{
218 struct nfs_read_data *rdata = (struct nfs_read_data *)data;
219
220 rpc_count_iostats(task, NFS_SERVER(rdata->inode)->client->cl_metrics);
221}
222
192static void filelayout_read_release(void *data) 223static void filelayout_read_release(void *data)
193{ 224{
194 struct nfs_read_data *rdata = (struct nfs_read_data *)data; 225 struct nfs_read_data *rdata = (struct nfs_read_data *)data;
195 226
227 put_lseg(rdata->lseg);
196 rdata->mds_ops->rpc_release(data); 228 rdata->mds_ops->rpc_release(data);
197} 229}
198 230
@@ -254,7 +286,7 @@ static void filelayout_write_prepare(struct rpc_task *task, void *data)
254 286
255 if (nfs41_setup_sequence(wdata->ds_clp->cl_session, 287 if (nfs41_setup_sequence(wdata->ds_clp->cl_session,
256 &wdata->args.seq_args, &wdata->res.seq_res, 288 &wdata->args.seq_args, &wdata->res.seq_res,
257 0, task)) 289 task))
258 return; 290 return;
259 291
260 rpc_call_start(task); 292 rpc_call_start(task);
@@ -268,10 +300,18 @@ static void filelayout_write_call_done(struct rpc_task *task, void *data)
268 wdata->mds_ops->rpc_call_done(task, data); 300 wdata->mds_ops->rpc_call_done(task, data);
269} 301}
270 302
303static void filelayout_write_count_stats(struct rpc_task *task, void *data)
304{
305 struct nfs_write_data *wdata = (struct nfs_write_data *)data;
306
307 rpc_count_iostats(task, NFS_SERVER(wdata->inode)->client->cl_metrics);
308}
309
271static void filelayout_write_release(void *data) 310static void filelayout_write_release(void *data)
272{ 311{
273 struct nfs_write_data *wdata = (struct nfs_write_data *)data; 312 struct nfs_write_data *wdata = (struct nfs_write_data *)data;
274 313
314 put_lseg(wdata->lseg);
275 wdata->mds_ops->rpc_release(data); 315 wdata->mds_ops->rpc_release(data);
276} 316}
277 317
@@ -282,24 +322,28 @@ static void filelayout_commit_release(void *data)
282 nfs_commit_release_pages(wdata); 322 nfs_commit_release_pages(wdata);
283 if (atomic_dec_and_test(&NFS_I(wdata->inode)->commits_outstanding)) 323 if (atomic_dec_and_test(&NFS_I(wdata->inode)->commits_outstanding))
284 nfs_commit_clear_lock(NFS_I(wdata->inode)); 324 nfs_commit_clear_lock(NFS_I(wdata->inode));
325 put_lseg(wdata->lseg);
285 nfs_commitdata_release(wdata); 326 nfs_commitdata_release(wdata);
286} 327}
287 328
288struct rpc_call_ops filelayout_read_call_ops = { 329static const struct rpc_call_ops filelayout_read_call_ops = {
289 .rpc_call_prepare = filelayout_read_prepare, 330 .rpc_call_prepare = filelayout_read_prepare,
290 .rpc_call_done = filelayout_read_call_done, 331 .rpc_call_done = filelayout_read_call_done,
332 .rpc_count_stats = filelayout_read_count_stats,
291 .rpc_release = filelayout_read_release, 333 .rpc_release = filelayout_read_release,
292}; 334};
293 335
294struct rpc_call_ops filelayout_write_call_ops = { 336static const struct rpc_call_ops filelayout_write_call_ops = {
295 .rpc_call_prepare = filelayout_write_prepare, 337 .rpc_call_prepare = filelayout_write_prepare,
296 .rpc_call_done = filelayout_write_call_done, 338 .rpc_call_done = filelayout_write_call_done,
339 .rpc_count_stats = filelayout_write_count_stats,
297 .rpc_release = filelayout_write_release, 340 .rpc_release = filelayout_write_release,
298}; 341};
299 342
300struct rpc_call_ops filelayout_commit_call_ops = { 343static const struct rpc_call_ops filelayout_commit_call_ops = {
301 .rpc_call_prepare = filelayout_write_prepare, 344 .rpc_call_prepare = filelayout_write_prepare,
302 .rpc_call_done = filelayout_write_call_done, 345 .rpc_call_done = filelayout_write_call_done,
346 .rpc_count_stats = filelayout_write_count_stats,
303 .rpc_release = filelayout_commit_release, 347 .rpc_release = filelayout_commit_release,
304}; 348};
305 349
@@ -367,7 +411,8 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync)
367 idx = nfs4_fl_calc_ds_index(lseg, j); 411 idx = nfs4_fl_calc_ds_index(lseg, j);
368 ds = nfs4_fl_prepare_ds(lseg, idx); 412 ds = nfs4_fl_prepare_ds(lseg, idx);
369 if (!ds) { 413 if (!ds) {
370 printk(KERN_ERR "%s: prepare_ds failed, use MDS\n", __func__); 414 printk(KERN_ERR "NFS: %s: prepare_ds failed, use MDS\n",
415 __func__);
371 set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags); 416 set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags);
372 set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags); 417 set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags);
373 return PNFS_NOT_ATTEMPTED; 418 return PNFS_NOT_ATTEMPTED;
@@ -575,7 +620,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
575 goto out_err_free; 620 goto out_err_free;
576 fl->fh_array[i]->size = be32_to_cpup(p++); 621 fl->fh_array[i]->size = be32_to_cpup(p++);
577 if (sizeof(struct nfs_fh) < fl->fh_array[i]->size) { 622 if (sizeof(struct nfs_fh) < fl->fh_array[i]->size) {
578 printk(KERN_ERR "Too big fh %d received %d\n", 623 printk(KERN_ERR "NFS: Too big fh %d received %d\n",
579 i, fl->fh_array[i]->size); 624 i, fl->fh_array[i]->size);
580 goto out_err_free; 625 goto out_err_free;
581 } 626 }
@@ -640,14 +685,16 @@ filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid,
640 int size = (fl->stripe_type == STRIPE_SPARSE) ? 685 int size = (fl->stripe_type == STRIPE_SPARSE) ?
641 fl->dsaddr->ds_num : fl->dsaddr->stripe_count; 686 fl->dsaddr->ds_num : fl->dsaddr->stripe_count;
642 687
643 fl->commit_buckets = kcalloc(size, sizeof(struct list_head), gfp_flags); 688 fl->commit_buckets = kcalloc(size, sizeof(struct nfs4_fl_commit_bucket), gfp_flags);
644 if (!fl->commit_buckets) { 689 if (!fl->commit_buckets) {
645 filelayout_free_lseg(&fl->generic_hdr); 690 filelayout_free_lseg(&fl->generic_hdr);
646 return NULL; 691 return NULL;
647 } 692 }
648 fl->number_of_buckets = size; 693 fl->number_of_buckets = size;
649 for (i = 0; i < size; i++) 694 for (i = 0; i < size; i++) {
650 INIT_LIST_HEAD(&fl->commit_buckets[i]); 695 INIT_LIST_HEAD(&fl->commit_buckets[i].written);
696 INIT_LIST_HEAD(&fl->commit_buckets[i].committing);
697 }
651 } 698 }
652 return &fl->generic_hdr; 699 return &fl->generic_hdr;
653} 700}
@@ -679,7 +726,7 @@ filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
679 return (p_stripe == r_stripe); 726 return (p_stripe == r_stripe);
680} 727}
681 728
682void 729static void
683filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio, 730filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
684 struct nfs_page *req) 731 struct nfs_page *req)
685{ 732{
@@ -696,7 +743,7 @@ filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
696 nfs_pageio_reset_read_mds(pgio); 743 nfs_pageio_reset_read_mds(pgio);
697} 744}
698 745
699void 746static void
700filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio, 747filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
701 struct nfs_page *req) 748 struct nfs_page *req)
702{ 749{
@@ -725,11 +772,6 @@ static const struct nfs_pageio_ops filelayout_pg_write_ops = {
725 .pg_doio = pnfs_generic_pg_writepages, 772 .pg_doio = pnfs_generic_pg_writepages,
726}; 773};
727 774
728static bool filelayout_mark_pnfs_commit(struct pnfs_layout_segment *lseg)
729{
730 return !FILELAYOUT_LSEG(lseg)->commit_through_mds;
731}
732
733static u32 select_bucket_index(struct nfs4_filelayout_segment *fl, u32 j) 775static u32 select_bucket_index(struct nfs4_filelayout_segment *fl, u32 j)
734{ 776{
735 if (fl->stripe_type == STRIPE_SPARSE) 777 if (fl->stripe_type == STRIPE_SPARSE)
@@ -738,13 +780,49 @@ static u32 select_bucket_index(struct nfs4_filelayout_segment *fl, u32 j)
738 return j; 780 return j;
739} 781}
740 782
741struct list_head *filelayout_choose_commit_list(struct nfs_page *req) 783/* The generic layer is about to remove the req from the commit list.
784 * If this will make the bucket empty, it will need to put the lseg reference.
785 */
786static void
787filelayout_clear_request_commit(struct nfs_page *req)
788{
789 struct pnfs_layout_segment *freeme = NULL;
790 struct inode *inode = req->wb_context->dentry->d_inode;
791
792 spin_lock(&inode->i_lock);
793 if (!test_and_clear_bit(PG_COMMIT_TO_DS, &req->wb_flags))
794 goto out;
795 if (list_is_singular(&req->wb_list)) {
796 struct inode *inode = req->wb_context->dentry->d_inode;
797 struct pnfs_layout_segment *lseg;
798
799 /* From here we can find the bucket, but for the moment,
800 * since there is only one relevant lseg...
801 */
802 list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list) {
803 if (lseg->pls_range.iomode == IOMODE_RW) {
804 freeme = lseg;
805 break;
806 }
807 }
808 }
809out:
810 nfs_request_remove_commit_list(req);
811 spin_unlock(&inode->i_lock);
812 put_lseg(freeme);
813}
814
815static struct list_head *
816filelayout_choose_commit_list(struct nfs_page *req,
817 struct pnfs_layout_segment *lseg)
742{ 818{
743 struct pnfs_layout_segment *lseg = req->wb_commit_lseg;
744 struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg); 819 struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg);
745 u32 i, j; 820 u32 i, j;
746 struct list_head *list; 821 struct list_head *list;
747 822
823 if (fl->commit_through_mds)
824 return &NFS_I(req->wb_context->dentry->d_inode)->commit_list;
825
748 /* Note that we are calling nfs4_fl_calc_j_index on each page 826 /* Note that we are calling nfs4_fl_calc_j_index on each page
749 * that ends up being committed to a data server. An attractive 827 * that ends up being committed to a data server. An attractive
750 * alternative is to add a field to nfs_write_data and nfs_page 828 * alternative is to add a field to nfs_write_data and nfs_page
@@ -754,14 +832,30 @@ struct list_head *filelayout_choose_commit_list(struct nfs_page *req)
754 j = nfs4_fl_calc_j_index(lseg, 832 j = nfs4_fl_calc_j_index(lseg,
755 (loff_t)req->wb_index << PAGE_CACHE_SHIFT); 833 (loff_t)req->wb_index << PAGE_CACHE_SHIFT);
756 i = select_bucket_index(fl, j); 834 i = select_bucket_index(fl, j);
757 list = &fl->commit_buckets[i]; 835 list = &fl->commit_buckets[i].written;
758 if (list_empty(list)) { 836 if (list_empty(list)) {
759 /* Non-empty buckets hold a reference on the lseg */ 837 /* Non-empty buckets hold a reference on the lseg. That ref
838 * is normally transferred to the COMMIT call and released
839 * there. It could also be released if the last req is pulled
840 * off due to a rewrite, in which case it will be done in
841 * filelayout_remove_commit_req
842 */
760 get_lseg(lseg); 843 get_lseg(lseg);
761 } 844 }
845 set_bit(PG_COMMIT_TO_DS, &req->wb_flags);
762 return list; 846 return list;
763} 847}
764 848
849static void
850filelayout_mark_request_commit(struct nfs_page *req,
851 struct pnfs_layout_segment *lseg)
852{
853 struct list_head *list;
854
855 list = filelayout_choose_commit_list(req, lseg);
856 nfs_request_add_commit_list(req, list);
857}
858
765static u32 calc_ds_index_from_commit(struct pnfs_layout_segment *lseg, u32 i) 859static u32 calc_ds_index_from_commit(struct pnfs_layout_segment *lseg, u32 i)
766{ 860{
767 struct nfs4_filelayout_segment *flseg = FILELAYOUT_LSEG(lseg); 861 struct nfs4_filelayout_segment *flseg = FILELAYOUT_LSEG(lseg);
@@ -797,11 +891,12 @@ static int filelayout_initiate_commit(struct nfs_write_data *data, int how)
797 idx = calc_ds_index_from_commit(lseg, data->ds_commit_index); 891 idx = calc_ds_index_from_commit(lseg, data->ds_commit_index);
798 ds = nfs4_fl_prepare_ds(lseg, idx); 892 ds = nfs4_fl_prepare_ds(lseg, idx);
799 if (!ds) { 893 if (!ds) {
800 printk(KERN_ERR "%s: prepare_ds failed, use MDS\n", __func__); 894 printk(KERN_ERR "NFS: %s: prepare_ds failed, use MDS\n",
895 __func__);
801 set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags); 896 set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags);
802 set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags); 897 set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags);
803 prepare_to_resend_writes(data); 898 prepare_to_resend_writes(data);
804 data->mds_ops->rpc_release(data); 899 filelayout_commit_release(data);
805 return -EAGAIN; 900 return -EAGAIN;
806 } 901 }
807 dprintk("%s ino %lu, how %d\n", __func__, data->inode->i_ino, how); 902 dprintk("%s ino %lu, how %d\n", __func__, data->inode->i_ino, how);
@@ -817,24 +912,87 @@ static int filelayout_initiate_commit(struct nfs_write_data *data, int how)
817/* 912/*
818 * This is only useful while we are using whole file layouts. 913 * This is only useful while we are using whole file layouts.
819 */ 914 */
820static struct pnfs_layout_segment *find_only_write_lseg(struct inode *inode) 915static struct pnfs_layout_segment *
916find_only_write_lseg_locked(struct inode *inode)
821{ 917{
822 struct pnfs_layout_segment *lseg, *rv = NULL; 918 struct pnfs_layout_segment *lseg;
823 919
824 spin_lock(&inode->i_lock);
825 list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list) 920 list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list)
826 if (lseg->pls_range.iomode == IOMODE_RW) 921 if (lseg->pls_range.iomode == IOMODE_RW)
827 rv = get_lseg(lseg); 922 return lseg;
923 return NULL;
924}
925
926static struct pnfs_layout_segment *find_only_write_lseg(struct inode *inode)
927{
928 struct pnfs_layout_segment *rv;
929
930 spin_lock(&inode->i_lock);
931 rv = find_only_write_lseg_locked(inode);
932 if (rv)
933 get_lseg(rv);
828 spin_unlock(&inode->i_lock); 934 spin_unlock(&inode->i_lock);
829 return rv; 935 return rv;
830} 936}
831 937
832static int alloc_ds_commits(struct inode *inode, struct list_head *list) 938static int
939filelayout_scan_ds_commit_list(struct nfs4_fl_commit_bucket *bucket, int max,
940 spinlock_t *lock)
941{
942 struct list_head *src = &bucket->written;
943 struct list_head *dst = &bucket->committing;
944 struct nfs_page *req, *tmp;
945 int ret = 0;
946
947 list_for_each_entry_safe(req, tmp, src, wb_list) {
948 if (!nfs_lock_request(req))
949 continue;
950 if (cond_resched_lock(lock))
951 list_safe_reset_next(req, tmp, wb_list);
952 nfs_request_remove_commit_list(req);
953 clear_bit(PG_COMMIT_TO_DS, &req->wb_flags);
954 nfs_list_add_request(req, dst);
955 ret++;
956 if (ret == max)
957 break;
958 }
959 return ret;
960}
961
962/* Move reqs from written to committing lists, returning count of number moved.
963 * Note called with i_lock held.
964 */
965static int filelayout_scan_commit_lists(struct inode *inode, int max,
966 spinlock_t *lock)
967{
968 struct pnfs_layout_segment *lseg;
969 struct nfs4_filelayout_segment *fl;
970 int i, rv = 0, cnt;
971
972 lseg = find_only_write_lseg_locked(inode);
973 if (!lseg)
974 goto out_done;
975 fl = FILELAYOUT_LSEG(lseg);
976 if (fl->commit_through_mds)
977 goto out_done;
978 for (i = 0; i < fl->number_of_buckets && max != 0; i++) {
979 cnt = filelayout_scan_ds_commit_list(&fl->commit_buckets[i],
980 max, lock);
981 max -= cnt;
982 rv += cnt;
983 }
984out_done:
985 return rv;
986}
987
988static unsigned int
989alloc_ds_commits(struct inode *inode, struct list_head *list)
833{ 990{
834 struct pnfs_layout_segment *lseg; 991 struct pnfs_layout_segment *lseg;
835 struct nfs4_filelayout_segment *fl; 992 struct nfs4_filelayout_segment *fl;
836 struct nfs_write_data *data; 993 struct nfs_write_data *data;
837 int i, j; 994 int i, j;
995 unsigned int nreq = 0;
838 996
839 /* Won't need this when non-whole file layout segments are supported 997 /* Won't need this when non-whole file layout segments are supported
840 * instead we will use a pnfs_layout_hdr structure */ 998 * instead we will use a pnfs_layout_hdr structure */
@@ -843,28 +1001,27 @@ static int alloc_ds_commits(struct inode *inode, struct list_head *list)
843 return 0; 1001 return 0;
844 fl = FILELAYOUT_LSEG(lseg); 1002 fl = FILELAYOUT_LSEG(lseg);
845 for (i = 0; i < fl->number_of_buckets; i++) { 1003 for (i = 0; i < fl->number_of_buckets; i++) {
846 if (list_empty(&fl->commit_buckets[i])) 1004 if (list_empty(&fl->commit_buckets[i].committing))
847 continue; 1005 continue;
848 data = nfs_commitdata_alloc(); 1006 data = nfs_commitdata_alloc();
849 if (!data) 1007 if (!data)
850 goto out_bad; 1008 break;
851 data->ds_commit_index = i; 1009 data->ds_commit_index = i;
852 data->lseg = lseg; 1010 data->lseg = lseg;
853 list_add(&data->pages, list); 1011 list_add(&data->pages, list);
1012 nreq++;
854 } 1013 }
855 put_lseg(lseg);
856 return 0;
857 1014
858out_bad: 1015 /* Clean up on error */
859 for (j = i; j < fl->number_of_buckets; j++) { 1016 for (j = i; j < fl->number_of_buckets; j++) {
860 if (list_empty(&fl->commit_buckets[i])) 1017 if (list_empty(&fl->commit_buckets[i].committing))
861 continue; 1018 continue;
862 nfs_retry_commit(&fl->commit_buckets[i], lseg); 1019 nfs_retry_commit(&fl->commit_buckets[i].committing, lseg);
863 put_lseg(lseg); /* associated with emptying bucket */ 1020 put_lseg(lseg); /* associated with emptying bucket */
864 } 1021 }
865 put_lseg(lseg); 1022 put_lseg(lseg);
866 /* Caller will clean up entries put on list */ 1023 /* Caller will clean up entries put on list */
867 return -ENOMEM; 1024 return nreq;
868} 1025}
869 1026
870/* This follows nfs_commit_list pretty closely */ 1027/* This follows nfs_commit_list pretty closely */
@@ -874,40 +1031,40 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
874{ 1031{
875 struct nfs_write_data *data, *tmp; 1032 struct nfs_write_data *data, *tmp;
876 LIST_HEAD(list); 1033 LIST_HEAD(list);
1034 unsigned int nreq = 0;
877 1035
878 if (!list_empty(mds_pages)) { 1036 if (!list_empty(mds_pages)) {
879 data = nfs_commitdata_alloc(); 1037 data = nfs_commitdata_alloc();
880 if (!data) 1038 if (data != NULL) {
881 goto out_bad; 1039 data->lseg = NULL;
882 data->lseg = NULL; 1040 list_add(&data->pages, &list);
883 list_add(&data->pages, &list); 1041 nreq++;
1042 } else
1043 nfs_retry_commit(mds_pages, NULL);
884 } 1044 }
885 1045
886 if (alloc_ds_commits(inode, &list)) 1046 nreq += alloc_ds_commits(inode, &list);
887 goto out_bad; 1047
1048 if (nreq == 0) {
1049 nfs_commit_clear_lock(NFS_I(inode));
1050 goto out;
1051 }
1052
1053 atomic_add(nreq, &NFS_I(inode)->commits_outstanding);
888 1054
889 list_for_each_entry_safe(data, tmp, &list, pages) { 1055 list_for_each_entry_safe(data, tmp, &list, pages) {
890 list_del_init(&data->pages); 1056 list_del_init(&data->pages);
891 atomic_inc(&NFS_I(inode)->commits_outstanding);
892 if (!data->lseg) { 1057 if (!data->lseg) {
893 nfs_init_commit(data, mds_pages, NULL); 1058 nfs_init_commit(data, mds_pages, NULL);
894 nfs_initiate_commit(data, NFS_CLIENT(inode), 1059 nfs_initiate_commit(data, NFS_CLIENT(inode),
895 data->mds_ops, how); 1060 data->mds_ops, how);
896 } else { 1061 } else {
897 nfs_init_commit(data, &FILELAYOUT_LSEG(data->lseg)->commit_buckets[data->ds_commit_index], data->lseg); 1062 nfs_init_commit(data, &FILELAYOUT_LSEG(data->lseg)->commit_buckets[data->ds_commit_index].committing, data->lseg);
898 filelayout_initiate_commit(data, how); 1063 filelayout_initiate_commit(data, how);
899 } 1064 }
900 } 1065 }
901 return 0; 1066out:
902 out_bad: 1067 return PNFS_ATTEMPTED;
903 list_for_each_entry_safe(data, tmp, &list, pages) {
904 nfs_retry_commit(&data->pages, data->lseg);
905 list_del_init(&data->pages);
906 nfs_commit_free(data);
907 }
908 nfs_retry_commit(mds_pages, NULL);
909 nfs_commit_clear_lock(NFS_I(inode));
910 return -ENOMEM;
911} 1068}
912 1069
913static void 1070static void
@@ -924,8 +1081,9 @@ static struct pnfs_layoutdriver_type filelayout_type = {
924 .free_lseg = filelayout_free_lseg, 1081 .free_lseg = filelayout_free_lseg,
925 .pg_read_ops = &filelayout_pg_read_ops, 1082 .pg_read_ops = &filelayout_pg_read_ops,
926 .pg_write_ops = &filelayout_pg_write_ops, 1083 .pg_write_ops = &filelayout_pg_write_ops,
927 .mark_pnfs_commit = filelayout_mark_pnfs_commit, 1084 .mark_request_commit = filelayout_mark_request_commit,
928 .choose_commit_list = filelayout_choose_commit_list, 1085 .clear_request_commit = filelayout_clear_request_commit,
1086 .scan_commit_lists = filelayout_scan_commit_lists,
929 .commit_pagelist = filelayout_commit_pagelist, 1087 .commit_pagelist = filelayout_commit_pagelist,
930 .read_pagelist = filelayout_read_pagelist, 1088 .read_pagelist = filelayout_read_pagelist,
931 .write_pagelist = filelayout_write_pagelist, 1089 .write_pagelist = filelayout_write_pagelist,