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;
}
Beispiel #2
0
static errcode_t create_system_file(ocfs2_filesys *fs, int type, int node)
{
	char fname[OCFS2_MAX_FILENAME_LEN];
	uint64_t blkno;
	errcode_t ret;

	ocfs2_sprintf_system_inode_name(fname, sizeof(fname),
		type, node);
	ret = ocfs2_lookup(fs, fs->fs_sysdir_blkno, fname, strlen(fname), NULL,
			   &blkno);
	if (!ret) {
		verbosef(VL_APP, "System file \"%s\" already exists!\n",
			 fname);
		return 0;
	}
	ret = ocfs2_new_system_inode(fs, &blkno,
				ocfs2_system_inodes[type].si_mode,
				ocfs2_system_inodes[type].si_iflags);
	if (ret) {
		tcom_err(ret, "while creating system file \"%s\"", fname);
		return ret;
	}

	ret = ocfs2_link(fs, fs->fs_sysdir_blkno, fname, blkno,
			 OCFS2_FT_REG_FILE);
	if (ret) {
		tcom_err(ret, "while linking file \"%s\" in the system "
			 "directory", fname);
		return ret;
	}
	return 0;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
static errcode_t create_orphan_file(ocfs2_filesys *fs, uint16_t slot)
{
	errcode_t ret;
	uint64_t dir, tmp_blkno;
	char name[OCFS2_MAX_FILENAME_LEN];
	int namelen;

	ret = ocfs2_lookup_system_inode(fs, ORPHAN_DIR_SYSTEM_INODE,
					slot, &dir);
	if (ret)
		return ret;

	namelen = sprintf(name, "test%ld", random());

	ret = ocfs2_lookup(fs, dir, name, namelen, NULL, &tmp_blkno);
	if (!ret)
		return 0;
	else if (ret != OCFS2_ET_FILE_NOT_FOUND)
		return ret;

	ret = ocfs2_new_inode(fs, &tmp_blkno, S_IFREG | 0755);
	if (ret)
		return ret;

	ret = ocfs2_link(fs, dir, name,
			 tmp_blkno, OCFS2_FT_REG_FILE);
	if (ret)
		return ret;

	return 0;
}
Beispiel #6
0
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;
}
Beispiel #7
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 ;
}
Beispiel #8
0
/*
 * 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 ;
}
Beispiel #9
0
static errcode_t fix_dirent_index(o2fsck_dirblock_entry *dbe,
				  struct dirblock_data *dd,
				  struct ocfs2_dir_entry *dirent,
				  unsigned int *flags)
{
	errcode_t ret = 0;
	struct ocfs2_dinode *di = (struct ocfs2_dinode *)dd->inoblock_buf;
	uint64_t ino;

	if (!ocfs2_supports_indexed_dirs(OCFS2_RAW_SB(dd->fs->fs_super)))
		goto out;

	if (di->i_dyn_features  & OCFS2_INDEXED_DIR_FL) {
		ret = ocfs2_lookup(dd->fs, dbe->e_ino, dirent->name,
				   dirent->name_len, NULL, &ino);
		if (ret) {
			if ((ret == OCFS2_ET_DIR_CORRUPTED) &&
			    prompt(dd->ost, PY, PR_DX_LOOKUP_FAILED,
				"Directory inode %"PRIu64" has invalid index. "
				"Rebuild index tree?", dbe->e_ino)) {
					*flags |= OCFS2_DIRENT_CHANGED;
					ret = 0;
					goto out;
			}

			if (ret != OCFS2_ET_FILE_NOT_FOUND)
				goto out;
			ret = 0;

			if (prompt(dd->ost, PY, PR_DX_LOOKUP_FAILED,
				   "Directory inode %"PRIu64" is missing "
				   "an index entry for the file \"%.*s\""
				   " (inode # %"PRIu64")\n. Repair this by "
				   "rebuilding the directory index?",
				   dbe->e_ino, dirent->name_len, dirent->name,
				   ino))
				*flags |= OCFS2_DIRENT_CHANGED;
			goto out;
		}
	}
out:
	return ret;
}
Beispiel #10
0
errcode_t ocfs2_lookup_system_inode(ocfs2_filesys *fs, int type,
				    int slot_num, uint64_t *blkno)
{
	errcode_t ret;
	char *buf;

	ret = ocfs2_malloc0(sizeof(char) * (OCFS2_MAX_FILENAME_LEN + 1), &buf);
	if (ret)
		return ret;

	ocfs2_sprintf_system_inode_name(buf, OCFS2_MAX_FILENAME_LEN, 
					type, slot_num);

	ret = ocfs2_lookup(fs, fs->fs_sysdir_blkno, buf,
			   strlen(buf), NULL, blkno);

	ocfs2_free(&buf);

	return ret;
}
Beispiel #11
0
static void get_truncate_log(ocfs2_filesys *fs, 
					uint16_t slotnum, uint64_t *blkno)
{
	errcode_t ret;
	char truncate_log[OCFS2_MAX_FILENAME_LEN];
	struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super);

	if (slotnum == UINT16_MAX)
		slotnum = 0;
	
	snprintf(truncate_log, sizeof(truncate_log), 	
		 ocfs2_system_inodes[TRUNCATE_LOG_SYSTEM_INODE].si_name,
		 slotnum);
	
	ret = ocfs2_lookup(fs, sb->s_system_dir_blkno, truncate_log,
			   strlen(truncate_log), NULL, blkno);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	return;
}
Beispiel #12
0
static void fix_dot_dot(o2fsck_state *ost, o2fsck_dir_parent *dir)
{
	errcode_t ret;

	struct fix_dot_dot_args args = {
		.ost = ost,
		.parent = dir->dp_dirent,
		.fixed = 0,
	};

	ret = ocfs2_dir_iterate(ost->ost_fs, dir->dp_ino, 
				OCFS2_DIRENT_FLAG_INCLUDE_EMPTY, NULL,
				fix_dot_dot_dirent, &args);
	if (ret) {
		com_err("fix_dot_dot", ret, "while iterating through dir "
			"inode %"PRIu64"'s directory entries.", dir->dp_dirent);
		/* XXX mark fs invalid */
		return;
	}

	if (!args.fixed) {
		fprintf(stderr, "Didn't find a '..' entry to fix.\n");
		/* XXX mark fs invalid */
		return;
	}

	dir->dp_dot_dot = dir->dp_dirent;
}

