diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/glock.c | 14 | ||||
-rw-r--r-- | fs/gfs2/ops_super.c | 131 | ||||
-rw-r--r-- | fs/gfs2/recovery.c | 22 | ||||
-rw-r--r-- | fs/gfs2/super.c | 164 | ||||
-rw-r--r-- | fs/gfs2/super.h | 4 |
5 files changed, 167 insertions, 168 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 07ffc8123d74..6e298b070117 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -1317,6 +1317,20 @@ static void blocking_cb(struct gfs2_sbd *sdp, struct lm_lockname *name, | |||
1317 | gfs2_glock_put(gl); | 1317 | gfs2_glock_put(gl); |
1318 | } | 1318 | } |
1319 | 1319 | ||
1320 | static void gfs2_jdesc_make_dirty(struct gfs2_sbd *sdp, unsigned int jid) | ||
1321 | { | ||
1322 | struct gfs2_jdesc *jd; | ||
1323 | |||
1324 | spin_lock(&sdp->sd_jindex_spin); | ||
1325 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | ||
1326 | if (jd->jd_jid != jid) | ||
1327 | continue; | ||
1328 | jd->jd_dirty = 1; | ||
1329 | break; | ||
1330 | } | ||
1331 | spin_unlock(&sdp->sd_jindex_spin); | ||
1332 | } | ||
1333 | |||
1320 | /** | 1334 | /** |
1321 | * gfs2_glock_cb - Callback used by locking module | 1335 | * gfs2_glock_cb - Callback used by locking module |
1322 | * @sdp: Pointer to the superblock | 1336 | * @sdp: Pointer to the superblock |
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index 29f8a5c0b45b..08837a728635 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c | |||
@@ -257,6 +257,137 @@ static void gfs2_unlockfs(struct super_block *sb) | |||
257 | } | 257 | } |
258 | 258 | ||
259 | /** | 259 | /** |
260 | * statfs_fill - fill in the sg for a given RG | ||
261 | * @rgd: the RG | ||
262 | * @sc: the sc structure | ||
263 | * | ||
264 | * Returns: 0 on success, -ESTALE if the LVB is invalid | ||
265 | */ | ||
266 | |||
267 | static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | ||
268 | struct gfs2_statfs_change_host *sc) | ||
269 | { | ||
270 | gfs2_rgrp_verify(rgd); | ||
271 | sc->sc_total += rgd->rd_data; | ||
272 | sc->sc_free += rgd->rd_free; | ||
273 | sc->sc_dinodes += rgd->rd_dinodes; | ||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | /** | ||
278 | * gfs2_statfs_slow - Stat a filesystem using asynchronous locking | ||
279 | * @sdp: the filesystem | ||
280 | * @sc: the sc info that will be returned | ||
281 | * | ||
282 | * Any error (other than a signal) will cause this routine to fall back | ||
283 | * to the synchronous version. | ||
284 | * | ||
285 | * FIXME: This really shouldn't busy wait like this. | ||
286 | * | ||
287 | * Returns: errno | ||
288 | */ | ||
289 | |||
290 | static int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | ||
291 | { | ||
292 | struct gfs2_holder ri_gh; | ||
293 | struct gfs2_rgrpd *rgd_next; | ||
294 | struct gfs2_holder *gha, *gh; | ||
295 | unsigned int slots = 64; | ||
296 | unsigned int x; | ||
297 | int done; | ||
298 | int error = 0, err; | ||
299 | |||
300 | memset(sc, 0, sizeof(struct gfs2_statfs_change_host)); | ||
301 | gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); | ||
302 | if (!gha) | ||
303 | return -ENOMEM; | ||
304 | |||
305 | error = gfs2_rindex_hold(sdp, &ri_gh); | ||
306 | if (error) | ||
307 | goto out; | ||
308 | |||
309 | rgd_next = gfs2_rgrpd_get_first(sdp); | ||
310 | |||
311 | for (;;) { | ||
312 | done = 1; | ||
313 | |||
314 | for (x = 0; x < slots; x++) { | ||
315 | gh = gha + x; | ||
316 | |||
317 | if (gh->gh_gl && gfs2_glock_poll(gh)) { | ||
318 | err = gfs2_glock_wait(gh); | ||
319 | if (err) { | ||
320 | gfs2_holder_uninit(gh); | ||
321 | error = err; | ||
322 | } else { | ||
323 | if (!error) | ||
324 | error = statfs_slow_fill( | ||
325 | gh->gh_gl->gl_object, sc); | ||
326 | gfs2_glock_dq_uninit(gh); | ||
327 | } | ||
328 | } | ||
329 | |||
330 | if (gh->gh_gl) | ||
331 | done = 0; | ||
332 | else if (rgd_next && !error) { | ||
333 | error = gfs2_glock_nq_init(rgd_next->rd_gl, | ||
334 | LM_ST_SHARED, | ||
335 | GL_ASYNC, | ||
336 | gh); | ||
337 | rgd_next = gfs2_rgrpd_get_next(rgd_next); | ||
338 | done = 0; | ||
339 | } | ||
340 | |||
341 | if (signal_pending(current)) | ||
342 | error = -ERESTARTSYS; | ||
343 | } | ||
344 | |||
345 | if (done) | ||
346 | break; | ||
347 | |||
348 | yield(); | ||
349 | } | ||
350 | |||
351 | gfs2_glock_dq_uninit(&ri_gh); | ||
352 | |||
353 | out: | ||
354 | kfree(gha); | ||
355 | return error; | ||
356 | } | ||
357 | |||
358 | /** | ||
359 | * gfs2_statfs_i - Do a statfs | ||
360 | * @sdp: the filesystem | ||
361 | * @sg: the sg structure | ||
362 | * | ||
363 | * Returns: errno | ||
364 | */ | ||
365 | |||
366 | static int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | ||
367 | { | ||
368 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | ||
369 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | ||
370 | |||
371 | spin_lock(&sdp->sd_statfs_spin); | ||
372 | |||
373 | *sc = *m_sc; | ||
374 | sc->sc_total += l_sc->sc_total; | ||
375 | sc->sc_free += l_sc->sc_free; | ||
376 | sc->sc_dinodes += l_sc->sc_dinodes; | ||
377 | |||
378 | spin_unlock(&sdp->sd_statfs_spin); | ||
379 | |||
380 | if (sc->sc_free < 0) | ||
381 | sc->sc_free = 0; | ||
382 | if (sc->sc_free > sc->sc_total) | ||
383 | sc->sc_free = sc->sc_total; | ||
384 | if (sc->sc_dinodes < 0) | ||
385 | sc->sc_dinodes = 0; | ||
386 | |||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | /** | ||
260 | * gfs2_statfs - Gather and return stats about the filesystem | 391 | * gfs2_statfs - Gather and return stats about the filesystem |
261 | * @sb: The superblock | 392 | * @sb: The superblock |
262 | * @statfsbuf: The buffer | 393 | * @statfsbuf: The buffer |
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index b56ba3db7771..efd09c3d2b26 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c | |||
@@ -585,6 +585,28 @@ fail: | |||
585 | return error; | 585 | return error; |
586 | } | 586 | } |
587 | 587 | ||
588 | static struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp) | ||
589 | { | ||
590 | struct gfs2_jdesc *jd; | ||
591 | int found = 0; | ||
592 | |||
593 | spin_lock(&sdp->sd_jindex_spin); | ||
594 | |||
595 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | ||
596 | if (jd->jd_dirty) { | ||
597 | jd->jd_dirty = 0; | ||
598 | found = 1; | ||
599 | break; | ||
600 | } | ||
601 | } | ||
602 | spin_unlock(&sdp->sd_jindex_spin); | ||
603 | |||
604 | if (!found) | ||
605 | jd = NULL; | ||
606 | |||
607 | return jd; | ||
608 | } | ||
609 | |||
588 | /** | 610 | /** |
589 | * gfs2_check_journals - Recover any dirty journals | 611 | * gfs2_check_journals - Recover any dirty journals |
590 | * @sdp: the filesystem | 612 | * @sdp: the filesystem |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 3dd9f5788cb0..141b781f2fcc 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -96,39 +96,6 @@ struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid) | |||
96 | return jd; | 96 | return jd; |
97 | } | 97 | } |
98 | 98 | ||
99 | void gfs2_jdesc_make_dirty(struct gfs2_sbd *sdp, unsigned int jid) | ||
100 | { | ||
101 | struct gfs2_jdesc *jd; | ||
102 | |||
103 | spin_lock(&sdp->sd_jindex_spin); | ||
104 | jd = jdesc_find_i(&sdp->sd_jindex_list, jid); | ||
105 | if (jd) | ||
106 | jd->jd_dirty = 1; | ||
107 | spin_unlock(&sdp->sd_jindex_spin); | ||
108 | } | ||
109 | |||
110 | struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp) | ||
111 | { | ||
112 | struct gfs2_jdesc *jd; | ||
113 | int found = 0; | ||
114 | |||
115 | spin_lock(&sdp->sd_jindex_spin); | ||
116 | |||
117 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | ||
118 | if (jd->jd_dirty) { | ||
119 | jd->jd_dirty = 0; | ||
120 | found = 1; | ||
121 | break; | ||
122 | } | ||
123 | } | ||
124 | spin_unlock(&sdp->sd_jindex_spin); | ||
125 | |||
126 | if (!found) | ||
127 | jd = NULL; | ||
128 | |||
129 | return jd; | ||
130 | } | ||
131 | |||
132 | int gfs2_jdesc_check(struct gfs2_jdesc *jd) | 99 | int gfs2_jdesc_check(struct gfs2_jdesc *jd) |
133 | { | 100 | { |
134 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); | 101 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); |
@@ -353,137 +320,6 @@ out: | |||
353 | return error; | 320 | return error; |
354 | } | 321 | } |
355 | 322 | ||
356 | /** | ||
357 | * gfs2_statfs_i - Do a statfs | ||
358 | * @sdp: the filesystem | ||
359 | * @sg: the sg structure | ||
360 | * | ||
361 | * Returns: errno | ||
362 | */ | ||
363 | |||
364 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | ||
365 | { | ||
366 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | ||
367 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | ||
368 | |||
369 | spin_lock(&sdp->sd_statfs_spin); | ||
370 | |||
371 | *sc = *m_sc; | ||
372 | sc->sc_total += l_sc->sc_total; | ||
373 | sc->sc_free += l_sc->sc_free; | ||
374 | sc->sc_dinodes += l_sc->sc_dinodes; | ||
375 | |||
376 | spin_unlock(&sdp->sd_statfs_spin); | ||
377 | |||
378 | if (sc->sc_free < 0) | ||
379 | sc->sc_free = 0; | ||
380 | if (sc->sc_free > sc->sc_total) | ||
381 | sc->sc_free = sc->sc_total; | ||
382 | if (sc->sc_dinodes < 0) | ||
383 | sc->sc_dinodes = 0; | ||
384 | |||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | /** | ||
389 | * statfs_fill - fill in the sg for a given RG | ||
390 | * @rgd: the RG | ||
391 | * @sc: the sc structure | ||
392 | * | ||
393 | * Returns: 0 on success, -ESTALE if the LVB is invalid | ||
394 | */ | ||
395 | |||
396 | static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | ||
397 | struct gfs2_statfs_change_host *sc) | ||
398 | { | ||
399 | gfs2_rgrp_verify(rgd); | ||
400 | sc->sc_total += rgd->rd_data; | ||
401 | sc->sc_free += rgd->rd_free; | ||
402 | sc->sc_dinodes += rgd->rd_dinodes; | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | /** | ||
407 | * gfs2_statfs_slow - Stat a filesystem using asynchronous locking | ||
408 | * @sdp: the filesystem | ||
409 | * @sc: the sc info that will be returned | ||
410 | * | ||
411 | * Any error (other than a signal) will cause this routine to fall back | ||
412 | * to the synchronous version. | ||
413 | * | ||
414 | * FIXME: This really shouldn't busy wait like this. | ||
415 | * | ||
416 | * Returns: errno | ||
417 | */ | ||
418 | |||
419 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | ||
420 | { | ||
421 | struct gfs2_holder ri_gh; | ||
422 | struct gfs2_rgrpd *rgd_next; | ||
423 | struct gfs2_holder *gha, *gh; | ||
424 | unsigned int slots = 64; | ||
425 | unsigned int x; | ||
426 | int done; | ||
427 | int error = 0, err; | ||
428 | |||
429 | memset(sc, 0, sizeof(struct gfs2_statfs_change_host)); | ||
430 | gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); | ||
431 | if (!gha) | ||
432 | return -ENOMEM; | ||
433 | |||
434 | error = gfs2_rindex_hold(sdp, &ri_gh); | ||
435 | if (error) | ||
436 | goto out; | ||
437 | |||
438 | rgd_next = gfs2_rgrpd_get_first(sdp); | ||
439 | |||
440 | for (;;) { | ||
441 | done = 1; | ||
442 | |||
443 | for (x = 0; x < slots; x++) { | ||
444 | gh = gha + x; | ||
445 | |||
446 | if (gh->gh_gl && gfs2_glock_poll(gh)) { | ||
447 | err = gfs2_glock_wait(gh); | ||
448 | if (err) { | ||
449 | gfs2_holder_uninit(gh); | ||
450 | error = err; | ||
451 | } else { | ||
452 | if (!error) | ||
453 | error = statfs_slow_fill( | ||
454 | gh->gh_gl->gl_object, sc); | ||
455 | gfs2_glock_dq_uninit(gh); | ||
456 | } | ||
457 | } | ||
458 | |||
459 | if (gh->gh_gl) | ||
460 | done = 0; | ||
461 | else if (rgd_next && !error) { | ||
462 | error = gfs2_glock_nq_init(rgd_next->rd_gl, | ||
463 | LM_ST_SHARED, | ||
464 | GL_ASYNC, | ||
465 | gh); | ||
466 | rgd_next = gfs2_rgrpd_get_next(rgd_next); | ||
467 | done = 0; | ||
468 | } | ||
469 | |||
470 | if (signal_pending(current)) | ||
471 | error = -ERESTARTSYS; | ||
472 | } | ||
473 | |||
474 | if (done) | ||
475 | break; | ||
476 | |||
477 | yield(); | ||
478 | } | ||
479 | |||
480 | gfs2_glock_dq_uninit(&ri_gh); | ||
481 | |||
482 | out: | ||
483 | kfree(gha); | ||
484 | return error; | ||
485 | } | ||
486 | |||
487 | struct lfcc { | 323 | struct lfcc { |
488 | struct list_head list; | 324 | struct list_head list; |
489 | struct gfs2_holder gh; | 325 | struct gfs2_holder gh; |
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index c6254596713a..f6b8b00ad881 100644 --- a/fs/gfs2/super.h +++ b/fs/gfs2/super.h | |||
@@ -28,8 +28,6 @@ static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp) | |||
28 | void gfs2_jindex_free(struct gfs2_sbd *sdp); | 28 | void gfs2_jindex_free(struct gfs2_sbd *sdp); |
29 | 29 | ||
30 | struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid); | 30 | struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid); |
31 | void gfs2_jdesc_make_dirty(struct gfs2_sbd *sdp, unsigned int jid); | ||
32 | struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp); | ||
33 | int gfs2_jdesc_check(struct gfs2_jdesc *jd); | 31 | int gfs2_jdesc_check(struct gfs2_jdesc *jd); |
34 | 32 | ||
35 | int gfs2_lookup_in_master_dir(struct gfs2_sbd *sdp, char *filename, | 33 | int gfs2_lookup_in_master_dir(struct gfs2_sbd *sdp, char *filename, |
@@ -41,8 +39,6 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp); | |||
41 | void gfs2_statfs_change(struct gfs2_sbd *sdp, | 39 | void gfs2_statfs_change(struct gfs2_sbd *sdp, |
42 | s64 total, s64 free, s64 dinodes); | 40 | s64 total, s64 free, s64 dinodes); |
43 | int gfs2_statfs_sync(struct gfs2_sbd *sdp); | 41 | int gfs2_statfs_sync(struct gfs2_sbd *sdp); |
44 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc); | ||
45 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc); | ||
46 | 42 | ||
47 | int gfs2_freeze_fs(struct gfs2_sbd *sdp); | 43 | int gfs2_freeze_fs(struct gfs2_sbd *sdp); |
48 | void gfs2_unfreeze_fs(struct gfs2_sbd *sdp); | 44 | void gfs2_unfreeze_fs(struct gfs2_sbd *sdp); |