diff options
Diffstat (limited to 'fs/gfs2/super.c')
-rw-r--r-- | fs/gfs2/super.c | 246 |
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 | |||
48 | int 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 | ||
169 | void 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 | |||
180 | struct 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 | |||
202 | int gfs2_jdesc_check(struct gfs2_jdesc *jd) | 99 | int 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 | |||
434 | int 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 | |||
466 | static 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 | |||
489 | int 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 | |||
552 | out: | ||
553 | kfree(gha); | ||
554 | return error; | ||
555 | } | ||
556 | |||
557 | struct lfcc { | 323 | struct 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) { |