diff options
author | Weston Andros Adamson <dros@primarydata.com> | 2014-05-15 11:56:52 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-05-29 11:11:48 -0400 |
commit | f0cb9ab8d5589fc553761068200e5a8342f61de0 (patch) | |
tree | ae7f0bc99fa85e90333c2400d050620167dd1b8f /fs/nfs/pagelist.c | |
parent | 0f9c429eca07aca2764ccd751e2b48ba5397b936 (diff) |
nfs: use > 1 request to handle bsize < PAGE_SIZE
Use the newly added support for multiple requests per page for
rsize/wsize < PAGE_SIZE, instead of having multiple read / write
data structures per pageio header.
This allows us to get rid of nfs_pgio_multi.
Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/pagelist.c')
-rw-r--r-- | fs/nfs/pagelist.c | 80 |
1 files changed, 11 insertions, 69 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 838f7c9664f5..ec4311df05d9 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -443,21 +443,13 @@ nfs_wait_on_request(struct nfs_page *req) | |||
443 | size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, | 443 | size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, |
444 | struct nfs_page *prev, struct nfs_page *req) | 444 | struct nfs_page *prev, struct nfs_page *req) |
445 | { | 445 | { |
446 | if (!prev) | 446 | if (desc->pg_count > desc->pg_bsize) { |
447 | return req->wb_bytes; | 447 | /* should never happen */ |
448 | /* | 448 | WARN_ON_ONCE(1); |
449 | * FIXME: ideally we should be able to coalesce all requests | ||
450 | * that are not block boundary aligned, but currently this | ||
451 | * is problematic for the case of bsize < PAGE_CACHE_SIZE, | ||
452 | * since nfs_flush_multi and nfs_pagein_multi assume you | ||
453 | * can have only one struct nfs_page. | ||
454 | */ | ||
455 | if (desc->pg_bsize < PAGE_SIZE) | ||
456 | return 0; | 449 | return 0; |
450 | } | ||
457 | 451 | ||
458 | if (desc->pg_count + req->wb_bytes <= desc->pg_bsize) | 452 | return min(desc->pg_bsize - desc->pg_count, (size_t)req->wb_bytes); |
459 | return req->wb_bytes; | ||
460 | return 0; | ||
461 | } | 453 | } |
462 | EXPORT_SYMBOL_GPL(nfs_generic_pg_test); | 454 | EXPORT_SYMBOL_GPL(nfs_generic_pg_test); |
463 | 455 | ||
@@ -766,50 +758,6 @@ static void nfs_pgio_result(struct rpc_task *task, void *calldata) | |||
766 | } | 758 | } |
767 | 759 | ||
768 | /* | 760 | /* |
769 | * Generate multiple small requests to read or write a single | ||
770 | * contiguous dirty on one page. | ||
771 | */ | ||
772 | static int nfs_pgio_multi(struct nfs_pageio_descriptor *desc, | ||
773 | struct nfs_pgio_header *hdr) | ||
774 | { | ||
775 | struct nfs_page *req = hdr->req; | ||
776 | struct page *page = req->wb_page; | ||
777 | struct nfs_pgio_data *data; | ||
778 | size_t wsize = desc->pg_bsize, nbytes; | ||
779 | unsigned int offset; | ||
780 | int requests = 0; | ||
781 | struct nfs_commit_info cinfo; | ||
782 | |||
783 | nfs_init_cinfo(&cinfo, desc->pg_inode, desc->pg_dreq); | ||
784 | |||
785 | if ((desc->pg_ioflags & FLUSH_COND_STABLE) && | ||
786 | (desc->pg_moreio || nfs_reqs_to_commit(&cinfo) || | ||
787 | desc->pg_count > wsize)) | ||
788 | desc->pg_ioflags &= ~FLUSH_COND_STABLE; | ||
789 | |||
790 | offset = 0; | ||
791 | nbytes = desc->pg_count; | ||
792 | do { | ||
793 | size_t len = min(nbytes, wsize); | ||
794 | |||
795 | data = nfs_pgio_data_alloc(hdr, 1); | ||
796 | if (!data) | ||
797 | return nfs_pgio_error(desc, hdr); | ||
798 | data->pages.pagevec[0] = page; | ||
799 | nfs_pgio_rpcsetup(data, len, offset, desc->pg_ioflags, &cinfo); | ||
800 | list_add(&data->list, &hdr->rpc_list); | ||
801 | requests++; | ||
802 | nbytes -= len; | ||
803 | offset += len; | ||
804 | } while (nbytes != 0); | ||
805 | |||
806 | nfs_list_remove_request(req); | ||
807 | nfs_list_add_request(req, &hdr->pages); | ||
808 | desc->pg_rpc_callops = &nfs_pgio_common_ops; | ||
809 | return 0; | ||
810 | } | ||
811 | |||
812 | /* | ||
813 | * Create an RPC task for the given read or write request and kick it. | 761 | * Create an RPC task for the given read or write request and kick it. |
814 | * The page must have been locked by the caller. | 762 | * The page must have been locked by the caller. |
815 | * | 763 | * |
@@ -817,8 +765,8 @@ static int nfs_pgio_multi(struct nfs_pageio_descriptor *desc, | |||
817 | * This is the case if nfs_updatepage detects a conflicting request | 765 | * This is the case if nfs_updatepage detects a conflicting request |
818 | * that has been written but not committed. | 766 | * that has been written but not committed. |
819 | */ | 767 | */ |
820 | static int nfs_pgio_one(struct nfs_pageio_descriptor *desc, | 768 | int nfs_generic_pgio(struct nfs_pageio_descriptor *desc, |
821 | struct nfs_pgio_header *hdr) | 769 | struct nfs_pgio_header *hdr) |
822 | { | 770 | { |
823 | struct nfs_page *req; | 771 | struct nfs_page *req; |
824 | struct page **pages; | 772 | struct page **pages; |
@@ -850,6 +798,7 @@ static int nfs_pgio_one(struct nfs_pageio_descriptor *desc, | |||
850 | desc->pg_rpc_callops = &nfs_pgio_common_ops; | 798 | desc->pg_rpc_callops = &nfs_pgio_common_ops; |
851 | return 0; | 799 | return 0; |
852 | } | 800 | } |
801 | EXPORT_SYMBOL_GPL(nfs_generic_pgio); | ||
853 | 802 | ||
854 | static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) | 803 | static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) |
855 | { | 804 | { |
@@ -875,15 +824,6 @@ static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) | |||
875 | return ret; | 824 | return ret; |
876 | } | 825 | } |
877 | 826 | ||
878 | int nfs_generic_pgio(struct nfs_pageio_descriptor *desc, | ||
879 | struct nfs_pgio_header *hdr) | ||
880 | { | ||
881 | if (desc->pg_bsize < PAGE_CACHE_SIZE) | ||
882 | return nfs_pgio_multi(desc, hdr); | ||
883 | return nfs_pgio_one(desc, hdr); | ||
884 | } | ||
885 | EXPORT_SYMBOL_GPL(nfs_generic_pgio); | ||
886 | |||
887 | static bool nfs_match_open_context(const struct nfs_open_context *ctx1, | 827 | static bool nfs_match_open_context(const struct nfs_open_context *ctx1, |
888 | const struct nfs_open_context *ctx2) | 828 | const struct nfs_open_context *ctx2) |
889 | { | 829 | { |
@@ -925,7 +865,9 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev, | |||
925 | return false; | 865 | return false; |
926 | } | 866 | } |
927 | size = pgio->pg_ops->pg_test(pgio, prev, req); | 867 | size = pgio->pg_ops->pg_test(pgio, prev, req); |
928 | WARN_ON_ONCE(size && size != req->wb_bytes); | 868 | WARN_ON_ONCE(size > req->wb_bytes); |
869 | if (size && size < req->wb_bytes) | ||
870 | req->wb_bytes = size; | ||
929 | return size > 0; | 871 | return size > 0; |
930 | } | 872 | } |
931 | 873 | ||