Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a59108a7 authored by Nikolay Borisov's avatar Nikolay Borisov Committed by David Sterba
Browse files

btrfs: Make btrfs_log_inode take btrfs_inode

parent 6d889a3b
Loading
Loading
Loading
Loading
+48 −49
Original line number Original line Diff line number Diff line
@@ -97,7 +97,7 @@
#define LOG_WALK_REPLAY_ALL 3
#define LOG_WALK_REPLAY_ALL 3


static int btrfs_log_inode(struct btrfs_trans_handle *trans,
static int btrfs_log_inode(struct btrfs_trans_handle *trans,
			   struct btrfs_root *root, struct inode *inode,
			   struct btrfs_root *root, struct btrfs_inode *inode,
			   int inode_only,
			   int inode_only,
			   const loff_t start,
			   const loff_t start,
			   const loff_t end,
			   const loff_t end,
@@ -4594,7 +4594,7 @@ static int btrfs_check_ref_name_override(struct extent_buffer *eb,
 * This handles both files and directories.
 * This handles both files and directories.
 */
 */
static int btrfs_log_inode(struct btrfs_trans_handle *trans,
static int btrfs_log_inode(struct btrfs_trans_handle *trans,
			   struct btrfs_root *root, struct inode *inode,
			   struct btrfs_root *root, struct btrfs_inode *inode,
			   int inode_only,
			   int inode_only,
			   const loff_t start,
			   const loff_t start,
			   const loff_t end,
			   const loff_t end,
@@ -4615,8 +4615,8 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
	int ins_start_slot = 0;
	int ins_start_slot = 0;
	int ins_nr;
	int ins_nr;
	bool fast_search = false;
	bool fast_search = false;
	u64 ino = btrfs_ino(BTRFS_I(inode));
	u64 ino = btrfs_ino(inode);
	struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
	struct extent_map_tree *em_tree = &inode->extent_tree;
	u64 logged_isize = 0;
	u64 logged_isize = 0;
	bool need_log_inode_item = true;
	bool need_log_inode_item = true;


@@ -4637,9 +4637,9 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,




	/* today the code can only do partial logging of directories */
	/* today the code can only do partial logging of directories */
	if (S_ISDIR(inode->i_mode) ||
	if (S_ISDIR(inode->vfs_inode.i_mode) ||
	    (!test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
	    (!test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
		       &BTRFS_I(inode)->runtime_flags) &&
		       &inode->runtime_flags) &&
	     inode_only >= LOG_INODE_EXISTS))
	     inode_only >= LOG_INODE_EXISTS))
		max_key.type = BTRFS_XATTR_ITEM_KEY;
		max_key.type = BTRFS_XATTR_ITEM_KEY;
	else
	else
@@ -4652,11 +4652,11 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
	 * order for the log replay code to mark inodes for link count
	 * order for the log replay code to mark inodes for link count
	 * fixup (create temporary BTRFS_TREE_LOG_FIXUP_OBJECTID items).
	 * fixup (create temporary BTRFS_TREE_LOG_FIXUP_OBJECTID items).
	 */
	 */
	if (S_ISDIR(inode->i_mode) ||
	if (S_ISDIR(inode->vfs_inode.i_mode) ||
	    BTRFS_I(inode)->generation > fs_info->last_trans_committed)
	    inode->generation > fs_info->last_trans_committed)
		ret = btrfs_commit_inode_delayed_items(trans, BTRFS_I(inode));
		ret = btrfs_commit_inode_delayed_items(trans, inode);
	else
	else
		ret = btrfs_commit_inode_delayed_inode(BTRFS_I(inode));
		ret = btrfs_commit_inode_delayed_inode(inode);


	if (ret) {
	if (ret) {
		btrfs_free_path(path);
		btrfs_free_path(path);
@@ -4666,17 +4666,16 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,


	if (inode_only == LOG_OTHER_INODE) {
	if (inode_only == LOG_OTHER_INODE) {
		inode_only = LOG_INODE_EXISTS;
		inode_only = LOG_INODE_EXISTS;
		mutex_lock_nested(&BTRFS_I(inode)->log_mutex,
		mutex_lock_nested(&inode->log_mutex, SINGLE_DEPTH_NESTING);
				  SINGLE_DEPTH_NESTING);
	} else {
	} else {
		mutex_lock(&BTRFS_I(inode)->log_mutex);
		mutex_lock(&inode->log_mutex);
	}
	}


	/*
	/*
	 * a brute force approach to making sure we get the most uptodate
	 * a brute force approach to making sure we get the most uptodate
	 * copies of everything.
	 * copies of everything.
	 */
	 */
	if (S_ISDIR(inode->i_mode)) {
	if (S_ISDIR(inode->vfs_inode.i_mode)) {
		int max_key_type = BTRFS_DIR_LOG_INDEX_KEY;
		int max_key_type = BTRFS_DIR_LOG_INDEX_KEY;


		if (inode_only == LOG_INODE_EXISTS)
		if (inode_only == LOG_INODE_EXISTS)
@@ -4697,31 +4696,30 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
			 * (zeroes), as if an expanding truncate happened,
			 * (zeroes), as if an expanding truncate happened,
			 * instead of getting a file of 4Kb only.
			 * instead of getting a file of 4Kb only.
			 */
			 */
			err = logged_inode_size(log, BTRFS_I(inode), path,
			err = logged_inode_size(log, inode, path, &logged_isize);
						&logged_isize);
			if (err)
			if (err)
				goto out_unlock;
				goto out_unlock;
		}
		}
		if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
		if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
			     &BTRFS_I(inode)->runtime_flags)) {
			     &inode->runtime_flags)) {
			if (inode_only == LOG_INODE_EXISTS) {
			if (inode_only == LOG_INODE_EXISTS) {
				max_key.type = BTRFS_XATTR_ITEM_KEY;
				max_key.type = BTRFS_XATTR_ITEM_KEY;
				ret = drop_objectid_items(trans, log, path, ino,
				ret = drop_objectid_items(trans, log, path, ino,
							  max_key.type);
							  max_key.type);
			} else {
			} else {
				clear_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
				clear_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
					  &BTRFS_I(inode)->runtime_flags);
					  &inode->runtime_flags);
				clear_bit(BTRFS_INODE_COPY_EVERYTHING,
				clear_bit(BTRFS_INODE_COPY_EVERYTHING,
					  &BTRFS_I(inode)->runtime_flags);
					  &inode->runtime_flags);
				while(1) {
				while(1) {
					ret = btrfs_truncate_inode_items(trans,
					ret = btrfs_truncate_inode_items(trans,
							 log, inode, 0, 0);
						log, &inode->vfs_inode, 0, 0);
					if (ret != -EAGAIN)
					if (ret != -EAGAIN)
						break;
						break;
				}
				}
			}
			}
		} else if (test_and_clear_bit(BTRFS_INODE_COPY_EVERYTHING,
		} else if (test_and_clear_bit(BTRFS_INODE_COPY_EVERYTHING,
					      &BTRFS_I(inode)->runtime_flags) ||
					      &inode->runtime_flags) ||
			   inode_only == LOG_INODE_EXISTS) {
			   inode_only == LOG_INODE_EXISTS) {
			if (inode_only == LOG_INODE_ALL)
			if (inode_only == LOG_INODE_ALL)
				fast_search = true;
				fast_search = true;
@@ -4762,12 +4760,11 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,


		if ((min_key.type == BTRFS_INODE_REF_KEY ||
		if ((min_key.type == BTRFS_INODE_REF_KEY ||
		     min_key.type == BTRFS_INODE_EXTREF_KEY) &&
		     min_key.type == BTRFS_INODE_EXTREF_KEY) &&
		    BTRFS_I(inode)->generation == trans->transid) {
		    inode->generation == trans->transid) {
			u64 other_ino = 0;
			u64 other_ino = 0;


			ret = btrfs_check_ref_name_override(path->nodes[0],
			ret = btrfs_check_ref_name_override(path->nodes[0],
							    path->slots[0],
					path->slots[0], &min_key, inode,
							    &min_key, BTRFS_I(inode),
					&other_ino);
					&other_ino);
			if (ret < 0) {
			if (ret < 0) {
				err = ret;
				err = ret;
@@ -4783,7 +4780,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
					ins_nr = 1;
					ins_nr = 1;
					ins_start_slot = path->slots[0];
					ins_start_slot = path->slots[0];
				}
				}
				ret = copy_items(trans, BTRFS_I(inode), dst_path, path,
				ret = copy_items(trans, inode, dst_path, path,
						 &last_extent, ins_start_slot,
						 &last_extent, ins_start_slot,
						 ins_nr, inode_only,
						 ins_nr, inode_only,
						 logged_isize);
						 logged_isize);
@@ -4821,9 +4818,10 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
				 * update the log with the new name before we
				 * update the log with the new name before we
				 * unpin it.
				 * unpin it.
				 */
				 */
				err = btrfs_log_inode(trans, root, other_inode,
				err = btrfs_log_inode(trans, root,
						      LOG_OTHER_INODE,
						BTRFS_I(other_inode),
						      0, LLONG_MAX, ctx);
						LOG_OTHER_INODE, 0, LLONG_MAX,
						ctx);
				iput(other_inode);
				iput(other_inode);
				if (err)
				if (err)
					goto out_unlock;
					goto out_unlock;
@@ -4836,7 +4834,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
		if (min_key.type == BTRFS_XATTR_ITEM_KEY) {
		if (min_key.type == BTRFS_XATTR_ITEM_KEY) {
			if (ins_nr == 0)
			if (ins_nr == 0)
				goto next_slot;
				goto next_slot;
			ret = copy_items(trans, BTRFS_I(inode), dst_path, path,
			ret = copy_items(trans, inode, dst_path, path,
					 &last_extent, ins_start_slot,
					 &last_extent, ins_start_slot,
					 ins_nr, inode_only, logged_isize);
					 ins_nr, inode_only, logged_isize);
			if (ret < 0) {
			if (ret < 0) {
@@ -4861,7 +4859,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
			goto next_slot;
			goto next_slot;
		}
		}


		ret = copy_items(trans, BTRFS_I(inode), dst_path, path, &last_extent,
		ret = copy_items(trans, inode, dst_path, path, &last_extent,
				 ins_start_slot, ins_nr, inode_only,
				 ins_start_slot, ins_nr, inode_only,
				 logged_isize);
				 logged_isize);
		if (ret < 0) {
		if (ret < 0) {
@@ -4885,7 +4883,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
			goto again;
			goto again;
		}
		}
		if (ins_nr) {
		if (ins_nr) {
			ret = copy_items(trans, BTRFS_I(inode), dst_path, path,
			ret = copy_items(trans, inode, dst_path, path,
					 &last_extent, ins_start_slot,
					 &last_extent, ins_start_slot,
					 ins_nr, inode_only, logged_isize);
					 ins_nr, inode_only, logged_isize);
			if (ret < 0) {
			if (ret < 0) {
@@ -4907,7 +4905,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
		}
		}
	}
	}
	if (ins_nr) {
	if (ins_nr) {
		ret = copy_items(trans, BTRFS_I(inode), dst_path, path, &last_extent,
		ret = copy_items(trans, inode, dst_path, path, &last_extent,
				 ins_start_slot, ins_nr, inode_only,
				 ins_start_slot, ins_nr, inode_only,
				 logged_isize);
				 logged_isize);
		if (ret < 0) {
		if (ret < 0) {
@@ -4920,13 +4918,13 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,


	btrfs_release_path(path);
	btrfs_release_path(path);
	btrfs_release_path(dst_path);
	btrfs_release_path(dst_path);
	err = btrfs_log_all_xattrs(trans, root, BTRFS_I(inode), path, dst_path);
	err = btrfs_log_all_xattrs(trans, root, inode, path, dst_path);
	if (err)
	if (err)
		goto out_unlock;
		goto out_unlock;
	if (max_key.type >= BTRFS_EXTENT_DATA_KEY && !fast_search) {
	if (max_key.type >= BTRFS_EXTENT_DATA_KEY && !fast_search) {
		btrfs_release_path(path);
		btrfs_release_path(path);
		btrfs_release_path(dst_path);
		btrfs_release_path(dst_path);
		err = btrfs_log_trailing_hole(trans, root, BTRFS_I(inode), path);
		err = btrfs_log_trailing_hole(trans, root, inode, path);
		if (err)
		if (err)
			goto out_unlock;
			goto out_unlock;
	}
	}
@@ -4934,12 +4932,12 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
	btrfs_release_path(path);
	btrfs_release_path(path);
	btrfs_release_path(dst_path);
	btrfs_release_path(dst_path);
	if (need_log_inode_item) {
	if (need_log_inode_item) {
		err = log_inode_item(trans, log, dst_path, BTRFS_I(inode));
		err = log_inode_item(trans, log, dst_path, inode);
		if (err)
		if (err)
			goto out_unlock;
			goto out_unlock;
	}
	}
	if (fast_search) {
	if (fast_search) {
		ret = btrfs_log_changed_extents(trans, root, BTRFS_I(inode), dst_path,
		ret = btrfs_log_changed_extents(trans, root, inode, dst_path,
						&logged_list, ctx, start, end);
						&logged_list, ctx, start, end);
		if (ret) {
		if (ret) {
			err = ret;
			err = ret;
@@ -4977,25 +4975,25 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
		write_unlock(&em_tree->lock);
		write_unlock(&em_tree->lock);
	}
	}


	if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) {
	if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->vfs_inode.i_mode)) {
		ret = log_directory_changes(trans, root, BTRFS_I(inode), path,
		ret = log_directory_changes(trans, root, inode, path, dst_path,
				dst_path, ctx);
					ctx);
		if (ret) {
		if (ret) {
			err = ret;
			err = ret;
			goto out_unlock;
			goto out_unlock;
		}
		}
	}
	}


	spin_lock(&BTRFS_I(inode)->lock);
	spin_lock(&inode->lock);
	BTRFS_I(inode)->logged_trans = trans->transid;
	inode->logged_trans = trans->transid;
	BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans;
	inode->last_log_commit = inode->last_sub_trans;
	spin_unlock(&BTRFS_I(inode)->lock);
	spin_unlock(&inode->lock);
out_unlock:
out_unlock:
	if (unlikely(err))
	if (unlikely(err))
		btrfs_put_logged_extents(&logged_list);
		btrfs_put_logged_extents(&logged_list);
	else
	else
		btrfs_submit_logged_extents(&logged_list, log);
		btrfs_submit_logged_extents(&logged_list, log);
	mutex_unlock(&BTRFS_I(inode)->log_mutex);
	mutex_unlock(&inode->log_mutex);


	btrfs_free_path(path);
	btrfs_free_path(path);
	btrfs_free_path(dst_path);
	btrfs_free_path(dst_path);
@@ -5243,7 +5241,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans,
			ctx->log_new_dentries = false;
			ctx->log_new_dentries = false;
			if (type == BTRFS_FT_DIR || type == BTRFS_FT_SYMLINK)
			if (type == BTRFS_FT_DIR || type == BTRFS_FT_SYMLINK)
				log_mode = LOG_INODE_ALL;
				log_mode = LOG_INODE_ALL;
			ret = btrfs_log_inode(trans, root, di_inode,
			ret = btrfs_log_inode(trans, root, BTRFS_I(di_inode),
					      log_mode, 0, LLONG_MAX, ctx);
					      log_mode, 0, LLONG_MAX, ctx);
			if (!ret &&
			if (!ret &&
			    btrfs_must_commit_transaction(trans, BTRFS_I(di_inode)))
			    btrfs_must_commit_transaction(trans, BTRFS_I(di_inode)))
@@ -5363,7 +5361,7 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,


			if (ctx)
			if (ctx)
				ctx->log_new_dentries = false;
				ctx->log_new_dentries = false;
			ret = btrfs_log_inode(trans, root, dir_inode,
			ret = btrfs_log_inode(trans, root, BTRFS_I(dir_inode),
					      LOG_INODE_ALL, 0, LLONG_MAX, ctx);
					      LOG_INODE_ALL, 0, LLONG_MAX, ctx);
			if (!ret &&
			if (!ret &&
			    btrfs_must_commit_transaction(trans, BTRFS_I(dir_inode)))
			    btrfs_must_commit_transaction(trans, BTRFS_I(dir_inode)))
@@ -5443,7 +5441,8 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
	if (ret)
	if (ret)
		goto end_no_trans;
		goto end_no_trans;


	ret = btrfs_log_inode(trans, root, inode, inode_only, start, end, ctx);
	ret = btrfs_log_inode(trans, root, BTRFS_I(inode), inode_only,
			start, end, ctx);
	if (ret)
	if (ret)
		goto end_trans;
		goto end_trans;


@@ -5519,7 +5518,7 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
			break;
			break;


		if (BTRFS_I(inode)->generation > last_committed) {
		if (BTRFS_I(inode)->generation > last_committed) {
			ret = btrfs_log_inode(trans, root, inode,
			ret = btrfs_log_inode(trans, root, BTRFS_I(inode),
					      LOG_INODE_EXISTS,
					      LOG_INODE_EXISTS,
					      0, LLONG_MAX, ctx);
					      0, LLONG_MAX, ctx);
			if (ret)
			if (ret)