aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/super.c')
-rw-r--r--fs/gfs2/super.c246
1 files changed, 4 insertions, 242 deletions
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index c3ba3d9d0aac..141b781f2fcc 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -34,76 +34,6 @@
34#include "util.h" 34#include "util.h"
35 35
36/** 36/**
37 * gfs2_jindex_hold - Grab a lock on the jindex
38 * @sdp: The GFS2 superblock
39 * @ji_gh: the holder for the jindex glock
40 *
41 * This is very similar to the gfs2_rindex_hold() function, except that
42 * in general we hold the jindex lock for longer periods of time and
43 * we grab it far less frequently (in general) then the rgrp lock.
44 *
45 * Returns: errno
46 */
47
48int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
49{
50 struct gfs2_inode *dip = GFS2_I(sdp->sd_jindex);
51 struct qstr name;
52 char buf[20];
53 struct gfs2_jdesc *jd;
54 int error;
55
56 name.name = buf;
57
58 mutex_lock(&sdp->sd_jindex_mutex);
59
60 for (;;) {
61 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, ji_gh);
62 if (error)
63 break;
64
65 name.len = sprintf(buf, "journal%u", sdp->sd_journals);
66 name.hash = gfs2_disk_hash(name.name, name.len);
67
68 error = gfs2_dir_check(sdp->sd_jindex, &name, NULL);
69 if (error == -ENOENT) {
70 error = 0;
71 break;
72 }
73
74 gfs2_glock_dq_uninit(ji_gh);
75
76 if (error)
77 break;
78
79 error = -ENOMEM;
80 jd = kzalloc(sizeof(struct gfs2_jdesc), GFP_KERNEL);
81 if (!jd)
82 break;
83
84 INIT_LIST_HEAD(&jd->extent_list);
85 jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1);
86 if (!jd->jd_inode || IS_ERR(jd->jd_inode)) {
87 if (!jd->jd_inode)
88 error = -ENOENT;
89 else
90 error = PTR_ERR(jd->jd_inode);
91 kfree(jd);
92 break;
93 }
94
95 spin_lock(&sdp->sd_jindex_spin);
96 jd->jd_jid = sdp->sd_journals++;
97 list_add_tail(&jd->jd_list, &sdp->sd_jindex_list);
98 spin_unlock(&sdp->sd_jindex_spin);
99 }
100
101 mutex_unlock(&sdp->sd_jindex_mutex);
102
103 return error;
104}
105
106/**
107 * gfs2_jindex_free - Clear all the journal index information 37 * gfs2_jindex_free - Clear all the journal index information
108 * @sdp: The GFS2 superblock 38 * @sdp: The GFS2 superblock
109 * 39 *
@@ -166,39 +96,6 @@ struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid)
166 return jd; 96 return jd;
167} 97}
168 98
169void gfs2_jdesc_make_dirty(struct gfs2_sbd *sdp, unsigned int jid)
170{
171 struct gfs2_jdesc *jd;
172
173 spin_lock(&sdp->sd_jindex_spin);
174 jd = jdesc_find_i(&sdp->sd_jindex_list, jid);
175 if (jd)
176 jd->jd_dirty = 1;
177 spin_unlock(&sdp->sd_jindex_spin);
178}
179
180struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp)
181{
182 struct gfs2_jdesc *jd;
183 int found = 0;
184
185 spin_lock(&sdp->sd_jindex_spin);
186
187 list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
188 if (jd->jd_dirty) {
189 jd->jd_dirty = 0;
190 found = 1;
191 break;
192 }
193 }
194 spin_unlock(&sdp->sd_jindex_spin);
195
196 if (!found)
197 jd = NULL;
198
199 return jd;
200}
201
202int gfs2_jdesc_check(struct gfs2_jdesc *jd) 99int gfs2_jdesc_check(struct gfs2_jdesc *jd)
203{ 100{
204 struct gfs2_inode *ip = GFS2_I(jd->jd_inode); 101 struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
@@ -206,14 +103,14 @@ int gfs2_jdesc_check(struct gfs2_jdesc *jd)
206 int ar; 103 int ar;
207 int error; 104 int error;
208 105
209 if (ip->i_di.di_size < (8 << 20) || ip->i_di.di_size > (1 << 30) || 106 if (ip->i_disksize < (8 << 20) || ip->i_disksize > (1 << 30) ||
210 (ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1))) { 107 (ip->i_disksize & (sdp->sd_sb.sb_bsize - 1))) {
211 gfs2_consist_inode(ip); 108 gfs2_consist_inode(ip);
212 return -EIO; 109 return -EIO;
213 } 110 }
214 jd->jd_blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift; 111 jd->jd_blocks = ip->i_disksize >> sdp->sd_sb.sb_bsize_shift;
215 112
216 error = gfs2_write_alloc_required(ip, 0, ip->i_di.di_size, &ar); 113 error = gfs2_write_alloc_required(ip, 0, ip->i_disksize, &ar);
217 if (!error && ar) { 114 if (!error && ar) {
218 gfs2_consist_inode(ip); 115 gfs2_consist_inode(ip);
219 error = -EIO; 116 error = -EIO;
@@ -423,137 +320,6 @@ out:
423 return error; 320 return error;
424} 321}
425 322
426/**
427 * gfs2_statfs_i - Do a statfs
428 * @sdp: the filesystem
429 * @sg: the sg structure
430 *
431 * Returns: errno
432 */
433
434int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc)
435{
436 struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
437 struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
438
439 spin_lock(&sdp->sd_statfs_spin);
440
441 *sc = *m_sc;
442 sc->sc_total += l_sc->sc_total;
443 sc->sc_free += l_sc->sc_free;
444 sc->sc_dinodes += l_sc->sc_dinodes;
445
446 spin_unlock(&sdp->sd_statfs_spin);
447
448 if (sc->sc_free < 0)
449 sc->sc_free = 0;
450 if (sc->sc_free > sc->sc_total)
451 sc->sc_free = sc->sc_total;
452 if (sc->sc_dinodes < 0)
453 sc->sc_dinodes = 0;
454
455 return 0;
456}
457
458/**
459 * statfs_fill - fill in the sg for a given RG
460 * @rgd: the RG
461 * @sc: the sc structure
462 *
463 * Returns: 0 on success, -ESTALE if the LVB is invalid
464 */
465
466static int statfs_slow_fill(struct gfs2_rgrpd *rgd,
467 struct gfs2_statfs_change_host *sc)
468{
469 gfs2_rgrp_verify(rgd);
470 sc->sc_total += rgd->rd_data;
471 sc->sc_free += rgd->rd_rg.rg_free;
472 sc->sc_dinodes += rgd->rd_rg.rg_dinodes;
473 return 0;
474}
475
476/**
477 * gfs2_statfs_slow - Stat a filesystem using asynchronous locking
478 * @sdp: the filesystem
479 * @sc: the sc info that will be returned
480 *
481 * Any error (other than a signal) will cause this routine to fall back
482 * to the synchronous version.
483 *
484 * FIXME: This really shouldn't busy wait like this.
485 *
486 * Returns: errno
487 */
488
489int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc)
490{
491 struct gfs2_holder ri_gh;
492 struct gfs2_rgrpd *rgd_next;
493 struct gfs2_holder *gha, *gh;
494 unsigned int slots = 64;
495 unsigned int x;
496 int done;
497 int error = 0, err;
498
499 memset(sc, 0, sizeof(struct gfs2_statfs_change_host));
500 gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL);
501 if (!gha)
502 return -ENOMEM;
503
504 error = gfs2_rindex_hold(sdp, &ri_gh);
505 if (error)
506 goto out;
507
508 rgd_next = gfs2_rgrpd_get_first(sdp);
509
510 for (;;) {
511 done = 1;
512
513 for (x = 0; x < slots; x++) {
514 gh = gha + x;
515
516 if (gh->gh_gl && gfs2_glock_poll(gh)) {
517 err = gfs2_glock_wait(gh);
518 if (err) {
519 gfs2_holder_uninit(gh);
520 error = err;
521 } else {
522 if (!error)
523 error = statfs_slow_fill(
524 gh->gh_gl->gl_object, sc);
525 gfs2_glock_dq_uninit(gh);
526 }
527 }
528
529 if (gh->gh_gl)
530 done = 0;
531 else if (rgd_next && !error) {
532 error = gfs2_glock_nq_init(rgd_next->rd_gl,
533 LM_ST_SHARED,
534 GL_ASYNC,
535 gh);
536 rgd_next = gfs2_rgrpd_get_next(rgd_next);
537 done = 0;
538 }
539
540 if (signal_pending(current))
541 error = -ERESTARTSYS;
542 }
543
544 if (done)
545 break;
546
547 yield();
548 }
549
550 gfs2_glock_dq_uninit(&ri_gh);
551
552out:
553 kfree(gha);
554 return error;
555}
556
557struct lfcc { 323struct lfcc {
558 struct list_head list; 324 struct list_head list;
559 struct gfs2_holder gh; 325 struct gfs2_holder gh;
@@ -580,10 +346,6 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp,
580 struct gfs2_log_header_host lh; 346 struct gfs2_log_header_host lh;
581 int error; 347 int error;
582 348
583 error = gfs2_jindex_hold(sdp, &ji_gh);
584 if (error)
585 return error;
586
587 list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { 349 list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
588 lfcc = kmalloc(sizeof(struct lfcc), GFP_KERNEL); 350 lfcc = kmalloc(sizeof(struct lfcc), GFP_KERNEL);
589 if (!lfcc) { 351 if (!lfcc) {