X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=fs%2Fgfs2%2Fsuper.c;h=ef0562c3bc71986705dab6c7593f0f29c9908da4;hb=e662ee02cc9f1a61f309eaa44ce3c33dc6ed7b8a;hp=bae32ba0c481a35323ab8d34b2e65d0ba0740209;hpb=f42faf4fa4eaf7e108dd60f3f2ca5c6e9b45352c;p=safe%2Fjmp%2Flinux-2.6 diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index bae32ba..ef0562c 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1,10 +1,10 @@ /* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. - * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions - * of the GNU General Public License v.2. + * of the GNU General Public License version 2. */ #include @@ -12,12 +12,15 @@ #include #include #include -#include +#include +#include +#include +#include #include "gfs2.h" +#include "incore.h" #include "bmap.h" #include "dir.h" -#include "format.h" #include "glock.h" #include "glops.h" #include "inode.h" @@ -28,7 +31,15 @@ #include "rgrp.h" #include "super.h" #include "trans.h" -#include "unlinked.h" +#include "util.h" + +static const u32 gfs2_old_fs_formats[] = { + 0 +}; + +static const u32 gfs2_old_multihost_formats[] = { + 0 +}; /** * gfs2_tune_init - Fill a gfs2_tune structure with default values @@ -40,18 +51,12 @@ void gfs2_tune_init(struct gfs2_tune *gt) { spin_lock_init(>->gt_spin); - gt->gt_ilimit = 100; - gt->gt_ilimit_tries = 3; - gt->gt_ilimit_min = 1; gt->gt_demote_secs = 300; gt->gt_incore_log_blocks = 1024; gt->gt_log_flush_secs = 60; - gt->gt_jindex_refresh_secs = 60; - gt->gt_scand_secs = 15; gt->gt_recoverd_secs = 60; gt->gt_logd_secs = 1; gt->gt_quotad_secs = 5; - gt->gt_inoded_secs = 15; gt->gt_quota_simul_sync = 64; gt->gt_quota_warn_period = 10; gt->gt_quota_scale_num = 1; @@ -61,17 +66,9 @@ void gfs2_tune_init(struct gfs2_tune *gt) gt->gt_atime_quantum = 3600; gt->gt_new_files_jdata = 0; gt->gt_new_files_directio = 0; - gt->gt_max_atomic_write = 4 << 20; gt->gt_max_readahead = 1 << 18; - gt->gt_lockdump_size = 131072; gt->gt_stall_secs = 600; gt->gt_complain_secs = 10; - gt->gt_reclaim_limit = 5000; - gt->gt_entries_per_readdir = 32; - gt->gt_prefetch_secs = 10; - gt->gt_greedy_default = HZ / 10; - gt->gt_greedy_quantum = HZ / 40; - gt->gt_greedy_max = HZ / 4; gt->gt_statfs_quantum = 30; gt->gt_statfs_slow = 0; } @@ -87,14 +84,14 @@ void gfs2_tune_init(struct gfs2_tune *gt) * changed. */ -int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb *sb, int silent) +int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent) { unsigned int x; - if (sb->sb_header.mh_magic != GFS2_MAGIC || - sb->sb_header.mh_type != GFS2_METATYPE_SB) { + if (sb->sb_magic != GFS2_MAGIC || + sb->sb_type != GFS2_METATYPE_SB) { if (!silent) - printk("GFS2: not a GFS2 filesystem\n"); + printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n"); return -EINVAL; } @@ -110,44 +107,143 @@ int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb *sb, int silent) break; if (!gfs2_old_fs_formats[x]) { - printk("GFS2: code version (%u, %u) is incompatible " + printk(KERN_WARNING + "GFS2: code version (%u, %u) is incompatible " "with ondisk format (%u, %u)\n", GFS2_FORMAT_FS, GFS2_FORMAT_MULTI, sb->sb_fs_format, sb->sb_multihost_format); - printk("GFS2: I don't know how to upgrade this FS\n"); + printk(KERN_WARNING + "GFS2: I don't know how to upgrade this FS\n"); return -EINVAL; } } if (sb->sb_multihost_format != GFS2_FORMAT_MULTI) { for (x = 0; gfs2_old_multihost_formats[x]; x++) - if (gfs2_old_multihost_formats[x] == sb->sb_multihost_format) + if (gfs2_old_multihost_formats[x] == + sb->sb_multihost_format) break; if (!gfs2_old_multihost_formats[x]) { - printk("GFS2: code version (%u, %u) is incompatible " + printk(KERN_WARNING + "GFS2: code version (%u, %u) is incompatible " "with ondisk format (%u, %u)\n", GFS2_FORMAT_FS, GFS2_FORMAT_MULTI, sb->sb_fs_format, sb->sb_multihost_format); - printk("GFS2: I don't know how to upgrade this FS\n"); + printk(KERN_WARNING + "GFS2: I don't know how to upgrade this FS\n"); return -EINVAL; } } if (!sdp->sd_args.ar_upgrade) { - printk("GFS2: code version (%u, %u) is incompatible " + printk(KERN_WARNING + "GFS2: code version (%u, %u) is incompatible " "with ondisk format (%u, %u)\n", GFS2_FORMAT_FS, GFS2_FORMAT_MULTI, sb->sb_fs_format, sb->sb_multihost_format); - printk("GFS2: Use the \"upgrade\" mount option to upgrade " + printk(KERN_INFO + "GFS2: Use the \"upgrade\" mount option to upgrade " "the FS\n"); - printk("GFS2: See the manual for more details\n"); + printk(KERN_INFO "GFS2: See the manual for more details\n"); return -EINVAL; } return 0; } + +static void end_bio_io_page(struct bio *bio, int error) +{ + struct page *page = bio->bi_private; + + if (!error) + SetPageUptodate(page); + else + printk(KERN_WARNING "gfs2: error %d reading superblock\n", error); + unlock_page(page); +} + +static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) +{ + const struct gfs2_sb *str = buf; + + sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic); + sb->sb_type = be32_to_cpu(str->sb_header.mh_type); + sb->sb_format = be32_to_cpu(str->sb_header.mh_format); + sb->sb_fs_format = be32_to_cpu(str->sb_fs_format); + sb->sb_multihost_format = be32_to_cpu(str->sb_multihost_format); + sb->sb_bsize = be32_to_cpu(str->sb_bsize); + sb->sb_bsize_shift = be32_to_cpu(str->sb_bsize_shift); + sb->sb_master_dir.no_addr = be64_to_cpu(str->sb_master_dir.no_addr); + sb->sb_master_dir.no_formal_ino = be64_to_cpu(str->sb_master_dir.no_formal_ino); + sb->sb_root_dir.no_addr = be64_to_cpu(str->sb_root_dir.no_addr); + sb->sb_root_dir.no_formal_ino = be64_to_cpu(str->sb_root_dir.no_formal_ino); + + memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN); + memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); +} + +/** + * gfs2_read_super - Read the gfs2 super block from disk + * @sdp: The GFS2 super block + * @sector: The location of the super block + * @error: The error code to return + * + * This uses the bio functions to read the super block from disk + * because we want to be 100% sure that we never read cached data. + * A super block is read twice only during each GFS2 mount and is + * never written to by the filesystem. The first time its read no + * locks are held, and the only details which are looked at are those + * relating to the locking protocol. Once locking is up and working, + * the sb is read again under the lock to establish the location of + * the master directory (contains pointers to journals etc) and the + * root directory. + * + * Returns: 0 on success or error + */ + +int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector) +{ + struct super_block *sb = sdp->sd_vfs; + struct gfs2_sb *p; + struct page *page; + struct bio *bio; + + page = alloc_page(GFP_KERNEL); + if (unlikely(!page)) + return -ENOBUFS; + + ClearPageUptodate(page); + ClearPageDirty(page); + lock_page(page); + + bio = bio_alloc(GFP_KERNEL, 1); + if (unlikely(!bio)) { + __free_page(page); + return -ENOBUFS; + } + + bio->bi_sector = sector * (sb->s_blocksize >> 9); + bio->bi_bdev = sb->s_bdev; + bio_add_page(bio, page, PAGE_SIZE, 0); + + bio->bi_end_io = end_bio_io_page; + bio->bi_private = page; + submit_bio(READ_SYNC | (1 << BIO_RW_META), bio); + wait_on_page_locked(page); + bio_put(bio); + if (!PageUptodate(page)) { + __free_page(page); + return -EIO; + } + p = kmap(page); + gfs2_sb_in(&sdp->sd_sb, p); + kunmap(page); + __free_page(page); + return 0; +} + /** * gfs2_read_sb - Read super block * @sdp: The GFS2 superblock @@ -158,24 +254,18 @@ int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb *sb, int silent) int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent) { - struct buffer_head *bh; - uint32_t hash_blocks, ind_blocks, leaf_blocks; - uint32_t tmp_blocks; + u32 hash_blocks, ind_blocks, leaf_blocks; + u32 tmp_blocks; unsigned int x; int error; - error = gfs2_meta_read(gl, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift, - DIO_FORCE | DIO_START | DIO_WAIT, &bh); + error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); if (error) { if (!silent) fs_err(sdp, "can't read superblock\n"); return error; } - gfs2_assert(sdp, sizeof(struct gfs2_sb) <= bh->b_size); - gfs2_sb_in(&sdp->sd_sb, bh->b_data); - brelse(bh); - error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); if (error) return error; @@ -184,28 +274,25 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent) GFS2_BASIC_BLOCK_SHIFT; sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; sdp->sd_diptrs = (sdp->sd_sb.sb_bsize - - sizeof(struct gfs2_dinode)) / sizeof(uint64_t); + sizeof(struct gfs2_dinode)) / sizeof(u64); sdp->sd_inptrs = (sdp->sd_sb.sb_bsize - - sizeof(struct gfs2_meta_header)) / sizeof(uint64_t); + sizeof(struct gfs2_meta_header)) / sizeof(u64); sdp->sd_jbsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header); sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2; sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1; - sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t); - sdp->sd_ut_per_block = (sdp->sd_sb.sb_bsize - - sizeof(struct gfs2_meta_header)) / - sizeof(struct gfs2_unlinked_tag); + sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(u64); sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header)) / - sizeof(struct gfs2_quota_change); + sizeof(struct gfs2_quota_change); /* Compute maximum reservation required to add a entry to a directory */ - hash_blocks = DIV_RU(sizeof(uint64_t) * (1 << GFS2_DIR_MAX_DEPTH), + hash_blocks = DIV_ROUND_UP(sizeof(u64) * (1 << GFS2_DIR_MAX_DEPTH), sdp->sd_jbsize); ind_blocks = 0; for (tmp_blocks = hash_blocks; tmp_blocks > sdp->sd_diptrs;) { - tmp_blocks = DIV_RU(tmp_blocks, sdp->sd_inptrs); + tmp_blocks = DIV_ROUND_UP(tmp_blocks, sdp->sd_inptrs); ind_blocks += tmp_blocks; } @@ -217,8 +304,8 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent) sizeof(struct gfs2_dinode); sdp->sd_heightsize[1] = sdp->sd_sb.sb_bsize * sdp->sd_diptrs; for (x = 2;; x++) { - uint64_t space, d; - uint32_t m; + u64 space, d; + u32 m; space = sdp->sd_heightsize[x - 1] * sdp->sd_inptrs; d = space; @@ -235,8 +322,8 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent) sizeof(struct gfs2_dinode); sdp->sd_jheightsize[1] = sdp->sd_jbsize * sdp->sd_diptrs; for (x = 2;; x++) { - uint64_t space, d; - uint32_t m; + u64 space, d; + u32 m; space = sdp->sd_jheightsize[x - 1] * sdp->sd_inptrs; d = space; @@ -252,11 +339,6 @@ int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent) return 0; } -int gfs2_do_upgrade(struct gfs2_sbd *sdp, struct gfs2_glock *sb_gl) -{ - return 0; -} - /** * gfs2_jindex_hold - Grab a lock on the jindex * @sdp: The GFS2 superblock @@ -271,7 +353,7 @@ int gfs2_do_upgrade(struct gfs2_sbd *sdp, struct gfs2_glock *sb_gl) int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) { - struct gfs2_inode *dip = get_v2ip(sdp->sd_jindex); + struct gfs2_inode *dip = GFS2_I(sdp->sd_jindex); struct qstr name; char buf[20]; struct gfs2_jdesc *jd; @@ -279,17 +361,17 @@ int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) name.name = buf; - down(&sdp->sd_jindex_mutex); + mutex_lock(&sdp->sd_jindex_mutex); for (;;) { - error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, - GL_LOCAL_EXCL, ji_gh); + error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, ji_gh); if (error) break; name.len = sprintf(buf, "journal%u", sdp->sd_journals); + name.hash = gfs2_disk_hash(name.name, name.len); - error = gfs2_dir_search(get_v2ip(sdp->sd_jindex), &name, NULL, NULL); + error = gfs2_dir_check(sdp->sd_jindex, &name, NULL); if (error == -ENOENT) { error = 0; break; @@ -305,8 +387,13 @@ int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) if (!jd) break; - error = gfs2_lookupi(dip, &name, 1, &jd->jd_inode); - if (error) { + INIT_LIST_HEAD(&jd->extent_list); + jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1, NULL); + if (!jd->jd_inode || IS_ERR(jd->jd_inode)) { + if (!jd->jd_inode) + error = -ENOENT; + else + error = PTR_ERR(jd->jd_inode); kfree(jd); break; } @@ -317,7 +404,7 @@ int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) spin_unlock(&sdp->sd_jindex_spin); } - up(&sdp->sd_jindex_mutex); + mutex_unlock(&sdp->sd_jindex_mutex); return error; } @@ -330,8 +417,9 @@ int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) void gfs2_jindex_free(struct gfs2_sbd *sdp) { - struct list_head list; + struct list_head list, *head; struct gfs2_jdesc *jd; + struct gfs2_journal_extent *jext; spin_lock(&sdp->sd_jindex_spin); list_add(&list, &sdp->sd_jindex_list); @@ -341,8 +429,16 @@ void gfs2_jindex_free(struct gfs2_sbd *sdp) while (!list_empty(&list)) { jd = list_entry(list.next, struct gfs2_jdesc, jd_list); + head = &jd->extent_list; + while (!list_empty(head)) { + jext = list_entry(head->next, + struct gfs2_journal_extent, + extent_list); + list_del(&jext->extent_list); + kfree(jext); + } list_del(&jd->jd_list); - gfs2_inode_put(jd->jd_inode); + iput(jd->jd_inode); kfree(jd); } } @@ -411,22 +507,19 @@ struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp) int gfs2_jdesc_check(struct gfs2_jdesc *jd) { - struct gfs2_inode *ip = jd->jd_inode; - struct gfs2_sbd *sdp = ip->i_sbd; + struct gfs2_inode *ip = GFS2_I(jd->jd_inode); + struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); int ar; int error; - if (ip->i_di.di_size < (8 << 20) || - ip->i_di.di_size > (1 << 30) || + if (ip->i_di.di_size < (8 << 20) || ip->i_di.di_size > (1 << 30) || (ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1))) { gfs2_consist_inode(ip); return -EIO; } jd->jd_blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift; - error = gfs2_write_alloc_required(ip, - 0, ip->i_di.di_size, - &ar); + error = gfs2_write_alloc_required(ip, 0, ip->i_di.di_size, &ar); if (!error && ar) { gfs2_consist_inode(ip); error = -EIO; @@ -435,24 +528,6 @@ int gfs2_jdesc_check(struct gfs2_jdesc *jd) return error; } -int gfs2_lookup_master_dir(struct gfs2_sbd *sdp) -{ - struct inode *inode = NULL; - struct gfs2_glock *gl; - int error; - - error = gfs2_glock_get(sdp, - sdp->sd_sb.sb_master_dir.no_addr, - &gfs2_inode_glops, CREATE, &gl); - if (!error) { - error = gfs2_lookup_simple(sdp->sd_root_dir, ".gfs2_admin", &inode); - sdp->sd_master_dir = inode; - gfs2_glock_put(gl); - } - - return error; -} - /** * gfs2_make_fs_rw - Turn a Read-Only FS into a Read-Write one * @sdp: the filesystem @@ -462,18 +537,17 @@ int gfs2_lookup_master_dir(struct gfs2_sbd *sdp) int gfs2_make_fs_rw(struct gfs2_sbd *sdp) { - struct gfs2_glock *j_gl = sdp->sd_jdesc->jd_inode->i_gl; + struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); + struct gfs2_glock *j_gl = ip->i_gl; struct gfs2_holder t_gh; - struct gfs2_log_header head; + struct gfs2_log_header_host head; int error; - error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, - GL_LOCAL_EXCL | GL_NEVER_RECURSE, &t_gh); + error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &t_gh); if (error) return error; - gfs2_meta_cache_flush(sdp->sd_jdesc->jd_inode); - j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA); + j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); error = gfs2_find_jhead(sdp->sd_jdesc, &head); if (error) @@ -489,12 +563,9 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) sdp->sd_log_sequence = head.lh_sequence + 1; gfs2_log_pointers_init(sdp, head.lh_blkno); - error = gfs2_unlinked_init(sdp); - if (error) - goto fail; error = gfs2_quota_init(sdp); if (error) - goto fail_unlinked; + goto fail; set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); @@ -502,10 +573,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) return 0; - fail_unlinked: - gfs2_unlinked_cleanup(sdp); - - fail: +fail: t_gh.gh_flags |= GL_NOCACHE; gfs2_glock_dq_uninit(&t_gh); @@ -524,13 +592,11 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp) struct gfs2_holder t_gh; int error; - gfs2_unlinked_dealloc(sdp); gfs2_quota_sync(sdp); gfs2_statfs_sync(sdp); - error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, - GL_LOCAL_EXCL | GL_NEVER_RECURSE | GL_NOCACHE, - &t_gh); + error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE, + &t_gh); if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) return error; @@ -542,18 +608,35 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp) if (t_gh.gh_gl) gfs2_glock_dq_uninit(&t_gh); - gfs2_unlinked_cleanup(sdp); gfs2_quota_cleanup(sdp); return error; } +static void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) +{ + const struct gfs2_statfs_change *str = buf; + + sc->sc_total = be64_to_cpu(str->sc_total); + sc->sc_free = be64_to_cpu(str->sc_free); + sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); +} + +static void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf) +{ + struct gfs2_statfs_change *str = buf; + + str->sc_total = cpu_to_be64(sc->sc_total); + str->sc_free = cpu_to_be64(sc->sc_free); + str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); +} + int gfs2_statfs_init(struct gfs2_sbd *sdp) { - struct gfs2_inode *m_ip = get_v2ip(sdp->sd_statfs_inode); - struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master; - struct gfs2_inode *l_ip = get_v2ip(sdp->sd_sc_inode); - struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; + struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); + struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; + struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); + struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; struct buffer_head *m_bh, *l_bh; struct gfs2_holder gh; int error; @@ -587,20 +670,18 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp) brelse(l_bh); } - out_m_bh: +out_m_bh: brelse(m_bh); - - out: +out: gfs2_glock_dq_uninit(&gh); - return 0; } -void gfs2_statfs_change(struct gfs2_sbd *sdp, int64_t total, int64_t free, - int64_t dinodes) +void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, + s64 dinodes) { - struct gfs2_inode *l_ip = get_v2ip(sdp->sd_sc_inode); - struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; + struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); + struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; struct buffer_head *l_bh; int error; @@ -608,16 +689,13 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, int64_t total, int64_t free, if (error) return; - down(&sdp->sd_statfs_mutex); gfs2_trans_add_bh(l_ip->i_gl, l_bh, 1); - up(&sdp->sd_statfs_mutex); spin_lock(&sdp->sd_statfs_spin); l_sc->sc_total += total; l_sc->sc_free += free; l_sc->sc_dinodes += dinodes; - gfs2_statfs_change_out(l_sc, l_bh->b_data + - sizeof(struct gfs2_dinode)); + gfs2_statfs_change_out(l_sc, l_bh->b_data + sizeof(struct gfs2_dinode)); spin_unlock(&sdp->sd_statfs_spin); brelse(l_bh); @@ -625,10 +703,10 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, int64_t total, int64_t free, int gfs2_statfs_sync(struct gfs2_sbd *sdp) { - struct gfs2_inode *m_ip = get_v2ip(sdp->sd_statfs_inode); - struct gfs2_inode *l_ip = get_v2ip(sdp->sd_sc_inode); - struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master; - struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; + struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); + struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); + struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; + struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; struct gfs2_holder gh; struct buffer_head *m_bh, *l_bh; int error; @@ -644,7 +722,7 @@ int gfs2_statfs_sync(struct gfs2_sbd *sdp) spin_lock(&sdp->sd_statfs_spin); gfs2_statfs_change_in(m_sc, m_bh->b_data + - sizeof(struct gfs2_dinode)); + sizeof(struct gfs2_dinode)); if (!l_sc->sc_total && !l_sc->sc_free && !l_sc->sc_dinodes) { spin_unlock(&sdp->sd_statfs_spin); goto out_bh; @@ -659,9 +737,7 @@ int gfs2_statfs_sync(struct gfs2_sbd *sdp) if (error) goto out_bh2; - down(&sdp->sd_statfs_mutex); gfs2_trans_add_bh(l_ip->i_gl, l_bh, 1); - up(&sdp->sd_statfs_mutex); spin_lock(&sdp->sd_statfs_spin); m_sc->sc_total += l_sc->sc_total; @@ -677,15 +753,12 @@ int gfs2_statfs_sync(struct gfs2_sbd *sdp) gfs2_trans_end(sdp); - out_bh2: +out_bh2: brelse(l_bh); - - out_bh: +out_bh: brelse(m_bh); - - out: +out: gfs2_glock_dq_uninit(&gh); - return error; } @@ -697,10 +770,10 @@ int gfs2_statfs_sync(struct gfs2_sbd *sdp) * Returns: errno */ -int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) +int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) { - struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master; - struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; + struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; + struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; spin_lock(&sdp->sd_statfs_spin); @@ -730,10 +803,10 @@ int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) */ static int statfs_slow_fill(struct gfs2_rgrpd *rgd, - struct gfs2_statfs_change *sc) + struct gfs2_statfs_change_host *sc) { gfs2_rgrp_verify(rgd); - sc->sc_total += rgd->rd_ri.ri_data; + sc->sc_total += rgd->rd_data; sc->sc_free += rgd->rd_rg.rg_free; sc->sc_dinodes += rgd->rd_rg.rg_dinodes; return 0; @@ -752,7 +825,7 @@ static int statfs_slow_fill(struct gfs2_rgrpd *rgd, * Returns: errno */ -int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) +int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) { struct gfs2_holder ri_gh; struct gfs2_rgrpd *rgd_next; @@ -762,7 +835,7 @@ int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) int done; int error = 0, err; - memset(sc, 0, sizeof(struct gfs2_statfs_change)); + memset(sc, 0, sizeof(struct gfs2_statfs_change_host)); gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); if (!gha) return -ENOMEM; @@ -786,7 +859,8 @@ int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) error = err; } else { if (!error) - error = statfs_slow_fill(get_gl2rgd(gh->gh_gl), sc); + error = statfs_slow_fill( + gh->gh_gl->gl_object, sc); gfs2_glock_dq_uninit(gh); } } @@ -814,9 +888,8 @@ int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) gfs2_glock_dq_uninit(&ri_gh); - out: +out: kfree(gha); - return error; } @@ -835,13 +908,15 @@ struct lfcc { * Returns: errno */ -int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, struct gfs2_holder *t_gh) +static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, + struct gfs2_holder *t_gh) { + struct gfs2_inode *ip; struct gfs2_holder ji_gh; struct gfs2_jdesc *jd; struct lfcc *lfcc; LIST_HEAD(list); - struct gfs2_log_header lh; + struct gfs2_log_header_host lh; int error; error = gfs2_jindex_hold(sdp, &ji_gh); @@ -854,8 +929,8 @@ int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, struct gfs2_holder *t_gh) error = -ENOMEM; goto out; } - error = gfs2_glock_nq_init(jd->jd_inode->i_gl, LM_ST_SHARED, 0, - &lfcc->gh); + ip = GFS2_I(jd->jd_inode); + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &lfcc->gh); if (error) { kfree(lfcc); goto out; @@ -864,7 +939,7 @@ int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, struct gfs2_holder *t_gh) } error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_DEFERRED, - LM_FLAG_PRIORITY | GL_NEVER_RECURSE | GL_NOCACHE, + LM_FLAG_PRIORITY | GL_NOCACHE, t_gh); list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { @@ -883,7 +958,7 @@ int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, struct gfs2_holder *t_gh) if (error) gfs2_glock_dq_uninit(t_gh); - out: +out: while (!list_empty(&list)) { lfcc = list_entry(list.next, struct lfcc, list); list_del(&lfcc->list); @@ -891,7 +966,6 @@ int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, struct gfs2_holder *t_gh) kfree(lfcc); } gfs2_glock_dq_uninit(&ji_gh); - return error; } @@ -910,7 +984,7 @@ int gfs2_freeze_fs(struct gfs2_sbd *sdp) { int error = 0; - down(&sdp->sd_freeze_lock); + mutex_lock(&sdp->sd_freeze_lock); if (!sdp->sd_freeze_count++) { error = gfs2_lock_fs_check_clean(sdp, &sdp->sd_freeze_gh); @@ -918,7 +992,7 @@ int gfs2_freeze_fs(struct gfs2_sbd *sdp) sdp->sd_freeze_count--; } - up(&sdp->sd_freeze_lock); + mutex_unlock(&sdp->sd_freeze_lock); return error; } @@ -935,11 +1009,11 @@ int gfs2_freeze_fs(struct gfs2_sbd *sdp) void gfs2_unfreeze_fs(struct gfs2_sbd *sdp) { - down(&sdp->sd_freeze_lock); + mutex_lock(&sdp->sd_freeze_lock); if (sdp->sd_freeze_count && !--sdp->sd_freeze_count) gfs2_glock_dq_uninit(&sdp->sd_freeze_gh); - up(&sdp->sd_freeze_lock); + mutex_unlock(&sdp->sd_freeze_lock); }