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

📄 inode.c

📁 嵌入式系统设计与实验教材二源码linux内核移植与编译
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * linux/fs/hfs/inode.c * * Copyright (C) 1995-1997  Paul H. Hargrove * 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 * * "XXX" in a comment is a note to myself to consider changing something. * * In function preconditions the term "valid" applied to a pointer to * a structure means that the pointer is non-NULL and the structure it * points to has all fields initialized to consistent values. */#include "hfs.h"#include <linux/hfs_fs_sb.h>#include <linux/hfs_fs_i.h>#include <linux/hfs_fs.h>#include <linux/smp_lock.h>/*================ Variable-like macros ================*/#define HFS_VALID_MODE_BITS  (S_IFREG | S_IFDIR | S_IRWXUGO)/*================ File-local functions ================*//* * init_file_inode() * * Given an HFS catalog entry initialize an inode for a file. */static void init_file_inode(struct inode *inode, hfs_u8 fork){	struct hfs_fork *fk;	struct hfs_cat_entry *entry = HFS_I(inode)->entry;	if (fork == HFS_FK_DATA) {		inode->i_mode = S_IRWXUGO | S_IFREG;	} else {		inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;	}	if (fork == HFS_FK_DATA) {#if 0 /* XXX: disable crlf translations for now */		hfs_u32 type = hfs_get_nl(entry->info.file.finfo.fdType);		HFS_I(inode)->convert =			((HFS_SB(inode->i_sb)->s_conv == 't') ||			 ((HFS_SB(inode->i_sb)->s_conv == 'a') &&			  ((type == htonl(0x54455854)) ||   /* "TEXT" */			   (type == htonl(0x7474726f)))));  /* "ttro" */#else		HFS_I(inode)->convert = 0;#endif		fk = &entry->u.file.data_fork;	} else {		fk = &entry->u.file.rsrc_fork;		HFS_I(inode)->convert = 0;	}	HFS_I(inode)->fork = fk;	inode->i_size = fk->lsize;	inode->i_blocks = fk->psize;	inode->i_nlink = 1;}/*================ Global functions ================*//* * hfs_put_inode() * * This is the put_inode() entry in the super_operations for HFS * filesystems.  The purpose is to perform any filesystem-dependent  * cleanup necessary when the use-count of an inode falls to zero. */void hfs_put_inode(struct inode * inode){	struct hfs_cat_entry *entry = HFS_I(inode)->entry;	lock_kernel();	hfs_cat_put(entry);	if (atomic_read(&inode->i_count) == 1) {	  struct hfs_hdr_layout *tmp = HFS_I(inode)->layout;	  if (tmp) {		HFS_I(inode)->layout = NULL;		HFS_DELETE(tmp);	  }	}	unlock_kernel();}/* * hfs_notify_change() * * Based very closely on fs/msdos/inode.c by Werner Almesberger * * This is the notify_change() field in the super_operations structure * for HFS file systems.  The purpose is to take that changes made to * an inode and apply then in a filesystem-dependent manner.  In this * case the process has a few of tasks to do: *  1) prevent changes to the i_uid and i_gid fields. *  2) map file permissions to the closest allowable permissions *  3) Since multiple Linux files can share the same on-disk inode under *     HFS (for instance the data and resource forks of a file) a change *     to permissions must be applied to all other in-core inodes which  *     correspond to the same HFS file. */enum {HFS_NORM, HFS_HDR, HFS_CAP};static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int kind){	struct inode *inode = dentry->d_inode;	struct hfs_cat_entry *entry = HFS_I(inode)->entry;	struct dentry **de = entry->sys_entry;	struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);	int error, i;	error = inode_change_ok(inode, attr); /* basic permission checks */	if (error) {		/* Let netatalk's afpd think chmod() always succeeds */		if (hsb->s_afpd &&		    (attr->ia_valid == (ATTR_MODE | ATTR_CTIME))) {			return 0;		} else {			return error;		}	}	/* no uig/gid changes and limit which mode bits can be set */	if (((attr->ia_valid & ATTR_UID) && 	     (attr->ia_uid != hsb->s_uid)) ||	    ((attr->ia_valid & ATTR_GID) && 	     (attr->ia_gid != hsb->s_gid)) ||	    ((attr->ia_valid & ATTR_MODE) &&	     (((entry->type == HFS_CDR_DIR) &&	       (attr->ia_mode != inode->i_mode))||	      (attr->ia_mode & ~HFS_VALID_MODE_BITS)))) {		return hsb->s_quiet ? 0 : error;	}		if (entry->type == HFS_CDR_DIR) {		attr->ia_valid &= ~ATTR_MODE;	} else if (attr->ia_valid & ATTR_MODE) {		/* Only the 'w' bits can ever change and only all together. */		if (attr->ia_mode & S_IWUSR) {			attr->ia_mode = inode->i_mode | S_IWUGO;		} else {			attr->ia_mode = inode->i_mode & ~S_IWUGO;		}		attr->ia_mode &= ~hsb->s_umask;	}	/*	 * Normal files handle size change in normal way.	 * Oddballs are served here.	 */	if (attr->ia_valid & ATTR_SIZE) {		if (kind == HFS_CAP) {			inode->i_size = attr->ia_size;			if (inode->i_size > HFS_FORK_MAX)				inode->i_size = HFS_FORK_MAX;			mark_inode_dirty(inode);			attr->ia_valid &= ~ATTR_SIZE;		} else if (kind == HFS_HDR) {			hdr_truncate(inode, attr->ia_size);			attr->ia_valid &= ~ATTR_SIZE;		}	}	error = inode_setattr(inode, attr);	if (error)		return error;	/* We wouldn't want to mess with the sizes of the other fork */	attr->ia_valid &= ~ATTR_SIZE;	/* We must change all in-core inodes corresponding to this file. */	for (i = 0; i < 4; ++i) {	  if (de[i] && (de[i] != dentry)) {		inode_setattr(de[i]->d_inode, attr);	  }	}	/* Change the catalog entry if needed */	if (attr->ia_valid & ATTR_MTIME) {		entry->modify_date = hfs_u_to_mtime(inode->i_mtime);		hfs_cat_mark_dirty(entry);	}	if (attr->ia_valid & ATTR_MODE) {		hfs_u8 new_flags;		if (inode->i_mode & S_IWUSR) {			new_flags = entry->u.file.flags & ~HFS_FIL_LOCK;		} else {			new_flags = entry->u.file.flags | HFS_FIL_LOCK;		}		if (new_flags != entry->u.file.flags) {			entry->u.file.flags = new_flags;			hfs_cat_mark_dirty(entry);		}	}	/* size changes handled in hfs_extent_adj() */	return 0;}int hfs_notify_change(struct dentry *dentry, struct iattr * attr){	return __hfs_notify_change(dentry, attr, HFS_NORM);}int hfs_notify_change_cap(struct dentry *dentry, struct iattr * attr){	return __hfs_notify_change(dentry, attr, HFS_CAP);}int hfs_notify_change_hdr(struct dentry *dentry, struct iattr * attr){	return __hfs_notify_change(dentry, attr, HFS_HDR);}static int hfs_writepage(struct page *page){	return block_write_full_page(page,hfs_get_block);}static int hfs_readpage(struct file *file, struct page *page){	return block_read_full_page(page,hfs_get_block);}static int hfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to){	return cont_prepare_write(page,from,to,hfs_get_block,		&page->mapping->host->u.hfs_i.mmu_private);}static int hfs_bmap(struct address_space *mapping, long block){	return generic_block_bmap(mapping,block,hfs_get_block);}struct address_space_operations hfs_aops = {	readpage: hfs_readpage,	writepage: hfs_writepage,	sync_page: block_sync_page,	prepare_write: hfs_prepare_write,	commit_write: generic_commit_write,	bmap: hfs_bmap};/* * __hfs_iget()

⌨️ 快捷键说明

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