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

📄 inode.c

📁 Linux中使用的苹果的Macintosh文件系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/fs/hfs/inode.c * * Copyright (C) 1995-1997  Paul H. Hargrove * (C) 2003 Ardis Technologies <roman@ardistech.com> * This file may be distributed under the terms of the GNU General Public License. * * This file contains inode-related functions which do not depend on * which scheme is being used to represent forks. * * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds */#include <linux/pagemap.h>#include <linux/mpage.h>#include <linux/sched.h>#include "hfs_fs.h"#include "btree.h"static const struct file_operations hfs_file_operations;static const struct inode_operations hfs_file_inode_operations;/*================ Variable-like macros ================*/#define HFS_VALID_MODE_BITS  (S_IFREG | S_IFDIR | S_IRWXUGO)static int hfs_writepage(struct page *page, struct writeback_control *wbc){	return block_write_full_page(page, hfs_get_block, wbc);}static int hfs_readpage(struct file *file, struct page *page){	return block_read_full_page(page, hfs_get_block);}static int hfs_write_begin(struct file *file, struct address_space *mapping,			loff_t pos, unsigned len, unsigned flags,			struct page **pagep, void **fsdata){	*pagep = NULL;	return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,				hfs_get_block,				&HFS_I(mapping->host)->phys_size);}static sector_t hfs_bmap(struct address_space *mapping, sector_t block){	return generic_block_bmap(mapping, block, hfs_get_block);}static int hfs_releasepage(struct page *page, gfp_t mask){	struct inode *inode = page->mapping->host;	struct super_block *sb = inode->i_sb;	struct hfs_btree *tree;	struct hfs_bnode *node;	u32 nidx;	int i, res = 1;	switch (inode->i_ino) {	case HFS_EXT_CNID:		tree = HFS_SB(sb)->ext_tree;		break;	case HFS_CAT_CNID:		tree = HFS_SB(sb)->cat_tree;		break;	default:		BUG();		return 0;	}	if (tree->node_size >= PAGE_CACHE_SIZE) {		nidx = page->index >> (tree->node_size_shift - PAGE_CACHE_SHIFT);		spin_lock(&tree->hash_lock);		node = hfs_bnode_findhash(tree, nidx);		if (!node)			;		else if (atomic_read(&node->refcnt))			res = 0;		if (res && node) {			hfs_bnode_unhash(node);			hfs_bnode_free(node);		}		spin_unlock(&tree->hash_lock);	} else {		nidx = page->index << (PAGE_CACHE_SHIFT - tree->node_size_shift);		i = 1 << (PAGE_CACHE_SHIFT - tree->node_size_shift);		spin_lock(&tree->hash_lock);		do {			node = hfs_bnode_findhash(tree, nidx++);			if (!node)				continue;			if (atomic_read(&node->refcnt)) {				res = 0;				break;			}			hfs_bnode_unhash(node);			hfs_bnode_free(node);		} while (--i && nidx < tree->node_count);		spin_unlock(&tree->hash_lock);	}	return res ? try_to_free_buffers(page) : 0;}static ssize_t hfs_direct_IO(int rw, struct kiocb *iocb,		const struct iovec *iov, loff_t offset, unsigned long nr_segs){	struct file *file = iocb->ki_filp;	struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host;	return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,				  offset, nr_segs, hfs_get_block, NULL);}static int hfs_writepages(struct address_space *mapping,			  struct writeback_control *wbc){	return mpage_writepages(mapping, wbc, hfs_get_block);}const struct address_space_operations hfs_btree_aops = {	.readpage	= hfs_readpage,	.writepage	= hfs_writepage,	.sync_page	= block_sync_page,	.write_begin	= hfs_write_begin,	.write_end	= generic_write_end,	.bmap		= hfs_bmap,	.releasepage	= hfs_releasepage,};const struct address_space_operations hfs_aops = {	.readpage	= hfs_readpage,	.writepage	= hfs_writepage,	.sync_page	= block_sync_page,	.write_begin	= hfs_write_begin,	.write_end	= generic_write_end,	.bmap		= hfs_bmap,	.direct_IO	= hfs_direct_IO,	.writepages	= hfs_writepages,};/* * hfs_new_inode */struct inode *hfs_new_inode(struct inode *dir, struct qstr *name, int mode){	struct super_block *sb = dir->i_sb;	struct inode *inode = new_inode(sb);	if (!inode)		return NULL;	mutex_init(&HFS_I(inode)->extents_lock);	INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list);	hfs_cat_build_key(sb, (btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name);	inode->i_ino = HFS_SB(sb)->next_id++;	inode->i_mode = mode;	inode->i_uid = current_fsuid();	inode->i_gid = current_fsgid();	inode->i_nlink = 1;	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;	HFS_I(inode)->flags = 0;	HFS_I(inode)->rsrc_inode = NULL;	HFS_I(inode)->fs_blocks = 0;	if (S_ISDIR(mode)) {		inode->i_size = 2;		HFS_SB(sb)->folder_count++;		if (dir->i_ino == HFS_ROOT_CNID)			HFS_SB(sb)->root_dirs++;		inode->i_op = &hfs_dir_inode_operations;		inode->i_fop = &hfs_dir_operations;		inode->i_mode |= S_IRWXUGO;		inode->i_mode &= ~HFS_SB(inode->i_sb)->s_dir_umask;	} else if (S_ISREG(mode)) {		HFS_I(inode)->clump_blocks = HFS_SB(sb)->clumpablks;		HFS_SB(sb)->file_count++;		if (dir->i_ino == HFS_ROOT_CNID)			HFS_SB(sb)->root_files++;		inode->i_op = &hfs_file_inode_operations;		inode->i_fop = &hfs_file_operations;		inode->i_mapping->a_ops = &hfs_aops;		inode->i_mode |= S_IRUGO|S_IXUGO;		if (mode & S_IWUSR)			inode->i_mode |= S_IWUGO;		inode->i_mode &= ~HFS_SB(inode->i_sb)->s_file_umask;		HFS_I(inode)->phys_size = 0;		HFS_I(inode)->alloc_blocks = 0;		HFS_I(inode)->first_blocks = 0;		HFS_I(inode)->cached_start = 0;		HFS_I(inode)->cached_blocks = 0;		memset(HFS_I(inode)->first_extents, 0, sizeof(hfs_extent_rec));		memset(HFS_I(inode)->cached_extents, 0, sizeof(hfs_extent_rec));	}	insert_inode_hash(inode);	mark_inode_dirty(inode);	set_bit(HFS_FLG_MDB_DIRTY, &HFS_SB(sb)->flags);	sb->s_dirt = 1;	return inode;}void hfs_delete_inode(struct inode *inode){	struct super_block *sb = inode->i_sb;	dprint(DBG_INODE, "delete_inode: %lu\n", inode->i_ino);	if (S_ISDIR(inode->i_mode)) {		HFS_SB(sb)->folder_count--;		if (HFS_I(inode)->cat_key.ParID == cpu_to_be32(HFS_ROOT_CNID))			HFS_SB(sb)->root_dirs--;		set_bit(HFS_FLG_MDB_DIRTY, &HFS_SB(sb)->flags);		sb->s_dirt = 1;		return;	}	HFS_SB(sb)->file_count--;	if (HFS_I(inode)->cat_key.ParID == cpu_to_be32(HFS_ROOT_CNID))		HFS_SB(sb)->root_files--;	if (S_ISREG(inode->i_mode)) {		if (!inode->i_nlink) {			inode->i_size = 0;			hfs_file_truncate(inode);		}	}	set_bit(HFS_FLG_MDB_DIRTY, &HFS_SB(sb)->flags);	sb->s_dirt = 1;}void hfs_inode_read_fork(struct inode *inode, struct hfs_extent *ext,			 __be32 __log_size, __be32 phys_size, u32 clump_size){	struct super_block *sb = inode->i_sb;	u32 log_size = be32_to_cpu(__log_size);	u16 count;	int i;	memcpy(HFS_I(inode)->first_extents, ext, sizeof(hfs_extent_rec));	for (count = 0, i = 0; i < 3; i++)		count += be16_to_cpu(ext[i].count);	HFS_I(inode)->first_blocks = count;	inode->i_size = HFS_I(inode)->phys_size = log_size;	HFS_I(inode)->fs_blocks = (log_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits;	inode_set_bytes(inode, HFS_I(inode)->fs_blocks << sb->s_blocksize_bits);	HFS_I(inode)->alloc_blocks = be32_to_cpu(phys_size) /				     HFS_SB(sb)->alloc_blksz;	HFS_I(inode)->clump_blocks = clump_size / HFS_SB(sb)->alloc_blksz;	if (!HFS_I(inode)->clump_blocks)		HFS_I(inode)->clump_blocks = HFS_SB(sb)->clumpablks;}struct hfs_iget_data {	struct hfs_cat_key *key;	hfs_cat_rec *rec;};static int hfs_test_inode(struct inode *inode, void *data){	struct hfs_iget_data *idata = data;	hfs_cat_rec *rec;	rec = idata->rec;	switch (rec->type) {	case HFS_CDR_DIR:		return inode->i_ino == be32_to_cpu(rec->dir.DirID);	case HFS_CDR_FIL:		return inode->i_ino == be32_to_cpu(rec->file.FlNum);	default:		BUG();		return 1;	}}/* * hfs_read_inode */static int hfs_read_inode(struct inode *inode, void *data){	struct hfs_iget_data *idata = data;	struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);	hfs_cat_rec *rec;	HFS_I(inode)->flags = 0;	HFS_I(inode)->rsrc_inode = NULL;	mutex_init(&HFS_I(inode)->extents_lock);	INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list);	/* Initialize the inode */	inode->i_uid = hsb->s_uid;	inode->i_gid = hsb->s_gid;	inode->i_nlink = 1;	if (idata->key)		HFS_I(inode)->cat_key = *idata->key;	else		HFS_I(inode)->flags |= HFS_FLG_RSRC;	HFS_I(inode)->tz_secondswest = sys_tz.tz_minuteswest * 60;	rec = idata->rec;	switch (rec->type) {	case HFS_CDR_FIL:		if (!HFS_IS_RSRC(inode)) {			hfs_inode_read_fork(inode, rec->file.ExtRec, rec->file.LgLen,					    rec->file.PyLen, be16_to_cpu(rec->file.ClpSize));		} else {			hfs_inode_read_fork(inode, rec->file.RExtRec, rec->file.RLgLen,					    rec->file.RPyLen, be16_to_cpu(rec->file.ClpSize));		}

⌨️ 快捷键说明

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