/* add a directory entry that points to a given inode in lost+found. */
void o2fsck_reconnect_file(o2fsck_state *ost, uint64_t inode)
{
	static char iname[NAME_MAX + 1];
	char name[] = "lost+found";
	int namelen = sizeof(name) - 1;
	o2fsck_dir_parent *dp;
	errcode_t ret;
	uint8_t type;
	int len;

	if (ost->ost_lostfound_ino == 0) {
		ret = ocfs2_lookup(ost->ost_fs, ost->ost_fs->fs_root_blkno,
				   name, namelen, NULL,
				   &ost->ost_lostfound_ino);
		if (ret) {
			com_err(whoami, ret, "while trying to find the "
				"/lost+found directory so that inode "
				"%"PRIu64" could be moved there.", inode);
			goto out;
		}
	}

	len = snprintf(iname, sizeof(iname), "#%"PRIu64, inode);
	if (len <= 0) {
		ret = OCFS2_ET_NO_MEMORY;
		com_err(whoami, ret, "while trying to build a new file name "
			"for inode %"PRIu64" to use in /lost+found", inode);
		goto out;
	}

	ret = o2fsck_type_from_dinode(ost, inode, &type);
	if (ret)
		goto out;

	ret = ocfs2_link(ost->ost_fs, ost->ost_lostfound_ino, iname, inode,
			 type);
	if (ret) {
		com_err(whoami, ret, "while trying to link inode %"PRIu64" "
			"into /lost+found", inode);
		goto out;
	}

	/* add another ref to account for this new dirent */
	o2fsck_icount_delta(ost->ost_icount_refs, inode, 1);

	/* if we just added a directory to l+f we need to track that 
	 * the new dirent points to the dir.  we leave the dot_dot tracking
	 * intact because we didn't change that in the dirblock.. */
	if (type == OCFS2_FT_DIR) {
		dp = o2fsck_dir_parent_lookup(&ost->ost_dir_parents, inode);
		if (dp == NULL) {
			ret = OCFS2_ET_INTERNAL_FAILURE;
			com_err(whoami, ret, "while looking up the directory "
				"parent structure for inode %"PRIu64, inode);
			goto out;
		}
		dp->dp_dirent = ost->ost_lostfound_ino;
	}

out:
	return;
}

static uint64_t loop_no = 0;

