aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/glock.c14
-rw-r--r--fs/gfs2/ops_super.c131
-rw-r--r--fs/gfs2/recovery.c22
-rw-r--r--fs/gfs2/super.c164
-rw-r--r--fs/gfs2/super.h4
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
1320static 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
267static 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
290static 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
353out:
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
366static 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
588static 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
99void 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
110struct 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
132int gfs2_jdesc_check(struct gfs2_jdesc *jd) 99int 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
364int 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
396static 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
419int 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
482out:
483 kfree(gha);
484 return error;
485}
486
487struct lfcc { 323struct 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)
28void gfs2_jindex_free(struct gfs2_sbd *sdp); 28void gfs2_jindex_free(struct gfs2_sbd *sdp);
29 29
30struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid); 30struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid);
31void gfs2_jdesc_make_dirty(struct gfs2_sbd *sdp, unsigned int jid);
32struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp);
33int gfs2_jdesc_check(struct gfs2_jdesc *jd); 31int gfs2_jdesc_check(struct gfs2_jdesc *jd);
34 32
35int gfs2_lookup_in_master_dir(struct gfs2_sbd *sdp, char *filename, 33int gfs2_lookup_in_master_dir(struct gfs2_sbd *sdp, char *filename,
@@ -41,8 +39,6 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp);
41void gfs2_statfs_change(struct gfs2_sbd *sdp, 39void gfs2_statfs_change(struct gfs2_sbd *sdp,
42 s64 total, s64 free, s64 dinodes); 40 s64 total, s64 free, s64 dinodes);
43int gfs2_statfs_sync(struct gfs2_sbd *sdp); 41int gfs2_statfs_sync(struct gfs2_sbd *sdp);
44int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc);
45int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc);
46 42
47int gfs2_freeze_fs(struct gfs2_sbd *sdp); 43int gfs2_freeze_fs(struct gfs2_sbd *sdp);
48void gfs2_unfreeze_fs(struct gfs2_sbd *sdp); 44void gfs2_unfreeze_fs(struct gfs2_sbd *sdp);