aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2012-09-19 09:22:30 -0400
committerSteve French <smfrench@gmail.com>2012-09-24 22:46:32 -0400
commitc5fab6f4f081afcfcd7c1d444d9b900d6ef3e50b (patch)
treebfec76b22571f283e85491ad6a20f1aaba757122 /fs/cifs
parentf4e49cd2dce2ccac6feae64fbb4e90f7d8baf370 (diff)
cifs: turn the pages list in cifs_readdata into an array
We'll need an array to put into a smb_rqst, so convert this into an array instead of (ab)using the lru list_head. Signed-off-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsglob.h3
-rw-r--r--fs/cifs/file.c87
2 files changed, 52 insertions, 38 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 737289b50ca5..b70863ebedf2 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -977,12 +977,13 @@ struct cifs_readdata {
977 unsigned int bytes; 977 unsigned int bytes;
978 pid_t pid; 978 pid_t pid;
979 int result; 979 int result;
980 struct list_head pages;
981 struct work_struct work; 980 struct work_struct work;
982 int (*marshal_iov) (struct cifs_readdata *rdata, 981 int (*marshal_iov) (struct cifs_readdata *rdata,
983 unsigned int remaining); 982 unsigned int remaining);
984 unsigned int nr_iov; 983 unsigned int nr_iov;
985 struct kvec *iov; 984 struct kvec *iov;
985 unsigned int nr_pages;
986 struct page *pages[];
986}; 987};
987 988
988struct cifs_writedata; 989struct cifs_writedata;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 61b7c834069f..6eaf48270c97 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2419,13 +2419,13 @@ cifs_readdata_alloc(unsigned int nr_pages, work_func_t complete)
2419 if (!iov) 2419 if (!iov)
2420 return (struct cifs_readdata *)iov; 2420 return (struct cifs_readdata *)iov;
2421 2421
2422 rdata = kzalloc(sizeof(*rdata), GFP_KERNEL); 2422 rdata = kzalloc(sizeof(*rdata) + (sizeof(struct page *) * nr_pages),
2423 GFP_KERNEL);
2423 if (rdata != NULL) { 2424 if (rdata != NULL) {
2424 kref_init(&rdata->refcount); 2425 kref_init(&rdata->refcount);
2425 INIT_LIST_HEAD(&rdata->list); 2426 INIT_LIST_HEAD(&rdata->list);
2426 init_completion(&rdata->done); 2427 init_completion(&rdata->done);
2427 INIT_WORK(&rdata->work, complete); 2428 INIT_WORK(&rdata->work, complete);
2428 INIT_LIST_HEAD(&rdata->pages);
2429 rdata->iov = iov; 2429 rdata->iov = iov;
2430 } else { 2430 } else {
2431 kfree(iov); 2431 kfree(iov);
@@ -2448,25 +2448,25 @@ cifs_readdata_release(struct kref *refcount)
2448} 2448}
2449 2449
2450static int 2450static int
2451cifs_read_allocate_pages(struct list_head *list, unsigned int npages) 2451cifs_read_allocate_pages(struct cifs_readdata *rdata, unsigned int nr_pages)
2452{ 2452{
2453 int rc = 0; 2453 int rc = 0;
2454 struct page *page, *tpage; 2454 struct page *page;
2455 unsigned int i; 2455 unsigned int i;
2456 2456
2457 for (i = 0; i < npages; i++) { 2457 for (i = 0; i < nr_pages; i++) {
2458 page = alloc_page(GFP_KERNEL|__GFP_HIGHMEM); 2458 page = alloc_page(GFP_KERNEL|__GFP_HIGHMEM);
2459 if (!page) { 2459 if (!page) {
2460 rc = -ENOMEM; 2460 rc = -ENOMEM;
2461 break; 2461 break;
2462 } 2462 }
2463 list_add(&page->lru, list); 2463 rdata->pages[i] = page;
2464 } 2464 }
2465 2465
2466 if (rc) { 2466 if (rc) {
2467 list_for_each_entry_safe(page, tpage, list, lru) { 2467 for (i = 0; i < nr_pages; i++) {
2468 list_del(&page->lru); 2468 put_page(rdata->pages[i]);
2469 put_page(page); 2469 rdata->pages[i] = NULL;
2470 } 2470 }
2471 } 2471 }
2472 return rc; 2472 return rc;
@@ -2475,13 +2475,13 @@ cifs_read_allocate_pages(struct list_head *list, unsigned int npages)
2475static void 2475static void
2476cifs_uncached_readdata_release(struct kref *refcount) 2476cifs_uncached_readdata_release(struct kref *refcount)
2477{ 2477{
2478 struct page *page, *tpage;
2479 struct cifs_readdata *rdata = container_of(refcount, 2478 struct cifs_readdata *rdata = container_of(refcount,
2480 struct cifs_readdata, refcount); 2479 struct cifs_readdata, refcount);
2480 unsigned int i;
2481 2481
2482 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) { 2482 for (i = 0; i < rdata->nr_pages; i++) {
2483 list_del(&page->lru); 2483 put_page(rdata->pages[i]);
2484 put_page(page); 2484 rdata->pages[i] = NULL;
2485 } 2485 }
2486 cifs_readdata_release(refcount); 2486 cifs_readdata_release(refcount);
2487} 2487}
@@ -2525,17 +2525,18 @@ cifs_readdata_to_iov(struct cifs_readdata *rdata, const struct iovec *iov,
2525 int rc = 0; 2525 int rc = 0;
2526 struct iov_iter ii; 2526 struct iov_iter ii;
2527 size_t pos = rdata->offset - offset; 2527 size_t pos = rdata->offset - offset;
2528 struct page *page, *tpage;
2529 ssize_t remaining = rdata->bytes; 2528 ssize_t remaining = rdata->bytes;
2530 unsigned char *pdata; 2529 unsigned char *pdata;
2530 unsigned int i;
2531 2531
2532 /* set up iov_iter and advance to the correct offset */ 2532 /* set up iov_iter and advance to the correct offset */
2533 iov_iter_init(&ii, iov, nr_segs, iov_length(iov, nr_segs), 0); 2533 iov_iter_init(&ii, iov, nr_segs, iov_length(iov, nr_segs), 0);
2534 iov_iter_advance(&ii, pos); 2534 iov_iter_advance(&ii, pos);
2535 2535
2536 *copied = 0; 2536 *copied = 0;
2537 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) { 2537 for (i = 0; i < rdata->nr_pages; i++) {
2538 ssize_t copy; 2538 ssize_t copy;
2539 struct page *page = rdata->pages[i];
2539 2540
2540 /* copy a whole page or whatever's left */ 2541 /* copy a whole page or whatever's left */
2541 copy = min_t(ssize_t, remaining, PAGE_SIZE); 2542 copy = min_t(ssize_t, remaining, PAGE_SIZE);
@@ -2555,9 +2556,6 @@ cifs_readdata_to_iov(struct cifs_readdata *rdata, const struct iovec *iov,
2555 iov_iter_advance(&ii, copy); 2556 iov_iter_advance(&ii, copy);
2556 } 2557 }
2557 } 2558 }
2558
2559 list_del(&page->lru);
2560 put_page(page);
2561 } 2559 }
2562 2560
2563 return rc; 2561 return rc;
@@ -2568,13 +2566,12 @@ cifs_uncached_readv_complete(struct work_struct *work)
2568{ 2566{
2569 struct cifs_readdata *rdata = container_of(work, 2567 struct cifs_readdata *rdata = container_of(work,
2570 struct cifs_readdata, work); 2568 struct cifs_readdata, work);
2569 unsigned int i;
2571 2570
2572 /* if the result is non-zero then the pages weren't kmapped */ 2571 /* if the result is non-zero then the pages weren't kmapped */
2573 if (rdata->result == 0) { 2572 if (rdata->result == 0) {
2574 struct page *page; 2573 for (i = 0; i < rdata->nr_pages; i++)
2575 2574 kunmap(rdata->pages[i]);
2576 list_for_each_entry(page, &rdata->pages, lru)
2577 kunmap(page);
2578 } 2575 }
2579 2576
2580 complete(&rdata->done); 2577 complete(&rdata->done);
@@ -2586,10 +2583,13 @@ cifs_uncached_read_marshal_iov(struct cifs_readdata *rdata,
2586 unsigned int remaining) 2583 unsigned int remaining)
2587{ 2584{
2588 int len = 0; 2585 int len = 0;
2589 struct page *page, *tpage; 2586 unsigned int i;
2587 unsigned int nr_pages = rdata->nr_pages;
2590 2588
2591 rdata->nr_iov = 1; 2589 rdata->nr_iov = 1;
2592 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) { 2590 for (i = 0; i < nr_pages; i++) {
2591 struct page *page = rdata->pages[i];
2592
2593 if (remaining >= PAGE_SIZE) { 2593 if (remaining >= PAGE_SIZE) {
2594 /* enough data to fill the page */ 2594 /* enough data to fill the page */
2595 rdata->iov[rdata->nr_iov].iov_base = kmap(page); 2595 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
@@ -2616,7 +2616,8 @@ cifs_uncached_read_marshal_iov(struct cifs_readdata *rdata,
2616 remaining = 0; 2616 remaining = 0;
2617 } else { 2617 } else {
2618 /* no need to hold page hostage */ 2618 /* no need to hold page hostage */
2619 list_del(&page->lru); 2619 rdata->pages[i] = NULL;
2620 rdata->nr_pages--;
2620 put_page(page); 2621 put_page(page);
2621 } 2622 }
2622 } 2623 }
@@ -2675,11 +2676,12 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
2675 goto error; 2676 goto error;
2676 } 2677 }
2677 2678
2678 rc = cifs_read_allocate_pages(&rdata->pages, npages); 2679 rc = cifs_read_allocate_pages(rdata, npages);
2679 if (rc) 2680 if (rc)
2680 goto error; 2681 goto error;
2681 2682
2682 rdata->cfile = cifsFileInfo_get(open_file); 2683 rdata->cfile = cifsFileInfo_get(open_file);
2684 rdata->nr_pages = npages;
2683 rdata->offset = offset; 2685 rdata->offset = offset;
2684 rdata->bytes = cur_len; 2686 rdata->bytes = cur_len;
2685 rdata->pid = pid; 2687 rdata->pid = pid;
@@ -2923,12 +2925,13 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
2923static void 2925static void
2924cifs_readv_complete(struct work_struct *work) 2926cifs_readv_complete(struct work_struct *work)
2925{ 2927{
2928 unsigned int i;
2926 struct cifs_readdata *rdata = container_of(work, 2929 struct cifs_readdata *rdata = container_of(work,
2927 struct cifs_readdata, work); 2930 struct cifs_readdata, work);
2928 struct page *page, *tpage;
2929 2931
2930 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) { 2932 for (i = 0; i < rdata->nr_pages; i++) {
2931 list_del(&page->lru); 2933 struct page *page = rdata->pages[i];
2934
2932 lru_cache_add_file(page); 2935 lru_cache_add_file(page);
2933 2936
2934 if (rdata->result == 0) { 2937 if (rdata->result == 0) {
@@ -2943,6 +2946,7 @@ cifs_readv_complete(struct work_struct *work)
2943 cifs_readpage_to_fscache(rdata->mapping->host, page); 2946 cifs_readpage_to_fscache(rdata->mapping->host, page);
2944 2947
2945 page_cache_release(page); 2948 page_cache_release(page);
2949 rdata->pages[i] = NULL;
2946 } 2950 }
2947 kref_put(&rdata->refcount, cifs_readdata_release); 2951 kref_put(&rdata->refcount, cifs_readdata_release);
2948} 2952}
@@ -2951,9 +2955,10 @@ static int
2951cifs_readpages_marshal_iov(struct cifs_readdata *rdata, unsigned int remaining) 2955cifs_readpages_marshal_iov(struct cifs_readdata *rdata, unsigned int remaining)
2952{ 2956{
2953 int len = 0; 2957 int len = 0;
2954 struct page *page, *tpage; 2958 unsigned int i;
2955 u64 eof; 2959 u64 eof;
2956 pgoff_t eof_index; 2960 pgoff_t eof_index;
2961 unsigned int nr_pages = rdata->nr_pages;
2957 2962
2958 /* determine the eof that the server (probably) has */ 2963 /* determine the eof that the server (probably) has */
2959 eof = CIFS_I(rdata->mapping->host)->server_eof; 2964 eof = CIFS_I(rdata->mapping->host)->server_eof;
@@ -2961,7 +2966,9 @@ cifs_readpages_marshal_iov(struct cifs_readdata *rdata, unsigned int remaining)
2961 cFYI(1, "eof=%llu eof_index=%lu", eof, eof_index); 2966 cFYI(1, "eof=%llu eof_index=%lu", eof, eof_index);
2962 2967
2963 rdata->nr_iov = 1; 2968 rdata->nr_iov = 1;
2964 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) { 2969 for (i = 0; i < nr_pages; i++) {
2970 struct page *page = rdata->pages[i];
2971
2965 if (remaining >= PAGE_CACHE_SIZE) { 2972 if (remaining >= PAGE_CACHE_SIZE) {
2966 /* enough data to fill the page */ 2973 /* enough data to fill the page */
2967 rdata->iov[rdata->nr_iov].iov_base = kmap(page); 2974 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
@@ -2996,18 +3003,20 @@ cifs_readpages_marshal_iov(struct cifs_readdata *rdata, unsigned int remaining)
2996 * fill them until the writes are flushed. 3003 * fill them until the writes are flushed.
2997 */ 3004 */
2998 zero_user(page, 0, PAGE_CACHE_SIZE); 3005 zero_user(page, 0, PAGE_CACHE_SIZE);
2999 list_del(&page->lru);
3000 lru_cache_add_file(page); 3006 lru_cache_add_file(page);
3001 flush_dcache_page(page); 3007 flush_dcache_page(page);
3002 SetPageUptodate(page); 3008 SetPageUptodate(page);
3003 unlock_page(page); 3009 unlock_page(page);
3004 page_cache_release(page); 3010 page_cache_release(page);
3011 rdata->pages[i] = NULL;
3012 rdata->nr_pages--;
3005 } else { 3013 } else {
3006 /* no need to hold page hostage */ 3014 /* no need to hold page hostage */
3007 list_del(&page->lru);
3008 lru_cache_add_file(page); 3015 lru_cache_add_file(page);
3009 unlock_page(page); 3016 unlock_page(page);
3010 page_cache_release(page); 3017 page_cache_release(page);
3018 rdata->pages[i] = NULL;
3019 rdata->nr_pages--;
3011 } 3020 }
3012 } 3021 }
3013 3022
@@ -3065,6 +3074,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
3065 * the rdata->pages, then we want them in increasing order. 3074 * the rdata->pages, then we want them in increasing order.
3066 */ 3075 */
3067 while (!list_empty(page_list)) { 3076 while (!list_empty(page_list)) {
3077 unsigned int i;
3068 unsigned int bytes = PAGE_CACHE_SIZE; 3078 unsigned int bytes = PAGE_CACHE_SIZE;
3069 unsigned int expected_index; 3079 unsigned int expected_index;
3070 unsigned int nr_pages = 1; 3080 unsigned int nr_pages = 1;
@@ -3135,13 +3145,16 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
3135 rdata->bytes = bytes; 3145 rdata->bytes = bytes;
3136 rdata->pid = pid; 3146 rdata->pid = pid;
3137 rdata->marshal_iov = cifs_readpages_marshal_iov; 3147 rdata->marshal_iov = cifs_readpages_marshal_iov;
3138 list_splice_init(&tmplist, &rdata->pages); 3148
3149 list_for_each_entry_safe(page, tpage, &tmplist, lru) {
3150 list_del(&page->lru);
3151 rdata->pages[rdata->nr_pages++] = page;
3152 }
3139 3153
3140 rc = cifs_retry_async_readv(rdata); 3154 rc = cifs_retry_async_readv(rdata);
3141 if (rc != 0) { 3155 if (rc != 0) {
3142 list_for_each_entry_safe(page, tpage, &rdata->pages, 3156 for (i = 0; i < rdata->nr_pages; i++) {
3143 lru) { 3157 page = rdata->pages[i];
3144 list_del(&page->lru);
3145 lru_cache_add_file(page); 3158 lru_cache_add_file(page);
3146 unlock_page(page); 3159 unlock_page(page);
3147 page_cache_release(page); 3160 page_cache_release(page);