fs/btrfs/ordered-data.c

Source file repositories/reference/linux-study-clean/fs/btrfs/ordered-data.c

File Facts

System
Linux kernel
Corpus path
fs/btrfs/ordered-data.c
Extension
.c
Size
41244 bytes
Lines
1372
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (cur >= entry_end) {
			node = rb_next(node);
			/* No more ordered extents, exit */
			if (!node)
				break;
			entry = rb_entry(node, struct btrfs_ordered_extent,
					 rb_node);

			/* Go to next ordered extent and continue */
			cur = entry->file_offset;
			continue;
		}
		/*
		 * |	|<--- OE --->|
		 * cur
		 * Go to the start of OE.
		 */
		if (cur < entry->file_offset) {
			cur = entry->file_offset;
			continue;
		}

		/*
		 * Now we are definitely inside one ordered extent.
		 *
		 * |<--- OE --->|
		 *	|
		 *	cur
		 */
		this_end = min(entry_end, end);
		len = this_end - cur;
		ASSERT(len < U32_MAX);

		if (can_finish_ordered_extent(entry, cur, len, uptodate)) {
			spin_unlock(&inode->ordered_tree_lock);
			btrfs_queue_ordered_fn(entry);
			spin_lock(&inode->ordered_tree_lock);
		}
		cur += len;
	}
	spin_unlock(&inode->ordered_tree_lock);
}

/*
 * Finish IO for one ordered extent across a given range.  The range can only
 * contain one ordered extent.
 *
 * @cached:	 The cached ordered extent. If not NULL, we can skip the tree
 *               search and use the ordered extent directly.
 * 		 Will be also used to store the finished ordered extent.
 * @file_offset: File offset for the finished IO
 * @io_size:	 Length of the finish IO range
 *
 * Return true if the ordered extent is finished in the range, and update
 * @cached.
 * Return false otherwise.
 *
 * NOTE: The range can NOT cross multiple ordered extents.
 * Thus caller should ensure the range doesn't cross ordered extents.
 */
bool btrfs_dec_test_ordered_pending(struct btrfs_inode *inode,
				    struct btrfs_ordered_extent **cached,
				    u64 file_offset, u64 io_size)
{
	struct rb_node *node;
	struct btrfs_ordered_extent *entry = NULL;
	bool finished = false;

	spin_lock(&inode->ordered_tree_lock);
	if (cached && *cached) {
		entry = *cached;
		goto have_entry;
	}

	node = ordered_tree_search(inode, file_offset);
	if (!node)
		goto out;

	entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
have_entry:
	if (!in_range(file_offset, entry->file_offset, entry->num_bytes))
		goto out;

	if (io_size > entry->bytes_left)
		btrfs_crit(inode->root->fs_info,
			   "bad ordered accounting left %llu size %llu",
		       entry->bytes_left, io_size);

	entry->bytes_left -= io_size;

Annotation

Implementation Notes