diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/read.c | 8 | ||||
-rw-r--r-- | fs/nfs/write.c | 20 |
2 files changed, 23 insertions, 5 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index c2e49c397a27..8b58bbf6e39e 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -65,13 +65,19 @@ struct nfs_read_data *nfs_readdata_alloc(size_t len) | |||
65 | return p; | 65 | return p; |
66 | } | 66 | } |
67 | 67 | ||
68 | static void nfs_readdata_free(struct nfs_read_data *p) | 68 | static void nfs_readdata_rcu_free(struct rcu_head *head) |
69 | { | 69 | { |
70 | struct nfs_read_data *p = container_of(head, struct nfs_read_data, task.u.tk_rcu); | ||
70 | if (p && (p->pagevec != &p->page_array[0])) | 71 | if (p && (p->pagevec != &p->page_array[0])) |
71 | kfree(p->pagevec); | 72 | kfree(p->pagevec); |
72 | mempool_free(p, nfs_rdata_mempool); | 73 | mempool_free(p, nfs_rdata_mempool); |
73 | } | 74 | } |
74 | 75 | ||
76 | static void nfs_readdata_free(struct nfs_read_data *rdata) | ||
77 | { | ||
78 | call_rcu_bh(&rdata->task.u.tk_rcu, nfs_readdata_rcu_free); | ||
79 | } | ||
80 | |||
75 | void nfs_readdata_release(void *data) | 81 | void nfs_readdata_release(void *data) |
76 | { | 82 | { |
77 | nfs_readdata_free(data); | 83 | nfs_readdata_free(data); |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 883dd4a1c157..29d88209199d 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -102,13 +102,19 @@ struct nfs_write_data *nfs_commit_alloc(void) | |||
102 | return p; | 102 | return p; |
103 | } | 103 | } |
104 | 104 | ||
105 | void nfs_commit_free(struct nfs_write_data *p) | 105 | void nfs_commit_rcu_free(struct rcu_head *head) |
106 | { | 106 | { |
107 | struct nfs_write_data *p = container_of(head, struct nfs_write_data, task.u.tk_rcu); | ||
107 | if (p && (p->pagevec != &p->page_array[0])) | 108 | if (p && (p->pagevec != &p->page_array[0])) |
108 | kfree(p->pagevec); | 109 | kfree(p->pagevec); |
109 | mempool_free(p, nfs_commit_mempool); | 110 | mempool_free(p, nfs_commit_mempool); |
110 | } | 111 | } |
111 | 112 | ||
113 | void nfs_commit_free(struct nfs_write_data *wdata) | ||
114 | { | ||
115 | call_rcu_bh(&wdata->task.u.tk_rcu, nfs_commit_rcu_free); | ||
116 | } | ||
117 | |||
112 | struct nfs_write_data *nfs_writedata_alloc(size_t len) | 118 | struct nfs_write_data *nfs_writedata_alloc(size_t len) |
113 | { | 119 | { |
114 | unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | 120 | unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; |
@@ -131,13 +137,19 @@ struct nfs_write_data *nfs_writedata_alloc(size_t len) | |||
131 | return p; | 137 | return p; |
132 | } | 138 | } |
133 | 139 | ||
134 | static void nfs_writedata_free(struct nfs_write_data *p) | 140 | static void nfs_writedata_rcu_free(struct rcu_head *head) |
135 | { | 141 | { |
142 | struct nfs_write_data *p = container_of(head, struct nfs_write_data, task.u.tk_rcu); | ||
136 | if (p && (p->pagevec != &p->page_array[0])) | 143 | if (p && (p->pagevec != &p->page_array[0])) |
137 | kfree(p->pagevec); | 144 | kfree(p->pagevec); |
138 | mempool_free(p, nfs_wdata_mempool); | 145 | mempool_free(p, nfs_wdata_mempool); |
139 | } | 146 | } |
140 | 147 | ||
148 | static void nfs_writedata_free(struct nfs_write_data *wdata) | ||
149 | { | ||
150 | call_rcu_bh(&wdata->task.u.tk_rcu, nfs_writedata_rcu_free); | ||
151 | } | ||
152 | |||
141 | void nfs_writedata_release(void *wdata) | 153 | void nfs_writedata_release(void *wdata) |
142 | { | 154 | { |
143 | nfs_writedata_free(wdata); | 155 | nfs_writedata_free(wdata); |
@@ -258,7 +270,7 @@ static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode, | |||
258 | io_error: | 270 | io_error: |
259 | nfs_end_data_update(inode); | 271 | nfs_end_data_update(inode); |
260 | end_page_writeback(page); | 272 | end_page_writeback(page); |
261 | nfs_writedata_free(wdata); | 273 | nfs_writedata_release(wdata); |
262 | return written ? written : result; | 274 | return written ? written : result; |
263 | } | 275 | } |
264 | 276 | ||
@@ -1043,7 +1055,7 @@ out_bad: | |||
1043 | while (!list_empty(&list)) { | 1055 | while (!list_empty(&list)) { |
1044 | data = list_entry(list.next, struct nfs_write_data, pages); | 1056 | data = list_entry(list.next, struct nfs_write_data, pages); |
1045 | list_del(&data->pages); | 1057 | list_del(&data->pages); |
1046 | nfs_writedata_free(data); | 1058 | nfs_writedata_release(data); |
1047 | } | 1059 | } |
1048 | nfs_mark_request_dirty(req); | 1060 | nfs_mark_request_dirty(req); |
1049 | nfs_clear_page_writeback(req); | 1061 | nfs_clear_page_writeback(req); |