Commit 19c6e12c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull ext2, udf, reiserfs fixes from Jan Kara:
 "Several ext2, udf, and reiserfs fixes"

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
  ext2: Fix memory leak when truncate races ext2_get_blocks
  reiserfs: fix race in prealloc discard
  reiserfs: don't preallocate blocks for extended attributes
  udf: Convert udf_disk_stamp_to_time() to use mktime64()
  udf: Use time64_to_tm for timestamp conversion
  udf: Fix deadlock between writeback and udf_setsize()
  udf: Use i_size_read() in udf_adinicb_writepage()
  udf: Fix races with i_size changes during readpage
  udf: Remove unused UDF_DEFAULT_BLOCKSIZE
parents 954e6e03 4d9bcadd
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -659,6 +659,7 @@ static int ext2_get_blocks(struct inode *inode,
				 */
				 */
				err = -EAGAIN;
				err = -EAGAIN;
				count = 0;
				count = 0;
				partial = chain + depth - 1;
				break;
				break;
			}
			}
			blk = le32_to_cpu(*(chain[depth-1].p + count));
			blk = le32_to_cpu(*(chain[depth-1].p + count));
+11 −3
Original line number Original line Diff line number Diff line
@@ -513,9 +513,17 @@ static void __discard_prealloc(struct reiserfs_transaction_handle *th,
			       "inode has negative prealloc blocks count.");
			       "inode has negative prealloc blocks count.");
#endif
#endif
	while (ei->i_prealloc_count > 0) {
	while (ei->i_prealloc_count > 0) {
		reiserfs_free_prealloc_block(th, inode, ei->i_prealloc_block);
		b_blocknr_t block_to_free;
		ei->i_prealloc_block++;

		/*
		 * reiserfs_free_prealloc_block can drop the write lock,
		 * which could allow another caller to free the same block.
		 * We can protect against it by modifying the prealloc
		 * state before calling it.
		 */
		block_to_free = ei->i_prealloc_block++;
		ei->i_prealloc_count--;
		ei->i_prealloc_count--;
		reiserfs_free_prealloc_block(th, inode, block_to_free);
		dirty = 1;
		dirty = 1;
	}
	}
	if (dirty)
	if (dirty)
@@ -1128,7 +1136,7 @@ static int determine_prealloc_size(reiserfs_blocknr_hint_t * hint)
	hint->prealloc_size = 0;
	hint->prealloc_size = 0;


	if (!hint->formatted_node && hint->preallocate) {
	if (!hint->formatted_node && hint->preallocate) {
		if (S_ISREG(hint->inode->i_mode)
		if (S_ISREG(hint->inode->i_mode) && !IS_PRIVATE(hint->inode)
		    && hint->inode->i_size >=
		    && hint->inode->i_size >=
		    REISERFS_SB(hint->th->t_super)->s_alloc_options.
		    REISERFS_SB(hint->th->t_super)->s_alloc_options.
		    preallocmin * hint->inode->i_sb->s_blocksize)
		    preallocmin * hint->inode->i_sb->s_blocksize)
+9 −3
Original line number Original line Diff line number Diff line
@@ -43,10 +43,15 @@ static void __udf_adinicb_readpage(struct page *page)
	struct inode *inode = page->mapping->host;
	struct inode *inode = page->mapping->host;
	char *kaddr;
	char *kaddr;
	struct udf_inode_info *iinfo = UDF_I(inode);
	struct udf_inode_info *iinfo = UDF_I(inode);
	loff_t isize = i_size_read(inode);


	/*
	 * We have to be careful here as truncate can change i_size under us.
	 * So just sample it once and use the same value everywhere.
	 */
	kaddr = kmap_atomic(page);
	kaddr = kmap_atomic(page);
	memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, inode->i_size);
	memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, isize);
	memset(kaddr + inode->i_size, 0, PAGE_SIZE - inode->i_size);
	memset(kaddr + isize, 0, PAGE_SIZE - isize);
	flush_dcache_page(page);
	flush_dcache_page(page);
	SetPageUptodate(page);
	SetPageUptodate(page);
	kunmap_atomic(kaddr);
	kunmap_atomic(kaddr);
@@ -71,7 +76,8 @@ static int udf_adinicb_writepage(struct page *page,
	BUG_ON(!PageLocked(page));
	BUG_ON(!PageLocked(page));


	kaddr = kmap_atomic(page);
	kaddr = kmap_atomic(page);
	memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr, inode->i_size);
	memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr,
		i_size_read(inode));
	SetPageUptodate(page);
	SetPageUptodate(page);
	kunmap_atomic(kaddr);
	kunmap_atomic(kaddr);
	mark_inode_dirty(inode);
	mark_inode_dirty(inode);
+2 −2
Original line number Original line Diff line number Diff line
@@ -1222,8 +1222,8 @@ int udf_setsize(struct inode *inode, loff_t newsize)
			return err;
			return err;
		}
		}
set_size:
set_size:
		truncate_setsize(inode, newsize);
		up_write(&iinfo->i_data_sem);
		up_write(&iinfo->i_data_sem);
		truncate_setsize(inode, newsize);
	} else {
	} else {
		if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
		if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
			down_write(&iinfo->i_data_sem);
			down_write(&iinfo->i_data_sem);
@@ -1240,9 +1240,9 @@ set_size:
					  udf_get_block);
					  udf_get_block);
		if (err)
		if (err)
			return err;
			return err;
		truncate_setsize(inode, newsize);
		down_write(&iinfo->i_data_sem);
		down_write(&iinfo->i_data_sem);
		udf_clear_extent_cache(inode);
		udf_clear_extent_cache(inode);
		truncate_setsize(inode, newsize);
		udf_truncate_extents(inode);
		udf_truncate_extents(inode);
		up_write(&iinfo->i_data_sem);
		up_write(&iinfo->i_data_sem);
	}
	}
+0 −2
Original line number Original line Diff line number Diff line
@@ -73,8 +73,6 @@
#define VDS_POS_TERMINATING_DESC	6
#define VDS_POS_TERMINATING_DESC	6
#define VDS_POS_LENGTH			7
#define VDS_POS_LENGTH			7


#define UDF_DEFAULT_BLOCKSIZE 2048

#define VSD_FIRST_SECTOR_OFFSET		32768
#define VSD_FIRST_SECTOR_OFFSET		32768
#define VSD_MAX_SECTOR_OFFSET		0x800000
#define VSD_MAX_SECTOR_OFFSET		0x800000


Loading