static errcode_t connect_directory(o2fsck_state *ost,
				   o2fsck_dir_parent *dir)
{
	o2fsck_dir_parent *dp = dir, *par;
	errcode_t ret = 0;
	int fix;

	verbosef("checking dir inode %"PRIu64" parent %"PRIu64" dot_dot "
		"%"PRIu64"\n", dir->dp_ino, dp->dp_dirent, dp->dp_dot_dot);

	loop_no++;

	while(!dp->dp_connected) {

		/* we either will ascend to a parent that is connected or
		 * we'll graft the subtree with this directory on to lost
		 * and found. */ 
		dp->dp_connected = 1;

		/* move on to the parent dir only if it exists and we haven't
		 * already traversed it in this instance of parent walking */
		if (dp->dp_dirent) {
			par = o2fsck_dir_parent_lookup(&ost->ost_dir_parents, 
							dp->dp_dirent);
			if (par == NULL) {
				ret = OCFS2_ET_INTERNAL_FAILURE;
				com_err(whoami, ret, "no dir info for parent "
					"%"PRIu64, dp->dp_dirent);
				goto out;
			}
			if (par->dp_loop_no != loop_no) {
				par->dp_loop_no = loop_no;
				dp = par;
				continue;
			}
		}

		/* ok, we hit an orphan subtree with no parent or are at 
		 * the dir in a subtree that is the first to try to reference
		 * a dir in its children */
		fix = prompt(ost, PY, PR_DIR_NOT_CONNECTED,
			     "Directory inode %"PRIu64" isn't "
			     "connected to the filesystem.  Move it to "
			     "lost+found?", dp->dp_ino);
		if (fix)
			o2fsck_reconnect_file(ost, dp->dp_ino);

		break;
	}

	/* 
	 * orphan dirs are a magically awesome special case.  they have
	 * their i_link_count increased when subdirs are added but
	 * the subdirs '..' entry isn't updated to point to the orphan
	 * dir.  we alter our book-keeping to it look like the '..'
	 * was reasonable on disk.
	 */
	if (dir->dp_in_orphan_dir) {
		/* previous '..' entry is garbage */
		if (dir->dp_dot_dot)
			o2fsck_icount_delta(ost->ost_icount_refs,
					    dir->dp_dot_dot, -1);
		/* pretend '..' pointed to the orphan dir */
		dir->dp_dot_dot = dir->dp_dirent;
		o2fsck_icount_delta(ost->ost_icount_refs, dir->dp_dot_dot, 1);
	}
	if (dir->dp_dirent != dir->dp_dot_dot) {
		fix = prompt(ost, PY, PR_DIR_DOTDOT,
			     "Directory inode %"PRIu64" is "
			     "referenced by a dirent in directory %"PRIu64" "
			     "but its '..' entry points to inode %"PRIu64". "
			     "Fix the '..' entry to reference %"PRIu64"?", 
			     dir->dp_ino, dir->dp_dirent, dir->dp_dot_dot, 
			     dir->dp_dirent);
		if (fix)
			fix_dot_dot(ost, dir);
	}
out:
	return ret;
}
Beispiel #13
0
static void check_lostfound(o2fsck_state *ost)
{
	char name[] = "lost+found";
	int namelen = sizeof(name) - 1;
	uint64_t blkno;
	errcode_t ret;

	ret = ocfs2_lookup(ost->ost_fs, ost->ost_fs->fs_root_blkno, name,
			   namelen, NULL, &ost->ost_lostfound_ino);
	if (ret == 0)
		return;

	if (!prompt(ost, PY, PR_LOSTFOUND_MISSING,
		    "/lost+found does not exist.  Create it so "
		    "that we can possibly fill it with orphaned inodes?"))
		return;

	ret = ocfs2_new_inode(ost->ost_fs, &blkno, 0755 | S_IFDIR);
	if (ret) {
		com_err(whoami, ret, "while trying to allocate a new inode "
			"for /lost+found");
		return;
	}

	ret = ocfs2_init_dir(ost->ost_fs, blkno, ost->ost_fs->fs_root_blkno);
	if (ret) {
		com_err(whoami, ret, "while trying to expand a new "
			"/lost+found directory");
		goto out;
	}

	ret = ocfs2_link(ost->ost_fs, ost->ost_fs->fs_root_blkno, name, blkno,
			 OCFS2_FT_DIR);
	if (ret) {
		com_err(whoami, ret, "while linking inode %"PRIu64" as "
			"/lost+found", blkno);
		goto out;
	}

	/* XXX maybe this should be a helper to clean up the dir tracking
	 * for any new dir.  "2" for both the l+f dirent pointing to the
	 * inode and the "." dirent in its dirblock */
	o2fsck_icount_set(ost->ost_icount_in_inodes, blkno, 2);
	o2fsck_icount_set(ost->ost_icount_refs, blkno, 2);
	ret = o2fsck_add_dir_parent(&ost->ost_dir_parents, blkno, 
				    ost->ost_fs->fs_root_blkno,
				    ost->ost_fs->fs_root_blkno, 0);
	if (ret) {
		com_err(whoami, ret, "while recording a new /lost+found "
			"directory");
		goto out;
	}

	/* we've already iterated through the dirblocks in pass2 so there
	 * is no need to register l+f's new dir block */

	ost->ost_lostfound_ino = blkno;
	blkno = 0;
out:
	if (blkno) {
		ret = ocfs2_delete_inode(ost->ost_fs, blkno);
		if (ret) {
			com_err(whoami, ret, "while trying to clean up an "
			        "an allocated inode after linking /lost+found "
				"failed");
		}
	}
}
static errcode_t add_slots(ocfs2_filesys *fs, int num_slots)
{
	errcode_t ret;
	uint16_t old_num = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
	char fname[OCFS2_MAX_FILENAME_LEN];
	uint64_t blkno;
	int i, j, max_slots;
	int ftype;
	struct tools_progress *prog = NULL;

	if (ocfs2_uses_extended_slot_map(OCFS2_RAW_SB(fs->fs_super))) {
		ret = TUNEFS_ET_TOO_MANY_SLOTS_EXTENDED;
		max_slots = INT16_MAX;
	} else {
		ret = TUNEFS_ET_TOO_MANY_SLOTS_OLD;
		max_slots = OCFS2_MAX_SLOTS;
	}
	if (num_slots > max_slots)
		goto bail;

	prog = tools_progress_start("Adding slots", "addslots",
				    (NUM_SYSTEM_INODES -
				     OCFS2_LAST_GLOBAL_SYSTEM_INODE - 1) *
				    (num_slots - old_num));
	if (!prog) {
		ret = TUNEFS_ET_NO_MEMORY;
		goto bail;
	}

	ret = 0;
	for (i = OCFS2_LAST_GLOBAL_SYSTEM_INODE + 1; i < NUM_SYSTEM_INODES; ++i) {
		for (j = old_num; j < num_slots; ++j) {
			ocfs2_sprintf_system_inode_name(fname,
							OCFS2_MAX_FILENAME_LEN,
							i, j);
			verbosef(VL_APP, "Creating system file \"%s\"\n",
				 fname);

			/* Goto next if file already exists */
			ret = ocfs2_lookup(fs, fs->fs_sysdir_blkno, fname,
					   strlen(fname), NULL, &blkno);
			if (!ret) {
				verbosef(VL_APP,
					 "System file \"%s\" already exists\n",
					 fname);
				tools_progress_step(prog, 1);
				continue;
			}

			/* create inode for system file */
			ret = ocfs2_new_system_inode(fs, &blkno,
						     ocfs2_system_inodes[i].si_mode,
						     ocfs2_system_inodes[i].si_iflags);
			if (ret) {
				verbosef(VL_APP,
					 "%s while creating inode for "
					 "system file \"%s\"\n",
					 error_message(ret), fname);
				goto bail;
			}

			ftype = (S_ISDIR(ocfs2_system_inodes[i].si_mode) ?
				 OCFS2_FT_DIR : OCFS2_FT_REG_FILE);

			/* if dir, alloc space to it */
			if (ftype == OCFS2_FT_DIR) {
				ret = ocfs2_init_dir(fs, blkno,
						     fs->fs_sysdir_blkno);
				if (ret) {
					verbosef(VL_APP,
						 "%s while initializing "
						 "directory \"%s\"\n",
						 error_message(ret),
						 fname);
					goto bail;
				}
			}

			/* Add the inode to the system dir */
			ret = ocfs2_link(fs, fs->fs_sysdir_blkno, fname,
					 blkno, ftype);
			if (ret) {
				verbosef(VL_APP,
					"%s while linking inode %"PRIu64" "
					"as \"%s\" in the system "
					"directory\n",
					error_message(ret), blkno, fname);
				goto bail;
			}
			verbosef(VL_APP, "System file \"%s\" created\n",
				 fname);
			tools_progress_step(prog, 1);
		}
	}

bail:
	if (prog)
		tools_progress_stop(prog);

	return ret;
}
Beispiel #15
0
int main(int argc, char *argv[])
{
	errcode_t ret;
	uint64_t blkno, result_blkno;
	int c, len;
	char *filename, *lookup_path, *buf;
	char *filebuf;
	char *p;
	char lookup_name[256];
	ocfs2_filesys *fs;

	blkno = 0;

	initialize_ocfs_error_table();

	while ((c = getopt(argc, argv, "i:")) != EOF) {
		switch (c) {
			case 'i':
				blkno = read_number(optarg);
				if (blkno <= OCFS2_SUPER_BLOCK_BLKNO) {
					fprintf(stderr,
						"Invalid inode block: %s\n",
						optarg);
					print_usage();
					return 1;
				}
				break;

			default:
				print_usage();
				return 1;
				break;
		}
	}

	if (optind >= argc) {
		fprintf(stderr, "Missing filename\n");
		print_usage();
		return 1;
	}
	filename = argv[optind];
	optind++;

	if (optind >= argc) {
		fprintf(stdout, "Missing path to lookup\n");
		print_usage();
		return 1;
	}
	lookup_path = argv[optind];

	ret = ocfs2_open(filename, OCFS2_FLAG_RO, 0, 0, &fs);
	if (ret) {
		com_err(argv[0], ret,
			"while opening file \"%s\"", filename);
		goto out;
	}

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret) {
		com_err(argv[0], ret,
			"while allocating inode buffer");
		goto out_close;
	}

	if (!blkno)
		blkno = OCFS2_RAW_SB(fs->fs_super)->s_root_blkno;

	for (p = lookup_path; *p == '/'; p++);

	lookup_path = p;

	for (p = lookup_path; ; p++) {
		if (*p && *p != '/')
			continue;

		memcpy(lookup_name, lookup_path, p - lookup_path);
		lookup_name[p - lookup_path] = '\0';
		ret = ocfs2_lookup(fs, blkno, lookup_name,
				   strlen(lookup_name), NULL,
				   &result_blkno);
		if (ret) {
			com_err(argv[0], ret,
				"while looking up \"%s\" in inode %"PRIu64
			       	" on \"%s\"\n",
				lookup_name, blkno, filename);
			goto out_free;
		}

		blkno = result_blkno;

		for (; *p == '/'; p++);

		lookup_path = p;

		if (!*p)
			break;
	}

	if (ocfs2_check_directory(fs, blkno) != OCFS2_ET_NO_DIRECTORY) {
		com_err(argv[0], ret, "\"%s\" is not a file", filename);
		goto out_free;
	}

	ret = ocfs2_read_whole_file(fs, blkno, &filebuf, &len);
	if (ret) {
		com_err(argv[0], ret,
			"while reading file \"%s\" -- read %d bytes",
			filename, len);
		goto out_free_filebuf;
	}
	if (!len)
		fprintf(stderr, "boo!\n");

	dump_filebuf(filebuf, len);

