diff options
Diffstat (limited to 'fs/logfs')
-rw-r--r-- | fs/logfs/dir.c | 5 | ||||
-rw-r--r-- | fs/logfs/file.c | 18 | ||||
-rw-r--r-- | fs/logfs/inode.c | 51 | ||||
-rw-r--r-- | fs/logfs/journal.c | 2 | ||||
-rw-r--r-- | fs/logfs/logfs.h | 4 | ||||
-rw-r--r-- | fs/logfs/readwrite.c | 62 | ||||
-rw-r--r-- | fs/logfs/segment.c | 1 | ||||
-rw-r--r-- | fs/logfs/super.c | 23 |
8 files changed, 79 insertions, 87 deletions
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index 72d1893ddd36..675cc49197fe 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c | |||
@@ -434,8 +434,11 @@ static int __logfs_create(struct inode *dir, struct dentry *dentry, | |||
434 | int ret; | 434 | int ret; |
435 | 435 | ||
436 | ta = kzalloc(sizeof(*ta), GFP_KERNEL); | 436 | ta = kzalloc(sizeof(*ta), GFP_KERNEL); |
437 | if (!ta) | 437 | if (!ta) { |
438 | inode->i_nlink--; | ||
439 | iput(inode); | ||
438 | return -ENOMEM; | 440 | return -ENOMEM; |
441 | } | ||
439 | 442 | ||
440 | ta->state = CREATE_1; | 443 | ta->state = CREATE_1; |
441 | ta->ino = inode->i_ino; | 444 | ta->ino = inode->i_ino; |
diff --git a/fs/logfs/file.c b/fs/logfs/file.c index abe1cafbd4c2..4dd0f7c06e39 100644 --- a/fs/logfs/file.c +++ b/fs/logfs/file.c | |||
@@ -232,15 +232,19 @@ static int logfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
232 | struct inode *inode = dentry->d_inode; | 232 | struct inode *inode = dentry->d_inode; |
233 | int err = 0; | 233 | int err = 0; |
234 | 234 | ||
235 | if (attr->ia_valid & ATTR_SIZE) | 235 | err = inode_change_ok(inode, attr); |
236 | if (err) | ||
237 | return err; | ||
238 | |||
239 | if (attr->ia_valid & ATTR_SIZE) { | ||
236 | err = logfs_truncate(inode, attr->ia_size); | 240 | err = logfs_truncate(inode, attr->ia_size); |
237 | attr->ia_valid &= ~ATTR_SIZE; | 241 | if (err) |
242 | return err; | ||
243 | } | ||
238 | 244 | ||
239 | if (!err) | 245 | setattr_copy(inode, attr); |
240 | err = inode_change_ok(inode, attr); | 246 | mark_inode_dirty(inode); |
241 | if (!err) | 247 | return 0; |
242 | err = inode_setattr(inode, attr); | ||
243 | return err; | ||
244 | } | 248 | } |
245 | 249 | ||
246 | const struct inode_operations logfs_reg_iops = { | 250 | const struct inode_operations logfs_reg_iops = { |
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c index f602e230e162..d8c71ece098f 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,18 +286,8 @@ 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 int logfs_drop_inode(struct inode *inode) |
313 | { | 291 | { |
314 | struct logfs_super *super = logfs_super(inode->i_sb); | 292 | struct logfs_super *super = logfs_super(inode->i_sb); |
315 | struct logfs_inode *li = logfs_inode(inode); | 293 | struct logfs_inode *li = logfs_inode(inode); |
@@ -317,7 +295,7 @@ static void logfs_drop_inode(struct inode *inode) | |||
317 | spin_lock(&logfs_inode_lock); | 295 | spin_lock(&logfs_inode_lock); |
318 | list_move(&li->li_freeing_list, &super->s_freeing_list); | 296 | list_move(&li->li_freeing_list, &super->s_freeing_list); |
319 | spin_unlock(&logfs_inode_lock); | 297 | spin_unlock(&logfs_inode_lock); |
320 | generic_drop_inode(inode); | 298 | return generic_drop_inode(inode); |
321 | } | 299 | } |
322 | 300 | ||
323 | static void logfs_set_ino_generation(struct super_block *sb, | 301 | static void logfs_set_ino_generation(struct super_block *sb, |
@@ -384,12 +362,21 @@ 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, | ||
390 | .delete_inode = logfs_delete_inode, | ||
391 | .destroy_inode = logfs_destroy_inode, | 376 | .destroy_inode = logfs_destroy_inode, |
377 | .evict_inode = logfs_evict_inode, | ||
392 | .drop_inode = logfs_drop_inode, | 378 | .drop_inode = logfs_drop_inode, |
379 | .put_super = logfs_put_super, | ||
393 | .write_inode = logfs_write_inode, | 380 | .write_inode = logfs_write_inode, |
394 | .statfs = logfs_statfs, | 381 | .statfs = logfs_statfs, |
395 | .sync_fs = logfs_sync_fs, | 382 | .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..5e3b72077951 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h | |||
@@ -525,13 +525,11 @@ 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); |
532 | int __logfs_write_inode(struct inode *inode, long flags); | 531 | int __logfs_write_inode(struct inode *inode, long flags); |
533 | void logfs_delete_inode(struct inode *inode); | 532 | void logfs_evict_inode(struct inode *inode); |
534 | void logfs_clear_inode(struct inode *inode); | ||
535 | 533 | ||
536 | /* journal.c */ | 534 | /* journal.c */ |
537 | void logfs_write_anchor(struct super_block *sb); | 535 | void logfs_write_anchor(struct super_block *sb); |
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index 0718d112a1a5..6127baf0e188 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c | |||
@@ -1972,31 +1972,6 @@ static struct page *inode_to_page(struct inode *inode) | |||
1972 | return page; | 1972 | return page; |
1973 | } | 1973 | } |
1974 | 1974 | ||
1975 | /* Cheaper version of write_inode. All changes are concealed in | ||
1976 | * aliases, which are moved back. No write to the medium happens. | ||
1977 | */ | ||
1978 | void logfs_clear_inode(struct inode *inode) | ||
1979 | { | ||
1980 | struct super_block *sb = inode->i_sb; | ||
1981 | struct logfs_inode *li = logfs_inode(inode); | ||
1982 | struct logfs_block *block = li->li_block; | ||
1983 | struct page *page; | ||
1984 | |||
1985 | /* Only deleted files may be dirty at this point */ | ||
1986 | BUG_ON(inode->i_state & I_DIRTY && inode->i_nlink); | ||
1987 | if (!block) | ||
1988 | return; | ||
1989 | if ((logfs_super(sb)->s_flags & LOGFS_SB_FLAG_SHUTDOWN)) { | ||
1990 | block->ops->free_block(inode->i_sb, block); | ||
1991 | return; | ||
1992 | } | ||
1993 | |||
1994 | BUG_ON(inode->i_ino < LOGFS_RESERVED_INOS); | ||
1995 | page = inode_to_page(inode); | ||
1996 | BUG_ON(!page); /* FIXME: Use emergency page */ | ||
1997 | logfs_put_write_page(page); | ||
1998 | } | ||
1999 | |||
2000 | static int do_write_inode(struct inode *inode) | 1975 | static int do_write_inode(struct inode *inode) |
2001 | { | 1976 | { |
2002 | struct super_block *sb = inode->i_sb; | 1977 | struct super_block *sb = inode->i_sb; |
@@ -2164,18 +2139,40 @@ static int do_delete_inode(struct inode *inode) | |||
2164 | * ZOMBIE inodes have already been deleted before and should remain dead, | 2139 | * ZOMBIE inodes have already been deleted before and should remain dead, |
2165 | * if it weren't for valid checking. No need to kill them again here. | 2140 | * if it weren't for valid checking. No need to kill them again here. |
2166 | */ | 2141 | */ |
2167 | void logfs_delete_inode(struct inode *inode) | 2142 | void logfs_evict_inode(struct inode *inode) |
2168 | { | 2143 | { |
2144 | struct super_block *sb = inode->i_sb; | ||
2169 | struct logfs_inode *li = logfs_inode(inode); | 2145 | struct logfs_inode *li = logfs_inode(inode); |
2146 | struct logfs_block *block = li->li_block; | ||
2147 | struct page *page; | ||
2170 | 2148 | ||
2171 | if (!(li->li_flags & LOGFS_IF_ZOMBIE)) { | 2149 | if (!inode->i_nlink) { |
2172 | li->li_flags |= LOGFS_IF_ZOMBIE; | 2150 | if (!(li->li_flags & LOGFS_IF_ZOMBIE)) { |
2173 | if (i_size_read(inode) > 0) | 2151 | li->li_flags |= LOGFS_IF_ZOMBIE; |
2174 | logfs_truncate(inode, 0); | 2152 | if (i_size_read(inode) > 0) |
2175 | do_delete_inode(inode); | 2153 | logfs_truncate(inode, 0); |
2154 | do_delete_inode(inode); | ||
2155 | } | ||
2176 | } | 2156 | } |
2177 | truncate_inode_pages(&inode->i_data, 0); | 2157 | truncate_inode_pages(&inode->i_data, 0); |
2178 | clear_inode(inode); | 2158 | end_writeback(inode); |
2159 | |||
2160 | /* Cheaper version of write_inode. All changes are concealed in | ||
2161 | * aliases, which are moved back. No write to the medium happens. | ||
2162 | */ | ||
2163 | /* Only deleted files may be dirty at this point */ | ||
2164 | BUG_ON(inode->i_state & I_DIRTY && inode->i_nlink); | ||
2165 | if (!block) | ||
2166 | return; | ||
2167 | if ((logfs_super(sb)->s_flags & LOGFS_SB_FLAG_SHUTDOWN)) { | ||
2168 | block->ops->free_block(inode->i_sb, block); | ||
2169 | return; | ||
2170 | } | ||
2171 | |||
2172 | BUG_ON(inode->i_ino < LOGFS_RESERVED_INOS); | ||
2173 | page = inode_to_page(inode); | ||
2174 | BUG_ON(!page); /* FIXME: Use emergency page */ | ||
2175 | logfs_put_write_page(page); | ||
2179 | } | 2176 | } |
2180 | 2177 | ||
2181 | void btree_write_block(struct logfs_block *block) | 2178 | void btree_write_block(struct logfs_block *block) |
@@ -2272,7 +2269,6 @@ void logfs_cleanup_rw(struct super_block *sb) | |||
2272 | { | 2269 | { |
2273 | struct logfs_super *super = logfs_super(sb); | 2270 | struct logfs_super *super = logfs_super(sb); |
2274 | 2271 | ||
2275 | destroy_meta_inode(super->s_segfile_inode); | ||
2276 | logfs_mempool_destroy(super->s_block_pool); | 2272 | logfs_mempool_destroy(super->s_block_pool); |
2277 | logfs_mempool_destroy(super->s_shadow_pool); | 2273 | logfs_mempool_destroy(super->s_shadow_pool); |
2278 | } | 2274 | } |
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: |