Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4

Pull ext4 fixes from Ted Ts'o:
"These are regression and bug fixes for ext4.

We had a number of new features in ext4 during this merge window
(ZERO_RANGE and COLLAPSE_RANGE fallocate modes, renameat, etc.) so
there were many more regression and bug fixes this time around. It
didn't help that xfstests hadn't been fully updated to fully stress
test COLLAPSE_RANGE until after -rc1"

* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (31 commits)
ext4: disable COLLAPSE_RANGE for bigalloc
ext4: fix COLLAPSE_RANGE failure with 1KB block size
ext4: use EINVAL if not a regular file in ext4_collapse_range()
ext4: enforce we are operating on a regular file in ext4_zero_range()
ext4: fix extent merging in ext4_ext_shift_path_extents()
ext4: discard preallocations after removing space
ext4: no need to truncate pagecache twice in collapse range
ext4: fix removing status extents in ext4_collapse_range()
ext4: use filemap_write_and_wait_range() correctly in collapse range
ext4: use truncate_pagecache() in collapse range
ext4: remove temporary shim used to merge COLLAPSE_RANGE and ZERO_RANGE
ext4: fix ext4_count_free_clusters() with EXT4FS_DEBUG and bigalloc enabled
ext4: always check ext4_ext_find_extent result
ext4: fix error handling in ext4_ext_shift_extents
ext4: silence sparse check warning for function ext4_trim_extent
ext4: COLLAPSE_RANGE only works on extent-based files
ext4: fix byte order problems introduced by the COLLAPSE_RANGE patches
ext4: use i_size_read in ext4_unaligned_aio()
fs: disallow all fallocate operation on active swapfile
fs: move falloc collapse range check into the filesystem methods
...