out_free_filebuf:
	if (len)
		ocfs2_free(&filebuf);

out_free:
	ocfs2_free(&buf);

out_close:
	ret = ocfs2_close(fs);
	if (ret) {
		com_err(argv[0], ret,
			"while closing file \"%s\"", filename);
	}

out:
	return 0;
}
Beispiel #16
0
errcode_t ocfs2_fill_heartbeat_desc(ocfs2_filesys *fs,
				    struct o2cb_region_desc *desc)
{
	errcode_t ret;
	char *filename;
	char *buf = NULL;
	uint64_t blkno, blocks, start_block;
	uint32_t block_bits, cluster_bits;
	int sectsize, sectsize_bits;
	struct ocfs2_dinode *di;
	struct ocfs2_extent_rec *rec;

	ret = ocfs2_get_device_sectsize(fs->fs_devname, &sectsize);
	if (ret) {
		if (ret == OCFS2_ET_CANNOT_DETERMINE_SECTOR_SIZE)
			sectsize = OCFS2_MIN_BLOCKSIZE;
		else
			goto leave;
	}

	sectsize_bits = ffs(sectsize) - 1;

	filename = ocfs2_system_inodes[HEARTBEAT_SYSTEM_INODE].si_name;

	ret = ocfs2_lookup(fs, fs->fs_sysdir_blkno, filename,
			   strlen(filename),  NULL, &blkno);
	if (ret)
		goto leave;

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		goto leave;

