diff options
Diffstat (limited to 'fs/gfs2/glops.c')
-rw-r--r-- | fs/gfs2/glops.c | 93 |
1 files changed, 24 insertions, 69 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 60561ca070c2..b068d10bcb6e 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -107,70 +107,6 @@ static void gfs2_pte_inval(struct gfs2_glock *gl) | |||
107 | } | 107 | } |
108 | 108 | ||
109 | /** | 109 | /** |
110 | * gfs2_page_inval - Invalidate all pages associated with a glock | ||
111 | * @gl: the glock | ||
112 | * | ||
113 | */ | ||
114 | |||
115 | static void gfs2_page_inval(struct gfs2_glock *gl) | ||
116 | { | ||
117 | struct gfs2_inode *ip; | ||
118 | struct inode *inode; | ||
119 | |||
120 | ip = gl->gl_object; | ||
121 | inode = &ip->i_inode; | ||
122 | if (!ip || !S_ISREG(inode->i_mode)) | ||
123 | return; | ||
124 | |||
125 | truncate_inode_pages(inode->i_mapping, 0); | ||
126 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !inode->i_mapping->nrpages); | ||
127 | clear_bit(GIF_PAGED, &ip->i_flags); | ||
128 | } | ||
129 | |||
130 | /** | ||
131 | * gfs2_page_wait - Wait for writeback of data | ||
132 | * @gl: the glock | ||
133 | * | ||
134 | * Syncs data (not metadata) for a regular file. | ||
135 | * No-op for all other types. | ||
136 | */ | ||
137 | |||
138 | static void gfs2_page_wait(struct gfs2_glock *gl) | ||
139 | { | ||
140 | struct gfs2_inode *ip = gl->gl_object; | ||
141 | struct inode *inode = &ip->i_inode; | ||
142 | struct address_space *mapping = inode->i_mapping; | ||
143 | int error; | ||
144 | |||
145 | if (!S_ISREG(inode->i_mode)) | ||
146 | return; | ||
147 | |||
148 | error = filemap_fdatawait(mapping); | ||
149 | |||
150 | /* Put back any errors cleared by filemap_fdatawait() | ||
151 | so they can be caught by someone who can pass them | ||
152 | up to user space. */ | ||
153 | |||
154 | if (error == -ENOSPC) | ||
155 | set_bit(AS_ENOSPC, &mapping->flags); | ||
156 | else if (error) | ||
157 | set_bit(AS_EIO, &mapping->flags); | ||
158 | |||
159 | } | ||
160 | |||
161 | static void gfs2_page_writeback(struct gfs2_glock *gl) | ||
162 | { | ||
163 | struct gfs2_inode *ip = gl->gl_object; | ||
164 | struct inode *inode = &ip->i_inode; | ||
165 | struct address_space *mapping = inode->i_mapping; | ||
166 | |||
167 | if (!S_ISREG(inode->i_mode)) | ||
168 | return; | ||
169 | |||
170 | filemap_fdatawrite(mapping); | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * meta_go_sync - sync out the metadata for this glock | 110 | * meta_go_sync - sync out the metadata for this glock |
175 | * @gl: the glock | 111 | * @gl: the glock |
176 | * | 112 | * |
@@ -264,11 +200,24 @@ static void inode_go_drop_th(struct gfs2_glock *gl) | |||
264 | 200 | ||
265 | static void inode_go_sync(struct gfs2_glock *gl) | 201 | static void inode_go_sync(struct gfs2_glock *gl) |
266 | { | 202 | { |
203 | struct gfs2_inode *ip = gl->gl_object; | ||
204 | |||
205 | if (ip && !S_ISREG(ip->i_inode.i_mode)) | ||
206 | ip = NULL; | ||
207 | |||
267 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) { | 208 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) { |
268 | gfs2_page_writeback(gl); | ||
269 | gfs2_log_flush(gl->gl_sbd, gl); | 209 | gfs2_log_flush(gl->gl_sbd, gl); |
210 | if (ip) | ||
211 | filemap_fdatawrite(ip->i_inode.i_mapping); | ||
270 | gfs2_meta_sync(gl); | 212 | gfs2_meta_sync(gl); |
271 | gfs2_page_wait(gl); | 213 | if (ip) { |
214 | struct address_space *mapping = ip->i_inode.i_mapping; | ||
215 | int error = filemap_fdatawait(mapping); | ||
216 | if (error == -ENOSPC) | ||
217 | set_bit(AS_ENOSPC, &mapping->flags); | ||
218 | else if (error) | ||
219 | set_bit(AS_EIO, &mapping->flags); | ||
220 | } | ||
272 | clear_bit(GLF_DIRTY, &gl->gl_flags); | 221 | clear_bit(GLF_DIRTY, &gl->gl_flags); |
273 | gfs2_ail_empty_gl(gl); | 222 | gfs2_ail_empty_gl(gl); |
274 | } | 223 | } |
@@ -283,14 +232,20 @@ static void inode_go_sync(struct gfs2_glock *gl) | |||
283 | 232 | ||
284 | static void inode_go_inval(struct gfs2_glock *gl, int flags) | 233 | static void inode_go_inval(struct gfs2_glock *gl, int flags) |
285 | { | 234 | { |
235 | struct gfs2_inode *ip = gl->gl_object; | ||
286 | int meta = (flags & DIO_METADATA); | 236 | int meta = (flags & DIO_METADATA); |
287 | 237 | ||
288 | if (meta) { | 238 | if (meta) { |
289 | struct gfs2_inode *ip = gl->gl_object; | ||
290 | gfs2_meta_inval(gl); | 239 | gfs2_meta_inval(gl); |
291 | set_bit(GIF_INVALID, &ip->i_flags); | 240 | if (ip) |
241 | set_bit(GIF_INVALID, &ip->i_flags); | ||
242 | } | ||
243 | |||
244 | if (ip && S_ISREG(ip->i_inode.i_mode)) { | ||
245 | truncate_inode_pages(ip->i_inode.i_mapping, 0); | ||
246 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !ip->i_inode.i_mapping->nrpages); | ||
247 | clear_bit(GIF_PAGED, &ip->i_flags); | ||
292 | } | 248 | } |
293 | gfs2_page_inval(gl); | ||
294 | } | 249 | } |
295 | 250 | ||
296 | /** | 251 | /** |