diff options
Diffstat (limited to 'fs/hfsplus/super.c')
-rw-r--r-- | fs/hfsplus/super.c | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index a9bca4b8768b..473332098013 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -124,7 +124,7 @@ static int hfsplus_system_write_inode(struct inode *inode) | |||
124 | 124 | ||
125 | if (fork->total_size != cpu_to_be64(inode->i_size)) { | 125 | if (fork->total_size != cpu_to_be64(inode->i_size)) { |
126 | set_bit(HFSPLUS_SB_WRITEBACKUP, &sbi->flags); | 126 | set_bit(HFSPLUS_SB_WRITEBACKUP, &sbi->flags); |
127 | inode->i_sb->s_dirt = 1; | 127 | hfsplus_mark_mdb_dirty(inode->i_sb); |
128 | } | 128 | } |
129 | hfsplus_inode_write_fork(inode, fork); | 129 | hfsplus_inode_write_fork(inode, fork); |
130 | if (tree) | 130 | if (tree) |
@@ -161,7 +161,7 @@ static void hfsplus_evict_inode(struct inode *inode) | |||
161 | } | 161 | } |
162 | } | 162 | } |
163 | 163 | ||
164 | int hfsplus_sync_fs(struct super_block *sb, int wait) | 164 | static int hfsplus_sync_fs(struct super_block *sb, int wait) |
165 | { | 165 | { |
166 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); | 166 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); |
167 | struct hfsplus_vh *vhdr = sbi->s_vhdr; | 167 | struct hfsplus_vh *vhdr = sbi->s_vhdr; |
@@ -171,9 +171,7 @@ int hfsplus_sync_fs(struct super_block *sb, int wait) | |||
171 | if (!wait) | 171 | if (!wait) |
172 | return 0; | 172 | return 0; |
173 | 173 | ||
174 | dprint(DBG_SUPER, "hfsplus_write_super\n"); | 174 | dprint(DBG_SUPER, "hfsplus_sync_fs\n"); |
175 | |||
176 | sb->s_dirt = 0; | ||
177 | 175 | ||
178 | /* | 176 | /* |
179 | * Explicitly write out the special metadata inodes. | 177 | * Explicitly write out the special metadata inodes. |
@@ -226,12 +224,34 @@ out: | |||
226 | return error; | 224 | return error; |
227 | } | 225 | } |
228 | 226 | ||
229 | static void hfsplus_write_super(struct super_block *sb) | 227 | static void delayed_sync_fs(struct work_struct *work) |
230 | { | 228 | { |
231 | if (!(sb->s_flags & MS_RDONLY)) | 229 | struct hfsplus_sb_info *sbi; |
232 | hfsplus_sync_fs(sb, 1); | 230 | |
233 | else | 231 | sbi = container_of(work, struct hfsplus_sb_info, sync_work.work); |
234 | sb->s_dirt = 0; | 232 | |
233 | spin_lock(&sbi->work_lock); | ||
234 | sbi->work_queued = 0; | ||
235 | spin_unlock(&sbi->work_lock); | ||
236 | |||
237 | hfsplus_sync_fs(sbi->alloc_file->i_sb, 1); | ||
238 | } | ||
239 | |||
240 | void hfsplus_mark_mdb_dirty(struct super_block *sb) | ||
241 | { | ||
242 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); | ||
243 | unsigned long delay; | ||
244 | |||
245 | if (sb->s_flags & MS_RDONLY) | ||
246 | return; | ||
247 | |||
248 | spin_lock(&sbi->work_lock); | ||
249 | if (!sbi->work_queued) { | ||
250 | delay = msecs_to_jiffies(dirty_writeback_interval * 10); | ||
251 | queue_delayed_work(system_long_wq, &sbi->sync_work, delay); | ||
252 | sbi->work_queued = 1; | ||
253 | } | ||
254 | spin_unlock(&sbi->work_lock); | ||
235 | } | 255 | } |
236 | 256 | ||
237 | static void hfsplus_put_super(struct super_block *sb) | 257 | static void hfsplus_put_super(struct super_block *sb) |
@@ -240,8 +260,7 @@ static void hfsplus_put_super(struct super_block *sb) | |||
240 | 260 | ||
241 | dprint(DBG_SUPER, "hfsplus_put_super\n"); | 261 | dprint(DBG_SUPER, "hfsplus_put_super\n"); |
242 | 262 | ||
243 | if (!sb->s_fs_info) | 263 | cancel_delayed_work_sync(&sbi->sync_work); |
244 | return; | ||
245 | 264 | ||
246 | if (!(sb->s_flags & MS_RDONLY) && sbi->s_vhdr) { | 265 | if (!(sb->s_flags & MS_RDONLY) && sbi->s_vhdr) { |
247 | struct hfsplus_vh *vhdr = sbi->s_vhdr; | 266 | struct hfsplus_vh *vhdr = sbi->s_vhdr; |
@@ -328,7 +347,6 @@ static const struct super_operations hfsplus_sops = { | |||
328 | .write_inode = hfsplus_write_inode, | 347 | .write_inode = hfsplus_write_inode, |
329 | .evict_inode = hfsplus_evict_inode, | 348 | .evict_inode = hfsplus_evict_inode, |
330 | .put_super = hfsplus_put_super, | 349 | .put_super = hfsplus_put_super, |
331 | .write_super = hfsplus_write_super, | ||
332 | .sync_fs = hfsplus_sync_fs, | 350 | .sync_fs = hfsplus_sync_fs, |
333 | .statfs = hfsplus_statfs, | 351 | .statfs = hfsplus_statfs, |
334 | .remount_fs = hfsplus_remount, | 352 | .remount_fs = hfsplus_remount, |
@@ -355,6 +373,8 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
355 | sb->s_fs_info = sbi; | 373 | sb->s_fs_info = sbi; |
356 | mutex_init(&sbi->alloc_mutex); | 374 | mutex_init(&sbi->alloc_mutex); |
357 | mutex_init(&sbi->vh_mutex); | 375 | mutex_init(&sbi->vh_mutex); |
376 | spin_lock_init(&sbi->work_lock); | ||
377 | INIT_DELAYED_WORK(&sbi->sync_work, delayed_sync_fs); | ||
358 | hfsplus_fill_defaults(sbi); | 378 | hfsplus_fill_defaults(sbi); |
359 | 379 | ||
360 | err = -EINVAL; | 380 | err = -EINVAL; |