/* * 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; } else if (entry->type == HFS_CDR_FIL) { init_file_inode(inode, HFS_FK_DATA); inode->i_op = &hfs_file_inode_operations; } 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; 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; HFS_I(inode)->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; } }
/* * 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; HFS_I(inode)->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; } } }
/*创建新的目录项*/ int make_file(int inode, char* name, int type) { char original_name_path[30]; int original_inode = inode_num;//记录当前的inode strcpy(original_name_path, name); if (eat_path(name) == -1) { if (type == File) printf("touch: cannot touch‘%s’: No such file or directory\n", original_name_path); if (type == Directory) printf("mkdir: cannot create directory ‘%s’: No such file or directory\n", original_name_path); return -1; } int new_node; int blk_need = 1;//本目录需要增加磁盘块则blk_need=2 int t; Inode temp; /*读取当前目录的Inode*/ fseek(Disk, InodeBeg + sizeof(Inode)*inode, SEEK_SET); fread(&temp, sizeof(Inode), 1, Disk); if (temp.access[1] == 0) { //当前目录不允许写 if (type == Directory) printf("mkdir: cannot create directory ‘%s’: Permission denied\n", original_name_path); if (type == File) printf("touch: cannot touch ‘%s’: Permission denied\n", original_name_path); close_dir(inode_num); inode_num = original_inode; open_dir(inode_num); return -1; } if (dir_num>MaxDirNum) {//超过了目录文件能包含的最大目录项 if (type == Directory) printf("mkdir: cannot create directory '%s' : Directory full\n", original_name_path); if (type == File) printf("touch: cannot create file '%s' : Directory full\n", original_name_path); close_dir(inode_num); inode_num = original_inode; open_dir(inode_num); return -1; } if (check_name(inode, name) != -1) {//防止重命名 if (type == Directory) printf("mkdir: cannnot create directory '%s' : Directory exist\n", original_name_path); if (type == File) printf("touch: cannot create file '%s' : File exist\n", original_name_path); close_dir(inode_num); inode_num = original_inode; open_dir(inode_num); return -1; } if (dir_num / DirPerBlk != (dir_num + 1) / DirPerBlk) {//本目录也要增加磁盘块 blk_need = 2; } // printf("blk_used:%d\n",super_blk.blk_used); if (super_blk.blk_used + blk_need>BlkNum) { if (type == Directory) printf("mkdir: cannot create directory '%s' :Block used up\n", original_name_path); if (type == File) printf("touch: cannot create file '%s' : Block used up\n", original_name_path); close_dir(inode_num); inode_num = original_inode; open_dir(inode_num); return -1; } if (blk_need == 2) {//本目录需要增加磁盘块 t = curr_inode.blk_num++; curr_inode.blk_identifier[t] = get_blk(); } /*申请inode*/ new_node = apply_inode(); if (new_node == -1) { if (type == Directory) printf("mkdir: cannot create directory '%s' :Inode used up\n", original_name_path); if (type == File) printf("touch: cannot create file '%s' : Inode used up\n", original_name_path); close_dir(inode_num); inode_num = original_inode; open_dir(inode_num); return -1; } if (type == Directory) { /*初始化新建目录的inode*/ init_dir_inode(new_node, inode); } else if (type == File) { /*初始化新建文件的inode*/ init_file_inode(new_node); } strcpy(dir_table[dir_num].name, name); dir_table[dir_num++].inode_num = new_node; close_dir(inode_num); inode_num = original_inode; open_dir(inode_num); return 0; }