diff options
-rw-r--r-- | fs/nfs/read.c | 42 | ||||
-rw-r--r-- | fs/nfs/write.c | 41 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 2 |
3 files changed, 53 insertions, 32 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index c394662c790e..248a55425853 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -213,17 +213,14 @@ EXPORT_SYMBOL_GPL(nfs_initiate_read); | |||
213 | /* | 213 | /* |
214 | * Set up the NFS read request struct | 214 | * Set up the NFS read request struct |
215 | */ | 215 | */ |
216 | static int nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, | 216 | static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, |
217 | const struct rpc_call_ops *call_ops, | 217 | unsigned int count, unsigned int offset) |
218 | unsigned int count, unsigned int offset, | ||
219 | struct pnfs_layout_segment *lseg) | ||
220 | { | 218 | { |
221 | struct inode *inode = req->wb_context->path.dentry->d_inode; | 219 | struct inode *inode = req->wb_context->path.dentry->d_inode; |
222 | 220 | ||
223 | data->req = req; | 221 | data->req = req; |
224 | data->inode = inode; | 222 | data->inode = inode; |
225 | data->cred = req->wb_context->cred; | 223 | data->cred = req->wb_context->cred; |
226 | data->lseg = get_lseg(lseg); | ||
227 | 224 | ||
228 | data->args.fh = NFS_FH(inode); | 225 | data->args.fh = NFS_FH(inode); |
229 | data->args.offset = req_offset(req) + offset; | 226 | data->args.offset = req_offset(req) + offset; |
@@ -237,10 +234,21 @@ static int nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data, | |||
237 | data->res.count = count; | 234 | data->res.count = count; |
238 | data->res.eof = 0; | 235 | data->res.eof = 0; |
239 | nfs_fattr_init(&data->fattr); | 236 | nfs_fattr_init(&data->fattr); |
237 | } | ||
240 | 238 | ||
241 | if (data->lseg && | 239 | static int nfs_do_read(struct nfs_read_data *data, |
242 | (pnfs_try_to_read_data(data, call_ops) == PNFS_ATTEMPTED)) | 240 | const struct rpc_call_ops *call_ops, |
243 | return 0; | 241 | struct pnfs_layout_segment *lseg) |
242 | { | ||
243 | struct inode *inode = data->args.context->path.dentry->d_inode; | ||
244 | |||
245 | if (lseg) { | ||
246 | data->lseg = get_lseg(lseg); | ||
247 | if (pnfs_try_to_read_data(data, call_ops) == PNFS_ATTEMPTED) | ||
248 | return 0; | ||
249 | put_lseg(data->lseg); | ||
250 | data->lseg = NULL; | ||
251 | } | ||
244 | 252 | ||
245 | return nfs_initiate_read(data, NFS_CLIENT(inode), call_ops); | 253 | return nfs_initiate_read(data, NFS_CLIENT(inode), call_ops); |
246 | } | 254 | } |
@@ -292,7 +300,7 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc) | |||
292 | data = nfs_readdata_alloc(1); | 300 | data = nfs_readdata_alloc(1); |
293 | if (!data) | 301 | if (!data) |
294 | goto out_bad; | 302 | goto out_bad; |
295 | list_add(&data->pages, &list); | 303 | list_add(&data->list, &list); |
296 | requests++; | 304 | requests++; |
297 | nbytes -= len; | 305 | nbytes -= len; |
298 | } while(nbytes != 0); | 306 | } while(nbytes != 0); |
@@ -304,15 +312,15 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc) | |||
304 | do { | 312 | do { |
305 | int ret2; | 313 | int ret2; |
306 | 314 | ||
307 | data = list_entry(list.next, struct nfs_read_data, pages); | 315 | data = list_entry(list.next, struct nfs_read_data, list); |
308 | list_del_init(&data->pages); | 316 | list_del_init(&data->list); |
309 | 317 | ||
310 | data->pagevec[0] = page; | 318 | data->pagevec[0] = page; |
311 | 319 | ||
312 | if (nbytes < rsize) | 320 | if (nbytes < rsize) |
313 | rsize = nbytes; | 321 | rsize = nbytes; |
314 | ret2 = nfs_read_rpcsetup(req, data, &nfs_read_partial_ops, | 322 | nfs_read_rpcsetup(req, data, rsize, offset); |
315 | rsize, offset, lseg); | 323 | ret2 = nfs_do_read(data, &nfs_read_partial_ops, lseg); |
316 | if (ret == 0) | 324 | if (ret == 0) |
317 | ret = ret2; | 325 | ret = ret2; |
318 | offset += rsize; | 326 | offset += rsize; |
@@ -325,8 +333,8 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc) | |||
325 | 333 | ||
326 | out_bad: | 334 | out_bad: |
327 | while (!list_empty(&list)) { | 335 | while (!list_empty(&list)) { |
328 | data = list_entry(list.next, struct nfs_read_data, pages); | 336 | data = list_entry(list.next, struct nfs_read_data, list); |
329 | list_del(&data->pages); | 337 | list_del(&data->list); |
330 | nfs_readdata_free(data); | 338 | nfs_readdata_free(data); |
331 | } | 339 | } |
332 | SetPageError(page); | 340 | SetPageError(page); |
@@ -362,8 +370,8 @@ static int nfs_pagein_one(struct nfs_pageio_descriptor *desc) | |||
362 | } | 370 | } |
363 | req = nfs_list_entry(data->pages.next); | 371 | req = nfs_list_entry(data->pages.next); |
364 | 372 | ||
365 | ret = nfs_read_rpcsetup(req, data, &nfs_read_full_ops, desc->pg_count, | 373 | nfs_read_rpcsetup(req, data, desc->pg_count, 0); |
366 | 0, lseg); | 374 | ret = nfs_do_read(data, &nfs_read_full_ops, lseg); |
367 | out: | 375 | out: |
368 | put_lseg(lseg); | 376 | put_lseg(lseg); |
369 | desc->pg_lseg = NULL; | 377 | desc->pg_lseg = NULL; |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 1af4d82c4959..0aeb09b38e4b 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -845,11 +845,9 @@ EXPORT_SYMBOL_GPL(nfs_initiate_write); | |||
845 | /* | 845 | /* |
846 | * Set up the argument/result storage required for the RPC call. | 846 | * Set up the argument/result storage required for the RPC call. |
847 | */ | 847 | */ |
848 | static int nfs_write_rpcsetup(struct nfs_page *req, | 848 | static void nfs_write_rpcsetup(struct nfs_page *req, |
849 | struct nfs_write_data *data, | 849 | struct nfs_write_data *data, |
850 | const struct rpc_call_ops *call_ops, | ||
851 | unsigned int count, unsigned int offset, | 850 | unsigned int count, unsigned int offset, |
852 | struct pnfs_layout_segment *lseg, | ||
853 | int how) | 851 | int how) |
854 | { | 852 | { |
855 | struct inode *inode = req->wb_context->path.dentry->d_inode; | 853 | struct inode *inode = req->wb_context->path.dentry->d_inode; |
@@ -860,7 +858,6 @@ static int nfs_write_rpcsetup(struct nfs_page *req, | |||
860 | data->req = req; | 858 | data->req = req; |
861 | data->inode = inode = req->wb_context->path.dentry->d_inode; | 859 | data->inode = inode = req->wb_context->path.dentry->d_inode; |
862 | data->cred = req->wb_context->cred; | 860 | data->cred = req->wb_context->cred; |
863 | data->lseg = get_lseg(lseg); | ||
864 | 861 | ||
865 | data->args.fh = NFS_FH(inode); | 862 | data->args.fh = NFS_FH(inode); |
866 | data->args.offset = req_offset(req) + offset; | 863 | data->args.offset = req_offset(req) + offset; |
@@ -886,10 +883,22 @@ static int nfs_write_rpcsetup(struct nfs_page *req, | |||
886 | data->res.count = count; | 883 | data->res.count = count; |
887 | data->res.verf = &data->verf; | 884 | data->res.verf = &data->verf; |
888 | nfs_fattr_init(&data->fattr); | 885 | nfs_fattr_init(&data->fattr); |
886 | } | ||
889 | 887 | ||
890 | if (data->lseg && | 888 | static int nfs_do_write(struct nfs_write_data *data, |
891 | (pnfs_try_to_write_data(data, call_ops, how) == PNFS_ATTEMPTED)) | 889 | const struct rpc_call_ops *call_ops, |
892 | return 0; | 890 | struct pnfs_layout_segment *lseg, |
891 | int how) | ||
892 | { | ||
893 | struct inode *inode = data->args.context->path.dentry->d_inode; | ||
894 | |||
895 | if (lseg != NULL) { | ||
896 | data->lseg = get_lseg(lseg); | ||
897 | if (pnfs_try_to_write_data(data, call_ops, how) == PNFS_ATTEMPTED) | ||
898 | return 0; | ||
899 | put_lseg(data->lseg); | ||
900 | data->lseg = NULL; | ||
901 | } | ||
893 | 902 | ||
894 | return nfs_initiate_write(data, NFS_CLIENT(inode), call_ops, how); | 903 | return nfs_initiate_write(data, NFS_CLIENT(inode), call_ops, how); |
895 | } | 904 | } |
@@ -938,7 +947,7 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc) | |||
938 | data = nfs_writedata_alloc(1); | 947 | data = nfs_writedata_alloc(1); |
939 | if (!data) | 948 | if (!data) |
940 | goto out_bad; | 949 | goto out_bad; |
941 | list_add(&data->pages, &list); | 950 | list_add(&data->list, &list); |
942 | requests++; | 951 | requests++; |
943 | nbytes -= len; | 952 | nbytes -= len; |
944 | } while (nbytes != 0); | 953 | } while (nbytes != 0); |
@@ -950,15 +959,16 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc) | |||
950 | do { | 959 | do { |
951 | int ret2; | 960 | int ret2; |
952 | 961 | ||
953 | data = list_entry(list.next, struct nfs_write_data, pages); | 962 | data = list_entry(list.next, struct nfs_write_data, list); |
954 | list_del_init(&data->pages); | 963 | list_del_init(&data->list); |
955 | 964 | ||
956 | data->pagevec[0] = page; | 965 | data->pagevec[0] = page; |
957 | 966 | ||
958 | if (nbytes < wsize) | 967 | if (nbytes < wsize) |
959 | wsize = nbytes; | 968 | wsize = nbytes; |
960 | ret2 = nfs_write_rpcsetup(req, data, &nfs_write_partial_ops, | 969 | nfs_write_rpcsetup(req, data, wsize, offset, desc->pg_ioflags); |
961 | wsize, offset, lseg, desc->pg_ioflags); | 970 | ret2 = nfs_do_write(data, &nfs_write_partial_ops, lseg, |
971 | desc->pg_ioflags); | ||
962 | if (ret == 0) | 972 | if (ret == 0) |
963 | ret = ret2; | 973 | ret = ret2; |
964 | offset += wsize; | 974 | offset += wsize; |
@@ -971,8 +981,8 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc) | |||
971 | 981 | ||
972 | out_bad: | 982 | out_bad: |
973 | while (!list_empty(&list)) { | 983 | while (!list_empty(&list)) { |
974 | data = list_entry(list.next, struct nfs_write_data, pages); | 984 | data = list_entry(list.next, struct nfs_write_data, list); |
975 | list_del(&data->pages); | 985 | list_del(&data->list); |
976 | nfs_writedata_free(data); | 986 | nfs_writedata_free(data); |
977 | } | 987 | } |
978 | nfs_redirty_request(req); | 988 | nfs_redirty_request(req); |
@@ -1024,7 +1034,8 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc) | |||
1024 | desc->pg_ioflags &= ~FLUSH_COND_STABLE; | 1034 | desc->pg_ioflags &= ~FLUSH_COND_STABLE; |
1025 | 1035 | ||
1026 | /* Set up the argument struct */ | 1036 | /* Set up the argument struct */ |
1027 | ret = nfs_write_rpcsetup(req, data, &nfs_write_full_ops, desc->pg_count, 0, lseg, desc->pg_ioflags); | 1037 | nfs_write_rpcsetup(req, data, desc->pg_count, 0, desc->pg_ioflags); |
1038 | ret = nfs_do_write(data, &nfs_write_full_ops, lseg, desc->pg_ioflags); | ||
1028 | out: | 1039 | out: |
1029 | put_lseg(lseg); /* Cleans any gotten in ->pg_test */ | 1040 | put_lseg(lseg); /* Cleans any gotten in ->pg_test */ |
1030 | desc->pg_lseg = NULL; | 1041 | desc->pg_lseg = NULL; |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 956d3576df7f..5b115956abac 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -1126,6 +1126,7 @@ struct nfs_read_data { | |||
1126 | struct rpc_cred *cred; | 1126 | struct rpc_cred *cred; |
1127 | struct nfs_fattr fattr; /* fattr storage */ | 1127 | struct nfs_fattr fattr; /* fattr storage */ |
1128 | struct list_head pages; /* Coalesced read requests */ | 1128 | struct list_head pages; /* Coalesced read requests */ |
1129 | struct list_head list; /* lists of struct nfs_read_data */ | ||
1129 | struct nfs_page *req; /* multi ops per nfs_page */ | 1130 | struct nfs_page *req; /* multi ops per nfs_page */ |
1130 | struct page **pagevec; | 1131 | struct page **pagevec; |
1131 | unsigned int npages; /* Max length of pagevec */ | 1132 | unsigned int npages; /* Max length of pagevec */ |
@@ -1149,6 +1150,7 @@ struct nfs_write_data { | |||
1149 | struct nfs_fattr fattr; | 1150 | struct nfs_fattr fattr; |
1150 | struct nfs_writeverf verf; | 1151 | struct nfs_writeverf verf; |
1151 | struct list_head pages; /* Coalesced requests we wish to flush */ | 1152 | struct list_head pages; /* Coalesced requests we wish to flush */ |
1153 | struct list_head list; /* lists of struct nfs_write_data */ | ||
1152 | struct nfs_page *req; /* multi ops per nfs_page */ | 1154 | struct nfs_page *req; /* multi ops per nfs_page */ |
1153 | struct page **pagevec; | 1155 | struct page **pagevec; |
1154 | unsigned int npages; /* Max length of pagevec */ | 1156 | unsigned int npages; /* Max length of pagevec */ |