diff options
Diffstat (limited to 'fs/ext4/inode.c')
| -rw-r--r-- | fs/ext4/inode.c | 66 | 
1 files changed, 33 insertions, 33 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index e274e9c1171f..61d49ff22c81 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1206,7 +1206,6 @@ static int ext4_journalled_write_end(struct file *file,   */  static int ext4_da_reserve_metadata(struct inode *inode, ext4_lblk_t lblock)  { -	int retries = 0;  	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);  	struct ext4_inode_info *ei = EXT4_I(inode);  	unsigned int md_needed; @@ -1218,7 +1217,6 @@ static int ext4_da_reserve_metadata(struct inode *inode, ext4_lblk_t lblock)  	 * in order to allocate nrblocks  	 * worse case is one extent per block  	 */ -repeat:  	spin_lock(&ei->i_block_reservation_lock);  	/*  	 * ext4_calc_metadata_amount() has side effects, which we have @@ -1238,10 +1236,6 @@ repeat:  		ei->i_da_metadata_calc_len = save_len;  		ei->i_da_metadata_calc_last_lblock = save_last_lblock;  		spin_unlock(&ei->i_block_reservation_lock); -		if (ext4_should_retry_alloc(inode->i_sb, &retries)) { -			cond_resched(); -			goto repeat; -		}  		return -ENOSPC;  	}  	ei->i_reserved_meta_blocks += md_needed; @@ -1255,7 +1249,6 @@ repeat:   */  static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock)  { -	int retries = 0;  	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);  	struct ext4_inode_info *ei = EXT4_I(inode);  	unsigned int md_needed; @@ -1277,7 +1270,6 @@ static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock)  	 * in order to allocate nrblocks  	 * worse case is one extent per block  	 */ -repeat:  	spin_lock(&ei->i_block_reservation_lock);  	/*  	 * ext4_calc_metadata_amount() has side effects, which we have @@ -1297,10 +1289,6 @@ repeat:  		ei->i_da_metadata_calc_len = save_len;  		ei->i_da_metadata_calc_last_lblock = save_last_lblock;  		spin_unlock(&ei->i_block_reservation_lock); -		if (ext4_should_retry_alloc(inode->i_sb, &retries)) { -			cond_resched(); -			goto repeat; -		}  		dquot_release_reservation_block(inode, EXT4_C2B(sbi, 1));  		return -ENOSPC;  	} @@ -2178,6 +2166,9 @@ static int mpage_map_one_extent(handle_t *handle, struct mpage_da_data *mpd)   *   * @handle - handle for journal operations   * @mpd - extent to map + * @give_up_on_write - we set this to true iff there is a fatal error and there + *                     is no hope of writing the data. The caller should discard + *                     dirty pages to avoid infinite loops.   *   * The function maps extent starting at mpd->lblk of length mpd->len. If it is   * delayed, blocks are allocated, if it is unwritten, we may need to convert @@ -2295,6 +2286,7 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)  	struct address_space *mapping = mpd->inode->i_mapping;  	struct pagevec pvec;  	unsigned int nr_pages; +	long left = mpd->wbc->nr_to_write;  	pgoff_t index = mpd->first_page;  	pgoff_t end = mpd->last_page;  	int tag; @@ -2330,6 +2322,17 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)  			if (page->index > end)  				goto out; +			/* +			 * Accumulated enough dirty pages? This doesn't apply +			 * to WB_SYNC_ALL mode. For integrity sync we have to +			 * keep going because someone may be concurrently +			 * dirtying pages, and we might have synced a lot of +			 * newly appeared dirty pages, but have not synced all +			 * of the old dirty pages. +			 */ +			if (mpd->wbc->sync_mode == WB_SYNC_NONE && left <= 0) +				goto out; +  			/* If we can't merge this page, we are done. */  			if (mpd->map.m_len > 0 && mpd->next_page != page->index)  				goto out; @@ -2364,19 +2367,7 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)  			if (err <= 0)  				goto out;  			err = 0; - -			/* -			 * Accumulated enough dirty pages? This doesn't apply -			 * to WB_SYNC_ALL mode. For integrity sync we have to -			 * keep going because someone may be concurrently -			 * dirtying pages, and we might have synced a lot of -			 * newly appeared dirty pages, but have not synced all -			 * of the old dirty pages. -			 */ -			if (mpd->wbc->sync_mode == WB_SYNC_NONE && -			    mpd->next_page - mpd->first_page >= -							mpd->wbc->nr_to_write) -				goto out; +			left--;  		}  		pagevec_release(&pvec);  		cond_resched(); @@ -2420,16 +2411,15 @@ static int ext4_writepages(struct address_space *mapping,  	 * because that could violate lock ordering on umount  	 */  	if (!mapping->nrpages || !mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) -		return 0; +		goto out_writepages;  	if (ext4_should_journal_data(inode)) {  		struct blk_plug plug; -		int ret;  		blk_start_plug(&plug);  		ret = write_cache_pages(mapping, wbc, __writepage, mapping);  		blk_finish_plug(&plug); -		return ret; +		goto out_writepages;  	}  	/* @@ -2442,8 +2432,10 @@ static int ext4_writepages(struct address_space *mapping,  	 * *never* be called, so if that ever happens, we would want  	 * the stack trace.  	 */ -	if (unlikely(sbi->s_mount_flags & EXT4_MF_FS_ABORTED)) -		return -EROFS; +	if (unlikely(sbi->s_mount_flags & EXT4_MF_FS_ABORTED)) { +		ret = -EROFS; +		goto out_writepages; +	}  	if (ext4_should_dioread_nolock(inode)) {  		/* @@ -4690,6 +4682,15 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,  	generic_fillattr(inode, stat);  	/* +	 * If there is inline data in the inode, the inode will normally not +	 * have data blocks allocated (it may have an external xattr block). +	 * Report at least one sector for such files, so tools like tar, rsync, +	 * others doen't incorrectly think the file is completely sparse. +	 */ +	if (unlikely(ext4_has_inline_data(inode))) +		stat->blocks += (stat->size + 511) >> 9; + +	/*  	 * We can't update i_blocks if the block allocation is delayed  	 * otherwise in the case of system crash before the real block  	 * allocation is done, we will have i_blocks inconsistent with @@ -4700,9 +4701,8 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,  	 * blocks for this file.  	 */  	delalloc_blocks = EXT4_C2B(EXT4_SB(inode->i_sb), -				EXT4_I(inode)->i_reserved_data_blocks); - -	stat->blocks += delalloc_blocks << (inode->i_sb->s_blocksize_bits-9); +				   EXT4_I(inode)->i_reserved_data_blocks); +	stat->blocks += delalloc_blocks << (inode->i_sb->s_blocksize_bits - 9);  	return 0;  }  | 