+187 -136
-3
fs/ceph/file.c
··· 1221 1221 if (!S_ISREG(inode->i_mode)) 1222 1222 return -EOPNOTSUPP; 1223 1223 1224 - if (IS_SWAPFILE(inode)) 1225 - return -ETXTBSY; 1226 - 1227 1224 mutex_lock(&inode->i_mutex); 1228 1225 1229 1226 if (ceph_snap(inode) != CEPH_NOSNAP) {
+1 -1
fs/ext4/balloc.c
··· 667 667 continue; 668 668 669 669 x = ext4_count_free(bitmap_bh->b_data, 670 - EXT4_BLOCKS_PER_GROUP(sb) / 8); 670 + EXT4_CLUSTERS_PER_GROUP(sb) / 8); 671 671 printk(KERN_DEBUG "group %u: stored = %d, counted = %u\n", 672 672 i, ext4_free_group_clusters(sb, gdp), x); 673 673 bitmap_count += x;
-17
fs/ext4/ext4.h
··· 2466 2466 up_write(&EXT4_I(inode)->i_data_sem); 2467 2467 } 2468 2468 2469 - /* 2470 - * Update i_disksize after writeback has been started. Races with truncate 2471 - * are avoided by checking i_size under i_data_sem. 2472 - */ 2473 - static inline void ext4_wb_update_i_disksize(struct inode *inode, loff_t newsize) 2474 - { 2475 - loff_t i_size; 2476 - 2477 - down_write(&EXT4_I(inode)->i_data_sem); 2478 - i_size = i_size_read(inode); 2479 - if (newsize > i_size) 2480 - newsize = i_size; 2481 - if (newsize > EXT4_I(inode)->i_disksize) 2482 - EXT4_I(inode)->i_disksize = newsize; 2483 - up_write(&EXT4_I(inode)->i_data_sem); 2484 - } 2485 - 2486 2469 struct ext4_group_info { 2487 2470 unsigned long bb_state; 2488 2471 struct rb_root bb_free_root;
+76 -33
fs/ext4/extents.c
··· 3313 3313 return PTR_ERR(path); 3314 3314 depth = ext_depth(inode); 3315 3315 ex = path[depth].p_ext; 3316 + if (!ex) { 3317 + EXT4_ERROR_INODE(inode, "unexpected hole at %lu", 3318 + (unsigned long) map->m_lblk); 3319 + return -EIO; 3320 + } 3316 3321 uninitialized = ext4_ext_is_uninitialized(ex); 3317 3322 split_flag1 = 0; 3318 3323 ··· 3699 3694 } 3700 3695 depth = ext_depth(inode); 3701 3696 ex = path[depth].p_ext; 3697 + if (!ex) { 3698 + EXT4_ERROR_INODE(inode, "unexpected hole at %lu", 3699 + (unsigned long) map->m_lblk); 3700 + err = -EIO; 3701 + goto out; 3702 + } 3702 3703 } 3703 3704 3704 3705 err = ext4_ext_get_access(handle, inode, path + depth); ··· 4741 4730 4742 4731 trace_ext4_zero_range(inode, offset, len, mode); 4743 4732 4733 + if (!S_ISREG(inode->i_mode)) 4734 + return -EINVAL; 4735 + 4744 4736 /* 4745 4737 * Write out all dirty pages to avoid race conditions 4746 4738 * Then release them. ··· 4892 4878 if (mode & FALLOC_FL_PUNCH_HOLE) 4893 4879 return ext4_punch_hole(inode, offset, len); 4894 4880 4895 - if (mode & FALLOC_FL_COLLAPSE_RANGE) 4896 - return ext4_collapse_range(inode, offset, len); 4897 - 4898 4881 ret = ext4_convert_inline_data(inode); 4899 4882 if (ret) 4900 4883 return ret; ··· 4902 4891 */ 4903 4892 if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) 4904 4893 return -EOPNOTSUPP; 4894 + 4895 + if (mode & FALLOC_FL_COLLAPSE_RANGE) 4896 + return ext4_collapse_range(inode, offset, len); 4905 4897 4906 4898 if (mode & FALLOC_FL_ZERO_RANGE) 4907 4899 return ext4_zero_range(file, offset, len, mode); ··· 5243 5229 if (ex_start == EXT_FIRST_EXTENT(path[depth].p_hdr)) 5244 5230 update = 1; 5245 5231 5246 - *start = ex_last->ee_block + 5232 + *start = le32_to_cpu(ex_last->ee_block) + 5247 5233 ext4_ext_get_actual_len(ex_last); 5248 5234 5249 5235 while (ex_start <= ex_last) { 5250 - ex_start->ee_block -= shift; 5251 - if (ex_start > 5252 - EXT_FIRST_EXTENT(path[depth].p_hdr)) { 5253 - if (ext4_ext_try_to_merge_right(inode, 5254 - path, ex_start - 1)) 5255 - ex_last--; 5256 - } 5257 - ex_start++; 5236 + le32_add_cpu(&ex_start->ee_block, -shift); 5237 + /* Try to merge to the left. */ 5238 + if ((ex_start > 5239 + EXT_FIRST_EXTENT(path[depth].p_hdr)) && 5240 + ext4_ext_try_to_merge_right(inode, 5241 + path, ex_start - 1)) 5242 + ex_last--; 5243 + else 5244 + ex_start++; 5258 5245 } 5259 5246 err = ext4_ext_dirty(handle, inode, path + depth); 5260 5247 if (err) ··· 5270 5255 if (err) 5271 5256 goto out; 5272 5257 5273 - path[depth].p_idx->ei_block -= shift; 5258 + le32_add_cpu(&path[depth].p_idx->ei_block, -shift); 5274 5259 err = ext4_ext_dirty(handle, inode, path + depth); 5275 5260 if (err) 5276 5261 goto out; ··· 5315 5300 return ret; 5316 5301 } 5317 5302 5318 - stop_block = extent->ee_block + ext4_ext_get_actual_len(extent); 5303 + stop_block = le32_to_cpu(extent->ee_block) + 5304 + ext4_ext_get_actual_len(extent); 5319 5305 ext4_ext_drop_refs(path); 5320 5306 kfree(path); 5321 5307 ··· 5329 5313 * enough to accomodate the shift. 5330 5314 */ 5331 5315 path = ext4_ext_find_extent(inode, start - 1, NULL, 0); 5316 + if (IS_ERR(path)) 5317 + return PTR_ERR(path); 5332 5318 depth = path->p_depth; 5333 5319 extent = path[depth].p_ext; 5334 - ex_start = extent->ee_block; 5335 - ex_end = extent->ee_block + ext4_ext_get_actual_len(extent); 5320 + if (extent) { 5321 + ex_start = le32_to_cpu(extent->ee_block); 5322 + ex_end = le32_to_cpu(extent->ee_block) + 5323 + ext4_ext_get_actual_len(extent); 5324 + } else { 5325 + ex_start = 0; 5326 + ex_end = 0; 5327 + } 5336 5328 ext4_ext_drop_refs(path); 5337 5329 kfree(path); 5338 5330 ··· 5355 5331 return PTR_ERR(path); 5356 5332 depth = path->p_depth; 5357 5333 extent = path[depth].p_ext; 5358 - current_block = extent->ee_block; 5334 + if (!extent) { 5335 + EXT4_ERROR_INODE(inode, "unexpected hole at %lu", 5336 + (unsigned long) start); 5337 + return -EIO; 5338 + } 5339 + 5340 + current_block = le32_to_cpu(extent->ee_block); 5359 5341 if (start > current_block) { 5360 5342 /* Hole, move to the next extent */ 5361 5343 ret = mext_next_extent(inode, path, &extent); ··· 5395 5365 ext4_lblk_t punch_start, punch_stop; 5396 5366 handle_t *handle; 5397 5367 unsigned int credits; 5398 - loff_t new_size; 5368 + loff_t new_size, ioffset; 5399 5369 int ret; 5400 - 5401 - BUG_ON(offset + len > i_size_read(inode)); 5402 5370 5403 5371 /* Collapse range works only on fs block size aligned offsets. */ 5404 5372 if (offset & (EXT4_BLOCK_SIZE(sb) - 1) || ··· 5404 5376 return -EINVAL; 5405 5377 5406 5378 if (!S_ISREG(inode->i_mode)) 5379 + return -EINVAL; 5380 + 5381 + if (EXT4_SB(inode->i_sb)->s_cluster_ratio > 1) 5407 5382 return -EOPNOTSUPP; 5408 5383 5409 5384 trace_ext4_collapse_range(inode, offset, len); ··· 5414 5383 punch_start = offset >> EXT4_BLOCK_SIZE_BITS(sb); 5415 5384 punch_stop = (offset + len) >> EXT4_BLOCK_SIZE_BITS(sb); 5416 5385 5386 + /* Call ext4_force_commit to flush all data in case of data=journal. */ 5387 + if (ext4_should_journal_data(inode)) { 5388 + ret = ext4_force_commit(inode->i_sb); 5389 + if (ret) 5390 + return ret; 5391 + } 5392 + 5393 + /* 5394 + * Need to round down offset to be aligned with page size boundary 5395 + * for page size > block size. 5396 + */ 5397 + ioffset = round_down(offset, PAGE_SIZE); 5398 + 5417 5399 /* Write out all dirty pages */ 5418 - ret = filemap_write_and_wait_range(inode->i_mapping, offset, -1); 5400 + ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, 5401 + LLONG_MAX); 5419 5402 if (ret) 5420 5403 return ret; 5421 5404 5422 5405 /* Take mutex lock */ 5423 5406 mutex_lock(&inode->i_mutex); 5424 5407 5425 - /* It's not possible punch hole on append only file */ 5426 - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) { 5427 - ret = -EPERM; 5428 - goto out_mutex; 5429 - } 5430 - 5431 - if (IS_SWAPFILE(inode)) { 5432 - ret = -ETXTBSY; 5408 + /* 5409 + * There is no need to overlap collapse range with EOF, in which case 5410 + * it is effectively a truncate operation 5411 + */ 5412 + if (offset + len >= i_size_read(inode)) { 5413 + ret = -EINVAL; 5433 5414 goto out_mutex; 5434 5415 } 5435 5416 ··· 5451 5408 goto out_mutex; 5452 5409 } 5453 5410 5454 - truncate_pagecache_range(inode, offset, -1); 5411 + truncate_pagecache(inode, ioffset); 5455 5412 5456 5413 /* Wait for existing dio to complete */ 5457 5414 ext4_inode_block_unlocked_dio(inode); ··· 5468 5425 ext4_discard_preallocations(inode); 5469 5426 5470 5427 ret = ext4_es_remove_extent(inode, punch_start, 5471 - EXT_MAX_BLOCKS - punch_start - 1); 5428 + EXT_MAX_BLOCKS - punch_start); 5472 5429 if (ret) { 5473 5430 up_write(&EXT4_I(inode)->i_data_sem); 5474 5431 goto out_stop; ··· 5479 5436 up_write(&EXT4_I(inode)->i_data_sem); 5480 5437 goto out_stop; 5481 5438 } 5439 + ext4_discard_preallocations(inode); 5482 5440 5483 5441 ret = ext4_ext_shift_extents(inode, handle, punch_stop, 5484 5442 punch_stop - punch_start); ··· 5489 5445 } 5490 5446 5491 5447 new_size = i_size_read(inode) - len; 5492 - truncate_setsize(inode, new_size); 5448 + i_size_write(inode, new_size); 5493 5449 EXT4_I(inode)->i_disksize = new_size; 5494 5450 5495 - ext4_discard_preallocations(inode); 5496 5451 up_write(&EXT4_I(inode)->i_data_sem); 5497 5452 if (IS_SYNC(inode)) 5498 5453 ext4_handle_sync(handle);
+1 -1
fs/ext4/extents_status.c
··· 810 810 811 811 newes.es_lblk = end + 1; 812 812 newes.es_len = len2; 813 - block = 0x7FDEADBEEF; 813 + block = 0x7FDEADBEEFULL; 814 814 if (ext4_es_is_written(&orig_es) || 815 815 ext4_es_is_unwritten(&orig_es)) 816 816 block = ext4_es_pblock(&orig_es) +
+1 -1
fs/ext4/file.c
··· 82 82 size_t count = iov_length(iov, nr_segs); 83 83 loff_t final_size = pos + count; 84 84 85 - if (pos >= inode->i_size) 85 + if (pos >= i_size_read(inode)) 86 86 return 0; 87 87 88 88 if ((pos & blockmask) || (final_size & blockmask))
+27 -24
fs/ext4/inode.c
··· 522 522 if (unlikely(map->m_len > INT_MAX)) 523 523 map->m_len = INT_MAX; 524 524 525 + /* We can handle the block number less than EXT_MAX_BLOCKS */ 526 + if (unlikely(map->m_lblk >= EXT_MAX_BLOCKS)) 527 + return -EIO; 528 + 525 529 /* Lookup extent status tree firstly */ 526 530 if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) { 527 531 ext4_es_lru_add(inode); ··· 2247 2243 return err; 2248 2244 } while (map->m_len); 2249 2245 2250 - /* Update on-disk size after IO is submitted */ 2246 + /* 2247 + * Update on-disk size after IO is submitted. Races with 2248 + * truncate are avoided by checking i_size under i_data_sem. 2249 + */ 2251 2250 disksize = ((loff_t)mpd->first_page) << PAGE_CACHE_SHIFT; 2252 2251 if (disksize > EXT4_I(inode)->i_disksize) { 2253 2252 int err2; 2253 + loff_t i_size; 2254 2254 2255 - ext4_wb_update_i_disksize(inode, disksize); 2255 + down_write(&EXT4_I(inode)->i_data_sem); 2256 + i_size = i_size_read(inode); 2257 + if (disksize > i_size) 2258 + disksize = i_size; 2259 + if (disksize > EXT4_I(inode)->i_disksize) 2260 + EXT4_I(inode)->i_disksize = disksize; 2256 2261 err2 = ext4_mark_inode_dirty(handle, inode); 2262 + up_write(&EXT4_I(inode)->i_data_sem); 2257 2263 if (err2) 2258 2264 ext4_error(inode->i_sb, 2259 2265 "Failed to mark inode %lu dirty", ··· 3541 3527 } 3542 3528 3543 3529 mutex_lock(&inode->i_mutex); 3544 - /* It's not possible punch hole on append only file */ 3545 - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) { 3546 - ret = -EPERM; 3547 - goto out_mutex; 3548 - } 3549 - if (IS_SWAPFILE(inode)) { 3550 - ret = -ETXTBSY; 3551 - goto out_mutex; 3552 - } 3553 3530 3554 3531 /* No need to punch hole beyond i_size */ 3555 3532 if (offset >= inode->i_size) ··· 3621 3616 ret = ext4_free_hole_blocks(handle, inode, first_block, 3622 3617 stop_block); 3623 3618 3624 - ext4_discard_preallocations(inode); 3625 3619 up_write(&EXT4_I(inode)->i_data_sem); 3626 3620 if (IS_SYNC(inode)) 3627 3621 ext4_handle_sync(handle); ··· 4427 4423 * 4428 4424 * We are called from a few places: 4429 4425 * 4430 - * - Within generic_file_write() for O_SYNC files. 4426 + * - Within generic_file_aio_write() -> generic_write_sync() for O_SYNC files. 4431 4427 * Here, there will be no transaction running. We wait for any running 4432 4428 * transaction to commit. 4433 4429 * 4434 - * - Within sys_sync(), kupdate and such. 4435 - * We wait on commit, if tol to. 4430 + * - Within flush work (sys_sync(), kupdate and such). 4431 + * We wait on commit, if told to. 4436 4432 * 4437 - * - Within prune_icache() (PF_MEMALLOC == true) 4438 - * Here we simply return. We can't afford to block kswapd on the 4439 - * journal commit. 4433 + * - Within iput_final() -> write_inode_now() 4434 + * We wait on commit, if told to. 4440 4435 * 4441 4436 * In all cases it is actually safe for us to return without doing anything, 4442 4437 * because the inode has been copied into a raw inode buffer in 4443 - * ext4_mark_inode_dirty(). This is a correctness thing for O_SYNC and for 4444 - * knfsd. 4438 + * ext4_mark_inode_dirty(). This is a correctness thing for WB_SYNC_ALL 4439 + * writeback. 4445 4440 * 4446 4441 * Note that we are absolutely dependent upon all inode dirtiers doing the 4447 4442 * right thing: they *must* call mark_inode_dirty() after dirtying info in ··· 4452 4449 * stuff(); 4453 4450 * inode->i_size = expr; 4454 4451 * 4455 - * is in error because a kswapd-driven write_inode() could occur while 4456 - * `stuff()' is running, and the new i_size will be lost. Plus the inode 4457 - * will no longer be on the superblock's dirty inode list. 4452 + * is in error because write_inode() could occur while `stuff()' is running, 4453 + * and the new i_size will be lost. Plus the inode will no longer be on the 4454 + * superblock's dirty inode list. 4458 4455 */ 4459 4456 int ext4_write_inode(struct inode *inode, struct writeback_control *wbc) 4460 4457 { 4461 4458 int err; 4462 4459 4463 - if (current->flags & PF_MEMALLOC) 4460 + if (WARN_ON_ONCE(current->flags & PF_MEMALLOC)) 4464 4461 return 0; 4465 4462 4466 4463 if (EXT4_SB(inode->i_sb)->s_journal) {
+14 -4
fs/ext4/mballoc.c
··· 989 989 poff = block % blocks_per_page; 990 990 page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); 991 991 if (!page) 992 - return -EIO; 992 + return -ENOMEM; 993 993 BUG_ON(page->mapping != inode->i_mapping); 994 994 e4b->bd_bitmap_page = page; 995 995 e4b->bd_bitmap = page_address(page) + (poff * sb->s_blocksize); ··· 1003 1003 pnum = block / blocks_per_page; 1004 1004 page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); 1005 1005 if (!page) 1006 - return -EIO; 1006 + return -ENOMEM; 1007 1007 BUG_ON(page->mapping != inode->i_mapping); 1008 1008 e4b->bd_buddy_page = page; 1009 1009 return 0; ··· 1168 1168 unlock_page(page); 1169 1169 } 1170 1170 } 1171 - if (page == NULL || !PageUptodate(page)) { 1171 + if (page == NULL) { 1172 + ret = -ENOMEM; 1173 + goto err; 1174 + } 1175 + if (!PageUptodate(page)) { 1172 1176 ret = -EIO; 1173 1177 goto err; 1174 1178 } ··· 1201 1197 unlock_page(page); 1202 1198 } 1203 1199 } 1204 - if (page == NULL || !PageUptodate(page)) { 1200 + if (page == NULL) { 1201 + ret = -ENOMEM; 1202 + goto err; 1203 + } 1204 + if (!PageUptodate(page)) { 1205 1205 ret = -EIO; 1206 1206 goto err; 1207 1207 } ··· 5016 5008 */ 5017 5009 static int ext4_trim_extent(struct super_block *sb, int start, int count, 5018 5010 ext4_group_t group, struct ext4_buddy *e4b) 5011 + __releases(bitlock) 5012 + __acquires(bitlock) 5019 5013 { 5020 5014 struct ext4_free_extent ex; 5021 5015 int ret = 0;
+3 -2
fs/ext4/page-io.c
··· 308 308 if (error) { 309 309 struct inode *inode = io_end->inode; 310 310 311 - ext4_warning(inode->i_sb, "I/O error writing to inode %lu " 311 + ext4_warning(inode->i_sb, "I/O error %d writing to inode %lu " 312 312 "(offset %llu size %ld starting block %llu)", 313 - inode->i_ino, 313 + error, inode->i_ino, 314 314 (unsigned long long) io_end->offset, 315 315 (long) io_end->size, 316 316 (unsigned long long) 317 317 bi_sector >> (inode->i_blkbits - 9)); 318 + mapping_set_error(inode->i_mapping, error); 318 319 } 319 320 320 321 if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
+27 -24
fs/ext4/super.c
··· 3869 3869 goto failed_mount2; 3870 3870 } 3871 3871 } 3872 + 3873 + /* 3874 + * set up enough so that it can read an inode, 3875 + * and create new inode for buddy allocator 3876 + */ 3877 + sbi->s_gdb_count = db_count; 3878 + if (!test_opt(sb, NOLOAD) && 3879 + EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) 3880 + sb->s_op = &ext4_sops; 3881 + else 3882 + sb->s_op = &ext4_nojournal_sops; 3883 + 3884 + ext4_ext_init(sb); 3885 + err = ext4_mb_init(sb); 3886 + if (err) { 3887 + ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)", 3888 + err); 3889 + goto failed_mount2; 3890 + } 3891 + 3872 3892 if (!ext4_check_descriptors(sb, &first_not_zeroed)) { 3873 3893 ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); 3874 - goto failed_mount2; 3894 + goto failed_mount2a; 3875 3895 } 3876 3896 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) 3877 3897 if (!ext4_fill_flex_info(sb)) { 3878 3898 ext4_msg(sb, KERN_ERR, 3879 3899 "unable to initialize " 3880 3900 "flex_bg meta info!"); 3881 - goto failed_mount2; 3901 + goto failed_mount2a; 3882 3902 } 3883 3903 3884 - sbi->s_gdb_count = db_count; 3885 3904 get_random_bytes(&sbi->s_next_generation, sizeof(u32)); 3886 3905 spin_lock_init(&sbi->s_next_gen_lock); 3887 3906 ··· 3935 3916 sbi->s_stripe = ext4_get_stripe_size(sbi); 3936 3917 sbi->s_extent_max_zeroout_kb = 32; 3937 3918 3938 - /* 3939 - * set up enough so that it can read an inode 3940 - */ 3941 - if (!test_opt(sb, NOLOAD) && 3942 - EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) 3943 - sb->s_op = &ext4_sops; 3944 - else 3945 - sb->s_op = &ext4_nojournal_sops; 3946 3919 sb->s_export_op = &ext4_export_ops; 3947 3920 sb->s_xattr = ext4_xattr_handlers; 3948 3921 #ifdef CONFIG_QUOTA ··· 4124 4113 if (err) { 4125 4114 ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for " 4126 4115 "reserved pool", ext4_calculate_resv_clusters(sb)); 4127 - goto failed_mount4a; 4116 + goto failed_mount5; 4128 4117 } 4129 4118 4130 4119 err = ext4_setup_system_zone(sb); 4131 4120 if (err) { 4132 4121 ext4_msg(sb, KERN_ERR, "failed to initialize system " 4133 4122 "zone (%d)", err); 4134 - goto failed_mount4a; 4135 - } 4136 - 4137 - ext4_ext_init(sb); 4138 - err = ext4_mb_init(sb); 4139 - if (err) { 4140 - ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)", 4141 - err); 4142 4123 goto failed_mount5; 4143 4124 } 4144 4125 ··· 4207 4204 failed_mount7: 4208 4205 ext4_unregister_li_request(sb); 4209 4206 failed_mount6: 4210 - ext4_mb_release(sb); 4211 - failed_mount5: 4212 - ext4_ext_release(sb); 4213 4207 ext4_release_system_zone(sb); 4214 - failed_mount4a: 4208 + failed_mount5: 4215 4209 dput(sb->s_root); 4216 4210 sb->s_root = NULL; 4217 4211 failed_mount4: ··· 4232 4232 percpu_counter_destroy(&sbi->s_extent_cache_cnt); 4233 4233 if (sbi->s_mmp_tsk) 4234 4234 kthread_stop(sbi->s_mmp_tsk); 4235 + failed_mount2a: 4236 + ext4_mb_release(sb); 4235 4237 failed_mount2: 4236 4238 for (i = 0; i < db_count; i++) 4237 4239 brelse(sbi->s_group_desc[i]); 4238 4240 ext4_kvfree(sbi->s_group_desc); 4239 4241 failed_mount: 4242 + ext4_ext_release(sb); 4240 4243 if (sbi->s_chksum_driver) 4241 4244 crypto_free_shash(sbi->s_chksum_driver); 4242 4245 if (sbi->s_proc) {
+19 -4
fs/ext4/xattr.c
··· 520 520 } 521 521 522 522 /* 523 - * Release the xattr block BH: If the reference count is > 1, decrement 524 - * it; otherwise free the block. 523 + * Release the xattr block BH: If the reference count is > 1, decrement it; 524 + * otherwise free the block. 525 525 */ 526 526 static void 527 527 ext4_xattr_release_block(handle_t *handle, struct inode *inode, ··· 542 542 if (ce) 543 543 mb_cache_entry_free(ce); 544 544 get_bh(bh); 545 + unlock_buffer(bh); 545 546 ext4_free_blocks(handle, inode, bh, 0, 1, 546 547 EXT4_FREE_BLOCKS_METADATA | 547 548 EXT4_FREE_BLOCKS_FORGET); 548 - unlock_buffer(bh); 549 549 } else { 550 550 le32_add_cpu(&BHDR(bh)->h_refcount, -1); 551 551 if (ce) 552 552 mb_cache_entry_release(ce); 553 + /* 554 + * Beware of this ugliness: Releasing of xattr block references 555 + * from different inodes can race and so we have to protect 556 + * from a race where someone else frees the block (and releases 557 + * its journal_head) before we are done dirtying the buffer. In 558 + * nojournal mode this race is harmless and we actually cannot 559 + * call ext4_handle_dirty_xattr_block() with locked buffer as 560 + * that function can call sync_dirty_buffer() so for that case 561 + * we handle the dirtying after unlocking the buffer. 562 + */ 563 + if (ext4_handle_valid(handle)) 564 + error = ext4_handle_dirty_xattr_block(handle, inode, 565 + bh); 553 566 unlock_buffer(bh); 554 - error = ext4_handle_dirty_xattr_block(handle, inode, bh); 567 + if (!ext4_handle_valid(handle)) 568 + error = ext4_handle_dirty_xattr_block(handle, inode, 569 + bh); 555 570 if (IS_SYNC(inode)) 556 571 ext4_handle_sync(handle); 557 572 dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1));
+9 -12
fs/open.c
··· 254 254 return -EBADF; 255 255 256 256 /* 257 - * It's not possible to punch hole or perform collapse range 258 - * on append only file 257 + * We can only allow pure fallocate on append only files 259 258 */ 260 - if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE) 261 - && IS_APPEND(inode)) 259 + if ((mode & ~FALLOC_FL_KEEP_SIZE) && IS_APPEND(inode)) 262 260 return -EPERM; 263 261 264 262 if (IS_IMMUTABLE(inode)) 265 263 return -EPERM; 264 + 265 + /* 266 + * We can not allow to do any fallocate operation on an active 267 + * swapfile 268 + */ 269 + if (IS_SWAPFILE(inode)) 270 + ret = -ETXTBSY; 266 271 267 272 /* 268 273 * Revalidate the write permissions, in case security policy has ··· 290 285 /* Check for wrap through zero too */ 291 286 if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0)) 292 287 return -EFBIG; 293 - 294 - /* 295 - * There is no need to overlap collapse range with EOF, in which case 296 - * it is effectively a truncate operation 297 - */ 298 - if ((mode & FALLOC_FL_COLLAPSE_RANGE) && 299 - (offset + len >= i_size_read(inode))) 300 - return -EINVAL; 301 288 302 289 if (!file->f_op->fallocate) 303 290 return -EOPNOTSUPP;
+9 -1
fs/xfs/xfs_file.c
··· 841 841 goto out_unlock; 842 842 } 843 843 844 - ASSERT(offset + len < i_size_read(inode)); 844 + /* 845 + * There is no need to overlap collapse range with EOF, 846 + * in which case it is effectively a truncate operation 847 + */ 848 + if (offset + len >= i_size_read(inode)) { 849 + error = -EINVAL; 850 + goto out_unlock; 851 + } 852 + 845 853 new_size = i_size_read(inode) - len; 846 854 847 855 error = xfs_collapse_file_space(ip, offset, len);
-9
include/trace/events/ext4.h
··· 16 16 struct ext4_map_blocks; 17 17 struct extent_status; 18 18 19 - /* shim until we merge in the xfs_collapse_range branch */ 20 - #ifndef FALLOC_FL_COLLAPSE_RANGE 21 - #define FALLOC_FL_COLLAPSE_RANGE 0x08 22 - #endif 23 - 24 - #ifndef FALLOC_FL_ZERO_RANGE 25 - #define FALLOC_FL_ZERO_RANGE 0x10 26 - #endif 27 - 28 19 #define EXT4_I(inode) (container_of(inode, struct ext4_inode_info, vfs_inode)) 29 20 30 21 #define show_mballoc_flags(flags) __print_flags(flags, "|", \