diff options
-rw-r--r-- | fs/gfs2/inode.c | 54 | ||||
-rw-r--r-- | fs/gfs2/inode.h | 3 | ||||
-rw-r--r-- | fs/gfs2/log.c | 2 | ||||
-rw-r--r-- | fs/gfs2/log.h | 29 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 20 |
5 files changed, 54 insertions, 54 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 51d8061fa07a..b5612cbb62a5 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -242,34 +242,38 @@ fail: | |||
242 | } | 242 | } |
243 | 243 | ||
244 | /** | 244 | /** |
245 | * gfs2_unlinked_inode_lookup - Lookup an unlinked inode for reclamation | 245 | * gfs2_process_unlinked_inode - Lookup an unlinked inode for reclamation |
246 | * and try to reclaim it by doing iput. | ||
247 | * | ||
248 | * This function assumes no rgrp locks are currently held. | ||
249 | * | ||
246 | * @sb: The super block | 250 | * @sb: The super block |
247 | * no_addr: The inode number | 251 | * no_addr: The inode number |
248 | * @@inode: A pointer to the inode found, if any | ||
249 | * | 252 | * |
250 | * Returns: 0 and *inode if no errors occurred. If an error occurs, | ||
251 | * the resulting *inode may or may not be NULL. | ||
252 | */ | 253 | */ |
253 | 254 | ||
254 | int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr, | 255 | void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr) |
255 | struct inode **inode) | ||
256 | { | 256 | { |
257 | struct gfs2_sbd *sdp; | 257 | struct gfs2_sbd *sdp; |
258 | struct gfs2_inode *ip; | 258 | struct gfs2_inode *ip; |
259 | struct gfs2_glock *io_gl; | 259 | struct gfs2_glock *io_gl; |
260 | int error; | 260 | int error; |
261 | struct gfs2_holder gh; | 261 | struct gfs2_holder gh; |
262 | struct inode *inode; | ||
262 | 263 | ||
263 | *inode = gfs2_iget_skip(sb, no_addr); | 264 | inode = gfs2_iget_skip(sb, no_addr); |
264 | 265 | ||
265 | if (!(*inode)) | 266 | if (!inode) |
266 | return -ENOBUFS; | 267 | return; |
267 | 268 | ||
268 | if (!((*inode)->i_state & I_NEW)) | 269 | /* If it's not a new inode, someone's using it, so leave it alone. */ |
269 | return -ENOBUFS; | 270 | if (!(inode->i_state & I_NEW)) { |
271 | iput(inode); | ||
272 | return; | ||
273 | } | ||
270 | 274 | ||
271 | ip = GFS2_I(*inode); | 275 | ip = GFS2_I(inode); |
272 | sdp = GFS2_SB(*inode); | 276 | sdp = GFS2_SB(inode); |
273 | ip->i_no_formal_ino = -1; | 277 | ip->i_no_formal_ino = -1; |
274 | 278 | ||
275 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); | 279 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); |
@@ -284,15 +288,13 @@ int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr, | |||
284 | set_bit(GIF_INVALID, &ip->i_flags); | 288 | set_bit(GIF_INVALID, &ip->i_flags); |
285 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT, | 289 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT, |
286 | &ip->i_iopen_gh); | 290 | &ip->i_iopen_gh); |
287 | if (unlikely(error)) { | 291 | if (unlikely(error)) |
288 | if (error == GLR_TRYFAILED) | ||
289 | error = 0; | ||
290 | goto fail_iopen; | 292 | goto fail_iopen; |
291 | } | 293 | |
292 | ip->i_iopen_gh.gh_gl->gl_object = ip; | 294 | ip->i_iopen_gh.gh_gl->gl_object = ip; |
293 | gfs2_glock_put(io_gl); | 295 | gfs2_glock_put(io_gl); |
294 | 296 | ||
295 | (*inode)->i_mode = DT2IF(DT_UNKNOWN); | 297 | inode->i_mode = DT2IF(DT_UNKNOWN); |
296 | 298 | ||
297 | /* | 299 | /* |
298 | * We must read the inode in order to work out its type in | 300 | * We must read the inode in order to work out its type in |
@@ -303,16 +305,17 @@ int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr, | |||
303 | */ | 305 | */ |
304 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY, | 306 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY, |
305 | &gh); | 307 | &gh); |
306 | if (unlikely(error)) { | 308 | if (unlikely(error)) |
307 | if (error == GLR_TRYFAILED) | ||
308 | error = 0; | ||
309 | goto fail_glock; | 309 | goto fail_glock; |
310 | } | 310 | |
311 | /* Inode is now uptodate */ | 311 | /* Inode is now uptodate */ |
312 | gfs2_glock_dq_uninit(&gh); | 312 | gfs2_glock_dq_uninit(&gh); |
313 | gfs2_set_iop(*inode); | 313 | gfs2_set_iop(inode); |
314 | |||
315 | /* The iput will cause it to be deleted. */ | ||
316 | iput(inode); | ||
317 | return; | ||
314 | 318 | ||
315 | return 0; | ||
316 | fail_glock: | 319 | fail_glock: |
317 | gfs2_glock_dq(&ip->i_iopen_gh); | 320 | gfs2_glock_dq(&ip->i_iopen_gh); |
318 | fail_iopen: | 321 | fail_iopen: |
@@ -321,7 +324,8 @@ fail_put: | |||
321 | ip->i_gl->gl_object = NULL; | 324 | ip->i_gl->gl_object = NULL; |
322 | gfs2_glock_put(ip->i_gl); | 325 | gfs2_glock_put(ip->i_gl); |
323 | fail: | 326 | fail: |
324 | return error; | 327 | iget_failed(inode); |
328 | return; | ||
325 | } | 329 | } |
326 | 330 | ||
327 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | 331 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) |
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index e161461d4c57..300ada3f21de 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h | |||
@@ -84,8 +84,7 @@ static inline void gfs2_inum_out(const struct gfs2_inode *ip, | |||
84 | extern void gfs2_set_iop(struct inode *inode); | 84 | extern void gfs2_set_iop(struct inode *inode); |
85 | extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, | 85 | extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, |
86 | u64 no_addr, u64 no_formal_ino); | 86 | u64 no_addr, u64 no_formal_ino); |
87 | extern int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr, | 87 | extern void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr); |
88 | struct inode **inode); | ||
89 | extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); | 88 | extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); |
90 | 89 | ||
91 | extern int gfs2_inode_refresh(struct gfs2_inode *ip); | 90 | extern int gfs2_inode_refresh(struct gfs2_inode *ip); |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index b593f0e28f25..6a857e24f947 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -696,7 +696,7 @@ static void gfs2_ordered_wait(struct gfs2_sbd *sdp) | |||
696 | * | 696 | * |
697 | */ | 697 | */ |
698 | 698 | ||
699 | void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | 699 | void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) |
700 | { | 700 | { |
701 | struct gfs2_ail *ai; | 701 | struct gfs2_ail *ai; |
702 | 702 | ||
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h index eb570b4ad443..0d007f920234 100644 --- a/fs/gfs2/log.h +++ b/fs/gfs2/log.h | |||
@@ -47,28 +47,21 @@ static inline void gfs2_log_pointers_init(struct gfs2_sbd *sdp, | |||
47 | sdp->sd_log_head = sdp->sd_log_tail = value; | 47 | sdp->sd_log_head = sdp->sd_log_tail = value; |
48 | } | 48 | } |
49 | 49 | ||
50 | unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, | 50 | extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, |
51 | unsigned int ssize); | 51 | unsigned int ssize); |
52 | 52 | ||
53 | int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); | 53 | extern int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); |
54 | void gfs2_log_incr_head(struct gfs2_sbd *sdp); | 54 | extern void gfs2_log_incr_head(struct gfs2_sbd *sdp); |
55 | 55 | ||
56 | struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp); | 56 | extern struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp); |
57 | struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp, | 57 | extern struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp, |
58 | struct buffer_head *real); | 58 | struct buffer_head *real); |
59 | void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); | 59 | extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); |
60 | extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); | ||
61 | extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd); | ||
60 | 62 | ||
61 | static inline void gfs2_log_flush(struct gfs2_sbd *sbd, struct gfs2_glock *gl) | 63 | extern void gfs2_log_shutdown(struct gfs2_sbd *sdp); |
62 | { | 64 | extern void gfs2_meta_syncfs(struct gfs2_sbd *sdp); |
63 | if (!gl || test_bit(GLF_LFLUSH, &gl->gl_flags)) | 65 | extern int gfs2_logd(void *data); |
64 | __gfs2_log_flush(sbd, gl); | ||
65 | } | ||
66 | |||
67 | void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); | ||
68 | void gfs2_remove_from_ail(struct gfs2_bufdata *bd); | ||
69 | |||
70 | void gfs2_log_shutdown(struct gfs2_sbd *sdp); | ||
71 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp); | ||
72 | int gfs2_logd(void *data); | ||
73 | 66 | ||
74 | #endif /* __LOG_DOT_H__ */ | 67 | #endif /* __LOG_DOT_H__ */ |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 8bce73ed4d8e..6daf4c65a3c8 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -1191,7 +1191,6 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line) | |||
1191 | { | 1191 | { |
1192 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1192 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1193 | struct gfs2_alloc *al = ip->i_alloc; | 1193 | struct gfs2_alloc *al = ip->i_alloc; |
1194 | struct inode *inode; | ||
1195 | int error = 0; | 1194 | int error = 0; |
1196 | u64 last_unlinked = NO_BLOCK, unlinked; | 1195 | u64 last_unlinked = NO_BLOCK, unlinked; |
1197 | 1196 | ||
@@ -1209,22 +1208,27 @@ try_again: | |||
1209 | if (error) | 1208 | if (error) |
1210 | return error; | 1209 | return error; |
1211 | 1210 | ||
1211 | /* Find an rgrp suitable for allocation. If it encounters any unlinked | ||
1212 | dinodes along the way, error will equal -EAGAIN and unlinked will | ||
1213 | contains it block address. We then need to look up that inode and | ||
1214 | try to free it, and try the allocation again. */ | ||
1212 | error = get_local_rgrp(ip, &unlinked, &last_unlinked); | 1215 | error = get_local_rgrp(ip, &unlinked, &last_unlinked); |
1213 | if (error) { | 1216 | if (error) { |
1214 | if (ip != GFS2_I(sdp->sd_rindex)) | 1217 | if (ip != GFS2_I(sdp->sd_rindex)) |
1215 | gfs2_glock_dq_uninit(&al->al_ri_gh); | 1218 | gfs2_glock_dq_uninit(&al->al_ri_gh); |
1216 | if (error != -EAGAIN) | 1219 | if (error != -EAGAIN) |
1217 | return error; | 1220 | return error; |
1218 | error = gfs2_unlinked_inode_lookup(ip->i_inode.i_sb, | 1221 | |
1219 | unlinked, &inode); | 1222 | gfs2_process_unlinked_inode(ip->i_inode.i_sb, unlinked); |
1220 | if (inode) | 1223 | /* regardless of whether or not gfs2_process_unlinked_inode |
1221 | iput(inode); | 1224 | was successful, we don't want to repeat it again. */ |
1225 | last_unlinked = unlinked; | ||
1222 | gfs2_log_flush(sdp, NULL); | 1226 | gfs2_log_flush(sdp, NULL); |
1223 | if (error == GLR_TRYFAILED) | 1227 | error = 0; |
1224 | error = 0; | 1228 | |
1225 | goto try_again; | 1229 | goto try_again; |
1226 | } | 1230 | } |
1227 | 1231 | /* no error, so we have the rgrp set in the inode's allocation. */ | |
1228 | al->al_file = file; | 1232 | al->al_file = file; |
1229 | al->al_line = line; | 1233 | al->al_line = line; |
1230 | 1234 | ||