	ret = ocfs2_read_inode(fs, blkno, buf);
	if (ret)
		goto leave;

	di = (struct ocfs2_dinode *)buf;
	if (di->id2.i_list.l_tree_depth || 
	    di->id2.i_list.l_next_free_rec != 1) {
		ret = OCFS2_ET_BAD_HEARTBEAT_FILE;
		goto leave;
	}
	rec = &(di->id2.i_list.l_recs[0]);

	block_bits = OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits;
	cluster_bits = OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits;

	if (block_bits < sectsize_bits) {
		ret = OCFS2_ET_BLOCK_SIZE_TOO_SMALL_FOR_HARDWARE;
		goto leave;
	}

	blocks = ocfs2_rec_clusters(0, rec) << cluster_bits;
	blocks >>= block_bits;

	if (blocks > O2NM_MAX_NODES)
		blocks = O2NM_MAX_NODES;

	start_block = rec->e_blkno << block_bits;
	start_block >>= sectsize_bits;

	desc->r_name			= fs->uuid_str;
	desc->r_device_name		= fs->fs_devname;
	desc->r_block_bytes		= sectsize;
	desc->r_start_block		= start_block;
	desc->r_blocks			= blocks;

leave:
	if (buf)
		ocfs2_free(&buf);

	return ret;
}
Beispiel #17
0
int main(int argc, char *argv[])
{
	errcode_t ret;
	uint64_t blkno, sys_blkno;
	int c;
	char *filename, *buf;
	const char *bitmap_name = ocfs2_system_inodes[GLOBAL_BITMAP_SYSTEM_INODE].si_name;
	ocfs2_filesys *fs;
	struct ocfs2_dinode *di;
	struct walk_block wb;

	blkno = OCFS2_SUPER_BLOCK_BLKNO;

	initialize_ocfs_error_table();

	while ((c = getopt(argc, argv, "i:")) != EOF) {
		switch (c) {
			case 'i':
				blkno = read_number(optarg);
				if (blkno <= OCFS2_SUPER_BLOCK_BLKNO) {
					fprintf(stderr,
						"Invalid inode block: %s\n",
						optarg);
					print_usage();
					return 1;
				}
				break;

			default:
				print_usage();
				return 1;
				break;
		}
	}

	if (optind >= argc) {
		fprintf(stderr, "Missing filename\n");
		print_usage();
		return 1;
	}
	filename = argv[optind];

	ret = ocfs2_open(filename, OCFS2_FLAG_RW, 0, 0, &fs);
	if (ret) {
		com_err(argv[0], ret,
			"while opening file \"%s\"", filename);
		goto out;
	}

	if (blkno == OCFS2_SUPER_BLOCK_BLKNO) {
		sys_blkno = OCFS2_RAW_SB(fs->fs_super)->s_system_dir_blkno;

		ret = ocfs2_lookup(fs, sys_blkno, bitmap_name, 
				   strlen(bitmap_name), NULL, &blkno);
		if (ret) {
			com_err(argv[0], ret,
				"while looking up \"%s\"", bitmap_name);
			goto out;
		}
	}

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret) {
		com_err(argv[0], ret,
			"while allocating inode buffer");
		goto out_close;
	}

	memset(&wb, 0, sizeof(wb));

	ret = ocfs2_read_inode(fs, blkno, buf);
	if (ret) {
		com_err(argv[0], ret, "while reading inode %"PRIu64, blkno);
		goto out_free;
	}

	di = (struct ocfs2_dinode *)buf;

	wb.di = di;
	ret = ocfs2_malloc_block(fs->fs_io, &wb.buf);
	if (ret) {
		com_err(argv[0], ret,
			"while allocating block buffer");
		goto out_free;
	}

	ret = ocfs2_block_iterate(fs, blkno, 0,
				  walk_blocks_func,
				  &wb);
	if (ret) {
		com_err(argv[0], ret,
			"while walking blocks");
		goto out_free;
	}

	di->id1.bitmap1.i_used = wb.used;

	ret = ocfs2_write_inode(fs, blkno, buf);
	if (ret) {
		com_err(argv[0], ret, "while reading inode %"PRIu64, blkno);
		goto out_free;
	}

out_free:
	if (wb.buf)
		ocfs2_free(&wb.buf);

	ocfs2_free(&buf);

out_close:
	ret = ocfs2_close(fs);
	if (ret) {
		com_err(argv[0], ret,
			"while closing file \"%s\"", filename);
	}

out:
	return 0;
}