diff options
author | Joern Engel <joern@logfs.org> | 2010-03-04 15:30:58 -0500 |
---|---|---|
committer | Joern Engel <joern@logfs.org> | 2010-03-04 15:30:58 -0500 |
commit | 9421502b4fc894cc477be8fc49776830e37ca157 (patch) | |
tree | 9c9b1bfa42b2acdf4b5e080a256c3cd37852a94f /fs/logfs/super.c | |
parent | 5c564c2a04d4bb6ba79eeb83bd06de584479f362 (diff) |
[LogFS] Fix bdev erases
Erases for block devices were always just emulated by writing 0xff.
Some time back the write was removed and only the page cache was
changed to 0xff. Superficialy a good idea with two problems:
1. Touching the page cache isn't necessary either.
2. However, writing out 0xff _is_ necessary for the journal. As the
journal is scanned linearly, an old non-overwritten commit entry
can be used on next mount and cause havoc.
This should fix both aspects.
Diffstat (limited to 'fs/logfs/super.c')
-rw-r--r-- | fs/logfs/super.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/logfs/super.c b/fs/logfs/super.c index d128a2c1c8d1..94d80f7ee7c2 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c | |||
@@ -317,6 +317,7 @@ static int logfs_make_writeable(struct super_block *sb) | |||
317 | 317 | ||
318 | static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt) | 318 | static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt) |
319 | { | 319 | { |
320 | struct logfs_super *super = logfs_super(sb); | ||
320 | struct inode *rootdir; | 321 | struct inode *rootdir; |
321 | int err; | 322 | int err; |
322 | 323 | ||
@@ -329,15 +330,22 @@ static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt) | |||
329 | if (!sb->s_root) | 330 | if (!sb->s_root) |
330 | goto fail; | 331 | goto fail; |
331 | 332 | ||
333 | super->s_erase_page = alloc_pages(GFP_KERNEL, 0); | ||
334 | if (!super->s_erase_page) | ||
335 | goto fail2; | ||
336 | memset(page_address(super->s_erase_page), 0xFF, PAGE_SIZE); | ||
337 | |||
332 | /* FIXME: check for read-only mounts */ | 338 | /* FIXME: check for read-only mounts */ |
333 | err = logfs_make_writeable(sb); | 339 | err = logfs_make_writeable(sb); |
334 | if (err) | 340 | if (err) |
335 | goto fail2; | 341 | goto fail3; |
336 | 342 | ||
337 | log_super("LogFS: Finished mounting\n"); | 343 | log_super("LogFS: Finished mounting\n"); |
338 | simple_set_mnt(mnt, sb); | 344 | simple_set_mnt(mnt, sb); |
339 | return 0; | 345 | return 0; |
340 | 346 | ||
347 | fail3: | ||
348 | __free_page(super->s_erase_page); | ||
341 | fail2: | 349 | fail2: |
342 | iput(rootdir); | 350 | iput(rootdir); |
343 | fail: | 351 | fail: |
@@ -498,6 +506,8 @@ static void logfs_kill_sb(struct super_block *sb) | |||
498 | logfs_cleanup_journal(sb); | 506 | logfs_cleanup_journal(sb); |
499 | logfs_cleanup_areas(sb); | 507 | logfs_cleanup_areas(sb); |
500 | logfs_cleanup_rw(sb); | 508 | logfs_cleanup_rw(sb); |
509 | if (super->s_erase_page) | ||
510 | __free_page(super->s_erase_page); | ||
501 | super->s_devops->put_device(sb); | 511 | super->s_devops->put_device(sb); |
502 | mempool_destroy(super->s_btree_pool); | 512 | mempool_destroy(super->s_btree_pool); |
503 | mempool_destroy(super->s_alias_pool); | 513 | mempool_destroy(super->s_alias_pool); |