static int fs_is_clean(o2fsck_state *ost, char *filename) { struct ocfs2_super_block *sb = OCFS2_RAW_SB(ost->ost_fs->fs_super); time_t now = time(NULL); time_t next = sb->s_lastcheck + sb->s_checkinterval; static char reason[4096] = {'\0', }; struct tm local; if (ost->ost_force) strcpy(reason, "was run with -f"); else if ((OCFS2_RAW_SB(ost->ost_fs->fs_super)->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_RESIZE_INPROG)) strcpy(reason, "incomplete volume resize detected"); else if ((OCFS2_RAW_SB(ost->ost_fs->fs_super)->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_TUNEFS_INPROG)) strcpy(reason, "incomplete tunefs operation detected"); else if (sb->s_state & OCFS2_ERROR_FS) strcpy(reason, "contains a file system with errors"); else if (sb->s_max_mnt_count > 0 && sb->s_mnt_count > sb->s_max_mnt_count) { sprintf(reason, "has been mounted %u times without being " "checked", sb->s_mnt_count); } else if (sb->s_checkinterval > 0 && now >= next) { unsigned scaled_time; char *scaled_units; scale_time(now - sb->s_lastcheck, &scaled_time, &scaled_units); sprintf(reason, "has gone %u %s without being checked", scaled_time, scaled_units); } if (reason[0]) { printf("%s %s, check forced.\n", filename, reason); return 0; } reason[0] = '\0'; if (sb->s_max_mnt_count > 0) sprintf(reason, "after %u additional mounts", sb->s_max_mnt_count - sb->s_mnt_count); if (sb->s_checkinterval > 0) { localtime_r(&next, &local); if (reason[0]) ftso_strftime(reason + strlen(reason), sizeof(reason) - strlen(reason), " or by %c, whichever comes first", &local); else ftso_strftime(reason, sizeof(reason), "by %c", &local); } printf("%s is clean.", filename); if (reason[0]) printf(" It will be checked %s.\n", reason); return 1; }
static void print_uuid(o2fsck_state *ost) { unsigned char *uuid = OCFS2_RAW_SB(ost->ost_fs->fs_super)->s_uuid; size_t i, max = sizeof(OCFS2_RAW_SB(ost->ost_fs->fs_super)->s_uuid); for(i = 0; i < max; i++) printf("%02X", uuid[i]); printf("\n"); }
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 void update_volume_label(ocfs2_filesys *fs, const char *new_label) { int len; char label_buf[OCFS2_MAX_VOL_LABEL_LEN]; struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super); memset(label_buf, 0, OCFS2_MAX_VOL_LABEL_LEN); if (new_label) { len = strlen(new_label); if (len > OCFS2_MAX_VOL_LABEL_LEN) len = OCFS2_MAX_VOL_LABEL_LEN; if (!memcmp(sb->s_label, new_label, len)) { verbosef(VL_APP, "Device \"%s\" already has the label " "\"%.*s\"; label not updated\n", fs->fs_devname, OCFS2_MAX_VOL_LABEL_LEN, new_label); return; } strncpy(label_buf, new_label, OCFS2_MAX_VOL_LABEL_LEN); } else { strncpy(label_buf, (char *)sb->s_label, OCFS2_MAX_VOL_LABEL_LEN); len = strnlen(label_buf, OCFS2_MAX_VOL_LABEL_LEN); /* * If we don't have CLONED_LABEL at the end of the label, * add it. Truncate the existing label if necessary to * fit CLONED_LABEL. */ if (strncmp(label_buf + len - CLONED_LABEL_LEN, CLONED_LABEL, CLONED_LABEL_LEN)) { if ((len + CLONED_LABEL_LEN) > OCFS2_MAX_VOL_LABEL_LEN) len = OCFS2_MAX_VOL_LABEL_LEN - CLONED_LABEL_LEN; strncpy(label_buf + len, CLONED_LABEL, CLONED_LABEL_LEN); } } verbosef(VL_APP, "Setting the label \"%.*s\" on device \"%s\"\n", OCFS2_MAX_VOL_LABEL_LEN, label_buf, fs->fs_devname); memset(OCFS2_RAW_SB(fs->fs_super)->s_label, 0, OCFS2_MAX_VOL_LABEL_LEN); strncpy((char *)sb->s_label, label_buf, OCFS2_MAX_VOL_LABEL_LEN); }
/* Empty the content of the specified journal file. * Most of the code is copied from ocfs2_format_journal. */ static errcode_t empty_journal(ocfs2_filesys *fs, ocfs2_cached_inode *ci) { errcode_t ret = 0; char *buf = NULL; int bs_bits = OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits; uint64_t offset = 0; uint32_t wrote, count; #define BUFLEN 1048576 ret = ocfs2_malloc_blocks(fs->fs_io, (BUFLEN >> bs_bits), &buf); if (ret) goto out; memset(buf, 0, BUFLEN); count = (uint32_t) ci->ci_inode->i_size; while (count) { ret = ocfs2_file_write(ci, buf, ocfs2_min((uint32_t) BUFLEN, count), offset, &wrote); if (ret) goto out; offset += wrote; count -= wrote; } out: return ret; }
static void print_label(o2fsck_state *ost) { unsigned char *label = OCFS2_RAW_SB(ost->ost_fs->fs_super)->s_label; size_t i, max = sizeof(OCFS2_RAW_SB(ost->ost_fs->fs_super)->s_label); for(i = 0; i < max && label[i]; i++) { if (isprint(label[i])) printf("%c", label[i]); else printf("."); } if (i == 0) printf("<NONE>"); printf("\n"); }
static errcode_t orphan_dir_check(ocfs2_filesys *fs, uint16_t new_slots) { errcode_t ret = 0; uint64_t blkno; int i, has_orphan = 0; uint16_t max_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots; for (i = new_slots ; i < max_slots; ++i) { ret = ocfs2_lookup_system_inode(fs, ORPHAN_DIR_SYSTEM_INODE, i, &blkno); if (ret) { verbosef(VL_APP, "%s while looking up orphan dir for " "slot %u during orphan dir check\n", error_message(ret), i); break; } ret = ocfs2_dir_iterate(fs, blkno, OCFS2_DIRENT_FLAG_EXCLUDE_DOTS, NULL, orphan_iterate, &has_orphan); if (has_orphan) { ret = TUNEFS_ET_ORPHAN_DIR_NOT_EMPTY; verbosef(VL_APP, "Entries found in orphan dir for slot %u\n", i); break; } } return ret; }
static errcode_t check_journal_walk(o2fsck_state *ost, errcode_t (*func)(o2fsck_state *ost, ocfs2_cached_inode *ci, struct journal_check_context *jc), struct journal_check_context *jc) { errcode_t ret = 0; uint64_t blkno; ocfs2_filesys *fs = ost->ost_fs; uint16_t i, max_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots; ocfs2_cached_inode *ci = NULL; for (i = 0; i < max_slots; i++) { ret = ocfs2_lookup_system_inode(fs, JOURNAL_SYSTEM_INODE, i, &blkno); if (ret) break; ret = ocfs2_read_cached_inode(fs, blkno, &ci); if (ret) break; jc->jc_this_slot = i; ret = func(ost, ci, jc); if (ret) break; } if (ci) ocfs2_free_cached_inode(fs, ci); return ret; }
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; }
int open_ocfs2_volume(char *device_name) { int open_flags = OCFS2_FLAG_HEARTBEAT_DEV_OK | OCFS2_FLAG_RO; int ret; ret = ocfs2_open(device_name, open_flags, 0, 0, &fs); if (ret < 0) { fprintf(stderr, "Not a ocfs2 volume!\n"); return ret; } ocfs2_sb = OCFS2_RAW_SB(fs->fs_super); if (!(ocfs2_sb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_INLINE_DATA)) { fprintf(stderr, "Inline-data not supported" " on this ocfs2 volume\n"); return -1; } blocksize = 1 << ocfs2_sb->s_blocksize_bits; clustersize = 1 << ocfs2_sb->s_clustersize_bits; max_inline_size = ocfs2_max_inline_data_with_xattr(blocksize, NULL); return 0; }
static void mess_up_sys_chains(ocfs2_filesys *fs, uint16_t slotnum, enum fsck_type type) { errcode_t ret; char sysfile[OCFS2_MAX_FILENAME_LEN]; uint64_t blkno; struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super); if (slotnum == UINT16_MAX) snprintf(sysfile, sizeof(sysfile), "%s", ocfs2_system_inodes[GLOBAL_BITMAP_SYSTEM_INODE].si_name); else snprintf(sysfile, sizeof(sysfile), ocfs2_system_inodes[INODE_ALLOC_SYSTEM_INODE].si_name, slotnum); ret = ocfs2_lookup(fs, sb->s_system_dir_blkno, sysfile, strlen(sysfile), NULL, &blkno); if (ret) FSWRK_COM_FATAL(progname, ret); mess_up_sys_file(fs, blkno, type); return ; }
void mess_up_local_alloc_used(ocfs2_filesys *fs, enum fsck_type type, uint16_t slotnum) { errcode_t ret; uint64_t blkno; char alloc_inode[OCFS2_MAX_FILENAME_LEN]; struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super); if (slotnum == UINT16_MAX) slotnum = 0; snprintf(alloc_inode, sizeof(alloc_inode), ocfs2_system_inodes[LOCAL_ALLOC_SYSTEM_INODE].si_name,slotnum); ret = ocfs2_lookup(fs, sb->s_system_dir_blkno, alloc_inode, strlen(alloc_inode), NULL, &blkno); if (ret) FSWRK_COM_FATAL(progname, ret); create_local_alloc(fs, blkno); damage_local_alloc(fs, blkno, type); return; }
static int set_journal_block64_run(struct tunefs_operation *op, ocfs2_filesys *fs, int flags) { errcode_t err; int rc = 0; ocfs2_fs_options mask, options; struct ocfs2_super_block *super = OCFS2_RAW_SB(fs->fs_super); memset(&mask, 0, sizeof(ocfs2_fs_options)); memset(&options, 0, sizeof(ocfs2_fs_options)); mask.opt_incompat |= JBD2_FEATURE_INCOMPAT_64BIT; options.opt_incompat |= JBD2_FEATURE_INCOMPAT_64BIT; if (!tools_interact("Enable block64 journal feature on device \"%s\"? ", fs->fs_devname)) goto out; tunefs_block_signals(); super->s_feature_compat |= OCFS2_FEATURE_COMPAT_JBD2_SB; err = ocfs2_write_super(fs); if (!err) err = tunefs_set_journal_size(fs, 0, mask, options); tunefs_unblock_signals(); if (err) { rc = 1; tcom_err(err, "; unable to enable block64 journal feature on " "device \"%s\"", fs->fs_devname); } out: return rc; }
errcode_t ocfs2_clear_backup_super_list(ocfs2_filesys *fs, uint64_t *blocks, size_t len) { size_t i; errcode_t ret = 0; if (!len || !blocks || !*blocks) goto bail; len = ocfs2_min(len,(size_t)OCFS2_MAX_BACKUP_SUPERBLOCKS); /* * Don't clear anything if backup superblocks aren't enabled - * there might be real data there! If backup superblocks are * enabled, we know these blocks are backups, and we're * safe to clear them. */ if (!OCFS2_HAS_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super), OCFS2_FEATURE_COMPAT_BACKUP_SB)) goto bail; for (i = 0; i < len; i++) { ret = ocfs2_free_clusters(fs, 1, blocks[i]); if (ret) break; } bail: return ret; }
void mess_up_inode_orphaned(ocfs2_filesys *fs, enum fsck_type type, uint16_t slotnum) { errcode_t ret; uint64_t blkno, tmpblkno; char parentdir[OCFS2_MAX_FILENAME_LEN]; struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super); if (slotnum == UINT16_MAX) slotnum = 0; snprintf(parentdir, sizeof(parentdir), ocfs2_system_inodes[ORPHAN_DIR_SYSTEM_INODE].si_name, slotnum); ret = ocfs2_lookup(fs, sb->s_system_dir_blkno, parentdir, strlen(parentdir), NULL, &blkno); if (ret) FSWRK_COM_FATAL(progname, ret); create_file(fs, blkno, &tmpblkno); fprintf(stdout, "INODE_ORPHANED: " "Create an inode#%"PRIu64" under directory %s\n", tmpblkno, parentdir); return; }
static void create_named_directory(ocfs2_filesys *fs, char *dirname, uint64_t *blkno) { errcode_t ret; struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super); ret = ocfs2_lookup(fs, sb->s_root_blkno, dirname, strlen(dirname), NULL, blkno); if (!ret) return; else if (ret != OCFS2_ET_FILE_NOT_FOUND) FSWRK_COM_FATAL(progname, ret); ret = ocfs2_new_inode(fs, blkno, S_IFDIR | 0755); if (ret) FSWRK_COM_FATAL(progname, ret); ret = ocfs2_init_dir(fs, *blkno, fs->fs_root_blkno); if (ret) FSWRK_COM_FATAL(progname, ret); ret = ocfs2_link(fs, fs->fs_root_blkno, dirname, *blkno, OCFS2_FT_DIR); if (ret) FSWRK_COM_FATAL(progname, ret); return; }
static void update_volume_uuid(ocfs2_filesys *fs) { unsigned char new_uuid[OCFS2_VOL_UUID_LEN]; uuid_generate(new_uuid); memcpy(OCFS2_RAW_SB(fs->fs_super)->s_uuid, new_uuid, OCFS2_VOL_UUID_LEN); }
static int handle_incompat(FILE *stream, const struct printf_info *info, const void *const *args) { int len; len = handle_flag(stream, info, args, OCFS2_RAW_SB(query_fs->fs_super)->s_feature_incompat, incompat_flag_in_str); if (OCFS2_RAW_SB(query_fs->fs_super)->s_tunefs_flag) len += handle_flag(stream, info, args, OCFS2_RAW_SB(query_fs->fs_super)->s_tunefs_flag, tunefs_inprog_flag_in_str); if (!len) len = print_string(stream, info, args, "None"); return len; }
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 int handle_label(FILE *stream, const struct printf_info *info, const void *const *args) { char label[OCFS2_MAX_VOL_LABEL_LEN + 1]; snprintf(label, OCFS2_MAX_VOL_LABEL_LEN + 1, (char *)OCFS2_RAW_SB(query_fs->fs_super)->s_label); return print_string(stream, info, args, label); }
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; }
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; }
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; }
errcode_t ocfs2_refresh_backup_supers(ocfs2_filesys *fs) { int num; uint64_t blocks[OCFS2_MAX_BACKUP_SUPERBLOCKS]; if (!OCFS2_HAS_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super), OCFS2_FEATURE_COMPAT_BACKUP_SB)) return 0; /* Do nothing */ num = ocfs2_get_backup_super_offsets(fs, blocks, ARRAY_SIZE(blocks)); return num ? ocfs2_refresh_backup_super_list(fs, blocks, num) : 0; }
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; }
/* * Mark the already-existing extent at cpos as written for len clusters. * * If the existing extent is larger than the request, initiate a * split. An attempt will be made at merging with adjacent extents. * */ int ocfs2_mark_extent_written(ocfs2_filesys *fs, struct ocfs2_dinode *di, uint32_t cpos, uint32_t len, uint64_t p_blkno) { struct ocfs2_extent_tree et; if (!ocfs2_writes_unwritten_extents(OCFS2_RAW_SB(fs->fs_super))) return OCFS2_ET_UNSUPP_FEATURE; ocfs2_init_dinode_extent_tree(&et, fs, (char *)di, di->i_blkno); return ocfs2_change_extent_flag(fs, &et, cpos, len, p_blkno, 0, OCFS2_EXT_UNWRITTEN); }
static int enable_backup_super(ocfs2_filesys *fs, int flags) { errcode_t err = 0; struct ocfs2_super_block *super = OCFS2_RAW_SB(fs->fs_super); struct tools_progress *prog; if (OCFS2_HAS_COMPAT_FEATURE(super, OCFS2_FEATURE_COMPAT_BACKUP_SB)) { verbosef(VL_APP, "Backup superblock feature is already enabled; " "nothing to enable\n"); goto out; } if (!tools_interact("Enable the backup superblock feature on " "device \"%s\"? ", fs->fs_devname)) goto out; prog = tools_progress_start("Enable backup-super", "backup-super", 2); if (!prog) { err = TUNEFS_ET_NO_MEMORY; tcom_err(err, "while initializing the progress display"); goto out; } tunefs_block_signals(); err = check_backup_offsets(fs); tools_progress_step(prog, 1); if (!err) err = fill_backup_supers(fs); if (!err) { super->s_feature_compat |= OCFS2_FEATURE_COMPAT_BACKUP_SB; err = ocfs2_write_super(fs); if (err) tcom_err(err, "while writing out the superblock\n"); } tunefs_unblock_signals(); tools_progress_step(prog, 1); tools_progress_stop(prog); if (err) errorf("Unable to enable the backup superblock feature on " "device \"%s\"\n", fs->fs_devname); out: return err; }
errcode_t ocfs2_read_backup_super(ocfs2_filesys *fs, int backup, char *sbbuf) { int numsb; uint64_t blocks[OCFS2_MAX_BACKUP_SUPERBLOCKS]; if (!OCFS2_HAS_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super), OCFS2_FEATURE_COMPAT_BACKUP_SB)) return OCFS2_ET_NO_BACKUP_SUPER; numsb = ocfs2_get_backup_super_offsets(fs, blocks, ARRAY_SIZE(blocks)); if (backup < 0 || backup >= numsb) return OCFS2_ET_NO_BACKUP_SUPER; return ocfs2_read_super(fs, blocks[backup], sbbuf); }
static int ocfs2_truncate_clusters(ocfs2_filesys *fs, struct ocfs2_extent_rec *rec, uint64_t ino, uint32_t len, uint64_t start) { if (!ocfs2_refcount_tree(OCFS2_RAW_SB(fs->fs_super)) || !(rec->e_flags & OCFS2_EXT_REFCOUNTED)) return ocfs2_free_clusters(fs, len, start); assert(ino); return ocfs2_decrease_refcount(fs, ino, ocfs2_blocks_to_clusters(fs, start), len, 1); }
/* * corrupt_chains() * */ void corrupt_chains(ocfs2_filesys *fs, int code, uint16_t slotnum) { errcode_t ret; uint64_t blkno; struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super); char sysfile[40]; switch (code) { case 3: case 4: case 5: case 6: case 7: case 8: case 10: case 11: case 12: snprintf(sysfile, sizeof(sysfile), ocfs2_system_inodes[GLOBAL_BITMAP_SYSTEM_INODE].si_name); break; #ifdef _LATER_ case X: snprintf(sysfile, sizeof(sysfile), ocfs2_system_inodes[GLOBAL_INODE_ALLOC_SYSTEM_INODE].si_name); break; case Y: snprintf(sysfile, sizeof(sysfile), ocfs2_system_inodes[EXTENT_ALLOC_SYSTEM_INODE].si_name, slotnum); break; case Z: snprintf(sysfile, sizeof(sysfile), ocfs2_system_inodes[INODE_ALLOC_SYSTEM_INODE].si_name, slotnum); break; #endif default: FSWRK_FATAL("Invalid code=%d", code); } ret = ocfs2_lookup(fs, sb->s_system_dir_blkno, sysfile, strlen(sysfile), NULL, &blkno); if (ret) FSWRK_FATAL(); mess_up_chains(fs, blkno, code); return ; }