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.c271
1 files changed, 214 insertions, 57 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 71ec08617e2..5acfd9ea8a3 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,48 @@ 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 pnfs_layout_segment *lseg;
797
798 /* From here we can find the bucket, but for the moment,
799 * since there is only one relevant lseg...
800 */
801 list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list) {
802 if (lseg->pls_range.iomode == IOMODE_RW) {
803 freeme = lseg;
804 break;
805 }
806 }
807 }
808out:
809 nfs_request_remove_commit_list(req);
810 spin_unlock(&inode->i_lock);
811 put_lseg(freeme);
812}
813
814static struct list_head *
815filelayout_choose_commit_list(struct nfs_page *req,
816 struct pnfs_layout_segment *lseg)
742{ 817{
743 struct pnfs_layout_segment *lseg = req->wb_commit_lseg;
744 struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg); 818 struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg);
745 u32 i, j; 819 u32 i, j;
746 struct list_head *list; 820 struct list_head *list;
747 821
822 if (fl->commit_through_mds)
823 return &NFS_I(req->wb_context->dentry->d_inode)->commit_list;
824
748 /* Note that we are calling nfs4_fl_calc_j_index on each page 825 /* 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 826 * 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 827 * alternative is to add a field to nfs_write_data and nfs_page
@@ -754,14 +831,30 @@ struct list_head *filelayout_choose_commit_list(struct nfs_page *req)
754 j = nfs4_fl_calc_j_index(lseg, 831 j = nfs4_fl_calc_j_index(lseg,
755 (loff_t)req->wb_index << PAGE_CACHE_SHIFT); 832 (loff_t)req->wb_index << PAGE_CACHE_SHIFT);
756 i = select_bucket_index(fl, j); 833 i = select_bucket_index(fl, j);
757 list = &fl->commit_buckets[i]; 834 list = &fl->commit_buckets[i].written;
758 if (list_empty(list)) { 835 if (list_empty(list)) {
759 /* Non-empty buckets hold a reference on the lseg */ 836 /* Non-empty buckets hold a reference on the lseg. That ref
837 * is normally transferred to the COMMIT call and released
838 * there. It could also be released if the last req is pulled
839 * off due to a rewrite, in which case it will be done in
840 * filelayout_remove_commit_req
841 */
760 get_lseg(lseg); 842 get_lseg(lseg);
761 } 843 }
844 set_bit(PG_COMMIT_TO_DS, &req->wb_flags);
762 return list; 845 return list;
763} 846}
764 847
848static void
849filelayout_mark_request_commit(struct nfs_page *req,
850 struct pnfs_layout_segment *lseg)
851{
852 struct list_head *list;
853
854 list = filelayout_choose_commit_list(req, lseg);
855 nfs_request_add_commit_list(req, list);
856}
857
765static u32 calc_ds_index_from_commit(struct pnfs_layout_segment *lseg, u32 i) 858static u32 calc_ds_index_from_commit(struct pnfs_layout_segment *lseg, u32 i)
766{ 859{
767 struct nfs4_filelayout_segment *flseg = FILELAYOUT_LSEG(lseg); 860 struct nfs4_filelayout_segment *flseg = FILELAYOUT_LSEG(lseg);
@@ -797,11 +890,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); 890 idx = calc_ds_index_from_commit(lseg, data->ds_commit_index);
798 ds = nfs4_fl_prepare_ds(lseg, idx); 891 ds = nfs4_fl_prepare_ds(lseg, idx);
799 if (!ds) { 892 if (!ds) {
800 printk(KERN_ERR "%s: prepare_ds failed, use MDS\n", __func__); 893 printk(KERN_ERR "NFS: %s: prepare_ds failed, use MDS\n",
894 __func__);
801 set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags); 895 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); 896 set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags);
803 prepare_to_resend_writes(data); 897 prepare_to_resend_writes(data);
804 data->mds_ops->rpc_release(data); 898 filelayout_commit_release(data);
805 return -EAGAIN; 899 return -EAGAIN;
806 } 900 }
807 dprintk("%s ino %lu, how %d\n", __func__, data->inode->i_ino, how); 901 dprintk("%s ino %lu, how %d\n", __func__, data->inode->i_ino, how);
@@ -817,24 +911,87 @@ static int filelayout_initiate_commit(struct nfs_write_data *data, int how)
817/* 911/*
818 * This is only useful while we are using whole file layouts. 912 * This is only useful while we are using whole file layouts.
819 */ 913 */
820static struct pnfs_layout_segment *find_only_write_lseg(struct inode *inode) 914static struct pnfs_layout_segment *
915find_only_write_lseg_locked(struct inode *inode)
821{ 916{
822 struct pnfs_layout_segment *lseg, *rv = NULL; 917 struct pnfs_layout_segment *lseg;
823 918
824 spin_lock(&inode->i_lock);
825 list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list) 919 list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list)
826 if (lseg->pls_range.iomode == IOMODE_RW) 920 if (lseg->pls_range.iomode == IOMODE_RW)
827 rv = get_lseg(lseg); 921 return lseg;
922 return NULL;
923}
924
925static struct pnfs_layout_segment *find_only_write_lseg(struct inode *inode)
926{
927 struct pnfs_layout_segment *rv;
928
929 spin_lock(&inode->i_lock);
930 rv = find_only_write_lseg_locked(inode);
931 if (rv)
932 get_lseg(rv);
828 spin_unlock(&inode->i_lock); 933 spin_unlock(&inode->i_lock);
829 return rv; 934 return rv;
830} 935}
831 936
832static int alloc_ds_commits(struct inode *inode, struct list_head *list) 937static int
938filelayout_scan_ds_commit_list(struct nfs4_fl_commit_bucket *bucket, int max,
939 spinlock_t *lock)
940{
941 struct list_head *src = &bucket->written;
942 struct list_head *dst = &bucket->committing;
943 struct nfs_page *req, *tmp;
944 int ret = 0;
945
946 list_for_each_entry_safe(req, tmp, src, wb_list) {
947 if (!nfs_lock_request(req))
948 continue;
949 if (cond_resched_lock(lock))
950 list_safe_reset_next(req, tmp, wb_list);
951 nfs_request_remove_commit_list(req);
952 clear_bit(PG_COMMIT_TO_DS, &req->wb_flags);
953 nfs_list_add_request(req, dst);
954 ret++;
955 if (ret == max)
956 break;
957 }
958 return ret;
959}
960
961/* Move reqs from written to committing lists, returning count of number moved.
962 * Note called with i_lock held.
963 */
964static int filelayout_scan_commit_lists(struct inode *inode, int max,
965 spinlock_t *lock)
966{
967 struct pnfs_layout_segment *lseg;
968 struct nfs4_filelayout_segment *fl;
969 int i, rv = 0, cnt;
970
971 lseg = find_only_write_lseg_locked(inode);
972 if (!lseg)
973 goto out_done;
974 fl = FILELAYOUT_LSEG(lseg);
975 if (fl->commit_through_mds)
976 goto out_done;
977 for (i = 0; i < fl->number_of_buckets && max != 0; i++) {
978 cnt = filelayout_scan_ds_commit_list(&fl->commit_buckets[i],
979 max, lock);
980 max -= cnt;
981 rv += cnt;
982 }
983out_done:
984 return rv;
985}
986
987static unsigned int
988alloc_ds_commits(struct inode *inode, struct list_head *list)
833{ 989{
834 struct pnfs_layout_segment *lseg; 990 struct pnfs_layout_segment *lseg;
835 struct nfs4_filelayout_segment *fl; 991 struct nfs4_filelayout_segment *fl;
836 struct nfs_write_data *data; 992 struct nfs_write_data *data;
837 int i, j; 993 int i, j;
994 unsigned int nreq = 0;
838 995
839 /* Won't need this when non-whole file layout segments are supported 996 /* Won't need this when non-whole file layout segments are supported
840 * instead we will use a pnfs_layout_hdr structure */ 997 * instead we will use a pnfs_layout_hdr structure */
@@ -843,28 +1000,27 @@ static int alloc_ds_commits(struct inode *inode, struct list_head *list)
843 return 0; 1000 return 0;
844 fl = FILELAYOUT_LSEG(lseg); 1001 fl = FILELAYOUT_LSEG(lseg);
845 for (i = 0; i < fl->number_of_buckets; i++) { 1002 for (i = 0; i < fl->number_of_buckets; i++) {
846 if (list_empty(&fl->commit_buckets[i])) 1003 if (list_empty(&fl->commit_buckets[i].committing))
847 continue; 1004 continue;
848 data = nfs_commitdata_alloc(); 1005 data = nfs_commitdata_alloc();
849 if (!data) 1006 if (!data)
850 goto out_bad; 1007 break;
851 data->ds_commit_index = i; 1008 data->ds_commit_index = i;
852 data->lseg = lseg; 1009 data->lseg = lseg;
853 list_add(&data->pages, list); 1010 list_add(&data->pages, list);
1011 nreq++;
854 } 1012 }
855 put_lseg(lseg);
856 return 0;
857 1013
858out_bad: 1014 /* Clean up on error */
859 for (j = i; j < fl->number_of_buckets; j++) { 1015 for (j = i; j < fl->number_of_buckets; j++) {
860 if (list_empty(&fl->commit_buckets[i])) 1016 if (list_empty(&fl->commit_buckets[i].committing))
861 continue; 1017 continue;
862 nfs_retry_commit(&fl->commit_buckets[i], lseg); 1018 nfs_retry_commit(&fl->commit_buckets[i].committing, lseg);
863 put_lseg(lseg); /* associated with emptying bucket */ 1019 put_lseg(lseg); /* associated with emptying bucket */
864 } 1020 }
865 put_lseg(lseg); 1021 put_lseg(lseg);
866 /* Caller will clean up entries put on list */ 1022 /* Caller will clean up entries put on list */
867 return -ENOMEM; 1023 return nreq;
868} 1024}
869 1025
870/* This follows nfs_commit_list pretty closely */ 1026/* This follows nfs_commit_list pretty closely */
@@ -874,40 +1030,40 @@ filelayout_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
874{ 1030{
875 struct nfs_write_data *data, *tmp; 1031 struct nfs_write_data *data, *tmp;
876 LIST_HEAD(list); 1032 LIST_HEAD(list);
1033 unsigned int nreq = 0;
877 1034
878 if (!list_empty(mds_pages)) { 1035 if (!list_empty(mds_pages)) {
879 data = nfs_commitdata_alloc(); 1036 data = nfs_commitdata_alloc();
880 if (!data) 1037 if (data != NULL) {
881 goto out_bad; 1038 data->lseg = NULL;
882 data->lseg = NULL; 1039 list_add(&data->pages, &list);
883 list_add(&data->pages, &list); 1040 nreq++;
1041 } else
1042 nfs_retry_commit(mds_pages, NULL);
884 } 1043 }
885 1044
886 if (alloc_ds_commits(inode, &list)) 1045 nreq += alloc_ds_commits(inode, &list);
887 goto out_bad; 1046
1047 if (nreq == 0) {
1048 nfs_commit_clear_lock(NFS_I(inode));
1049 goto out;
1050 }
1051
1052 atomic_add(nreq, &NFS_I(inode)->commits_outstanding);
888 1053
889 list_for_each_entry_safe(data, tmp, &list, pages) { 1054 list_for_each_entry_safe(data, tmp, &list, pages) {
890 list_del_init(&data->pages); 1055 list_del_init(&data->pages);
891 atomic_inc(&NFS_I(inode)->commits_outstanding);
892 if (!data->lseg) { 1056 if (!data->lseg) {
893 nfs_init_commit(data, mds_pages, NULL); 1057 nfs_init_commit(data, mds_pages, NULL);
894 nfs_initiate_commit(data, NFS_CLIENT(inode), 1058 nfs_initiate_commit(data, NFS_CLIENT(inode),
895 data->mds_ops, how); 1059 data->mds_ops, how);
896 } else { 1060 } else {
897 nfs_init_commit(data, &FILELAYOUT_LSEG(data->lseg)->commit_buckets[data->ds_commit_index], data->lseg); 1061 nfs_init_commit(data, &FILELAYOUT_LSEG(data->lseg)->commit_buckets[data->ds_commit_index].committing, data->lseg);
898 filelayout_initiate_commit(data, how); 1062 filelayout_initiate_commit(data, how);
899 } 1063 }
900 } 1064 }
901 return 0; 1065out:
902 out_bad: 1066 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} 1067}
912 1068
913static void 1069static void
@@ -924,8 +1080,9 @@ static struct pnfs_layoutdriver_type filelayout_type = {
924 .free_lseg = filelayout_free_lseg, 1080 .free_lseg = filelayout_free_lseg,
925 .pg_read_ops = &filelayout_pg_read_ops, 1081 .pg_read_ops = &filelayout_pg_read_ops,
926 .pg_write_ops = &filelayout_pg_write_ops, 1082 .pg_write_ops = &filelayout_pg_write_ops,
927 .mark_pnfs_commit = filelayout_mark_pnfs_commit, 1083 .mark_request_commit = filelayout_mark_request_commit,
928 .choose_commit_list = filelayout_choose_commit_list, 1084 .clear_request_commit = filelayout_clear_request_commit,
1085 .scan_commit_lists = filelayout_scan_commit_lists,
929 .commit_pagelist = filelayout_commit_pagelist, 1086 .commit_pagelist = filelayout_commit_pagelist,
930 .read_pagelist = filelayout_read_pagelist, 1087 .read_pagelist = filelayout_read_pagelist,
931 .write_pagelist = filelayout_write_pagelist, 1088 .write_pagelist = filelayout_write_pagelist,