diff options
Diffstat (limited to 'fs/btrfs/inode.c')
| -rw-r--r-- | fs/btrfs/inode.c | 130 | 
1 files changed, 60 insertions, 70 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e6811c42e41e..2b790bda7998 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -560,8 +560,9 @@ cont:  			 * we don't need to create any more async work items.  			 * Unlock and free up our temp pages.  			 */ -			extent_clear_unlock_delalloc(inode, start, end, NULL, -						     clear_flags, PAGE_UNLOCK | +			extent_clear_unlock_delalloc(inode, start, end, end, +						     NULL, clear_flags, +						     PAGE_UNLOCK |  						     PAGE_CLEAR_DIRTY |  						     PAGE_SET_WRITEBACK |  						     page_error_op | @@ -837,6 +838,8 @@ retry:  		extent_clear_unlock_delalloc(inode, async_extent->start,  				async_extent->start +  				async_extent->ram_size - 1, +				async_extent->start + +				async_extent->ram_size - 1,  				NULL, EXTENT_LOCKED | EXTENT_DELALLOC,  				PAGE_UNLOCK | PAGE_CLEAR_DIRTY |  				PAGE_SET_WRITEBACK); @@ -856,7 +859,8 @@ retry:  			tree->ops->writepage_end_io_hook(p, start, end,  							 NULL, 0);  			p->mapping = NULL; -			extent_clear_unlock_delalloc(inode, start, end, NULL, 0, +			extent_clear_unlock_delalloc(inode, start, end, end, +						     NULL, 0,  						     PAGE_END_WRITEBACK |  						     PAGE_SET_ERROR);  			free_async_extent_pages(async_extent); @@ -873,6 +877,8 @@ out_free:  	extent_clear_unlock_delalloc(inode, async_extent->start,  				     async_extent->start +  				     async_extent->ram_size - 1, +				     async_extent->start + +				     async_extent->ram_size - 1,  				     NULL, EXTENT_LOCKED | EXTENT_DELALLOC |  				     EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING,  				     PAGE_UNLOCK | PAGE_CLEAR_DIRTY | @@ -966,7 +972,8 @@ static noinline int cow_file_range(struct inode *inode,  		ret = cow_file_range_inline(root, inode, start, end, 0, 0,  					    NULL);  		if (ret == 0) { -			extent_clear_unlock_delalloc(inode, start, end, NULL, +			extent_clear_unlock_delalloc(inode, start, end, +				     delalloc_end, NULL,  				     EXTENT_LOCKED | EXTENT_DELALLOC |  				     EXTENT_DEFRAG, PAGE_UNLOCK |  				     PAGE_CLEAR_DIRTY | PAGE_SET_WRITEBACK | @@ -1062,7 +1069,8 @@ static noinline int cow_file_range(struct inode *inode,  		op |= PAGE_SET_PRIVATE2;  		extent_clear_unlock_delalloc(inode, start, -					     start + ram_size - 1, locked_page, +					     start + ram_size - 1, +					     delalloc_end, locked_page,  					     EXTENT_LOCKED | EXTENT_DELALLOC,  					     op);  		disk_num_bytes -= cur_alloc_size; @@ -1079,7 +1087,8 @@ out_reserve:  	btrfs_dec_block_group_reservations(root->fs_info, ins.objectid);  	btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1);  out_unlock: -	extent_clear_unlock_delalloc(inode, start, end, locked_page, +	extent_clear_unlock_delalloc(inode, start, end, delalloc_end, +				     locked_page,  				     EXTENT_LOCKED | EXTENT_DO_ACCOUNTING |  				     EXTENT_DELALLOC | EXTENT_DEFRAG,  				     PAGE_UNLOCK | PAGE_CLEAR_DIRTY | @@ -1258,7 +1267,8 @@ static noinline int run_delalloc_nocow(struct inode *inode,  	path = btrfs_alloc_path();  	if (!path) { -		extent_clear_unlock_delalloc(inode, start, end, locked_page, +		extent_clear_unlock_delalloc(inode, start, end, end, +					     locked_page,  					     EXTENT_LOCKED | EXTENT_DELALLOC |  					     EXTENT_DO_ACCOUNTING |  					     EXTENT_DEFRAG, PAGE_UNLOCK | @@ -1276,7 +1286,8 @@ static noinline int run_delalloc_nocow(struct inode *inode,  		trans = btrfs_join_transaction(root);  	if (IS_ERR(trans)) { -		extent_clear_unlock_delalloc(inode, start, end, locked_page, +		extent_clear_unlock_delalloc(inode, start, end, end, +					     locked_page,  					     EXTENT_LOCKED | EXTENT_DELALLOC |  					     EXTENT_DO_ACCOUNTING |  					     EXTENT_DEFRAG, PAGE_UNLOCK | @@ -1490,7 +1501,7 @@ out_check:  		}  		extent_clear_unlock_delalloc(inode, cur_offset, -					     cur_offset + num_bytes - 1, +					     cur_offset + num_bytes - 1, end,  					     locked_page, EXTENT_LOCKED |  					     EXTENT_DELALLOC |  					     EXTENT_CLEAR_DATA_RESV, @@ -1522,7 +1533,7 @@ error:  		ret = err;  	if (ret && cur_offset < end) -		extent_clear_unlock_delalloc(inode, cur_offset, end, +		extent_clear_unlock_delalloc(inode, cur_offset, end, end,  					     locked_page, EXTENT_LOCKED |  					     EXTENT_DELALLOC | EXTENT_DEFRAG |  					     EXTENT_DO_ACCOUNTING, PAGE_UNLOCK | @@ -1988,7 +1999,7 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans,  }  int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end, -			      struct extent_state **cached_state) +			      struct extent_state **cached_state, int dedupe)  {  	WARN_ON((end & (PAGE_SIZE - 1)) == 0);  	return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end, @@ -2052,7 +2063,8 @@ again:  		goto out;  	 } -	btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state); +	btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state, +				  0);  	ClearPageChecked(page);  	set_page_dirty(page);  out: @@ -2309,7 +2321,7 @@ static noinline int record_one_backref(u64 inum, u64 offset, u64 root_id,  		if (PTR_ERR(root) == -ENOENT)  			return 0;  		WARN_ON(1); -		pr_debug("inum=%llu, offset=%llu, root_id=%llu\n", +		btrfs_debug(fs_info, "inum=%llu, offset=%llu, root_id=%llu",  			 inum, offset, root_id);  		return PTR_ERR(root);  	} @@ -3936,7 +3948,7 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans,  	 */  	if (!btrfs_is_free_space_inode(inode)  	    && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID -	    && !root->fs_info->log_root_recovering) { +	    && !test_bit(BTRFS_FS_LOG_RECOVERING, &root->fs_info->flags)) {  		btrfs_update_root_times(trans, root);  		ret = btrfs_delayed_update_inode(trans, root, inode); @@ -4059,7 +4071,7 @@ err:  	inode_inc_iversion(inode);  	inode_inc_iversion(dir);  	inode->i_ctime = dir->i_mtime = -		dir->i_ctime = current_fs_time(inode->i_sb); +		dir->i_ctime = current_time(inode);  	ret = btrfs_update_inode(trans, root, dir);  out:  	return ret; @@ -4202,7 +4214,7 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans,  	btrfs_i_size_write(dir, dir->i_size - name_len * 2);  	inode_inc_iversion(dir); -	dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb); +	dir->i_mtime = dir->i_ctime = current_time(dir);  	ret = btrfs_update_inode_fallback(trans, root, dir);  	if (ret)  		btrfs_abort_transaction(trans, ret); @@ -4757,7 +4769,7 @@ again:  			  0, 0, &cached_state, GFP_NOFS);  	ret = btrfs_set_extent_delalloc(inode, block_start, block_end, -					&cached_state); +					&cached_state, 0);  	if (ret) {  		unlock_extent_cached(io_tree, block_start, block_end,  				     &cached_state, GFP_NOFS); @@ -4965,7 +4977,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr)  		inode_inc_iversion(inode);  		if (!(mask & (ATTR_CTIME | ATTR_MTIME)))  			inode->i_ctime = inode->i_mtime = -				current_fs_time(inode->i_sb); +				current_time(inode);  	}  	if (newsize > oldsize) { @@ -5072,7 +5084,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)  	if (btrfs_root_readonly(root))  		return -EROFS; -	err = inode_change_ok(inode, attr); +	err = setattr_prepare(dentry, attr);  	if (err)  		return err; @@ -5223,7 +5235,7 @@ void btrfs_evict_inode(struct inode *inode)  	btrfs_free_io_failure_record(inode, 0, (u64)-1); -	if (root->fs_info->log_root_recovering) { +	if (test_bit(BTRFS_FS_LOG_RECOVERING, &root->fs_info->flags)) {  		BUG_ON(test_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,  				 &BTRFS_I(inode)->runtime_flags));  		goto no_delete; @@ -5672,7 +5684,7 @@ static struct inode *new_simple_dir(struct super_block *s,  	inode->i_op = &btrfs_dir_ro_inode_operations;  	inode->i_fop = &simple_dir_operations;  	inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO; -	inode->i_mtime = current_fs_time(inode->i_sb); +	inode->i_mtime = current_time(inode);  	inode->i_atime = inode->i_mtime;  	inode->i_ctime = inode->i_mtime;  	BTRFS_I(inode)->i_otime = inode->i_mtime; @@ -6258,7 +6270,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,  	inode_init_owner(inode, dir, mode);  	inode_set_bytes(inode, 0); -	inode->i_mtime = current_fs_time(inode->i_sb); +	inode->i_mtime = current_time(inode);  	inode->i_atime = inode->i_mtime;  	inode->i_ctime = inode->i_mtime;  	BTRFS_I(inode)->i_otime = inode->i_mtime; @@ -6372,7 +6384,7 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,  			   name_len * 2);  	inode_inc_iversion(parent_inode);  	parent_inode->i_mtime = parent_inode->i_ctime = -		current_fs_time(parent_inode->i_sb); +		current_time(parent_inode);  	ret = btrfs_update_inode(trans, root, parent_inode);  	if (ret)  		btrfs_abort_transaction(trans, ret); @@ -6590,7 +6602,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,  	BTRFS_I(inode)->dir_index = 0ULL;  	inc_nlink(inode);  	inode_inc_iversion(inode); -	inode->i_ctime = current_fs_time(inode->i_sb); +	inode->i_ctime = current_time(inode);  	ihold(inode);  	set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags); @@ -7012,8 +7024,9 @@ not_found_em:  insert:  	btrfs_release_path(path);  	if (em->start > start || extent_map_end(em) <= start) { -		btrfs_err(root->fs_info, "bad extent! em: [%llu %llu] passed [%llu %llu]", -			em->start, em->len, start, len); +		btrfs_err(root->fs_info, +			  "bad extent! em: [%llu %llu] passed [%llu %llu]", +			  em->start, em->len, start, len);  		err = -EIO;  		goto out;  	} @@ -7865,18 +7878,19 @@ static int btrfs_check_dio_repairable(struct inode *inode,  				      struct io_failure_record *failrec,  				      int failed_mirror)  { +	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);  	int num_copies; -	num_copies = btrfs_num_copies(BTRFS_I(inode)->root->fs_info, -				      failrec->logical, failrec->len); +	num_copies = btrfs_num_copies(fs_info, failrec->logical, failrec->len);  	if (num_copies == 1) {  		/*  		 * we only have a single copy of the data, so don't bother with  		 * all the retry and error correction code that follows. no  		 * matter what the error is, it is very likely to persist.  		 */ -		pr_debug("Check DIO Repairable: cannot repair, num_copies=%d, next_mirror %d, failed_mirror %d\n", -			 num_copies, failrec->this_mirror, failed_mirror); +		btrfs_debug(fs_info, +			"Check DIO Repairable: cannot repair, num_copies=%d, next_mirror %d, failed_mirror %d", +			num_copies, failrec->this_mirror, failed_mirror);  		return 0;  	} @@ -7886,8 +7900,9 @@ static int btrfs_check_dio_repairable(struct inode *inode,  		failrec->this_mirror++;  	if (failrec->this_mirror > num_copies) { -		pr_debug("Check DIO Repairable: (fail) num_copies=%d, next_mirror %d, failed_mirror %d\n", -			 num_copies, failrec->this_mirror, failed_mirror); +		btrfs_debug(fs_info, +			"Check DIO Repairable: (fail) num_copies=%d, next_mirror %d, failed_mirror %d", +			num_copies, failrec->this_mirror, failed_mirror);  		return 0;  	} @@ -8412,7 +8427,7 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip,  	if (!bio)  		return -ENOMEM; -	bio_set_op_attrs(bio, bio_op(orig_bio), orig_bio->bi_opf); +	bio_set_op_attrs(bio, bio_op(orig_bio), bio_flags(orig_bio));  	bio->bi_private = dip;  	bio->bi_end_io = btrfs_end_dio_bio;  	btrfs_io_bio(bio)->logical = file_offset; @@ -8450,7 +8465,8 @@ next_block:  						  start_sector, GFP_NOFS);  			if (!bio)  				goto out_err; -			bio_set_op_attrs(bio, bio_op(orig_bio), orig_bio->bi_opf); +			bio_set_op_attrs(bio, bio_op(orig_bio), +					 bio_flags(orig_bio));  			bio->bi_private = dip;  			bio->bi_end_io = btrfs_end_dio_bio;  			btrfs_io_bio(bio)->logical = file_offset; @@ -8618,7 +8634,7 @@ static ssize_t check_direct_IO(struct btrfs_root *root, struct kiocb *iocb,  		goto out;  	/* If this is a write we don't need to check anymore */ -	if (iov_iter_rw(iter) == WRITE) +	if (iov_iter_rw(iter) != READ || !iter_is_iovec(iter))  		return 0;  	/*  	 * Check to make sure we don't have duplicate iov_base's in this @@ -9054,7 +9070,7 @@ again:  			  0, 0, &cached_state, GFP_NOFS);  	ret = btrfs_set_extent_delalloc(inode, page_start, end, -					&cached_state); +					&cached_state, 0);  	if (ret) {  		unlock_extent_cached(io_tree, page_start, page_end,  				     &cached_state, GFP_NOFS); @@ -9376,8 +9392,9 @@ void btrfs_destroy_inode(struct inode *inode)  		if (!ordered)  			break;  		else { -			btrfs_err(root->fs_info, "found ordered extent %llu %llu on inode cleanup", -				ordered->file_offset, ordered->len); +			btrfs_err(root->fs_info, +				  "found ordered extent %llu %llu on inode cleanup", +				  ordered->file_offset, ordered->len);  			btrfs_remove_ordered_extent(inode, ordered);  			btrfs_put_ordered_extent(ordered);  			btrfs_put_ordered_extent(ordered); @@ -9492,7 +9509,7 @@ static int btrfs_rename_exchange(struct inode *old_dir,  	struct btrfs_root *dest = BTRFS_I(new_dir)->root;  	struct inode *new_inode = new_dentry->d_inode;  	struct inode *old_inode = old_dentry->d_inode; -	struct timespec ctime = CURRENT_TIME; +	struct timespec ctime = current_time(old_inode);  	struct dentry *parent;  	u64 old_ino = btrfs_ino(old_inode);  	u64 new_ino = btrfs_ino(new_inode); @@ -9860,7 +9877,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,  	inode_inc_iversion(old_inode);  	old_dir->i_ctime = old_dir->i_mtime =  	new_dir->i_ctime = new_dir->i_mtime = -	old_inode->i_ctime = current_fs_time(old_dir->i_sb); +	old_inode->i_ctime = current_time(old_dir);  	if (old_dentry->d_parent != new_dentry->d_parent)  		btrfs_record_unlink_dir(trans, old_dir, old_inode, 1); @@ -9885,7 +9902,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,  	if (new_inode) {  		inode_inc_iversion(new_inode); -		new_inode->i_ctime = current_fs_time(new_inode->i_sb); +		new_inode->i_ctime = current_time(new_inode);  		if (unlikely(btrfs_ino(new_inode) ==  			     BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) {  			root_objectid = BTRFS_I(new_inode)->location.objectid; @@ -10403,7 +10420,7 @@ next:  		*alloc_hint = ins.objectid + ins.offset;  		inode_inc_iversion(inode); -		inode->i_ctime = current_fs_time(inode->i_sb); +		inode->i_ctime = current_time(inode);  		BTRFS_I(inode)->flags |= BTRFS_INODE_PREALLOC;  		if (!(mode & FALLOC_FL_KEEP_SIZE) &&  		    (actual_len > inode->i_size) && @@ -10543,21 +10560,6 @@ out_inode:  } -/* Inspired by filemap_check_errors() */ -int btrfs_inode_check_errors(struct inode *inode) -{ -	int ret = 0; - -	if (test_bit(AS_ENOSPC, &inode->i_mapping->flags) && -	    test_and_clear_bit(AS_ENOSPC, &inode->i_mapping->flags)) -		ret = -ENOSPC; -	if (test_bit(AS_EIO, &inode->i_mapping->flags) && -	    test_and_clear_bit(AS_EIO, &inode->i_mapping->flags)) -		ret = -EIO; - -	return ret; -} -  static const struct inode_operations btrfs_dir_inode_operations = {  	.getattr	= btrfs_getattr,  	.lookup		= btrfs_lookup, @@ -10566,14 +10568,11 @@ static const struct inode_operations btrfs_dir_inode_operations = {  	.link		= btrfs_link,  	.mkdir		= btrfs_mkdir,  	.rmdir		= btrfs_rmdir, -	.rename2	= btrfs_rename2, +	.rename		= btrfs_rename2,  	.symlink	= btrfs_symlink,  	.setattr	= btrfs_setattr,  	.mknod		= btrfs_mknod, -	.setxattr	= generic_setxattr, -	.getxattr	= generic_getxattr,  	.listxattr	= btrfs_listxattr, -	.removexattr	= generic_removexattr,  	.permission	= btrfs_permission,  	.get_acl	= btrfs_get_acl,  	.set_acl	= btrfs_set_acl, @@ -10647,10 +10646,7 @@ static const struct address_space_operations btrfs_symlink_aops = {  static const struct inode_operations btrfs_file_inode_operations = {  	.getattr	= btrfs_getattr,  	.setattr	= btrfs_setattr, -	.setxattr	= generic_setxattr, -	.getxattr	= generic_getxattr,  	.listxattr      = btrfs_listxattr, -	.removexattr	= generic_removexattr,  	.permission	= btrfs_permission,  	.fiemap		= btrfs_fiemap,  	.get_acl	= btrfs_get_acl, @@ -10661,10 +10657,7 @@ static const struct inode_operations btrfs_special_inode_operations = {  	.getattr	= btrfs_getattr,  	.setattr	= btrfs_setattr,  	.permission	= btrfs_permission, -	.setxattr	= generic_setxattr, -	.getxattr	= generic_getxattr,  	.listxattr	= btrfs_listxattr, -	.removexattr	= generic_removexattr,  	.get_acl	= btrfs_get_acl,  	.set_acl	= btrfs_set_acl,  	.update_time	= btrfs_update_time, @@ -10675,10 +10668,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = {  	.getattr	= btrfs_getattr,  	.setattr	= btrfs_setattr,  	.permission	= btrfs_permission, -	.setxattr	= generic_setxattr, -	.getxattr	= generic_getxattr,  	.listxattr	= btrfs_listxattr, -	.removexattr	= generic_removexattr,  	.update_time	= btrfs_update_time,  };  |