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
This commit is contained in:
commit
a30124539b
@ -632,6 +632,8 @@ static int ext2_get_blocks(struct inode *inode,
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
ext2_fsblk_t first_block = 0;
|
ext2_fsblk_t first_block = 0;
|
||||||
|
|
||||||
|
BUG_ON(maxblocks == 0);
|
||||||
|
|
||||||
depth = ext2_block_to_path(inode,iblock,offsets,&blocks_to_boundary);
|
depth = ext2_block_to_path(inode,iblock,offsets,&blocks_to_boundary);
|
||||||
|
|
||||||
if (depth == 0)
|
if (depth == 0)
|
||||||
|
@ -35,6 +35,7 @@ __ext2_get_block(struct inode *inode, pgoff_t pgoff, int create,
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
memset(&tmp, 0, sizeof(struct buffer_head));
|
memset(&tmp, 0, sizeof(struct buffer_head));
|
||||||
|
tmp.b_size = 1 << inode->i_blkbits;
|
||||||
rc = ext2_get_block(inode, pgoff, &tmp, create);
|
rc = ext2_get_block(inode, pgoff, &tmp, create);
|
||||||
*result = tmp.b_blocknr;
|
*result = tmp.b_blocknr;
|
||||||
|
|
||||||
|
@ -2825,6 +2825,10 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf)
|
|||||||
* bitmap, and an inode table.
|
* bitmap, and an inode table.
|
||||||
*/
|
*/
|
||||||
overhead += ngroups * (2 + sbi->s_itb_per_group);
|
overhead += ngroups * (2 + sbi->s_itb_per_group);
|
||||||
|
|
||||||
|
/* Add the journal blocks as well */
|
||||||
|
overhead += sbi->s_journal->j_maxlen;
|
||||||
|
|
||||||
sbi->s_overhead_last = overhead;
|
sbi->s_overhead_last = overhead;
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);
|
sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count);
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/highmem.h>
|
#include <linux/highmem.h>
|
||||||
#include <linux/hrtimer.h>
|
#include <linux/hrtimer.h>
|
||||||
#include <linux/backing-dev.h>
|
|
||||||
|
|
||||||
static void __journal_temp_unlink_buffer(struct journal_head *jh);
|
static void __journal_temp_unlink_buffer(struct journal_head *jh);
|
||||||
|
|
||||||
@ -100,10 +99,11 @@ static int start_this_handle(journal_t *journal, handle_t *handle)
|
|||||||
|
|
||||||
alloc_transaction:
|
alloc_transaction:
|
||||||
if (!journal->j_running_transaction) {
|
if (!journal->j_running_transaction) {
|
||||||
new_transaction = kzalloc(sizeof(*new_transaction), GFP_NOFS);
|
new_transaction = kzalloc(sizeof(*new_transaction),
|
||||||
|
GFP_NOFS|__GFP_NOFAIL);
|
||||||
if (!new_transaction) {
|
if (!new_transaction) {
|
||||||
congestion_wait(BLK_RW_ASYNC, HZ/50);
|
ret = -ENOMEM;
|
||||||
goto alloc_transaction;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +117,7 @@ static int quota_setinfo(struct super_block *sb, int type, void __user *addr)
|
|||||||
|
|
||||||
static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src)
|
static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src)
|
||||||
{
|
{
|
||||||
|
memset(dst, 0, sizeof(*dst));
|
||||||
dst->dqb_bhardlimit = src->d_blk_hardlimit;
|
dst->dqb_bhardlimit = src->d_blk_hardlimit;
|
||||||
dst->dqb_bsoftlimit = src->d_blk_softlimit;
|
dst->dqb_bsoftlimit = src->d_blk_softlimit;
|
||||||
dst->dqb_curspace = src->d_bcount;
|
dst->dqb_curspace = src->d_bcount;
|
||||||
|
@ -76,6 +76,9 @@
|
|||||||
|
|
||||||
#define UDF_DEFAULT_BLOCKSIZE 2048
|
#define UDF_DEFAULT_BLOCKSIZE 2048
|
||||||
|
|
||||||
|
#define VSD_FIRST_SECTOR_OFFSET 32768
|
||||||
|
#define VSD_MAX_SECTOR_OFFSET 0x800000
|
||||||
|
|
||||||
enum { UDF_MAX_LINKS = 0xffff };
|
enum { UDF_MAX_LINKS = 0xffff };
|
||||||
|
|
||||||
/* These are the "meat" - everything else is stuffing */
|
/* These are the "meat" - everything else is stuffing */
|
||||||
@ -685,7 +688,7 @@ out_unlock:
|
|||||||
static loff_t udf_check_vsd(struct super_block *sb)
|
static loff_t udf_check_vsd(struct super_block *sb)
|
||||||
{
|
{
|
||||||
struct volStructDesc *vsd = NULL;
|
struct volStructDesc *vsd = NULL;
|
||||||
loff_t sector = 32768;
|
loff_t sector = VSD_FIRST_SECTOR_OFFSET;
|
||||||
int sectorsize;
|
int sectorsize;
|
||||||
struct buffer_head *bh = NULL;
|
struct buffer_head *bh = NULL;
|
||||||
int nsr02 = 0;
|
int nsr02 = 0;
|
||||||
@ -703,8 +706,18 @@ static loff_t udf_check_vsd(struct super_block *sb)
|
|||||||
udf_debug("Starting at sector %u (%ld byte sectors)\n",
|
udf_debug("Starting at sector %u (%ld byte sectors)\n",
|
||||||
(unsigned int)(sector >> sb->s_blocksize_bits),
|
(unsigned int)(sector >> sb->s_blocksize_bits),
|
||||||
sb->s_blocksize);
|
sb->s_blocksize);
|
||||||
/* Process the sequence (if applicable) */
|
/* Process the sequence (if applicable). The hard limit on the sector
|
||||||
for (; !nsr02 && !nsr03; sector += sectorsize) {
|
* offset is arbitrary, hopefully large enough so that all valid UDF
|
||||||
|
* filesystems will be recognised. There is no mention of an upper
|
||||||
|
* bound to the size of the volume recognition area in the standard.
|
||||||
|
* The limit will prevent the code to read all the sectors of a
|
||||||
|
* specially crafted image (like a bluray disc full of CD001 sectors),
|
||||||
|
* potentially causing minutes or even hours of uninterruptible I/O
|
||||||
|
* activity. This actually happened with uninitialised SSD partitions
|
||||||
|
* (all 0xFF) before the check for the limit and all valid IDs were
|
||||||
|
* added */
|
||||||
|
for (; !nsr02 && !nsr03 && sector < VSD_MAX_SECTOR_OFFSET;
|
||||||
|
sector += sectorsize) {
|
||||||
/* Read a block */
|
/* Read a block */
|
||||||
bh = udf_tread(sb, sector >> sb->s_blocksize_bits);
|
bh = udf_tread(sb, sector >> sb->s_blocksize_bits);
|
||||||
if (!bh)
|
if (!bh)
|
||||||
@ -714,10 +727,7 @@ static loff_t udf_check_vsd(struct super_block *sb)
|
|||||||
vsd = (struct volStructDesc *)(bh->b_data +
|
vsd = (struct volStructDesc *)(bh->b_data +
|
||||||
(sector & (sb->s_blocksize - 1)));
|
(sector & (sb->s_blocksize - 1)));
|
||||||
|
|
||||||
if (vsd->stdIdent[0] == 0) {
|
if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001,
|
||||||
brelse(bh);
|
|
||||||
break;
|
|
||||||
} else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001,
|
|
||||||
VSD_STD_ID_LEN)) {
|
VSD_STD_ID_LEN)) {
|
||||||
switch (vsd->structType) {
|
switch (vsd->structType) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -753,6 +763,17 @@ static loff_t udf_check_vsd(struct super_block *sb)
|
|||||||
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03,
|
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03,
|
||||||
VSD_STD_ID_LEN))
|
VSD_STD_ID_LEN))
|
||||||
nsr03 = sector;
|
nsr03 = sector;
|
||||||
|
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BOOT2,
|
||||||
|
VSD_STD_ID_LEN))
|
||||||
|
; /* nothing */
|
||||||
|
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CDW02,
|
||||||
|
VSD_STD_ID_LEN))
|
||||||
|
; /* nothing */
|
||||||
|
else {
|
||||||
|
/* invalid id : end of volume recognition area */
|
||||||
|
brelse(bh);
|
||||||
|
break;
|
||||||
|
}
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -760,7 +781,8 @@ static loff_t udf_check_vsd(struct super_block *sb)
|
|||||||
return nsr03;
|
return nsr03;
|
||||||
else if (nsr02)
|
else if (nsr02)
|
||||||
return nsr02;
|
return nsr02;
|
||||||
else if (sector - (sbi->s_session << sb->s_blocksize_bits) == 32768)
|
else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) ==
|
||||||
|
VSD_FIRST_SECTOR_OFFSET)
|
||||||
return -1;
|
return -1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
@ -1270,6 +1292,9 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block)
|
|||||||
* PHYSICAL partitions are already set up
|
* PHYSICAL partitions are already set up
|
||||||
*/
|
*/
|
||||||
type1_idx = i;
|
type1_idx = i;
|
||||||
|
#ifdef UDFFS_DEBUG
|
||||||
|
map = NULL; /* supress 'maybe used uninitialized' warning */
|
||||||
|
#endif
|
||||||
for (i = 0; i < sbi->s_partitions; i++) {
|
for (i = 0; i < sbi->s_partitions; i++) {
|
||||||
map = &sbi->s_partmaps[i];
|
map = &sbi->s_partmaps[i];
|
||||||
|
|
||||||
@ -1891,7 +1916,9 @@ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (nsr_off == -1)
|
if (nsr_off == -1)
|
||||||
udf_debug("Failed to read byte 32768. Assuming open disc. Skipping validity check\n");
|
udf_debug("Failed to read sector at offset %d. "
|
||||||
|
"Assuming open disc. Skipping validity "
|
||||||
|
"check\n", VSD_FIRST_SECTOR_OFFSET);
|
||||||
if (!sbi->s_last_block)
|
if (!sbi->s_last_block)
|
||||||
sbi->s_last_block = udf_get_last_block(sb);
|
sbi->s_last_block = udf_get_last_block(sb);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user