X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=fs%2Fsuper.c;h=aec99ddbe53f726a526d4cd0b02abb9f55179e0b;hb=346bc21026e7a92e1d7a4a1b3792c5e8b686133d;hp=057b5325b7ef3bf596163ab9b2ea2e729ef18cf4;hpb=37224470c8c6d90a4062e76a08d4dc1fcf91fc89;p=mv-sheeva.git diff --git a/fs/super.c b/fs/super.c index 057b5325b7e..aec99ddbe53 100644 --- a/fs/super.c +++ b/fs/super.c @@ -20,7 +20,6 @@ * Heavily rewritten for 'one fs - one tree' dcache architecture. AV, Mar 2000 */ -#include #include #include #include @@ -50,11 +49,12 @@ DEFINE_SPINLOCK(sb_lock); /** * alloc_super - create new superblock + * @type: filesystem type superblock should belong to * * Allocates and initializes a new &struct super_block. alloc_super() * returns a pointer new superblock or %NULL if allocation had failed. */ -static struct super_block *alloc_super(void) +static struct super_block *alloc_super(struct file_system_type *type) { struct super_block *s = kzalloc(sizeof(struct super_block), GFP_USER); static struct super_operations default_op; @@ -73,6 +73,13 @@ static struct super_block *alloc_super(void) INIT_LIST_HEAD(&s->s_inodes); init_rwsem(&s->s_umount); mutex_init(&s->s_lock); + lockdep_set_class(&s->s_umount, &type->s_umount_key); + /* + * The locking rules for s_lock are up to the + * filesystem. For example ext3fs has different + * lock ordering than usbfs: + */ + lockdep_set_class(&s->s_lock, &type->s_lock_key); down_write(&s->s_umount); s->s_count = S_BIAS; atomic_set(&s->s_active, 1); @@ -192,7 +199,7 @@ EXPORT_SYMBOL(deactivate_super); * success, 0 if we had failed (superblock contents was already dead or * dying when grab_super() had been called). */ -static int grab_super(struct super_block *s) +static int grab_super(struct super_block *s) __releases(sb_lock) { s->s_count++; spin_unlock(&sb_lock); @@ -213,6 +220,37 @@ static int grab_super(struct super_block *s) return 0; } +/* + * Write out and wait upon all dirty data associated with this + * superblock. Filesystem data as well as the underlying block + * device. Takes the superblock lock. Requires a second blkdev + * flush by the caller to complete the operation. + */ +void __fsync_super(struct super_block *sb) +{ + sync_inodes_sb(sb, 0); + DQUOT_SYNC(sb); + lock_super(sb); + if (sb->s_dirt && sb->s_op->write_super) + sb->s_op->write_super(sb); + unlock_super(sb); + if (sb->s_op->sync_fs) + sb->s_op->sync_fs(sb, 1); + sync_blockdev(sb->s_bdev); + sync_inodes_sb(sb, 1); +} + +/* + * Write out and wait upon all dirty data associated with this + * superblock. Filesystem data as well as the underlying block + * device. Takes the superblock lock. + */ +int fsync_super(struct super_block *sb) +{ + __fsync_super(sb); + return sync_blockdev(sb->s_bdev); +} + /** * generic_shutdown_super - common helper for ->kill_sb() * @sb: superblock to kill @@ -296,7 +334,7 @@ retry: } if (!s) { spin_unlock(&sb_lock); - s = alloc_super(); + s = alloc_super(type); if (!s) return ERR_PTR(-ENOMEM); goto retry; @@ -533,8 +571,10 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) { int retval; +#ifdef CONFIG_BLOCK if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev)) return -EACCES; +#endif if (flags & MS_RDONLY) acct_auto_close(sb); shrink_dcache_sb(sb); @@ -654,6 +694,7 @@ void kill_litter_super(struct super_block *sb) EXPORT_SYMBOL(kill_litter_super); +#ifdef CONFIG_BLOCK static int set_bdev_super(struct super_block *s, void *data) { s->s_bdev = data; @@ -749,6 +790,7 @@ void kill_block_super(struct super_block *sb) } EXPORT_SYMBOL(kill_block_super); +#endif int get_sb_nodev(struct file_system_type *fs_type, int flags, void *data, @@ -871,8 +913,6 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data) return mnt; } -EXPORT_SYMBOL_GPL(do_kern_mount); - struct vfsmount *kern_mount(struct file_system_type *type) { return vfs_kern_mount(type, 0, type->name, NULL);