aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/read.c8
-rw-r--r--fs/nfs/write.c20
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
68static void nfs_readdata_free(struct nfs_read_data *p) 68static 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
76static 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
75void nfs_readdata_release(void *data) 81void 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
105void nfs_commit_free(struct nfs_write_data *p) 105void 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
113void nfs_commit_free(struct nfs_write_data *wdata)
114{
115 call_rcu_bh(&wdata->task.u.tk_rcu, nfs_commit_rcu_free);
116}
117
112struct nfs_write_data *nfs_writedata_alloc(size_t len) 118struct 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
134static void nfs_writedata_free(struct nfs_write_data *p) 140static 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
148static 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
141void nfs_writedata_release(void *wdata) 153void 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,
258io_error: 270io_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);