diff options
author | Jeff Layton <jlayton@redhat.com> | 2012-05-16 07:13:17 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2012-05-16 21:13:30 -0400 |
commit | 6993f74a5bf836210e7f253d5ad3f76d73a95f51 (patch) | |
tree | 6b0cf7d6aed03e9d7d0b705cf7ba79792ab062a2 /fs/cifs/file.c | |
parent | 8d5ce4d23c79e0f9861b19fc534f5b2dc636f79c (diff) |
cifs: add refcounting to cifs_readdata structures
This isn't strictly necessary for the async readpages code, but the
uncached version will need to be able to collect the replies after
issuing the calls. Add a kref to cifs_readdata and use change the
code to take and put references appropriately.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 183381d9c4c1..ae285e0cf67b 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -2347,16 +2347,22 @@ cifs_readdata_alloc(unsigned int nr_vecs, work_func_t complete) | |||
2347 | rdata = kzalloc(sizeof(*rdata) + | 2347 | rdata = kzalloc(sizeof(*rdata) + |
2348 | sizeof(struct kvec) * nr_vecs, GFP_KERNEL); | 2348 | sizeof(struct kvec) * nr_vecs, GFP_KERNEL); |
2349 | if (rdata != NULL) { | 2349 | if (rdata != NULL) { |
2350 | kref_init(&rdata->refcount); | ||
2350 | INIT_WORK(&rdata->work, complete); | 2351 | INIT_WORK(&rdata->work, complete); |
2351 | INIT_LIST_HEAD(&rdata->pages); | 2352 | INIT_LIST_HEAD(&rdata->pages); |
2352 | } | 2353 | } |
2353 | return rdata; | 2354 | return rdata; |
2354 | } | 2355 | } |
2355 | 2356 | ||
2356 | static void | 2357 | void |
2357 | cifs_readdata_free(struct cifs_readdata *rdata) | 2358 | cifs_readdata_release(struct kref *refcount) |
2358 | { | 2359 | { |
2359 | cifsFileInfo_put(rdata->cfile); | 2360 | struct cifs_readdata *rdata = container_of(refcount, |
2361 | struct cifs_readdata, refcount); | ||
2362 | |||
2363 | if (rdata->cfile) | ||
2364 | cifsFileInfo_put(rdata->cfile); | ||
2365 | |||
2360 | kfree(rdata); | 2366 | kfree(rdata); |
2361 | } | 2367 | } |
2362 | 2368 | ||
@@ -2651,7 +2657,7 @@ cifs_readv_complete(struct work_struct *work) | |||
2651 | 2657 | ||
2652 | page_cache_release(page); | 2658 | page_cache_release(page); |
2653 | } | 2659 | } |
2654 | cifs_readdata_free(rdata); | 2660 | kref_put(&rdata->refcount, cifs_readdata_release); |
2655 | } | 2661 | } |
2656 | 2662 | ||
2657 | static int | 2663 | static int |
@@ -2837,9 +2843,8 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
2837 | } | 2843 | } |
2838 | 2844 | ||
2839 | spin_lock(&cifs_file_list_lock); | 2845 | spin_lock(&cifs_file_list_lock); |
2840 | cifsFileInfo_get(open_file); | ||
2841 | spin_unlock(&cifs_file_list_lock); | 2846 | spin_unlock(&cifs_file_list_lock); |
2842 | rdata->cfile = open_file; | 2847 | rdata->cfile = cifsFileInfo_get(open_file); |
2843 | rdata->mapping = mapping; | 2848 | rdata->mapping = mapping; |
2844 | rdata->offset = offset; | 2849 | rdata->offset = offset; |
2845 | rdata->bytes = bytes; | 2850 | rdata->bytes = bytes; |
@@ -2864,9 +2869,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
2864 | unlock_page(page); | 2869 | unlock_page(page); |
2865 | page_cache_release(page); | 2870 | page_cache_release(page); |
2866 | } | 2871 | } |
2867 | cifs_readdata_free(rdata); | 2872 | kref_put(&rdata->refcount, cifs_readdata_release); |
2868 | break; | 2873 | break; |
2869 | } | 2874 | } |
2875 | |||
2876 | kref_put(&rdata->refcount, cifs_readdata_release); | ||
2870 | } | 2877 | } |
2871 | 2878 | ||
2872 | return rc; | 2879 | return rc; |