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

📄 inode.c

📁 嵌入式系统设计与实验教材二源码linux内核移植与编译
💻 C
📖 第 1 页 / 共 2 页
字号:
 * * Given the MDB for a HFS filesystem, a 'key' and an 'entry' in * the catalog B-tree and the 'type' of the desired file return the * inode for that file/directory or NULL.  Note that 'type' indicates * whether we want the actual file or directory, or the corresponding * metadata (AppleDouble header file or CAP metadata file). * * In an ideal world we could call iget() and would not need this * function.  However, since there is no way to even know the inode * number until we've found the file/directory in the catalog B-tree * that simply won't happen. * * The main idea here is to look in the catalog B-tree to get the * vital info about the file or directory (including the file id which * becomes the inode number) and then to call iget() and return the * inode if it is complete.  If it is not then we use the catalog * entry to fill in the missing info, by calling the appropriate * 'fillin' function.  Note that these fillin functions are * essentially hfs_*_read_inode() functions, but since there is no way * to pass the catalog entry through iget() to such a read_inode() * function, we have to call them after iget() returns an incomplete * inode to us.	 This is pretty much the same problem faced in the NFS * code, and pretty much the same solution. The SMB filesystem deals * with this in a different way: by using the address of the * kmalloc()'d space which holds the data as the inode number. * * XXX: Both this function and NFS's corresponding nfs_fhget() would * benefit from a way to pass an additional (void *) through iget() to * the VFS read_inode() function. * * this will hfs_cat_put() the entry if it fails. */struct inode *hfs_iget(struct hfs_cat_entry *entry, ino_t type,		       struct dentry *dentry){	struct dentry **sys_entry;	struct super_block *sb;	struct inode *inode;	if (!entry) {		return NULL;	}	/* If there are several processes all calling __iget() for	   the same inode then they will all get the same one back.	   The first one to return from __iget() will notice that the	   i_mode field of the inode is blank and KNOW that it is	   the first to return.  Therefore, it will set the appropriate	   'sys_entry' field in the entry and initialize the inode.	   All the initialization must be done without sleeping,	   or else other processes could end up using a partially	   initialized inode.				*/	sb = entry->mdb->sys_mdb;	sys_entry = &entry->sys_entry[HFS_ITYPE_TO_INT(type)];	if (!(inode = iget(sb, ntohl(entry->cnid) | type))) {	        hfs_cat_put(entry);	        return NULL;	}	if (inode->i_dev != sb->s_dev) {	        iput(inode); /* automatically does an hfs_cat_put */		inode = NULL;	} else if (!inode->i_mode || (*sys_entry == NULL)) {		/* Initialize the inode */		struct hfs_sb_info *hsb = HFS_SB(sb);		inode->i_rdev = 0;		inode->i_ctime = inode->i_atime = inode->i_mtime =					hfs_m_to_utime(entry->modify_date);		inode->i_blksize = HFS_SECTOR_SIZE;		inode->i_uid = hsb->s_uid;		inode->i_gid = hsb->s_gid;		memset(HFS_I(inode), 0, sizeof(struct hfs_inode_info));		HFS_I(inode)->magic = HFS_INO_MAGIC;		HFS_I(inode)->entry = entry;		HFS_I(inode)->tz_secondswest = hfs_to_utc(0);		hsb->s_ifill(inode, type, hsb->s_version);		if (!hsb->s_afpd && (entry->type == HFS_CDR_FIL) &&		    (entry->u.file.flags & HFS_FIL_LOCK)) {			inode->i_mode &= ~S_IWUGO;		}		inode->i_mode &= ~hsb->s_umask;		if (!inode->i_mode) {			iput(inode); /* does an hfs_cat_put */			inode = NULL;		} else			*sys_entry = dentry; /* cache dentry */	}	return inode;}/*================ Scheme-specific functions ================*//*  * hfs_cap_ifill() * * This function serves the same purpose as a read_inode() function does * in other filesystems.  It is called by __hfs_iget() to fill in * the missing fields of an uninitialized inode under the CAP scheme. */void hfs_cap_ifill(struct inode * inode, ino_t type, const int version){	struct hfs_cat_entry *entry = HFS_I(inode)->entry;	HFS_I(inode)->d_drop_op = hfs_cap_drop_dentry;	if (type == HFS_CAP_FNDR) {		inode->i_size = sizeof(struct hfs_cap_info);		inode->i_blocks = 0;		inode->i_nlink = 1;		inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;		inode->i_op = &hfs_cap_info_inode_operations;		inode->i_fop = &hfs_cap_info_operations;	} else if (entry->type == HFS_CDR_FIL) {		init_file_inode(inode, (type == HFS_CAP_DATA) ?						HFS_FK_DATA : HFS_FK_RSRC);		inode->i_op = &hfs_file_inode_operations;		inode->i_fop = &hfs_file_operations;		inode->i_mapping->a_ops = &hfs_aops;		inode->u.hfs_i.mmu_private = inode->i_size;	} else { /* Directory */		struct hfs_dir *hdir = &entry->u.dir;		inode->i_blocks = 0;		inode->i_size = hdir->files + hdir->dirs + 5;		HFS_I(inode)->dir_size = 1;		if (type == HFS_CAP_NDIR) {			inode->i_mode = S_IRWXUGO | S_IFDIR;			inode->i_nlink = hdir->dirs + 4;			inode->i_op = &hfs_cap_ndir_inode_operations;			inode->i_fop = &hfs_cap_dir_operations;			HFS_I(inode)->file_type = HFS_CAP_NORM;		} else if (type == HFS_CAP_FDIR) {			inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;			inode->i_nlink = 2;			inode->i_op = &hfs_cap_fdir_inode_operations;			inode->i_fop = &hfs_cap_dir_operations;			HFS_I(inode)->file_type = HFS_CAP_FNDR;		} else if (type == HFS_CAP_RDIR) {			inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;			inode->i_nlink = 2;			inode->i_op = &hfs_cap_rdir_inode_operations;			inode->i_fop = &hfs_cap_dir_operations;			HFS_I(inode)->file_type = HFS_CAP_RSRC;		}	}}/*  * hfs_dbl_ifill() * * This function serves the same purpose as a read_inode() function does * in other filesystems.  It is called by __hfs_iget() to fill in * the missing fields of an uninitialized inode under the AppleDouble * scheme. */void hfs_dbl_ifill(struct inode * inode, ino_t type, const int version){	struct hfs_cat_entry *entry = HFS_I(inode)->entry;	HFS_I(inode)->d_drop_op = hfs_dbl_drop_dentry;	if (type == HFS_DBL_HDR) {		if (entry->type == HFS_CDR_FIL) {			init_file_inode(inode, HFS_FK_RSRC);			inode->i_size += HFS_DBL_HDR_LEN;			HFS_I(inode)->default_layout = &hfs_dbl_fil_hdr_layout;		} else {			inode->i_size = HFS_DBL_HDR_LEN;			inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;			inode->i_nlink = 1;			HFS_I(inode)->default_layout = &hfs_dbl_dir_hdr_layout;		}		inode->i_op = &hfs_hdr_inode_operations;		inode->i_fop = &hfs_hdr_operations;	} else if (entry->type == HFS_CDR_FIL) {		init_file_inode(inode, HFS_FK_DATA);		inode->i_op = &hfs_file_inode_operations;		inode->i_fop = &hfs_file_operations;		inode->i_mapping->a_ops = &hfs_aops;		inode->u.hfs_i.mmu_private = inode->i_size;	} else { /* Directory */		struct hfs_dir *hdir = &entry->u.dir;		inode->i_blocks = 0;		inode->i_nlink = hdir->dirs + 2;		inode->i_size = 3 + 2 * (hdir->dirs + hdir->files);		inode->i_mode = S_IRWXUGO | S_IFDIR;		inode->i_op = &hfs_dbl_dir_inode_operations;		inode->i_fop = &hfs_dbl_dir_operations;		HFS_I(inode)->file_type = HFS_DBL_NORM;		HFS_I(inode)->dir_size = 2;	}}/*  * hfs_nat_ifill() * * This function serves the same purpose as a read_inode() function does * in other filesystems.  It is called by __hfs_iget() to fill in * the missing fields of an uninitialized inode under the Netatalk * scheme. */void hfs_nat_ifill(struct inode * inode, ino_t type, const int version){	struct hfs_cat_entry *entry = HFS_I(inode)->entry;	HFS_I(inode)->d_drop_op = hfs_nat_drop_dentry;	if (type == HFS_NAT_HDR) {		if (entry->type == HFS_CDR_FIL) {			init_file_inode(inode, HFS_FK_RSRC);			inode->i_size += HFS_NAT_HDR_LEN;		} else {			inode->i_size = HFS_NAT_HDR_LEN;			inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;			inode->i_nlink = 1;		}		inode->i_op = &hfs_hdr_inode_operations;		inode->i_fop = &hfs_hdr_operations;		HFS_I(inode)->default_layout = (version == 2) ?			&hfs_nat2_hdr_layout : &hfs_nat_hdr_layout;	} else if (entry->type == HFS_CDR_FIL) {		init_file_inode(inode, HFS_FK_DATA);		inode->i_op = &hfs_file_inode_operations;		inode->i_fop = &hfs_file_operations;		inode->i_mapping->a_ops = &hfs_aops;		inode->u.hfs_i.mmu_private = inode->i_size;	} else { /* Directory */		struct hfs_dir *hdir = &entry->u.dir;		inode->i_blocks = 0;		inode->i_size = hdir->files + hdir->dirs + 4;		inode->i_mode = S_IRWXUGO | S_IFDIR;		HFS_I(inode)->dir_size = 1;		if (type == HFS_NAT_NDIR) {			inode->i_nlink = hdir->dirs + 3;			inode->i_op = &hfs_nat_ndir_inode_operations;			HFS_I(inode)->file_type = HFS_NAT_NORM;		} else if (type == HFS_NAT_HDIR) {			inode->i_nlink = 2;			inode->i_op = &hfs_nat_hdir_inode_operations;			HFS_I(inode)->file_type = HFS_NAT_HDR;		}		inode->i_fop = &hfs_nat_dir_operations;	}}

⌨️ 快捷键说明

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