errcode_t ocfs2_chain_iterate(ocfs2_filesys *fs, uint64_t blkno, int (*func)(ocfs2_filesys *fs, uint64_t gd_blkno, int chain_num, void *priv_data), void *priv_data) { int iret = 0; char *buf; struct ocfs2_dinode *inode; errcode_t ret; struct chain_context ctxt; ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) return ret; ret = ocfs2_read_inode(fs, blkno, buf); if (ret) goto out_buf; inode = (struct ocfs2_dinode *)buf; ret = OCFS2_ET_INODE_NOT_VALID; if (!(inode->i_flags & OCFS2_VALID_FL)) goto out_buf; ret = OCFS2_ET_INODE_CANNOT_BE_ITERATED; if (!(inode->i_flags & OCFS2_CHAIN_FL)) goto out_buf; ret = ocfs2_malloc0(fs->fs_blocksize, &ctxt.gd_buf); if (ret) goto out_gd_buf; ctxt.fs = fs; ctxt.func = func; ctxt.priv_data = priv_data; ret = 0; iret |= chain_iterate_cl(&inode->id2.i_chain, &ctxt); if (iret & OCFS2_EXTENT_ERROR) ret = ctxt.errcode; if (iret & OCFS2_EXTENT_CHANGED) { /* Do something */ } out_gd_buf: if (ctxt.gd_buf) ocfs2_free(&ctxt.gd_buf); out_buf: ocfs2_free(&buf); return ret; }
int is_dir_inlined(char *dirent_name, unsigned long *i_size, unsigned int *id_count) { int ret; uint64_t workplace_blk_no = 1; uint64_t testdir_blk_no = 1; char *buf = NULL; struct ocfs2_dinode *di; struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super); sync(); ocfs2_malloc_block(fs->fs_io, &buf); /*lookup worksplace inode*/ ret = ocfs2_lookup(fs, sb->s_root_blkno, WORK_PLACE, strlen(WORK_PLACE), NULL, &workplace_blk_no); if (ret < 0) { fprintf(stderr, "failed to lookup work_place(%s)'s" " inode blkno\n", work_place); ocfs2_free(&buf); exit(ret); } /*lookup file inode,then read*/ ret = ocfs2_lookup(fs, workplace_blk_no, dirent_name, strlen(dirent_name), NULL, &testdir_blk_no); if (ret < 0) { fprintf(stderr, "failed to lookup file(%s/%s)'s" " inode blkno\n", work_place, dirent_name); ocfs2_free(&buf); exit(ret); } ret = ocfs2_read_inode(fs, testdir_blk_no, buf); if (ret < 0) { fprintf(stderr, "failed to read file(%s/%s/%s)'s" " inode.\n", mount_point, WORK_PLACE, dirent_name); ocfs2_free(&buf); exit(ret); } di = (struct ocfs2_dinode *)buf; *i_size = di->i_size; *id_count = ((di->id2).i_data).id_count; if (di->i_dyn_features & OCFS2_INLINE_DATA_FL) ret = 1; else ret = 0; ocfs2_free(&buf); return ret; }
static int fs_features_run(struct o2info_operation *op, struct o2info_method *om, void *arg) { int rc = 0; static struct o2info_fs_features ofs; char *compat = NULL; char *incompat = NULL; char *rocompat = NULL; char *features = NULL; if (om->om_method == O2INFO_USE_IOCTL) rc = get_fs_features_ioctl(op, om->om_fd, &ofs); else rc = o2info_get_fs_features(om->om_fs, &ofs); if (rc) goto out; rc = o2info_get_compat_flag(ofs.compat, &compat); if (rc) goto out; rc = o2info_get_incompat_flag(ofs.incompat, &incompat); if (rc) goto out; rc = o2info_get_rocompat_flag(ofs.rocompat, &rocompat); if (rc) goto out; features = malloc(strlen(compat) + strlen(incompat) + strlen(rocompat) + 3); sprintf(features, "%s %s %s", compat, incompat, rocompat); o2info_print_line("", features, ' '); out: if (compat) ocfs2_free(&compat); if (incompat) ocfs2_free(&incompat); if (rocompat) ocfs2_free(&rocompat); if (features) ocfs2_free(&features); return rc; }
errcode_t io_close(io_channel *channel) { errcode_t ret = 0; io_destroy_cache(channel); if (close(channel->io_fd) < 0) ret = errno; ocfs2_free(&channel->io_name); ocfs2_free(&channel); return ret; }
/* * Emtpy the blocks on the disk. */ static errcode_t empty_blocks(ocfs2_filesys *fs, uint64_t start_blk, uint64_t num_blocks) { errcode_t ret; char *buf = NULL; ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) goto bail; memset(buf, 0, fs->fs_blocksize); while (num_blocks) { ret = io_write_block(fs->fs_io, start_blk, 1, buf); if (ret) goto bail; num_blocks--; start_blk++; } bail: if (buf) ocfs2_free(&buf); return ret; }
errcode_t ocfs2_extend_file(ocfs2_filesys *fs, uint64_t ino, uint64_t new_size) { errcode_t ret = 0; char *buf = NULL; struct ocfs2_dinode* di = NULL; if (!(fs->fs_flags & OCFS2_FLAG_RW)) return OCFS2_ET_RO_FILESYS; ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) return ret; ret = ocfs2_read_inode(fs, ino, buf); if (ret) goto out_free_buf; di = (struct ocfs2_dinode *)buf; if (di->i_size >= new_size) { ret = EINVAL; goto out_free_buf; } di->i_size = new_size; ret = ocfs2_write_inode(fs, ino, buf); out_free_buf: if (buf) ocfs2_free(&buf); return ret; }
/* * When creating printf fields for ourselves, we need to avoid the * standard specifiers. All lowercase specifiers are reserved by C99. * Reserved uppercase specifiers are: E, F, G, A, C, S, X, L */ static int query_run(struct tunefs_operation *op, ocfs2_filesys *fs, int flags) { char *queryfmt = op->to_private; char *fmt; fmt = process_escapes(queryfmt); if (!fmt) { tcom_err(TUNEFS_ET_NO_MEMORY, "while escaping the query format"); return 1; } register_printf_function('B', handle_blocksize, handle_arginfo); register_printf_function('T', handle_clustersize, handle_arginfo); register_printf_function('N', handle_numslots, handle_arginfo); register_printf_function('R', handle_rootdir, handle_arginfo); register_printf_function('Y', handle_sysdir, handle_arginfo); register_printf_function('P', handle_clustergroup, handle_arginfo); register_printf_function('V', handle_label, handle_arginfo); register_printf_function('U', handle_uuid, handle_arginfo); register_printf_function('M', handle_compat, handle_arginfo); register_printf_function('H', handle_incompat, handle_arginfo); register_printf_function('O', handle_ro_compat, handle_arginfo); query_fs = fs; fprintf(stdout, fmt); query_fs = NULL; ocfs2_free(&fmt); return 0; }
errcode_t ocfs2_image_free_bitmap(ocfs2_filesys *ofs) { struct ocfs2_image_state *ost = ofs->ost; int i; if (!ost->ost_bmparr) return 0; for (i=0; i<ost->ost_bmpblks; i++) if (ost->ost_bmparr[i].arr_self) ocfs2_free(&ost->ost_bmparr[i].arr_self); if (ost->ost_bmparr) ocfs2_free(&ost->ost_bmparr); return 0; }
errcode_t o2fsck_type_from_dinode(o2fsck_state *ost, uint64_t ino, uint8_t *type) { char *buf = NULL; errcode_t ret; struct ocfs2_dinode *dinode; const char *whoami = __FUNCTION__; *type = 0; ret = ocfs2_malloc_block(ost->ost_fs->fs_io, &buf); if (ret) { com_err(whoami, ret, "while allocating an inode buffer to " "read and discover the type of inode %"PRIu64, ino); goto out; } ret = ocfs2_read_inode(ost->ost_fs, ino, buf); if (ret) { com_err(whoami, ret, "while reading inode %"PRIu64" to " "discover its file type", ino); goto out; } dinode = (struct ocfs2_dinode *)buf; *type = ocfs2_type_by_mode[(dinode->i_mode & S_IFMT)>>S_SHIFT]; out: if (buf) ocfs2_free(&buf); return ret; }
static errcode_t ocfs2_validate_ocfs1_header(ocfs2_filesys *fs) { errcode_t ret; char *blk; struct ocfs1_vol_disk_hdr *hdr; ret = ocfs2_malloc_block(fs->fs_io, &blk); if (ret) return ret; ret = ocfs2_read_blocks(fs, 0, 1, blk); if (ret) goto out; hdr = (struct ocfs1_vol_disk_hdr *)blk; ret = OCFS2_ET_OCFS_REV; if (le32_to_cpu(hdr->major_version) == OCFS1_MAJOR_VERSION) goto out; if (!memcmp(hdr->signature, OCFS1_VOLUME_SIGNATURE, strlen(OCFS1_VOLUME_SIGNATURE))) goto out; ret = 0; out: ocfs2_free(&blk); return ret; }
errcode_t ocfs2_extent_iterate(ocfs2_filesys *fs, uint64_t blkno, int flags, char *block_buf, int (*func)(ocfs2_filesys *fs, struct ocfs2_extent_rec *rec, int tree_depth, uint32_t ccount, uint64_t ref_blkno, int ref_recno, void *priv_data), void *priv_data) { char *buf = NULL; struct ocfs2_dinode *inode; errcode_t ret; ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) return ret; ret = ocfs2_read_inode(fs, blkno, buf); if (ret) goto out_buf; inode = (struct ocfs2_dinode *)buf; ret = ocfs2_extent_iterate_inode(fs, inode, flags, block_buf, func, priv_data); out_buf: if (buf) ocfs2_free(&buf); return ret; }
errcode_t ocfs2_block_iterate(ocfs2_filesys *fs, uint64_t blkno, int flags, int (*func)(ocfs2_filesys *fs, uint64_t blkno, uint64_t bcount, uint16_t ext_flags, void *priv_data), void *priv_data) { struct ocfs2_dinode *inode; errcode_t ret; char *buf; ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) return ret; ret = ocfs2_read_inode(fs, blkno, buf); if (ret) goto out_buf; inode = (struct ocfs2_dinode *)buf; ret = ocfs2_block_iterate_inode(fs, inode, flags, func, priv_data); out_buf: ocfs2_free(&buf); return ret; }
void mess_up_inode_alloc(ocfs2_filesys *fs, enum fsck_type type, uint16_t slotnum) { errcode_t ret; uint64_t tmpblkno; char *buf = NULL; struct ocfs2_dinode *di; ret = ocfs2_new_inode(fs, &tmpblkno, S_IFREG | 0755); if (ret) FSWRK_COM_FATAL(progname, ret); ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) FSWRK_COM_FATAL(progname, ret); ret = ocfs2_read_inode(fs, tmpblkno, buf); if (ret) FSWRK_COM_FATAL(progname, ret); di = (struct ocfs2_dinode *)buf; di->i_flags &= ~OCFS2_VALID_FL; ret = ocfs2_write_inode(fs, tmpblkno, buf); if (ret) FSWRK_COM_FATAL(progname, ret); fprintf(stdout, "INODE_ALLOC_REPAIR: " "Create an inode#%"PRIu64" and invalidate it.\n", tmpblkno); if (buf) ocfs2_free(&buf); return; }
errcode_t ocfs2_write_backup_super(ocfs2_filesys *fs, uint64_t blkno) { errcode_t ret; char *buf = NULL; struct ocfs2_dinode *di; if (!(fs->fs_flags & OCFS2_FLAG_RW)) return OCFS2_ET_RO_FILESYS; ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) goto out_blk; memcpy(buf, (char *)fs->fs_super, fs->fs_blocksize); di = (struct ocfs2_dinode *)buf; ret = OCFS2_ET_BAD_MAGIC; if (memcmp(di->i_signature, OCFS2_SUPER_BLOCK_SIGNATURE, strlen(OCFS2_SUPER_BLOCK_SIGNATURE))) goto out_blk; di->i_blkno = blkno; OCFS2_SET_COMPAT_FEATURE(OCFS2_RAW_SB(di), OCFS2_FEATURE_COMPAT_BACKUP_SB); ret = ocfs2_write_inode(fs, blkno, buf); if (ret) goto out_blk; ret = 0; out_blk: if (buf) ocfs2_free(&buf); return ret; }
errcode_t ocfs2_bitmap_alloc_region(ocfs2_bitmap *bitmap, uint64_t start_bit, int bitmap_start, int total_bits, struct ocfs2_bitmap_region **ret_br) { errcode_t ret; struct ocfs2_bitmap_region *br; if (total_bits < 0) return OCFS2_ET_INVALID_BIT; ret = ocfs2_malloc0(sizeof(struct ocfs2_bitmap_region), &br); if (ret) return ret; br->br_start_bit = start_bit; br->br_bitmap_start = bitmap_start; br->br_valid_bits = total_bits; br->br_total_bits = total_bits + bitmap_start; br->br_bytes = ocfs2_align_total(br->br_total_bits); ret = ocfs2_malloc0(br->br_bytes, &br->br_bitmap); if (ret) ocfs2_free(&br); else *ret_br = br; return ret; }
static errcode_t create_local_alloc(ocfs2_filesys *fs, uint16_t slot) { errcode_t ret; char *buf = NULL; struct ocfs2_dinode *di; struct ocfs2_local_alloc *la; uint32_t la_size, found; uint64_t la_off, blkno; ret = ocfs2_lookup_system_inode(fs, LOCAL_ALLOC_SYSTEM_INODE, slot, &blkno); if (ret) goto bail; ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) goto bail; ret = ocfs2_read_inode(fs, blkno, buf); if (ret) goto bail; di = (struct ocfs2_dinode *)buf; if (!(di->i_flags & OCFS2_VALID_FL)) goto bail; if (!(di->i_flags & OCFS2_LOCAL_ALLOC_FL)) goto bail; if (di->id1.bitmap1.i_total > 0) { fprintf(stderr, "local alloc#%"PRIu64" file not empty." "Can't create a new one.\n", blkno); goto bail; } la_size = get_local_alloc_window_bits(); ret = ocfs2_new_clusters(fs, 1, la_size, &la_off, &found); if (ret) goto bail; if(la_size != found) goto bail; la = &(di->id2.i_lab); la->la_bm_off = ocfs2_blocks_to_clusters(fs, la_off); di->id1.bitmap1.i_total = la_size; di->id1.bitmap1.i_used = 0; memset(la->la_bitmap, 0, la->la_size); ret = ocfs2_write_inode(fs, blkno, buf); bail: if(buf) ocfs2_free(&buf); return ret; }
static void io_free_cache(struct io_cache *ic) { if (ic) { if (ic->ic_data_buffer) { if (ic->ic_locked) munlock(ic->ic_data_buffer, ic->ic_data_buffer_len); ocfs2_free(&ic->ic_data_buffer); } if (ic->ic_metadata_buffer) { if (ic->ic_locked) munlock(ic->ic_metadata_buffer, ic->ic_metadata_buffer_len); ocfs2_free(&ic->ic_metadata_buffer); } ocfs2_free(&ic); } }
static errcode_t truncate_log_check(ocfs2_filesys *fs, uint16_t new_slots) { errcode_t ret = 0; uint16_t i; uint64_t blkno; char *buf = NULL; struct ocfs2_dinode *di = NULL; uint16_t max_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots; ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) { verbosef(VL_APP, "%s while allocating inode buffer for " "truncate log check\n", error_message(ret)); goto bail; } for (i = new_slots; i < max_slots; ++i) { ret = ocfs2_lookup_system_inode(fs, TRUNCATE_LOG_SYSTEM_INODE, i, &blkno); if (ret) { verbosef(VL_APP, "%s while looking up truncate log for " "slot %u during truncate log check\n", error_message(ret), i); goto bail; } ret = ocfs2_read_inode(fs, blkno, buf); if (ret) { verbosef(VL_APP, "%s while reading inode %"PRIu64" " "during truncate log check\n", error_message(ret), blkno); goto bail; } di = (struct ocfs2_dinode *)buf; if (di->id2.i_dealloc.tl_used > 0) { ret = TUNEFS_ET_TRUNCATE_LOG_NOT_EMPTY; verbosef(VL_APP, "Truncate log for slot %u is not empty\n", i); goto bail; } } bail: if (buf) ocfs2_free(&buf); return ret; }
static void create_local_alloc(ocfs2_filesys *fs, uint64_t blkno) { errcode_t ret; char *buf = NULL; struct ocfs2_dinode *di; struct ocfs2_local_alloc *la; uint32_t la_size, found; uint64_t la_off; ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) FSWRK_COM_FATAL(progname, ret); ret = ocfs2_read_inode(fs, blkno, buf); if (ret) FSWRK_COM_FATAL(progname, ret); di = (struct ocfs2_dinode *)buf; if (!(di->i_flags & OCFS2_VALID_FL)) FSWRK_FATAL("not a file"); if (!(di->i_flags & OCFS2_LOCAL_ALLOC_FL)) FSWRK_FATAL("not a local alloc file"); if (di->id1.bitmap1.i_total > 0) { FSWRK_WARN("local alloc#%"PRIu64" file not empty." "Can't create a new one.\n", blkno); goto bail; } la_size = get_local_alloc_window_bits(); ret = ocfs2_new_clusters(fs, 1, la_size, &la_off, &found); if (ret) FSWRK_COM_FATAL(progname, ret); if(la_size != found) FSWRK_FATAL("can't allocate enough clusters for local alloc"); la = &(di->id2.i_lab); la->la_bm_off = la_off; di->id1.bitmap1.i_total = la_size; di->id1.bitmap1.i_used = 0; memset(la->la_bitmap, 0, la->la_size); ret = ocfs2_write_inode(fs, blkno, buf); if (ret) FSWRK_COM_FATAL(progname, ret); bail: if(buf) ocfs2_free(&buf); return; }
static errcode_t local_alloc_check(ocfs2_filesys *fs, uint16_t new_slots) { errcode_t ret = 0; uint16_t i; uint64_t blkno; char *buf = NULL; struct ocfs2_dinode *di = NULL; uint16_t max_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots; ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) { verbosef(VL_APP, "%s while allocating inode buffer for local " "alloc check\n", error_message(ret)); goto bail; } for (i = new_slots ; i < max_slots; ++i) { ret = ocfs2_lookup_system_inode(fs, LOCAL_ALLOC_SYSTEM_INODE, i, &blkno); if (ret) { verbosef(VL_APP, "%s while looking up local alloc for " "slot %u during local alloc check\n", error_message(ret), i); break; } ret = ocfs2_read_inode(fs, blkno, buf); if (ret) { verbosef(VL_APP, "%s while reading inode %"PRIu64" " "during local alloc check\n", error_message(ret), blkno); break; } di = (struct ocfs2_dinode *)buf; if (di->id1.bitmap1.i_total > 0) { ret = TUNEFS_ET_LOCAL_ALLOC_NOT_EMPTY; verbosef(VL_APP, "Local alloc for slot %u is not empty\n", i); break; } } bail: if (buf) ocfs2_free(&buf); return ret; }
void mess_up_inode_field(ocfs2_filesys *fs, enum fsck_type type, uint64_t blkno) { errcode_t ret; uint64_t tmpblkno; uint32_t clusters = 10; char *buf = NULL; struct ocfs2_dinode *di; create_file(fs, blkno, &tmpblkno); if ((type == INODE_SPARSE_SIZE) || (type == INODE_SPARSE_CLUSTERS)) { if (!ocfs2_sparse_alloc(OCFS2_RAW_SB(fs->fs_super))) FSWRK_FATAL("should specfiy a sparse file supported " "volume to do this corruption\n"); ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) FSWRK_COM_FATAL(progname, ret); ret = ocfs2_read_inode(fs, tmpblkno, buf); if (ret) FSWRK_COM_FATAL(progname, ret); di = (struct ocfs2_dinode *)buf; di->i_size = fs->fs_clustersize * 2; ret = ocfs2_write_inode(fs, tmpblkno, buf); if (ret) FSWRK_COM_FATAL(progname, ret); if (buf) ocfs2_free(&buf); } if ((type == INODE_CLUSTERS) || (type == INODE_SPARSE_CLUSTERS) || (type == INODE_SPARSE_SIZE)) { ret = ocfs2_extend_allocation(fs, tmpblkno, clusters); if (ret) FSWRK_COM_FATAL(progname, ret); } if (type == REFCOUNT_FLAG_INVALID && ocfs2_refcount_tree(OCFS2_RAW_SB(fs->fs_super))) FSWRK_FATAL("should specfiy a norefcount volume\n"); if (type == REFCOUNT_LOC_INVALID && !ocfs2_refcount_tree(OCFS2_RAW_SB(fs->fs_super))) FSWRK_FATAL("Should specify a refcount supported volume\n"); damage_inode(fs, tmpblkno, type); return; }
static errcode_t check_journals_func(o2fsck_state *ost, ocfs2_cached_inode *ci, struct journal_check_context *jc) { errcode_t err, ret; ocfs2_filesys *fs = ost->ost_fs; uint64_t contig; uint64_t blkno; char *buf = NULL; journal_superblock_t *jsb; struct journal_check_info *ji = &(jc->jc_info[jc->jc_this_slot]); ret = ocfs2_malloc_blocks(fs->fs_io, 1, &buf); if (ret) goto out; err = ocfs2_extent_map_get_blocks(ci, 0, 1, &blkno, &contig, NULL); if (err) { ji->i_error = err; goto out; } ji->i_clusters = ci->ci_inode->i_clusters; err = ocfs2_read_journal_superblock(fs, blkno, buf); if (err) { ji->i_error = err; goto out; } jsb = (journal_superblock_t *)buf; ji->i_features.opt_compat = jsb->s_feature_compat; ji->i_features.opt_ro_compat = jsb->s_feature_ro_compat; ji->i_features.opt_incompat = jsb->s_feature_incompat; if (!ji->i_clusters) { ji->i_error = OCFS2_ET_JOURNAL_TOO_SMALL; goto out; } jc->jc_max_clusters = ocfs2_max(jc->jc_max_clusters, ci->ci_inode->i_clusters); jc->jc_max_features.opt_compat |= jsb->s_feature_compat; jc->jc_max_features.opt_ro_compat |= jsb->s_feature_ro_compat; jc->jc_max_features.opt_incompat |= jsb->s_feature_incompat; ji->i_error = 0; out: if (buf) ocfs2_free(&buf); return ret; }
static int features_parse_option(struct tunefs_operation *op, char *arg) { int rc = 1; errcode_t err; struct feature_op_state *state = NULL; struct check_supported_context ctxt = { .sc_string = arg, }; if (!arg) { errorf("No features specified\n"); goto out; } err = ocfs2_malloc0(sizeof(struct feature_op_state), &state); if (err) { tcom_err(err, "while processing feature options"); goto out; } state->fo_op = op; err = ocfs2_parse_feature(arg, &state->fo_feature_set, &state->fo_reverse_set); if (err) { tcom_err(err, "while parsing feature options \"%s\"", arg); goto out; } ctxt.sc_state = state; ctxt.sc_action = FEATURE_ENABLE; ocfs2_feature_foreach(&state->fo_feature_set, check_supported_func, &ctxt); if (ctxt.sc_error) goto out; ctxt.sc_action = FEATURE_DISABLE; ocfs2_feature_reverse_foreach(&state->fo_reverse_set, check_supported_func, &ctxt); if (ctxt.sc_error) goto out; rc = 0; out: if (!rc) op->to_private = state; else if (state) ocfs2_free(&state); return rc; }
errcode_t ocfs2_set_backup_super_list(ocfs2_filesys *fs, uint64_t *blocks, size_t len) { size_t i; errcode_t ret = 0; char *buf = NULL; uint64_t *blkno = blocks; uint32_t cluster, bpc = fs->fs_clustersize / fs->fs_blocksize; if (!len || !blocks || !*blocks) goto bail; len = ocfs2_min(len,(size_t)OCFS2_MAX_BACKUP_SUPERBLOCKS); if (!OCFS2_HAS_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super), OCFS2_FEATURE_COMPAT_BACKUP_SB)) { /* check all the blkno to see whether it is used. */ for (i = 0; i < len; i++, blkno++) { ret = check_cluster(fs, ocfs2_blocks_to_clusters(fs, *blkno)); if (ret) goto bail; } } ret = ocfs2_malloc_blocks(fs->fs_io, bpc, &buf); if (ret) goto bail; memset(buf, 0, fs->fs_clustersize); /* zero all the clusters at first */ blkno = blocks; for (i = 0; i < len; i++, blkno++) { cluster = ocfs2_blocks_to_clusters(fs, *blkno); ret = io_write_block(fs->fs_io, cluster*bpc, bpc, buf); if (ret) goto bail; } ret = ocfs2_refresh_backup_super_list(fs, blocks, len); if (ret) goto bail; /* We just tested the clusters, so the allocation can't fail */ blkno = blocks; for (i = 0; i < len; i++, blkno++) ocfs2_new_specific_cluster(fs, ocfs2_blocks_to_clusters(fs, *blkno)); bail: if (buf) ocfs2_free(&buf); return ret; }
void mess_up_inline_flag(ocfs2_filesys *fs, enum fsck_type type, uint64_t blkno) { int i; errcode_t ret; char *buf = NULL, file_type[20]; uint64_t inline_blkno; struct ocfs2_dinode *di; struct ocfs2_super_block *osb; osb = OCFS2_RAW_SB(fs->fs_super); if (ocfs2_support_inline_data(osb)) FSWRK_FATAL("should specfiy a noinline-data supported " "volume to do this corruption\n"); ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) FSWRK_COM_FATAL(progname, ret); for (i = 0; i < 2; i++) { if (i == 0) { create_file(fs, blkno, &inline_blkno); snprintf(file_type, 20, "%s", "Regular file"); } else { create_directory(fs, blkno, &inline_blkno); snprintf(file_type, 20, "%s", "Diectory"); } ret = ocfs2_read_inode(fs, inline_blkno, buf); if (ret) FSWRK_COM_FATAL(progname, ret); di = (struct ocfs2_dinode *)buf; if (!(di->i_dyn_features & OCFS2_INLINE_DATA_FL)) { di->i_dyn_features |= OCFS2_INLINE_DATA_FL; ret = ocfs2_write_inode(fs, inline_blkno, buf); if (ret) FSWRK_COM_FATAL(progname, ret); } fprintf(stdout, "INLINE_DATA_FLAG_INVALID: " "Create an inlined inode#%"PRIu64"(%s) " "on a noinline-data supported volume\n", inline_blkno, file_type); } if (buf) ocfs2_free(&buf); return; }
void ocfs2_bitmap_free(ocfs2_bitmap **bitmap) { struct rb_node *node; struct ocfs2_bitmap_region *br; /* * If the bitmap needs to do extra cleanup of region, * it should have done it in destroy_notify. Same with the * private pointers. */ if ((*bitmap)->b_ops->destroy_notify) (*(*bitmap)->b_ops->destroy_notify)(*bitmap); while ((node = rb_first(&(*bitmap)->b_regions)) != NULL) { br = rb_entry(node, struct ocfs2_bitmap_region, br_node); rb_erase(&br->br_node, &(*bitmap)->b_regions); ocfs2_bitmap_free_region(br); } ocfs2_free(&(*bitmap)->b_description); ocfs2_free(bitmap); }
static errcode_t dump_xattr_buckets(FILE *out, ocfs2_filesys *fs, uint64_t blkno, uint32_t clusters, uint64_t *xattrs_bucket, int verbose) { int i; errcode_t ret = 0; char *bucket = NULL; struct ocfs2_xattr_header *xh; int blk_per_bucket = ocfs2_blocks_per_xattr_bucket(fs); uint32_t bpc = ocfs2_xattr_buckets_per_cluster(fs); uint32_t num_buckets = clusters * bpc; ret = ocfs2_malloc_blocks(fs->fs_io, blk_per_bucket, &bucket); if (ret) goto out; fprintf(out, "\tExtended Attributes extent record start at #%"PRIu64 " Has clusters: %u", blkno, clusters); for (i = 0; i < num_buckets; i++, blkno += blk_per_bucket) { ret = ocfs2_read_xattr_bucket(fs, blkno, bucket); if (ret) goto out; xh = (struct ocfs2_xattr_header *)bucket; /* * The real bucket num in this series of blocks is stored * in the 1st bucket. */ if (i == 0) { num_buckets = xh->xh_num_buckets; fprintf(out, " Has buckets: %d\n", num_buckets); } fprintf(out, "\t\tExtended Attributes in bucket #%d: %u\n", i, xh->xh_count); if (verbose) dump_xattr(out, xh); *xattrs_bucket += xh->xh_count; } out: if (bucket) ocfs2_free(&bucket); return ret; }
/* * NOTE: ocfs2_truncate_inline() also handles fast symlink, * since truncating for inline file and fasy symlink are * almost the same thing per se. */ errcode_t ocfs2_truncate_inline(ocfs2_filesys *fs, uint64_t ino, uint64_t new_i_size) { errcode_t ret = 0; char *buf = NULL; struct ocfs2_dinode *di = NULL; struct ocfs2_inline_data *idata = NULL; if (!(fs->fs_flags & OCFS2_FLAG_RW)) return OCFS2_ET_RO_FILESYS; ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) return ret; ret = ocfs2_read_inode(fs, ino, buf); if (ret) goto out_free_buf; di = (struct ocfs2_dinode *)buf; if (di->i_size < new_i_size) { ret = EINVAL; goto out_free_buf; } idata = &di->id2.i_data; if (!(di->i_dyn_features & OCFS2_INLINE_DATA_FL) && !(S_ISLNK(di->i_mode) && !di->i_clusters)) { ret = EINVAL; goto out_free_buf; } if (di->i_dyn_features & OCFS2_INLINE_DATA_FL) memset(idata->id_data + new_i_size, 0, di->i_size - new_i_size); else memset(di->id2.i_symlink + new_i_size, 0, di->i_size - new_i_size); di->i_size = new_i_size; ret = ocfs2_write_inode(fs, ino, buf); out_free_buf: if (buf) ocfs2_free(&buf); return ret; }
static void o2info_print_line(char const *qualifier, char *content, char splitter) { char *ptr = NULL, *token = NULL, *tmp = NULL; uint32_t max_len = 80, len = 0; tmp = malloc(max_len); ptr = content; snprintf(tmp, max_len, "%s", qualifier); fprintf(stdout, "%s", tmp); len += strlen(tmp); while (ptr) { token = ptr; ptr = strchr(ptr, splitter); if (ptr) *ptr = 0; if (strcmp(token, "") != 0) { snprintf(tmp, max_len, "%s ", token); len += strlen(tmp); if (len > max_len) { fprintf(stdout, "\n"); len = 0; snprintf(tmp, max_len, "%s", qualifier); fprintf(stdout, "%s", tmp); len += strlen(tmp); snprintf(tmp, max_len, "%s ", token); fprintf(stdout, "%s", tmp); len += strlen(tmp); } else fprintf(stdout, "%s", tmp); } if (!ptr) break; ptr++; } fprintf(stdout, "\n"); if (tmp) ocfs2_free(&tmp); }
errcode_t handle_slots_system_file(ocfs2_filesys *fs, int type, errcode_t (*func)(ocfs2_filesys *fs, struct ocfs2_dinode *di, int slot)) { errcode_t ret; uint64_t blkno; int slot, max_slots; char *buf = NULL; struct ocfs2_dinode *di; ret = ocfs2_malloc_block(fs->fs_io, &buf); if (ret) goto bail; di = (struct ocfs2_dinode *)buf; max_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots; for (slot = 0; slot < max_slots; slot++) { ret = ocfs2_lookup_system_inode(fs, type, slot, &blkno); if (ret) goto bail; ret = ocfs2_read_inode(fs, blkno, buf); if (ret) goto bail; if (func) { ret = func(fs, di, slot); if (ret) goto bail; } } bail: if (buf) ocfs2_free(&buf); return ret; }