void do_set_bmap(int argc, char **argv) { const char *usage = "[--uninit] <lblk> <pblk>"; struct ext2fs_extent extent; errcode_t retval; blk_t logical; blk_t physical; char *cmd = argv[0]; int flags = 0; int err; if (common_extent_args_process(argc, argv, 3, 5, "set_bmap", usage, CHECK_FS_RW | CHECK_FS_BITMAPS)) return; if (argc > 2 && !strcmp(argv[1], "--uninit")) { argc--; argv++; flags |= EXT2_EXTENT_SET_BMAP_UNINIT; } if (argc != 3) { fprintf(stderr, "Usage: %s %s\n", cmd, usage); return; } logical = parse_ulong(argv[1], cmd, "logical block", &err); if (err) return; physical = parse_ulong(argv[2], cmd, "physical block", &err); if (err) return; retval = ext2fs_extent_set_bmap(current_handle, logical, (blk64_t) physical, flags); if (retval) { com_err(cmd, retval, 0); return; } retval = ext2fs_extent_get(current_handle, EXT2_EXTENT_CURRENT, &extent); if (retval) return; dbg_print_extent(0, &extent); }
errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum, const char *name) { ext2_extent_handle_t handle; errcode_t retval; struct ext2_inode parent_inode, inode; ext2_ino_t ino = inum; ext2_ino_t scratch_ino; blk64_t blk; char *block = 0; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); /* * Allocate an inode, if necessary */ if (!ino) { retval = ext2fs_new_inode(fs, parent, LINUX_S_IFDIR | 0755, 0, &ino); if (retval) goto cleanup; } /* * Allocate a data block for the directory */ retval = ext2fs_new_block2(fs, 0, 0, &blk); if (retval) goto cleanup; /* * Create a scratch template for the directory */ retval = ext2fs_new_dir_block(fs, ino, parent, &block); if (retval) goto cleanup; /* * Get the parent's inode, if necessary */ if (parent != ino) { retval = ext2fs_read_inode(fs, parent, &parent_inode); if (retval) goto cleanup; } else memset(&parent_inode, 0, sizeof(parent_inode)); /* * Create the inode structure.... */ memset(&inode, 0, sizeof(struct ext2_inode)); inode.i_mode = LINUX_S_IFDIR | (0777 & ~fs->umask); inode.i_uid = inode.i_gid = 0; ext2fs_iblk_set(fs, &inode, 1); if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) inode.i_flags |= EXT4_EXTENTS_FL; else inode.i_block[0] = blk; inode.i_links_count = 2; inode.i_size = fs->blocksize; /* * Write out the inode and inode data block */ retval = ext2fs_write_dir_block(fs, blk, block); if (retval) goto cleanup; retval = ext2fs_write_new_inode(fs, ino, &inode); if (retval) goto cleanup; if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) { retval = ext2fs_extent_open2(fs, ino, &inode, &handle); if (retval) goto cleanup; retval = ext2fs_extent_set_bmap(handle, 0, blk, 0); ext2fs_extent_free(handle); if (retval) goto cleanup; } /* * Link the directory into the filesystem hierarchy */ if (name) { retval = ext2fs_lookup(fs, parent, name, strlen(name), 0, &scratch_ino); if (!retval) { retval = EXT2_ET_DIR_EXISTS; name = 0; goto cleanup; } if (retval != EXT2_ET_FILE_NOT_FOUND) goto cleanup; retval = ext2fs_link(fs, parent, name, ino, EXT2_FT_DIR); if (retval) goto cleanup; } /* * Update parent inode's counts */ if (parent != ino) { parent_inode.i_links_count++; retval = ext2fs_write_inode(fs, parent, &parent_inode); if (retval) goto cleanup; } /* * Update accounting.... */ ext2fs_block_alloc_stats2(fs, blk, +1); ext2fs_inode_alloc_stats2(fs, ino, +1, 1); cleanup: if (block) ext2fs_free_mem(&block); return retval; }