⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bnode.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/fs/hfsplus/bnode.c * * Copyright (C) 2001 * Brad Boyer (flar@allandria.com) * (C) 2003 Ardis Technologies <roman@ardistech.com> * * Handle basic btree node operations */#include <linux/string.h>#include <linux/slab.h>#include <linux/pagemap.h>#include <linux/fs.h>#include <linux/swap.h>#include "hfsplus_fs.h"#include "hfsplus_raw.h"/* Copy a specified range of bytes from the raw data of a node */void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len){	struct page **pagep;	int l;	off += node->page_offset;	pagep = node->page + (off >> PAGE_CACHE_SHIFT);	off &= ~PAGE_CACHE_MASK;	l = min(len, (int)PAGE_CACHE_SIZE - off);	memcpy(buf, kmap(*pagep) + off, l);	kunmap(*pagep);	while ((len -= l) != 0) {		buf += l;		l = min(len, (int)PAGE_CACHE_SIZE);		memcpy(buf, kmap(*++pagep), l);		kunmap(*pagep);	}}u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off){	__be16 data;	// optimize later...	hfs_bnode_read(node, &data, off, 2);	return be16_to_cpu(data);}u8 hfs_bnode_read_u8(struct hfs_bnode *node, int off){	u8 data;	// optimize later...	hfs_bnode_read(node, &data, off, 1);	return data;}void hfs_bnode_read_key(struct hfs_bnode *node, void *key, int off){	struct hfs_btree *tree;	int key_len;	tree = node->tree;	if (node->type == HFS_NODE_LEAF ||	    tree->attributes & HFS_TREE_VARIDXKEYS)		key_len = hfs_bnode_read_u16(node, off) + 2;	else		key_len = tree->max_key_len + 2;	hfs_bnode_read(node, key, off, key_len);}void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len){	struct page **pagep;	int l;	off += node->page_offset;	pagep = node->page + (off >> PAGE_CACHE_SHIFT);	off &= ~PAGE_CACHE_MASK;	l = min(len, (int)PAGE_CACHE_SIZE - off);	memcpy(kmap(*pagep) + off, buf, l);	set_page_dirty(*pagep);	kunmap(*pagep);	while ((len -= l) != 0) {		buf += l;		l = min(len, (int)PAGE_CACHE_SIZE);		memcpy(kmap(*++pagep), buf, l);		set_page_dirty(*pagep);		kunmap(*pagep);	}}void hfs_bnode_write_u16(struct hfs_bnode *node, int off, u16 data){	__be16 v = cpu_to_be16(data);	// optimize later...	hfs_bnode_write(node, &v, off, 2);}void hfs_bnode_clear(struct hfs_bnode *node, int off, int len){	struct page **pagep;	int l;	off += node->page_offset;	pagep = node->page + (off >> PAGE_CACHE_SHIFT);	off &= ~PAGE_CACHE_MASK;	l = min(len, (int)PAGE_CACHE_SIZE - off);	memset(kmap(*pagep) + off, 0, l);	set_page_dirty(*pagep);	kunmap(*pagep);	while ((len -= l) != 0) {		l = min(len, (int)PAGE_CACHE_SIZE);		memset(kmap(*++pagep), 0, l);		set_page_dirty(*pagep);		kunmap(*pagep);	}}void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst,		    struct hfs_bnode *src_node, int src, int len){	struct hfs_btree *tree;	struct page **src_page, **dst_page;	int l;	dprint(DBG_BNODE_MOD, "copybytes: %u,%u,%u\n", dst, src, len);	if (!len)		return;	tree = src_node->tree;	src += src_node->page_offset;	dst += dst_node->page_offset;	src_page = src_node->page + (src >> PAGE_CACHE_SHIFT);	src &= ~PAGE_CACHE_MASK;	dst_page = dst_node->page + (dst >> PAGE_CACHE_SHIFT);	dst &= ~PAGE_CACHE_MASK;	if (src == dst) {		l = min(len, (int)PAGE_CACHE_SIZE - src);		memcpy(kmap(*dst_page) + src, kmap(*src_page) + src, l);		kunmap(*src_page);		set_page_dirty(*dst_page);		kunmap(*dst_page);		while ((len -= l) != 0) {			l = min(len, (int)PAGE_CACHE_SIZE);			memcpy(kmap(*++dst_page), kmap(*++src_page), l);			kunmap(*src_page);			set_page_dirty(*dst_page);			kunmap(*dst_page);		}	} else {		void *src_ptr, *dst_ptr;		do {			src_ptr = kmap(*src_page) + src;			dst_ptr = kmap(*dst_page) + dst;			if (PAGE_CACHE_SIZE - src < PAGE_CACHE_SIZE - dst) {				l = PAGE_CACHE_SIZE - src;				src = 0;				dst += l;			} else {				l = PAGE_CACHE_SIZE - dst;				src += l;				dst = 0;			}			l = min(len, l);			memcpy(dst_ptr, src_ptr, l);			kunmap(*src_page);			set_page_dirty(*dst_page);			kunmap(*dst_page);			if (!dst)				dst_page++;			else				src_page++;		} while ((len -= l));	}}void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len){	struct page **src_page, **dst_page;	int l;	dprint(DBG_BNODE_MOD, "movebytes: %u,%u,%u\n", dst, src, len);	if (!len)		return;	src += node->page_offset;	dst += node->page_offset;	if (dst > src) {		src += len - 1;		src_page = node->page + (src >> PAGE_CACHE_SHIFT);		src = (src & ~PAGE_CACHE_MASK) + 1;		dst += len - 1;		dst_page = node->page + (dst >> PAGE_CACHE_SHIFT);		dst = (dst & ~PAGE_CACHE_MASK) + 1;		if (src == dst) {			while (src < len) {				memmove(kmap(*dst_page), kmap(*src_page), src);				kunmap(*src_page);				set_page_dirty(*dst_page);				kunmap(*dst_page);				len -= src;				src = PAGE_CACHE_SIZE;				src_page--;				dst_page--;			}			src -= len;			memmove(kmap(*dst_page) + src, kmap(*src_page) + src, len);			kunmap(*src_page);			set_page_dirty(*dst_page);			kunmap(*dst_page);		} else {			void *src_ptr, *dst_ptr;			do {				src_ptr = kmap(*src_page) + src;				dst_ptr = kmap(*dst_page) + dst;				if (src < dst) {					l = src;					src = PAGE_CACHE_SIZE;					dst -= l;				} else {					l = dst;					src -= l;					dst = PAGE_CACHE_SIZE;				}				l = min(len, l);				memmove(dst_ptr - l, src_ptr - l, l);				kunmap(*src_page);				set_page_dirty(*dst_page);				kunmap(*dst_page);				if (dst == PAGE_CACHE_SIZE)					dst_page--;				else					src_page--;			} while ((len -= l));		}	} else {		src_page = node->page + (src >> PAGE_CACHE_SHIFT);		src &= ~PAGE_CACHE_MASK;		dst_page = node->page + (dst >> PAGE_CACHE_SHIFT);		dst &= ~PAGE_CACHE_MASK;		if (src == dst) {			l = min(len, (int)PAGE_CACHE_SIZE - src);			memmove(kmap(*dst_page) + src, kmap(*src_page) + src, l);			kunmap(*src_page);			set_page_dirty(*dst_page);			kunmap(*dst_page);			while ((len -= l) != 0) {				l = min(len, (int)PAGE_CACHE_SIZE);				memmove(kmap(*++dst_page), kmap(*++src_page), l);				kunmap(*src_page);				set_page_dirty(*dst_page);				kunmap(*dst_page);			}		} else {			void *src_ptr, *dst_ptr;			do {				src_ptr = kmap(*src_page) + src;				dst_ptr = kmap(*dst_page) + dst;				if (PAGE_CACHE_SIZE - src < PAGE_CACHE_SIZE - dst) {					l = PAGE_CACHE_SIZE - src;					src = 0;					dst += l;				} else {					l = PAGE_CACHE_SIZE - dst;					src += l;					dst = 0;				}				l = min(len, l);				memmove(dst_ptr, src_ptr, l);				kunmap(*src_page);				set_page_dirty(*dst_page);				kunmap(*dst_page);				if (!dst)					dst_page++;				else					src_page++;			} while ((len -= l));		}	}}void hfs_bnode_dump(struct hfs_bnode *node){	struct hfs_bnode_desc desc;	__be32 cnid;	int i, off, key_off;	dprint(DBG_BNODE_MOD, "bnode: %d\n", node->this);	hfs_bnode_read(node, &desc, 0, sizeof(desc));	dprint(DBG_BNODE_MOD, "%d, %d, %d, %d, %d\n",		be32_to_cpu(desc.next), be32_to_cpu(desc.prev),		desc.type, desc.height, be16_to_cpu(desc.num_recs));	off = node->tree->node_size - 2;	for (i = be16_to_cpu(desc.num_recs); i >= 0; off -= 2, i--) {		key_off = hfs_bnode_read_u16(node, off);		dprint(DBG_BNODE_MOD, " %d", key_off);		if (i && node->type == HFS_NODE_INDEX) {			int tmp;			if (node->tree->attributes & HFS_TREE_VARIDXKEYS)				tmp = hfs_bnode_read_u16(node, key_off) + 2;			else				tmp = node->tree->max_key_len + 2;			dprint(DBG_BNODE_MOD, " (%d", tmp);			hfs_bnode_read(node, &cnid, key_off + tmp, 4);			dprint(DBG_BNODE_MOD, ",%d)", be32_to_cpu(cnid));		} else if (i && node->type == HFS_NODE_LEAF) {			int tmp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -