diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-13 01:25:47 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-13 01:25:47 -0500 |
| commit | a30124539b2641c5b3551193af7d21a6fc61ba98 (patch) | |
| tree | a1c7f5e641b8f44b16f1b1d201870bb7f155e8d6 | |
| parent | dd1d1399f2884102172f761816c32aa311bceafb (diff) | |
| parent | 7ba3ec5749ddb61f79f7be17b5fd7720eebc52de (diff) | |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull ext[23], udf and quota fixes from Jan Kara:
"Assorted fixes in quota, ext2, ext3 & udf.
Probably the most important is a fix of fs corruption issue in ext2
XIP support (OTOH xip is rarely used)"
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
ext2: Fix fs corruption in ext2_get_xip_mem()
quota: info leak in quota_getquota()
jbd: Revert "jbd: remove dependency on __GFP_NOFAIL"
udf: fix for pathetic mount times in case of invalid file system
ext3: Count journal as bsddf overhead in ext3_statfs
| -rw-r--r-- | fs/ext2/inode.c | 2 | ||||
| -rw-r--r-- | fs/ext2/xip.c | 1 | ||||
| -rw-r--r-- | fs/ext3/super.c | 4 | ||||
| -rw-r--r-- | fs/jbd/transaction.c | 8 | ||||
| -rw-r--r-- | fs/quota/quota.c | 1 | ||||
| -rw-r--r-- | fs/udf/super.c | 45 |
6 files changed, 48 insertions, 13 deletions
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index c260de6d7b6d..8a337640a46a 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
| @@ -632,6 +632,8 @@ static int ext2_get_blocks(struct inode *inode, | |||
| 632 | int count = 0; | 632 | int count = 0; |
| 633 | ext2_fsblk_t first_block = 0; | 633 | ext2_fsblk_t first_block = 0; |
| 634 | 634 | ||
| 635 | BUG_ON(maxblocks == 0); | ||
| 636 | |||
| 635 | depth = ext2_block_to_path(inode,iblock,offsets,&blocks_to_boundary); | 637 | depth = ext2_block_to_path(inode,iblock,offsets,&blocks_to_boundary); |
| 636 | 638 | ||
| 637 | if (depth == 0) | 639 | if (depth == 0) |
diff --git a/fs/ext2/xip.c b/fs/ext2/xip.c index 1c3312858fcf..e98171a11cfe 100644 --- a/fs/ext2/xip.c +++ b/fs/ext2/xip.c | |||
| @@ -35,6 +35,7 @@ __ext2_get_block(struct inode *inode, pgoff_t pgoff, int create, | |||
| 35 | int rc; | 35 | int rc; |
| 36 | 36 | ||
| 37 | memset(&tmp, 0, sizeof(struct buffer_head)); | 37 | memset(&tmp, 0, sizeof(struct buffer_head)); |
| 38 | tmp.b_size = 1 << inode->i_blkbits; | ||
| 38 | rc = ext2_get_block(inode, pgoff, &tmp, create); | 39 | rc = ext2_get_block(inode, pgoff, &tmp, create); |
| 39 | *result = tmp.b_blocknr; | 40 | *result = tmp.b_blocknr; |
| 40 | 41 | ||
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index c50c76190373..37fd31ed16e7 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
| @@ -2825,6 +2825,10 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
| 2825 | * bitmap, and an inode table. | 2825 | * bitmap, and an inode table. |
| 2826 | */ | 2826 | */ |
| 2827 | overhead += ngroups * (2 + sbi->s_itb_per_group); | 2827 | overhead += ngroups * (2 + sbi->s_itb_per_group); |
| 2828 | |||
| 2829 | /* Add the journal blocks as well */ | ||
| 2830 | overhead += sbi->s_journal->j_maxlen; | ||
| 2831 | |||
| 2828 | sbi->s_overhead_last = overhead; | 2832 | sbi->s_overhead_last = overhead; |
| 2829 | smp_wmb(); | 2833 | smp_wmb(); |
| 2830 | sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count); | 2834 | sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count); |
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index be0c39b66fe0..aa603e017d22 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
| 27 | #include <linux/highmem.h> | 27 | #include <linux/highmem.h> |
| 28 | #include <linux/hrtimer.h> | 28 | #include <linux/hrtimer.h> |
| 29 | #include <linux/backing-dev.h> | ||
| 30 | 29 | ||
| 31 | static void __journal_temp_unlink_buffer(struct journal_head *jh); | 30 | static void __journal_temp_unlink_buffer(struct journal_head *jh); |
| 32 | 31 | ||
| @@ -100,10 +99,11 @@ static int start_this_handle(journal_t *journal, handle_t *handle) | |||
| 100 | 99 | ||
| 101 | alloc_transaction: | 100 | alloc_transaction: |
| 102 | if (!journal->j_running_transaction) { | 101 | if (!journal->j_running_transaction) { |
| 103 | new_transaction = kzalloc(sizeof(*new_transaction), GFP_NOFS); | 102 | new_transaction = kzalloc(sizeof(*new_transaction), |
| 103 | GFP_NOFS|__GFP_NOFAIL); | ||
| 104 | if (!new_transaction) { | 104 | if (!new_transaction) { |
| 105 | congestion_wait(BLK_RW_ASYNC, HZ/50); | 105 | ret = -ENOMEM; |
| 106 | goto alloc_transaction; | 106 | goto out; |
| 107 | } | 107 | } |
| 108 | } | 108 | } |
| 109 | 109 | ||
diff --git a/fs/quota/quota.c b/fs/quota/quota.c index dea86e8967ee..2b363e23f36e 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c | |||
| @@ -117,6 +117,7 @@ static int quota_setinfo(struct super_block *sb, int type, void __user *addr) | |||
| 117 | 117 | ||
| 118 | static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src) | 118 | static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src) |
| 119 | { | 119 | { |
| 120 | memset(dst, 0, sizeof(*dst)); | ||
| 120 | dst->dqb_bhardlimit = src->d_blk_hardlimit; | 121 | dst->dqb_bhardlimit = src->d_blk_hardlimit; |
| 121 | dst->dqb_bsoftlimit = src->d_blk_softlimit; | 122 | dst->dqb_bsoftlimit = src->d_blk_softlimit; |
| 122 | dst->dqb_curspace = src->d_bcount; | 123 | dst->dqb_curspace = src->d_bcount; |
diff --git a/fs/udf/super.c b/fs/udf/super.c index 91219385691d..3306b9f69bed 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
| @@ -76,6 +76,9 @@ | |||
| 76 | 76 | ||
| 77 | #define UDF_DEFAULT_BLOCKSIZE 2048 | 77 | #define UDF_DEFAULT_BLOCKSIZE 2048 |
| 78 | 78 | ||
| 79 | #define VSD_FIRST_SECTOR_OFFSET 32768 | ||
| 80 | #define VSD_MAX_SECTOR_OFFSET 0x800000 | ||
| 81 | |||
| 79 | enum { UDF_MAX_LINKS = 0xffff }; | 82 | enum { UDF_MAX_LINKS = 0xffff }; |
| 80 | 83 | ||
| 81 | /* These are the "meat" - everything else is stuffing */ | 84 | /* These are the "meat" - everything else is stuffing */ |
| @@ -685,7 +688,7 @@ out_unlock: | |||
| 685 | static loff_t udf_check_vsd(struct super_block *sb) | 688 | static loff_t udf_check_vsd(struct super_block *sb) |
| 686 | { | 689 | { |
| 687 | struct volStructDesc *vsd = NULL; | 690 | struct volStructDesc *vsd = NULL; |
| 688 | loff_t sector = 32768; | 691 | loff_t sector = VSD_FIRST_SECTOR_OFFSET; |
| 689 | int sectorsize; | 692 | int sectorsize; |
| 690 | struct buffer_head *bh = NULL; | 693 | struct buffer_head *bh = NULL; |
| 691 | int nsr02 = 0; | 694 | int nsr02 = 0; |
| @@ -703,8 +706,18 @@ static loff_t udf_check_vsd(struct super_block *sb) | |||
| 703 | udf_debug("Starting at sector %u (%ld byte sectors)\n", | 706 | udf_debug("Starting at sector %u (%ld byte sectors)\n", |
| 704 | (unsigned int)(sector >> sb->s_blocksize_bits), | 707 | (unsigned int)(sector >> sb->s_blocksize_bits), |
| 705 | sb->s_blocksize); | 708 | sb->s_blocksize); |
| 706 | /* Process the sequence (if applicable) */ | 709 | /* Process the sequence (if applicable). The hard limit on the sector |
| 707 | for (; !nsr02 && !nsr03; sector += sectorsize) { | 710 | * offset is arbitrary, hopefully large enough so that all valid UDF |
| 711 | * filesystems will be recognised. There is no mention of an upper | ||
| 712 | * bound to the size of the volume recognition area in the standard. | ||
| 713 | * The limit will prevent the code to read all the sectors of a | ||
| 714 | * specially crafted image (like a bluray disc full of CD001 sectors), | ||
| 715 | * potentially causing minutes or even hours of uninterruptible I/O | ||
| 716 | * activity. This actually happened with uninitialised SSD partitions | ||
| 717 | * (all 0xFF) before the check for the limit and all valid IDs were | ||
| 718 | * added */ | ||
| 719 | for (; !nsr02 && !nsr03 && sector < VSD_MAX_SECTOR_OFFSET; | ||
| 720 | sector += sectorsize) { | ||
| 708 | /* Read a block */ | 721 | /* Read a block */ |
| 709 | bh = udf_tread(sb, sector >> sb->s_blocksize_bits); | 722 | bh = udf_tread(sb, sector >> sb->s_blocksize_bits); |
| 710 | if (!bh) | 723 | if (!bh) |
| @@ -714,10 +727,7 @@ static loff_t udf_check_vsd(struct super_block *sb) | |||
| 714 | vsd = (struct volStructDesc *)(bh->b_data + | 727 | vsd = (struct volStructDesc *)(bh->b_data + |
| 715 | (sector & (sb->s_blocksize - 1))); | 728 | (sector & (sb->s_blocksize - 1))); |
| 716 | 729 | ||
| 717 | if (vsd->stdIdent[0] == 0) { | 730 | if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, |
| 718 | brelse(bh); | ||
| 719 | break; | ||
| 720 | } else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, | ||
| 721 | VSD_STD_ID_LEN)) { | 731 | VSD_STD_ID_LEN)) { |
| 722 | switch (vsd->structType) { | 732 | switch (vsd->structType) { |
| 723 | case 0: | 733 | case 0: |
| @@ -753,6 +763,17 @@ static loff_t udf_check_vsd(struct super_block *sb) | |||
| 753 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03, | 763 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03, |
| 754 | VSD_STD_ID_LEN)) | 764 | VSD_STD_ID_LEN)) |
| 755 | nsr03 = sector; | 765 | nsr03 = sector; |
| 766 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BOOT2, | ||
| 767 | VSD_STD_ID_LEN)) | ||
| 768 | ; /* nothing */ | ||
| 769 | else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CDW02, | ||
| 770 | VSD_STD_ID_LEN)) | ||
| 771 | ; /* nothing */ | ||
| 772 | else { | ||
| 773 | /* invalid id : end of volume recognition area */ | ||
| 774 | brelse(bh); | ||
| 775 | break; | ||
| 776 | } | ||
| 756 | brelse(bh); | 777 | brelse(bh); |
| 757 | } | 778 | } |
| 758 | 779 | ||
| @@ -760,7 +781,8 @@ static loff_t udf_check_vsd(struct super_block *sb) | |||
| 760 | return nsr03; | 781 | return nsr03; |
| 761 | else if (nsr02) | 782 | else if (nsr02) |
| 762 | return nsr02; | 783 | return nsr02; |
| 763 | else if (sector - (sbi->s_session << sb->s_blocksize_bits) == 32768) | 784 | else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) == |
| 785 | VSD_FIRST_SECTOR_OFFSET) | ||
| 764 | return -1; | 786 | return -1; |
| 765 | else | 787 | else |
| 766 | return 0; | 788 | return 0; |
| @@ -1270,6 +1292,9 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block) | |||
| 1270 | * PHYSICAL partitions are already set up | 1292 | * PHYSICAL partitions are already set up |
| 1271 | */ | 1293 | */ |
| 1272 | type1_idx = i; | 1294 | type1_idx = i; |
| 1295 | #ifdef UDFFS_DEBUG | ||
| 1296 | map = NULL; /* supress 'maybe used uninitialized' warning */ | ||
| 1297 | #endif | ||
| 1273 | for (i = 0; i < sbi->s_partitions; i++) { | 1298 | for (i = 0; i < sbi->s_partitions; i++) { |
| 1274 | map = &sbi->s_partmaps[i]; | 1299 | map = &sbi->s_partmaps[i]; |
| 1275 | 1300 | ||
| @@ -1891,7 +1916,9 @@ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt, | |||
| 1891 | return 0; | 1916 | return 0; |
| 1892 | } | 1917 | } |
| 1893 | if (nsr_off == -1) | 1918 | if (nsr_off == -1) |
| 1894 | udf_debug("Failed to read byte 32768. Assuming open disc. Skipping validity check\n"); | 1919 | udf_debug("Failed to read sector at offset %d. " |
| 1920 | "Assuming open disc. Skipping validity " | ||
| 1921 | "check\n", VSD_FIRST_SECTOR_OFFSET); | ||
| 1895 | if (!sbi->s_last_block) | 1922 | if (!sbi->s_last_block) |
| 1896 | sbi->s_last_block = udf_get_last_block(sb); | 1923 | sbi->s_last_block = udf_get_last_block(sb); |
| 1897 | } else { | 1924 | } else { |
