aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hfsplus/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/hfsplus/super.c')
-rw-r--r--fs/hfsplus/super.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index f2a64020f42e..9fc3af0c0dab 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -152,15 +152,14 @@ static void hfsplus_clear_inode(struct inode *inode)
152 } 152 }
153} 153}
154 154
155static void hfsplus_write_super(struct super_block *sb) 155static int hfsplus_sync_fs(struct super_block *sb, int wait)
156{ 156{
157 struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr; 157 struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr;
158 158
159 dprint(DBG_SUPER, "hfsplus_write_super\n"); 159 dprint(DBG_SUPER, "hfsplus_write_super\n");
160
161 lock_super(sb);
160 sb->s_dirt = 0; 162 sb->s_dirt = 0;
161 if (sb->s_flags & MS_RDONLY)
162 /* warn? */
163 return;
164 163
165 vhdr->free_blocks = cpu_to_be32(HFSPLUS_SB(sb).free_blocks); 164 vhdr->free_blocks = cpu_to_be32(HFSPLUS_SB(sb).free_blocks);
166 vhdr->next_alloc = cpu_to_be32(HFSPLUS_SB(sb).next_alloc); 165 vhdr->next_alloc = cpu_to_be32(HFSPLUS_SB(sb).next_alloc);
@@ -192,6 +191,16 @@ static void hfsplus_write_super(struct super_block *sb)
192 } 191 }
193 HFSPLUS_SB(sb).flags &= ~HFSPLUS_SB_WRITEBACKUP; 192 HFSPLUS_SB(sb).flags &= ~HFSPLUS_SB_WRITEBACKUP;
194 } 193 }
194 unlock_super(sb);
195 return 0;
196}
197
198static void hfsplus_write_super(struct super_block *sb)
199{
200 if (!(sb->s_flags & MS_RDONLY))
201 hfsplus_sync_fs(sb, 1);
202 else
203 sb->s_dirt = 0;
195} 204}
196 205
197static void hfsplus_put_super(struct super_block *sb) 206static void hfsplus_put_super(struct super_block *sb)
@@ -199,6 +208,11 @@ static void hfsplus_put_super(struct super_block *sb)
199 dprint(DBG_SUPER, "hfsplus_put_super\n"); 208 dprint(DBG_SUPER, "hfsplus_put_super\n");
200 if (!sb->s_fs_info) 209 if (!sb->s_fs_info)
201 return; 210 return;
211
212 lock_kernel();
213
214 if (sb->s_dirt)
215 hfsplus_write_super(sb);
202 if (!(sb->s_flags & MS_RDONLY) && HFSPLUS_SB(sb).s_vhdr) { 216 if (!(sb->s_flags & MS_RDONLY) && HFSPLUS_SB(sb).s_vhdr) {
203 struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr; 217 struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr;
204 218
@@ -218,6 +232,8 @@ static void hfsplus_put_super(struct super_block *sb)
218 unload_nls(HFSPLUS_SB(sb).nls); 232 unload_nls(HFSPLUS_SB(sb).nls);
219 kfree(sb->s_fs_info); 233 kfree(sb->s_fs_info);
220 sb->s_fs_info = NULL; 234 sb->s_fs_info = NULL;
235
236 unlock_kernel();
221} 237}
222 238
223static int hfsplus_statfs(struct dentry *dentry, struct kstatfs *buf) 239static int hfsplus_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -279,6 +295,7 @@ static const struct super_operations hfsplus_sops = {
279 .clear_inode = hfsplus_clear_inode, 295 .clear_inode = hfsplus_clear_inode,
280 .put_super = hfsplus_put_super, 296 .put_super = hfsplus_put_super,
281 .write_super = hfsplus_write_super, 297 .write_super = hfsplus_write_super,
298 .sync_fs = hfsplus_sync_fs,
282 .statfs = hfsplus_statfs, 299 .statfs = hfsplus_statfs,
283 .remount_fs = hfsplus_remount, 300 .remount_fs = hfsplus_remount,
284 .show_options = hfsplus_show_options, 301 .show_options = hfsplus_show_options,