diff options
Diffstat (limited to 'fs/hfs/super.c')
| -rw-r--r-- | fs/hfs/super.c | 73 | 
1 files changed, 36 insertions, 37 deletions
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 7b4c537d6e1..4eb873e0c07 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -29,43 +29,9 @@ static struct kmem_cache *hfs_inode_cachep;  MODULE_LICENSE("GPL"); -/* - * hfs_write_super() - * - * Description: - *   This function is called by the VFS only. When the filesystem - *   is mounted r/w it updates the MDB on disk. - * Input Variable(s): - *   struct super_block *sb: Pointer to the hfs superblock - * Output Variable(s): - *   NONE - * Returns: - *   void - * Preconditions: - *   'sb' points to a "valid" (struct super_block). - * Postconditions: - *   The MDB is marked 'unsuccessfully unmounted' by clearing bit 8 of drAtrb - *   (hfs_put_super() must set this flag!). Some MDB fields are updated - *   and the MDB buffer is written to disk by calling hfs_mdb_commit(). - */ -static void hfs_write_super(struct super_block *sb) -{ -	lock_super(sb); -	sb->s_dirt = 0; - -	/* sync everything to the buffers */ -	if (!(sb->s_flags & MS_RDONLY)) -		hfs_mdb_commit(sb); -	unlock_super(sb); -} -  static int hfs_sync_fs(struct super_block *sb, int wait)  { -	lock_super(sb);  	hfs_mdb_commit(sb); -	sb->s_dirt = 0; -	unlock_super(sb); -  	return 0;  } @@ -78,13 +44,44 @@ static int hfs_sync_fs(struct super_block *sb, int wait)   */  static void hfs_put_super(struct super_block *sb)  { -	if (sb->s_dirt) -		hfs_write_super(sb); +	cancel_delayed_work_sync(&HFS_SB(sb)->mdb_work);  	hfs_mdb_close(sb);  	/* release the MDB's resources */  	hfs_mdb_put(sb);  } +static void flush_mdb(struct work_struct *work) +{ +	struct hfs_sb_info *sbi; +	struct super_block *sb; + +	sbi = container_of(work, struct hfs_sb_info, mdb_work.work); +	sb = sbi->sb; + +	spin_lock(&sbi->work_lock); +	sbi->work_queued = 0; +	spin_unlock(&sbi->work_lock); + +	hfs_mdb_commit(sb); +} + +void hfs_mark_mdb_dirty(struct super_block *sb) +{ +	struct hfs_sb_info *sbi = HFS_SB(sb); +	unsigned long delay; + +	if (sb->s_flags & MS_RDONLY) +		return; + +	spin_lock(&sbi->work_lock); +	if (!sbi->work_queued) { +		delay = msecs_to_jiffies(dirty_writeback_interval * 10); +		queue_delayed_work(system_long_wq, &sbi->mdb_work, delay); +		sbi->work_queued = 1; +	} +	spin_unlock(&sbi->work_lock); +} +  /*   * hfs_statfs()   * @@ -184,7 +181,6 @@ static const struct super_operations hfs_super_operations = {  	.write_inode	= hfs_write_inode,  	.evict_inode	= hfs_evict_inode,  	.put_super	= hfs_put_super, -	.write_super	= hfs_write_super,  	.sync_fs	= hfs_sync_fs,  	.statfs		= hfs_statfs,  	.remount_fs     = hfs_remount, @@ -387,7 +383,10 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent)  	if (!sbi)  		return -ENOMEM; +	sbi->sb = sb;  	sb->s_fs_info = sbi; +	spin_lock_init(&sbi->work_lock); +	INIT_DELAYED_WORK(&sbi->mdb_work, flush_mdb);  	res = -EINVAL;  	if (!parse_options((char *)data, sbi)) {  |