1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| int32_t sys_mkdir(const char* pathname) { uint8_t rollback_step = 0; void* io_buf = sys_malloc(SECTOR_SIZE * 2); if (io_buf == NULL) { printk("sys_mkdir: sys_malloc for io_buf failed\n"); return -1; }
struct path_search_record searched_record; memset(&searched_record, 0, sizeof(struct path_search_record)); int inode_no = -1; inode_no = search_file(pathname, &searched_record); if (inode_no != -1) { printk("sys_mkdir: file or directory %s exist!\n", pathname); rollback_step = 1; goto rollback; } else { uint32_t pathname_depth = path_depth_cnt((char*)pathname); uint32_t path_searched_depth = path_depth_cnt(searched_record.searched_path); if (pathname_depth != path_searched_depth) { printk("sys_mkdir: can`t access %s, subpath %s is`t exist\n", pathname, searched_record.searched_path); rollback_step = 1; goto rollback; } }
struct dir* parent_dir = searched_record.parent_dir; char* dirname = strrchr(searched_record.searched_path, '/') + 1;
inode_no = inode_bitmap_alloc(cur_part); if (inode_no == -1) { printk("sys_mkdir: allocate inode failed\n"); rollback_step = 1; goto rollback; }
struct inode new_dir_inode; inode_init(inode_no, &new_dir_inode);
uint32_t block_bitmap_idx = 0; int32_t block_lba = -1;
block_lba = block_bitmap_alloc(cur_part); if (block_lba == -1) { printk("sys_mkdir: block_bitmap_alloc for create directory failed\n"); rollback_step = 2; goto rollback; } new_dir_inode.i_sectors[0] = block_lba; block_bitmap_idx = block_lba - cur_part->sb->data_start_lba; ASSERT(block_bitmap_idx != 0); bitmap_sync(cur_part, block_bitmap_idx, BLOCK_BITMAP); memset(io_buf, 0, SECTOR_SIZE * 2); struct dir_entry* p_de = (struct dir_entry*)io_buf; memcpy(p_de->filename, ".", 1); p_de->i_no = inode_no ; p_de->f_type = FT_DIRECTORY;
p_de++; memcpy(p_de->filename, "..", 2); p_de->i_no = parent_dir->inode->i_no; p_de->f_type = FT_DIRECTORY; ide_write(cur_part->my_disk, new_dir_inode.i_sectors[0], io_buf, 1);
new_dir_inode.i_size = 2 * cur_part->sb->dir_entry_size;
struct dir_entry new_dir_entry; memset(&new_dir_entry, 0, sizeof(struct dir_entry)); create_dir_entry(dirname, inode_no, FT_DIRECTORY, &new_dir_entry); memset(io_buf, 0, SECTOR_SIZE * 2); if (!sync_dir_entry(parent_dir, &new_dir_entry, io_buf)) { printk("sys_mkdir: sync_dir_entry to disk failed!\n"); rollback_step = 2; goto rollback; }
memset(io_buf, 0, SECTOR_SIZE * 2); inode_sync(cur_part, parent_dir->inode, io_buf);
memset(io_buf, 0, SECTOR_SIZE * 2); inode_sync(cur_part, &new_dir_inode, io_buf);
bitmap_sync(cur_part, inode_no, INODE_BITMAP);
sys_free(io_buf);
dir_close(searched_record.parent_dir); return 0;
rollback: switch (rollback_step) { case 2: bitmap_set(&cur_part->inode_bitmap, inode_no, 0); case 1: dir_close(searched_record.parent_dir); break; } sys_free(io_buf); return -1; }
|