diff options
Diffstat (limited to 'fs/hfsplus')
-rw-r--r-- | fs/hfsplus/bitmap.c | 4 | ||||
-rw-r--r-- | fs/hfsplus/dir.c | 6 | ||||
-rw-r--r-- | fs/hfsplus/hfsplus_fs.h | 7 | ||||
-rw-r--r-- | fs/hfsplus/inode.c | 8 | ||||
-rw-r--r-- | fs/hfsplus/super.c | 46 |
5 files changed, 47 insertions, 24 deletions
diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c index 1cad80c789cb..4cfbe2edd296 100644 --- a/fs/hfsplus/bitmap.c +++ b/fs/hfsplus/bitmap.c | |||
@@ -153,7 +153,7 @@ done: | |||
153 | kunmap(page); | 153 | kunmap(page); |
154 | *max = offset + (curr - pptr) * 32 + i - start; | 154 | *max = offset + (curr - pptr) * 32 + i - start; |
155 | sbi->free_blocks -= *max; | 155 | sbi->free_blocks -= *max; |
156 | sb->s_dirt = 1; | 156 | hfsplus_mark_mdb_dirty(sb); |
157 | dprint(DBG_BITMAP, "-> %u,%u\n", start, *max); | 157 | dprint(DBG_BITMAP, "-> %u,%u\n", start, *max); |
158 | out: | 158 | out: |
159 | mutex_unlock(&sbi->alloc_mutex); | 159 | mutex_unlock(&sbi->alloc_mutex); |
@@ -228,7 +228,7 @@ out: | |||
228 | set_page_dirty(page); | 228 | set_page_dirty(page); |
229 | kunmap(page); | 229 | kunmap(page); |
230 | sbi->free_blocks += len; | 230 | sbi->free_blocks += len; |
231 | sb->s_dirt = 1; | 231 | hfsplus_mark_mdb_dirty(sb); |
232 | mutex_unlock(&sbi->alloc_mutex); | 232 | mutex_unlock(&sbi->alloc_mutex); |
233 | 233 | ||
234 | return 0; | 234 | return 0; |
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 26b53fb09f68..6b9f921ef2fa 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
@@ -25,7 +25,7 @@ static inline void hfsplus_instantiate(struct dentry *dentry, | |||
25 | 25 | ||
26 | /* Find the entry inside dir named dentry->d_name */ | 26 | /* Find the entry inside dir named dentry->d_name */ |
27 | static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry, | 27 | static struct dentry *hfsplus_lookup(struct inode *dir, struct dentry *dentry, |
28 | struct nameidata *nd) | 28 | unsigned int flags) |
29 | { | 29 | { |
30 | struct inode *inode = NULL; | 30 | struct inode *inode = NULL; |
31 | struct hfs_find_data fd; | 31 | struct hfs_find_data fd; |
@@ -316,7 +316,7 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir, | |||
316 | inode->i_ctime = CURRENT_TIME_SEC; | 316 | inode->i_ctime = CURRENT_TIME_SEC; |
317 | mark_inode_dirty(inode); | 317 | mark_inode_dirty(inode); |
318 | sbi->file_count++; | 318 | sbi->file_count++; |
319 | dst_dir->i_sb->s_dirt = 1; | 319 | hfsplus_mark_mdb_dirty(dst_dir->i_sb); |
320 | out: | 320 | out: |
321 | mutex_unlock(&sbi->vh_mutex); | 321 | mutex_unlock(&sbi->vh_mutex); |
322 | return res; | 322 | return res; |
@@ -465,7 +465,7 @@ out: | |||
465 | } | 465 | } |
466 | 466 | ||
467 | static int hfsplus_create(struct inode *dir, struct dentry *dentry, umode_t mode, | 467 | static int hfsplus_create(struct inode *dir, struct dentry *dentry, umode_t mode, |
468 | struct nameidata *nd) | 468 | bool excl) |
469 | { | 469 | { |
470 | return hfsplus_mknod(dir, dentry, mode, 0); | 470 | return hfsplus_mknod(dir, dentry, mode, 0); |
471 | } | 471 | } |
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 4e75ac646fea..558dbb463a4e 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h | |||
@@ -153,8 +153,11 @@ struct hfsplus_sb_info { | |||
153 | gid_t gid; | 153 | gid_t gid; |
154 | 154 | ||
155 | int part, session; | 155 | int part, session; |
156 | |||
157 | unsigned long flags; | 156 | unsigned long flags; |
157 | |||
158 | int work_queued; /* non-zero delayed work is queued */ | ||
159 | struct delayed_work sync_work; /* FS sync delayed work */ | ||
160 | spinlock_t work_lock; /* protects sync_work and work_queued */ | ||
158 | }; | 161 | }; |
159 | 162 | ||
160 | #define HFSPLUS_SB_WRITEBACKUP 0 | 163 | #define HFSPLUS_SB_WRITEBACKUP 0 |
@@ -428,7 +431,7 @@ int hfsplus_show_options(struct seq_file *, struct dentry *); | |||
428 | 431 | ||
429 | /* super.c */ | 432 | /* super.c */ |
430 | struct inode *hfsplus_iget(struct super_block *, unsigned long); | 433 | struct inode *hfsplus_iget(struct super_block *, unsigned long); |
431 | int hfsplus_sync_fs(struct super_block *sb, int wait); | 434 | void hfsplus_mark_mdb_dirty(struct super_block *sb); |
432 | 435 | ||
433 | /* tables.c */ | 436 | /* tables.c */ |
434 | extern u16 hfsplus_case_fold_table[]; | 437 | extern u16 hfsplus_case_fold_table[]; |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 82b69ee4dacc..3d8b4a675ba0 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
@@ -168,7 +168,7 @@ const struct dentry_operations hfsplus_dentry_operations = { | |||
168 | }; | 168 | }; |
169 | 169 | ||
170 | static struct dentry *hfsplus_file_lookup(struct inode *dir, | 170 | static struct dentry *hfsplus_file_lookup(struct inode *dir, |
171 | struct dentry *dentry, struct nameidata *nd) | 171 | struct dentry *dentry, unsigned int flags) |
172 | { | 172 | { |
173 | struct hfs_find_data fd; | 173 | struct hfs_find_data fd; |
174 | struct super_block *sb = dir->i_sb; | 174 | struct super_block *sb = dir->i_sb; |
@@ -431,7 +431,7 @@ struct inode *hfsplus_new_inode(struct super_block *sb, umode_t mode) | |||
431 | sbi->file_count++; | 431 | sbi->file_count++; |
432 | insert_inode_hash(inode); | 432 | insert_inode_hash(inode); |
433 | mark_inode_dirty(inode); | 433 | mark_inode_dirty(inode); |
434 | sb->s_dirt = 1; | 434 | hfsplus_mark_mdb_dirty(sb); |
435 | 435 | ||
436 | return inode; | 436 | return inode; |
437 | } | 437 | } |
@@ -442,7 +442,7 @@ void hfsplus_delete_inode(struct inode *inode) | |||
442 | 442 | ||
443 | if (S_ISDIR(inode->i_mode)) { | 443 | if (S_ISDIR(inode->i_mode)) { |
444 | HFSPLUS_SB(sb)->folder_count--; | 444 | HFSPLUS_SB(sb)->folder_count--; |
445 | sb->s_dirt = 1; | 445 | hfsplus_mark_mdb_dirty(sb); |
446 | return; | 446 | return; |
447 | } | 447 | } |
448 | HFSPLUS_SB(sb)->file_count--; | 448 | HFSPLUS_SB(sb)->file_count--; |
@@ -455,7 +455,7 @@ void hfsplus_delete_inode(struct inode *inode) | |||
455 | inode->i_size = 0; | 455 | inode->i_size = 0; |
456 | hfsplus_file_truncate(inode); | 456 | hfsplus_file_truncate(inode); |
457 | } | 457 | } |
458 | sb->s_dirt = 1; | 458 | hfsplus_mark_mdb_dirty(sb); |
459 | } | 459 | } |
460 | 460 | ||
461 | void hfsplus_inode_read_fork(struct inode *inode, struct hfsplus_fork_raw *fork) | 461 | void hfsplus_inode_read_fork(struct inode *inode, struct hfsplus_fork_raw *fork) |
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; |