diff options
Diffstat (limited to 'fs/ext3/inode.c')
| -rw-r--r-- | fs/ext3/inode.c | 45 | 
1 files changed, 29 insertions, 16 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 455e6e6e5cb9..7f920b7263a4 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -196,6 +196,9 @@ void ext3_delete_inode (struct inode * inode)  {  	handle_t *handle; +	if (!is_bad_inode(inode)) +		dquot_initialize(inode); +  	truncate_inode_pages(&inode->i_data, 0);  	if (is_bad_inode(inode)) @@ -1378,7 +1381,7 @@ static int ext3_journalled_write_end(struct file *file,  	 */  	if (pos + len > inode->i_size && ext3_can_truncate(inode))  		ext3_orphan_add(handle, inode); -	EXT3_I(inode)->i_state |= EXT3_STATE_JDATA; +	ext3_set_inode_state(inode, EXT3_STATE_JDATA);  	if (inode->i_size > EXT3_I(inode)->i_disksize) {  		EXT3_I(inode)->i_disksize = inode->i_size;  		ret2 = ext3_mark_inode_dirty(handle, inode); @@ -1417,7 +1420,7 @@ static sector_t ext3_bmap(struct address_space *mapping, sector_t block)  	journal_t *journal;  	int err; -	if (EXT3_I(inode)->i_state & EXT3_STATE_JDATA) { +	if (ext3_test_inode_state(inode, EXT3_STATE_JDATA)) {  		/*  		 * This is a REALLY heavyweight approach, but the use of  		 * bmap on dirty files is expected to be extremely rare: @@ -1436,7 +1439,7 @@ static sector_t ext3_bmap(struct address_space *mapping, sector_t block)  		 * everything they get.  		 */ -		EXT3_I(inode)->i_state &= ~EXT3_STATE_JDATA; +		ext3_clear_inode_state(inode, EXT3_STATE_JDATA);  		journal = EXT3_JOURNAL(inode);  		journal_lock_updates(journal);  		err = journal_flush(journal); @@ -1528,6 +1531,7 @@ static int ext3_ordered_writepage(struct page *page,  	int err;  	J_ASSERT(PageLocked(page)); +	WARN_ON_ONCE(IS_RDONLY(inode));  	/*  	 * We give up here if we're reentered, because it might be for a @@ -1600,6 +1604,9 @@ static int ext3_writeback_writepage(struct page *page,  	int ret = 0;  	int err; +	J_ASSERT(PageLocked(page)); +	WARN_ON_ONCE(IS_RDONLY(inode)); +  	if (ext3_journal_current_handle())  		goto out_fail; @@ -1642,6 +1649,9 @@ static int ext3_journalled_writepage(struct page *page,  	int ret = 0;  	int err; +	J_ASSERT(PageLocked(page)); +	WARN_ON_ONCE(IS_RDONLY(inode)); +  	if (ext3_journal_current_handle())  		goto no_write; @@ -1670,7 +1680,7 @@ static int ext3_journalled_writepage(struct page *page,  				PAGE_CACHE_SIZE, NULL, write_end_fn);  		if (ret == 0)  			ret = err; -		EXT3_I(inode)->i_state |= EXT3_STATE_JDATA; +		ext3_set_inode_state(inode, EXT3_STATE_JDATA);  		unlock_page(page);  	} else {  		/* @@ -1785,8 +1795,9 @@ retry:  		handle = ext3_journal_start(inode, 2);  		if (IS_ERR(handle)) {  			/* This is really bad luck. We've written the data -			 * but cannot extend i_size. Bail out and pretend -			 * the write failed... */ +			 * but cannot extend i_size. Truncate allocated blocks +			 * and pretend the write failed... */ +			ext3_truncate(inode);  			ret = PTR_ERR(handle);  			goto out;  		} @@ -2402,7 +2413,7 @@ void ext3_truncate(struct inode *inode)  		goto out_notrans;  	if (inode->i_size == 0 && ext3_should_writeback_data(inode)) -		ei->i_state |= EXT3_STATE_FLUSH_ON_CLOSE; +		ext3_set_inode_state(inode, EXT3_STATE_FLUSH_ON_CLOSE);  	/*  	 * We have to lock the EOF page here, because lock_page() nests @@ -2721,7 +2732,7 @@ int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc)  {  	/* We have all inode data except xattrs in memory here. */  	return __ext3_get_inode_loc(inode, iloc, -		!(EXT3_I(inode)->i_state & EXT3_STATE_XATTR)); +		!ext3_test_inode_state(inode, EXT3_STATE_XATTR));  }  void ext3_set_inode_flags(struct inode *inode) @@ -2893,7 +2904,7 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino)  					EXT3_GOOD_OLD_INODE_SIZE +  					ei->i_extra_isize;  			if (*magic == cpu_to_le32(EXT3_XATTR_MAGIC)) -				 ei->i_state |= EXT3_STATE_XATTR; +				 ext3_set_inode_state(inode, EXT3_STATE_XATTR);  		}  	} else  		ei->i_extra_isize = 0; @@ -2955,7 +2966,7 @@ again:  	/* For fields not not tracking in the in-memory inode,  	 * initialise them to zero for new inodes. */ -	if (ei->i_state & EXT3_STATE_NEW) +	if (ext3_test_inode_state(inode, EXT3_STATE_NEW))  		memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size);  	ext3_get_inode_flags(ei); @@ -3052,7 +3063,7 @@ again:  	rc = ext3_journal_dirty_metadata(handle, bh);  	if (!err)  		err = rc; -	ei->i_state &= ~EXT3_STATE_NEW; +	ext3_clear_inode_state(inode, EXT3_STATE_NEW);  	atomic_set(&ei->i_sync_tid, handle->h_transaction->t_tid);  out_brelse: @@ -3096,7 +3107,7 @@ out_brelse:   * `stuff()' is running, and the new i_size will be lost.  Plus the inode   * will no longer be on the superblock's dirty inode list.   */ -int ext3_write_inode(struct inode *inode, int wait) +int ext3_write_inode(struct inode *inode, struct writeback_control *wbc)  {  	if (current->flags & PF_MEMALLOC)  		return 0; @@ -3107,7 +3118,7 @@ int ext3_write_inode(struct inode *inode, int wait)  		return -EIO;  	} -	if (!wait) +	if (wbc->sync_mode != WB_SYNC_ALL)  		return 0;  	return ext3_force_commit(inode->i_sb); @@ -3140,6 +3151,8 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr)  	if (error)  		return error; +	if (ia_valid & ATTR_SIZE) +		dquot_initialize(inode);  	if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||  		(ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {  		handle_t *handle; @@ -3152,7 +3165,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr)  			error = PTR_ERR(handle);  			goto err_out;  		} -		error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; +		error = dquot_transfer(inode, attr);  		if (error) {  			ext3_journal_stop(handle);  			return error; @@ -3237,7 +3250,7 @@ static int ext3_writepage_trans_blocks(struct inode *inode)  		ret = 2 * (bpp + indirects) + 2;  #ifdef CONFIG_QUOTA -	/* We know that structure was already allocated during vfs_dq_init so +	/* We know that structure was already allocated during dquot_initialize so  	 * we will be updating only the data blocks + inodes */  	ret += EXT3_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb);  #endif @@ -3328,7 +3341,7 @@ int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode)   * i_size has been changed by generic_commit_write() and we thus need   * to include the updated inode in the current transaction.   * - * Also, vfs_dq_alloc_space() will always dirty the inode when blocks + * Also, dquot_alloc_space() will always dirty the inode when blocks   * are allocated to the file.   *   * If the inode is marked synchronous, we don't honour that here - doing  |