diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2010-06-07 12:22:31 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-08-09 16:48:26 -0400 |
commit | 8e22c1a4e429e9facf309c7e7a03ba9cdfd7b106 (patch) | |
tree | cf708706e742d96fed8bf997feb279dc4f9a7426 /fs | |
parent | 6fd1e5c994c392ebdbe45600051b2a32ec4860f1 (diff) |
logfs: get rid of magical inodes
ordering problems at ->kill_sb() time are solved by doing iput()
of these suckers in ->put_super()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/logfs/inode.c | 44 | ||||
-rw-r--r-- | fs/logfs/journal.c | 2 | ||||
-rw-r--r-- | fs/logfs/logfs.h | 1 | ||||
-rw-r--r-- | fs/logfs/readwrite.c | 1 | ||||
-rw-r--r-- | fs/logfs/segment.c | 1 | ||||
-rw-r--r-- | fs/logfs/super.c | 23 |
6 files changed, 31 insertions, 41 deletions
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c index f602e230e162..7811a2a35935 100644 --- a/fs/logfs/inode.c +++ b/fs/logfs/inode.c | |||
@@ -235,33 +235,21 @@ static struct inode *logfs_alloc_inode(struct super_block *sb) | |||
235 | * purpose is to create a new inode that will not trigger the warning if such | 235 | * purpose is to create a new inode that will not trigger the warning if such |
236 | * an inode is still in use. An ugly hack, no doubt. Suggections for | 236 | * an inode is still in use. An ugly hack, no doubt. Suggections for |
237 | * improvement are welcome. | 237 | * improvement are welcome. |
238 | * | ||
239 | * AV: that's what ->put_super() is for... | ||
238 | */ | 240 | */ |
239 | struct inode *logfs_new_meta_inode(struct super_block *sb, u64 ino) | 241 | struct inode *logfs_new_meta_inode(struct super_block *sb, u64 ino) |
240 | { | 242 | { |
241 | struct inode *inode; | 243 | struct inode *inode; |
242 | 244 | ||
243 | inode = logfs_alloc_inode(sb); | 245 | inode = new_inode(sb); |
244 | if (!inode) | 246 | if (!inode) |
245 | return ERR_PTR(-ENOMEM); | 247 | return ERR_PTR(-ENOMEM); |
246 | 248 | ||
247 | inode->i_mode = S_IFREG; | 249 | inode->i_mode = S_IFREG; |
248 | inode->i_ino = ino; | 250 | inode->i_ino = ino; |
249 | inode->i_sb = sb; | 251 | inode->i_data.a_ops = &logfs_reg_aops; |
250 | 252 | mapping_set_gfp_mask(&inode->i_data, GFP_NOFS); | |
251 | /* This is a blatant copy of alloc_inode code. We'd need alloc_inode | ||
252 | * to be nonstatic, alas. */ | ||
253 | { | ||
254 | struct address_space * const mapping = &inode->i_data; | ||
255 | |||
256 | mapping->a_ops = &logfs_reg_aops; | ||
257 | mapping->host = inode; | ||
258 | mapping->flags = 0; | ||
259 | mapping_set_gfp_mask(mapping, GFP_NOFS); | ||
260 | mapping->assoc_mapping = NULL; | ||
261 | mapping->backing_dev_info = &default_backing_dev_info; | ||
262 | inode->i_mapping = mapping; | ||
263 | inode->i_nlink = 1; | ||
264 | } | ||
265 | 253 | ||
266 | return inode; | 254 | return inode; |
267 | } | 255 | } |
@@ -277,7 +265,7 @@ struct inode *logfs_read_meta_inode(struct super_block *sb, u64 ino) | |||
277 | 265 | ||
278 | err = logfs_read_inode(inode); | 266 | err = logfs_read_inode(inode); |
279 | if (err) { | 267 | if (err) { |
280 | destroy_meta_inode(inode); | 268 | iput(inode); |
281 | return ERR_PTR(err); | 269 | return ERR_PTR(err); |
282 | } | 270 | } |
283 | logfs_inode_setops(inode); | 271 | logfs_inode_setops(inode); |
@@ -298,16 +286,6 @@ static int logfs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
298 | return ret; | 286 | return ret; |
299 | } | 287 | } |
300 | 288 | ||
301 | void destroy_meta_inode(struct inode *inode) | ||
302 | { | ||
303 | if (inode) { | ||
304 | if (inode->i_data.nrpages) | ||
305 | truncate_inode_pages(&inode->i_data, 0); | ||
306 | logfs_clear_inode(inode); | ||
307 | kmem_cache_free(logfs_inode_cache, logfs_inode(inode)); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | /* called with inode_lock held */ | 289 | /* called with inode_lock held */ |
312 | static void logfs_drop_inode(struct inode *inode) | 290 | static void logfs_drop_inode(struct inode *inode) |
313 | { | 291 | { |
@@ -384,12 +362,22 @@ static int logfs_sync_fs(struct super_block *sb, int wait) | |||
384 | return 0; | 362 | return 0; |
385 | } | 363 | } |
386 | 364 | ||
365 | static void logfs_put_super(struct super_block *sb) | ||
366 | { | ||
367 | struct logfs_super *super = logfs_super(sb); | ||
368 | /* kill the meta-inodes */ | ||
369 | iput(super->s_master_inode); | ||
370 | iput(super->s_segfile_inode); | ||
371 | iput(super->s_mapping_inode); | ||
372 | } | ||
373 | |||
387 | const struct super_operations logfs_super_operations = { | 374 | const struct super_operations logfs_super_operations = { |
388 | .alloc_inode = logfs_alloc_inode, | 375 | .alloc_inode = logfs_alloc_inode, |
389 | .clear_inode = logfs_clear_inode, | 376 | .clear_inode = logfs_clear_inode, |
390 | .delete_inode = logfs_delete_inode, | 377 | .delete_inode = logfs_delete_inode, |
391 | .destroy_inode = logfs_destroy_inode, | 378 | .destroy_inode = logfs_destroy_inode, |
392 | .drop_inode = logfs_drop_inode, | 379 | .drop_inode = logfs_drop_inode, |
380 | .put_super = logfs_put_super, | ||
393 | .write_inode = logfs_write_inode, | 381 | .write_inode = logfs_write_inode, |
394 | .statfs = logfs_statfs, | 382 | .statfs = logfs_statfs, |
395 | .sync_fs = logfs_sync_fs, | 383 | .sync_fs = logfs_sync_fs, |
diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c index 4b0e0616b357..f46ee8b0e135 100644 --- a/fs/logfs/journal.c +++ b/fs/logfs/journal.c | |||
@@ -889,8 +889,6 @@ void logfs_cleanup_journal(struct super_block *sb) | |||
889 | struct logfs_super *super = logfs_super(sb); | 889 | struct logfs_super *super = logfs_super(sb); |
890 | 890 | ||
891 | btree_grim_visitor32(&super->s_reserved_segments, 0, NULL); | 891 | btree_grim_visitor32(&super->s_reserved_segments, 0, NULL); |
892 | destroy_meta_inode(super->s_master_inode); | ||
893 | super->s_master_inode = NULL; | ||
894 | 892 | ||
895 | kfree(super->s_compressed_je); | 893 | kfree(super->s_compressed_je); |
896 | kfree(super->s_je); | 894 | kfree(super->s_je); |
diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h index c838c4d72111..5e65171dad23 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h | |||
@@ -525,7 +525,6 @@ struct inode *logfs_new_meta_inode(struct super_block *sb, u64 ino); | |||
525 | struct inode *logfs_read_meta_inode(struct super_block *sb, u64 ino); | 525 | struct inode *logfs_read_meta_inode(struct super_block *sb, u64 ino); |
526 | int logfs_init_inode_cache(void); | 526 | int logfs_init_inode_cache(void); |
527 | void logfs_destroy_inode_cache(void); | 527 | void logfs_destroy_inode_cache(void); |
528 | void destroy_meta_inode(struct inode *inode); | ||
529 | void logfs_set_blocks(struct inode *inode, u64 no); | 528 | void logfs_set_blocks(struct inode *inode, u64 no); |
530 | /* these logically belong into inode.c but actually reside in readwrite.c */ | 529 | /* these logically belong into inode.c but actually reside in readwrite.c */ |
531 | int logfs_read_inode(struct inode *inode); | 530 | int logfs_read_inode(struct inode *inode); |
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index 0718d112a1a5..580d126d597d 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c | |||
@@ -2272,7 +2272,6 @@ void logfs_cleanup_rw(struct super_block *sb) | |||
2272 | { | 2272 | { |
2273 | struct logfs_super *super = logfs_super(sb); | 2273 | struct logfs_super *super = logfs_super(sb); |
2274 | 2274 | ||
2275 | destroy_meta_inode(super->s_segfile_inode); | ||
2276 | logfs_mempool_destroy(super->s_block_pool); | 2275 | logfs_mempool_destroy(super->s_block_pool); |
2277 | logfs_mempool_destroy(super->s_shadow_pool); | 2276 | logfs_mempool_destroy(super->s_shadow_pool); |
2278 | } | 2277 | } |
diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c index a9657afb70ad..9d5187353255 100644 --- a/fs/logfs/segment.c +++ b/fs/logfs/segment.c | |||
@@ -929,5 +929,4 @@ void logfs_cleanup_areas(struct super_block *sb) | |||
929 | for_each_area(i) | 929 | for_each_area(i) |
930 | free_area(super->s_area[i]); | 930 | free_area(super->s_area[i]); |
931 | free_area(super->s_journal_area); | 931 | free_area(super->s_journal_area); |
932 | destroy_meta_inode(super->s_mapping_inode); | ||
933 | } | 932 | } |
diff --git a/fs/logfs/super.c b/fs/logfs/super.c index d651e10a1e9c..5336155c5d81 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c | |||
@@ -342,24 +342,27 @@ static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt) | |||
342 | goto fail; | 342 | goto fail; |
343 | } | 343 | } |
344 | 344 | ||
345 | /* at that point we know that ->put_super() will be called */ | ||
345 | super->s_erase_page = alloc_pages(GFP_KERNEL, 0); | 346 | super->s_erase_page = alloc_pages(GFP_KERNEL, 0); |
346 | if (!super->s_erase_page) | 347 | if (!super->s_erase_page) |
347 | goto fail; | 348 | return -ENOMEM; |
348 | memset(page_address(super->s_erase_page), 0xFF, PAGE_SIZE); | 349 | memset(page_address(super->s_erase_page), 0xFF, PAGE_SIZE); |
349 | 350 | ||
350 | /* FIXME: check for read-only mounts */ | 351 | /* FIXME: check for read-only mounts */ |
351 | err = logfs_make_writeable(sb); | 352 | err = logfs_make_writeable(sb); |
352 | if (err) | 353 | if (err) { |
353 | goto fail1; | 354 | __free_page(super->s_erase_page); |
355 | return err; | ||
356 | } | ||
354 | 357 | ||
355 | log_super("LogFS: Finished mounting\n"); | 358 | log_super("LogFS: Finished mounting\n"); |
356 | simple_set_mnt(mnt, sb); | 359 | simple_set_mnt(mnt, sb); |
357 | return 0; | 360 | return 0; |
358 | 361 | ||
359 | fail1: | ||
360 | __free_page(super->s_erase_page); | ||
361 | fail: | 362 | fail: |
362 | iput(logfs_super(sb)->s_master_inode); | 363 | iput(super->s_master_inode); |
364 | iput(super->s_segfile_inode); | ||
365 | iput(super->s_mapping_inode); | ||
363 | return -EIO; | 366 | return -EIO; |
364 | } | 367 | } |
365 | 368 | ||
@@ -580,10 +583,14 @@ int logfs_get_sb_device(struct file_system_type *type, int flags, | |||
580 | sb->s_flags |= MS_ACTIVE; | 583 | sb->s_flags |= MS_ACTIVE; |
581 | err = logfs_get_sb_final(sb, mnt); | 584 | err = logfs_get_sb_final(sb, mnt); |
582 | if (err) | 585 | if (err) |
583 | goto err1; | 586 | deactivate_locked_super(sb); |
584 | return 0; | 587 | return err; |
585 | 588 | ||
586 | err1: | 589 | err1: |
590 | /* no ->s_root, no ->put_super() */ | ||
591 | iput(super->s_master_inode); | ||
592 | iput(super->s_segfile_inode); | ||
593 | iput(super->s_mapping_inode); | ||
587 | deactivate_locked_super(sb); | 594 | deactivate_locked_super(sb); |
588 | return err; | 595 | return err; |
589 | err0: | 596 | err0: |