fs/hfsplus/bnode.c

Source file repositories/reference/linux-study-clean/fs/hfsplus/bnode.c

File Facts

System
Linux kernel
Corpus path
fs/hfsplus/bnode.c
Extension
.c
Size
17165 bytes
Lines
713
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

while ((len -= l) != 0) {
			l = min_t(u32, len, PAGE_SIZE);
			memcpy_page(*++dst_page, 0, *++src_page, 0, l);
			set_page_dirty(*dst_page);
		}
	} else {
		void *src_ptr, *dst_ptr;

		do {
			dst_ptr = kmap_local_page(*dst_page) + dst;
			src_ptr = kmap_local_page(*src_page) + src;
			if (PAGE_SIZE - src < PAGE_SIZE - dst) {
				l = PAGE_SIZE - src;
				src = 0;
				dst += l;
			} else {
				l = PAGE_SIZE - dst;
				src += l;
				dst = 0;
			}
			l = min(len, l);
			memcpy(dst_ptr, src_ptr, l);
			kunmap_local(src_ptr);
			set_page_dirty(*dst_page);
			kunmap_local(dst_ptr);
			if (!dst)
				dst_page++;
			else
				src_page++;
		} while ((len -= l));
	}
}

void hfs_bnode_move(struct hfs_bnode *node, u32 dst, u32 src, u32 len)
{
	struct page **src_page, **dst_page;
	void *src_ptr, *dst_ptr;
	u32 l;

	hfs_dbg("dst %u, src %u, len %u\n", dst, src, len);
	if (!len)
		return;

	len = check_and_correct_requested_length(node, src, len);
	len = check_and_correct_requested_length(node, dst, len);

	src += node->page_offset;
	dst += node->page_offset;
	if (dst > src) {
		src += len - 1;
		src_page = node->page + (src >> PAGE_SHIFT);
		src = (src & ~PAGE_MASK) + 1;
		dst += len - 1;
		dst_page = node->page + (dst >> PAGE_SHIFT);
		dst = (dst & ~PAGE_MASK) + 1;

		if (src == dst) {
			while (src < len) {
				dst_ptr = kmap_local_page(*dst_page);
				src_ptr = kmap_local_page(*src_page);
				memmove(dst_ptr, src_ptr, src);
				kunmap_local(src_ptr);
				set_page_dirty(*dst_page);
				kunmap_local(dst_ptr);
				len -= src;
				src = PAGE_SIZE;
				src_page--;
				dst_page--;
			}
			src -= len;
			dst_ptr = kmap_local_page(*dst_page);
			src_ptr = kmap_local_page(*src_page);
			memmove(dst_ptr + src, src_ptr + src, len);
			kunmap_local(src_ptr);
			set_page_dirty(*dst_page);
			kunmap_local(dst_ptr);
		} else {
			do {
				dst_ptr = kmap_local_page(*dst_page) + dst;
				src_ptr = kmap_local_page(*src_page) + src;
				if (src < dst) {
					l = src;
					src = PAGE_SIZE;
					dst -= l;
				} else {
					l = dst;
					src -= l;
					dst = PAGE_SIZE;
				}
				l = min(len, l);

Annotation

Implementation Notes