diff options
| author | Ingo Molnar <mingo@elte.hu> | 2010-08-12 15:38:56 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-08-12 15:39:04 -0400 |
| commit | f46a6804135795f77d096ab0128f27531c7d051c (patch) | |
| tree | 7cd33f69e3661327739ae4c96e5a8389e7fc912e /fs/logfs | |
| parent | b3e84ffa21f916e3354a12a7f19169c9febe96d0 (diff) | |
| parent | ad41a1e0cab07c5125456e8d38e5b1ab148d04aa (diff) | |
Merge branch 'linus' into perf/urgent
Merge reason: Fix upstream breakage introduced by:
de5d9bf: Move list types from <linux/list.h> to <linux/types.h>.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
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: |
