X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=fs%2Flogfs%2Fsuper.c;h=5866ee6e13278ce873a4771966b5285e0b81db44;hb=16a5b3c4143fc7f6cbe0ef9fd4e9a58376f91506;hp=1d081b7ede5ab73976574a2e5c232b227b2cc6d4;hpb=c6d3830140f1d56b07d8ab56a6e14ca3c492a39a;p=safe%2Fjmp%2Flinux-2.6 diff --git a/fs/logfs/super.c b/fs/logfs/super.c index 1d081b7..5866ee6 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c @@ -11,6 +11,8 @@ */ #include "logfs.h" #include +#include +#include #include #include #include @@ -136,6 +138,10 @@ static int logfs_sb_set(struct super_block *sb, void *_super) sb->s_fs_info = super; sb->s_mtd = super->s_mtd; sb->s_bdev = super->s_bdev; + if (sb->s_bdev) + sb->s_bdi = &bdev_get_queue(sb->s_bdev)->backing_dev_info; + if (sb->s_mtd) + sb->s_bdi = sb->s_mtd->backing_dev_info; return 0; } @@ -277,7 +283,7 @@ static int logfs_recover_sb(struct super_block *sb) } if (valid0 && valid1 && ds_cmp(ds0, ds1)) { printk(KERN_INFO"Superblocks don't match - fixing.\n"); - return write_one_sb(sb, super->s_devops->find_last_sb); + return logfs_write_sb(sb); } /* If neither is valid now, something's wrong. Didn't we properly * check them before?!? */ @@ -289,6 +295,10 @@ static int logfs_make_writeable(struct super_block *sb) { int err; + err = logfs_open_segfile(sb); + if (err) + return err; + /* Repair any broken superblock copies */ err = logfs_recover_sb(sb); if (err) @@ -299,10 +309,6 @@ static int logfs_make_writeable(struct super_block *sb) if (err) return err; - err = logfs_open_segfile(sb); - if (err) - return err; - /* Do one GC pass before any data gets dirtied */ logfs_gc_pass(sb); @@ -328,7 +334,7 @@ static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt) sb->s_root = d_alloc_root(rootdir); if (!sb->s_root) - goto fail; + goto fail2; super->s_erase_page = alloc_pages(GFP_KERNEL, 0); if (!super->s_erase_page) @@ -440,7 +446,7 @@ static int __logfs_read_sb(struct super_block *sb) return 0; } -static int logfs_read_sb(struct super_block *sb) +static int logfs_read_sb(struct super_block *sb, int read_only) { struct logfs_super *super = logfs_super(sb); int ret; @@ -451,6 +457,8 @@ static int logfs_read_sb(struct super_block *sb) btree_init_mempool64(&super->s_shadow_tree.new, super->s_btree_pool); btree_init_mempool64(&super->s_shadow_tree.old, super->s_btree_pool); + btree_init_mempool32(&super->s_shadow_tree.segment_map, + super->s_btree_pool); ret = logfs_init_mapping(sb); if (ret) @@ -460,6 +468,12 @@ static int logfs_read_sb(struct super_block *sb) if (ret) return ret; + if (super->s_feature_incompat & ~LOGFS_FEATURES_INCOMPAT) + return -EIO; + if ((super->s_feature_ro_compat & ~LOGFS_FEATURES_RO_COMPAT) && + !read_only) + return -EIO; + mutex_init(&super->s_dirop_mutex); mutex_init(&super->s_object_alias_mutex); INIT_LIST_HEAD(&super->s_freeing_list); @@ -509,8 +523,8 @@ static void logfs_kill_sb(struct super_block *sb) if (super->s_erase_page) __free_page(super->s_erase_page); super->s_devops->put_device(sb); - mempool_destroy(super->s_btree_pool); - mempool_destroy(super->s_alias_pool); + logfs_mempool_destroy(super->s_btree_pool); + logfs_mempool_destroy(super->s_alias_pool); kfree(super); log_super("LogFS: Finished unmounting\n"); } @@ -555,7 +569,7 @@ int logfs_get_sb_device(struct file_system_type *type, int flags, sb->s_op = &logfs_super_operations; sb->s_flags = flags | MS_NOATIME; - err = logfs_read_sb(sb); + err = logfs_read_sb(sb, sb->s_flags & MS_RDONLY); if (err) goto err1; @@ -566,8 +580,7 @@ int logfs_get_sb_device(struct file_system_type *type, int flags, return 0; err1: - up_write(&sb->s_umount); - deactivate_super(sb); + deactivate_locked_super(sb); return err; err0: kfree(super);