lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Mon, 19 Aug 2013 17:06:02 +1000
From:	Stephen Rothwell <sfr@...b.auug.org.au>
To:	Andrew Morton <akpm@...ux-foundation.org>
Cc:	linux-next@...r.kernel.org, linux-kernel@...r.kernel.org,
	"Kirill A. Shutemov" <kirill.shutemov@...ux.intel.com>,
	Jan Kara <jack@...e.cz>, "Theodore Ts'o" <tytso@....edu>
Subject: linux-next: manual merge of the akpm-current tree with the ext4
 tree

Hi Andrew,

Today's linux-next merge of the akpm-current tree got a conflict in
fs/ext4/inode.c between commit 4958dee0e70f ("ext4: simplify truncation
code in ext4_setattr()") from the ext4 tree and commit fb6854ec9753
("truncate: drop 'oldsize' truncate_pagecache() parameter") from the
akpm-current tree.

I fixed it up (see below) and can carry the fix as necessary (no action
is required).

-- 
Cheers,
Stephen Rothwell                    sfr@...b.auug.org.au

diff --cc fs/ext4/inode.c
index fc4051e,9257d79..0000000
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@@ -4598,9 -4523,7 +4598,8 @@@ int ext4_setattr(struct dentry *dentry
  		ext4_journal_stop(handle);
  	}
  
 -	if (attr->ia_valid & ATTR_SIZE) {
 +	if (attr->ia_valid & ATTR_SIZE && attr->ia_size != inode->i_size) {
 +		handle_t *handle;
- 		loff_t oldsize = inode->i_size;
  
  		if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
  			struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
@@@ -4608,69 -4531,71 +4607,69 @@@
  			if (attr->ia_size > sbi->s_bitmap_maxbytes)
  				return -EFBIG;
  		}
 -	}
 -
 -	if (S_ISREG(inode->i_mode) &&
 -	    attr->ia_valid & ATTR_SIZE &&
 -	    (attr->ia_size < inode->i_size)) {
 -		handle_t *handle;
 -
 -		handle = ext4_journal_start(inode, EXT4_HT_INODE, 3);
 -		if (IS_ERR(handle)) {
 -			error = PTR_ERR(handle);
 -			goto err_out;
 -		}
 -		if (ext4_handle_valid(handle)) {
 -			error = ext4_orphan_add(handle, inode);
 -			orphan = 1;
 -		}
 -		EXT4_I(inode)->i_disksize = attr->ia_size;
 -		rc = ext4_mark_inode_dirty(handle, inode);
 -		if (!error)
 -			error = rc;
 -		ext4_journal_stop(handle);
 -
 -		if (ext4_should_order_data(inode)) {
 -			error = ext4_begin_ordered_truncate(inode,
 +		if (S_ISREG(inode->i_mode) &&
 +		    (attr->ia_size < inode->i_size)) {
 +			if (ext4_should_order_data(inode)) {
 +				error = ext4_begin_ordered_truncate(inode,
  							    attr->ia_size);
 -			if (error) {
 -				/* Do as much error cleanup as possible */
 -				handle = ext4_journal_start(inode,
 -							    EXT4_HT_INODE, 3);
 -				if (IS_ERR(handle)) {
 -					ext4_orphan_del(NULL, inode);
 +				if (error)
  					goto err_out;
 -				}
 -				ext4_orphan_del(handle, inode);
 -				orphan = 0;
 -				ext4_journal_stop(handle);
 +			}
 +			handle = ext4_journal_start(inode, EXT4_HT_INODE, 3);
 +			if (IS_ERR(handle)) {
 +				error = PTR_ERR(handle);
  				goto err_out;
  			}
 -		}
 -	}
 -
 -	if (attr->ia_valid & ATTR_SIZE) {
 -		if (attr->ia_size != inode->i_size) {
 -			i_size_write(inode, attr->ia_size);
 -			/*
 -			 * Blocks are going to be removed from the inode. Wait
 -			 * for dio in flight.  Temporarily disable
 -			 * dioread_nolock to prevent livelock.
 -			 */
 -			if (orphan) {
 -				if (!ext4_should_journal_data(inode)) {
 -					ext4_inode_block_unlocked_dio(inode);
 -					inode_dio_wait(inode);
 -					ext4_inode_resume_unlocked_dio(inode);
 -				} else
 -					ext4_wait_for_tail_page_commit(inode);
 +			if (ext4_handle_valid(handle)) {
 +				error = ext4_orphan_add(handle, inode);
 +				orphan = 1;
  			}
 +			down_write(&EXT4_I(inode)->i_data_sem);
 +			EXT4_I(inode)->i_disksize = attr->ia_size;
 +			rc = ext4_mark_inode_dirty(handle, inode);
 +			if (!error)
 +				error = rc;
  			/*
 -			 * Truncate pagecache after we've waited for commit
 -			 * in data=journal mode to make pages freeable.
 +			 * We have to update i_size under i_data_sem together
 +			 * with i_disksize to avoid races with writeback code
 +			 * running ext4_wb_update_i_disksize().
  			 */
 -			truncate_pagecache(inode, inode->i_size);
 +			if (!error)
 +				i_size_write(inode, attr->ia_size);
 +			up_write(&EXT4_I(inode)->i_data_sem);
 +			ext4_journal_stop(handle);
 +			if (error) {
 +				ext4_orphan_del(NULL, inode);
 +				goto err_out;
 +			}
 +		} else
 +			i_size_write(inode, attr->ia_size);
 +
 +		/*
 +		 * Blocks are going to be removed from the inode. Wait
 +		 * for dio in flight.  Temporarily disable
 +		 * dioread_nolock to prevent livelock.
 +		 */
 +		if (orphan) {
 +			if (!ext4_should_journal_data(inode)) {
 +				ext4_inode_block_unlocked_dio(inode);
 +				inode_dio_wait(inode);
 +				ext4_inode_resume_unlocked_dio(inode);
 +			} else
 +				ext4_wait_for_tail_page_commit(inode);
  		}
 -		ext4_truncate(inode);
 +		/*
 +		 * Truncate pagecache after we've waited for commit
 +		 * in data=journal mode to make pages freeable.
 +		 */
- 		truncate_pagecache(inode, oldsize, inode->i_size);
++		truncate_pagecache(inode, inode->i_size);
  	}
 +	/*
 +	 * We want to call ext4_truncate() even if attr->ia_size ==
 +	 * inode->i_size for cases like truncation of fallocated space
 +	 */
 +	if (attr->ia_valid & ATTR_SIZE)
 +		ext4_truncate(inode);
  
  	if (!rc) {
  		setattr_copy(inode, attr);

Content of type "application/pgp-signature" skipped

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