Exemple #1
0
void ocfs2_evict_inode(struct inode *inode)
{
	if (!inode->i_nlink ||
	    (OCFS2_I(inode)->ip_flags & OCFS2_INODE_MAYBE_ORPHANED)) {
		ocfs2_delete_inode(inode);
	} else {
		truncate_inode_pages(&inode->i_data, 0);
	}
	ocfs2_clear_inode(inode);
}
Exemple #2
0
static int remove_quota_files_iterate(struct ocfs2_dir_entry *dirent,
				      uint64_t blocknr, int offset,
				      int blocksize, char *buf,
				      void *priv_data)
{
	struct remove_quota_files_ctxt *ctxt = priv_data;
	char dname[OCFS2_MAX_FILENAME_LEN];
	char wname[OCFS2_MAX_FILENAME_LEN];
	errcode_t ret;
	int tail, i;
	int ret_flags = 0;

	strncpy(dname, dirent->name, dirent->name_len);
	dname[dirent->name_len] = 0;

	/* Check whether entry is quota file of type we want - i.e. matching
	 * aquota.user:[0-9][0-9][0-9][0-9] or aquota.user for type == USRQUOTA
	 * and similarly for type == GRPQUOTA */
	strcpy(wname, "aquota.");
	strcat(wname, type2name(ctxt->type));
	tail = strlen(wname);
	if (strncmp(dname, wname, tail))
		return 0;
	if (dname[tail] == ':') {	/* May be local file? */
		tail++;
		for (i = 0; i < 4; i++)
			if (dname[tail + i] < '0' || dname[tail + i] > '9')
				return 0;
		if (dname[tail + i])
			return 0;
	} else if (dname[tail])		/* May be global file? */
		return 0;

	verbosef(VL_APP, "Deleting quota file %s\n",
		 dname);
	ret = ocfs2_truncate(ctxt->fs, dirent->inode, 0);
	if (ret) {
		tcom_err(ret, "while truncating quota file \"%s\"", dname);
		ret_flags |= OCFS2_DIRENT_ERROR;
		ctxt->err = ret;
		goto out;
	}
	ret = ocfs2_delete_inode(ctxt->fs, dirent->inode);
	if (ret) {
		tcom_err(ret, "while deleting quota file \"%s\"", dname);
		ret_flags |= OCFS2_DIRENT_ERROR;
		ctxt->err = ret;
	} else {
		dirent->inode = 0;
		ret_flags |= OCFS2_DIRENT_CHANGED;
	}
out:
	return ret_flags;
}
static int remove_slot_iterate(struct ocfs2_dir_entry *dirent, int offset,
			       int blocksize, char *buf, void *priv_data)
{
	struct remove_slot_ctxt *ctxt =
		(struct remove_slot_ctxt *)priv_data;
	int taillen, ret_flags = 0;
	errcode_t ret;
	char dname[OCFS2_MAX_FILENAME_LEN];
	char tail[OCFS2_MAX_FILENAME_LEN];

	sprintf(tail, ":%04d", ctxt->removed_slot);
	taillen = strlen(tail);

	strncpy(dname, dirent->name, dirent->name_len);
	dname[dirent->name_len] = '\0';

	if (!strcmp(dname + (dirent->name_len - taillen), tail)) {
		verbosef(VL_APP, "Unlinking system file \"%s\"\n",
			 dname);
		ret = ocfs2_delete_inode(ctxt->fs, dirent->inode);
		if (ret) {
			verbosef(VL_APP,
				 "%s while unlinking system file \"%s\"\n",
				 error_message(ret), dname);
			ret_flags |= OCFS2_DIRENT_ERROR;
			ctxt->errcode = ret;
		} else {
			verbosef(VL_APP,
				 "Successfully unlinked system file "
				 "\"%s\"\n",
				 dname);
			dirent->inode = 0;
			ret_flags |= OCFS2_DIRENT_CHANGED;
		}
	}

	return ret_flags;
}
Exemple #4
0
static void check_root(o2fsck_state *ost)
{
	struct ocfs2_super_block *sb = OCFS2_RAW_SB(ost->ost_fs->fs_super);
	errcode_t ret;
	uint64_t blkno, old_root;
	int was_set;

	if (o2fsck_test_inode_allocated(ost, ost->ost_fs->fs_root_blkno)) {
		ocfs2_bitmap_test(ost->ost_dir_inodes, 
				ost->ost_fs->fs_root_blkno, &was_set);
		if (!was_set)
			printf("The root inode exists but isn't a "
			       "directory.\n");
		return;
	}

	if (!prompt(ost, PY, PR_ROOT_DIR_MISSING,
		    "The super block claims that inode %"PRIu64" is the root "
		    "directory but it isn't allocated.  Create a new root "
		    "directory and update the super block?",
		    ost->ost_fs->fs_root_blkno))
		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 the root directory\n");
		return;
	}

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

	o2fsck_icount_set(ost->ost_icount_in_inodes, blkno, 1);
	o2fsck_icount_set(ost->ost_icount_refs, blkno, 1);
	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 root directory");
		goto out;
	}

	old_root = sb->s_root_blkno;
	ost->ost_fs->fs_root_blkno = blkno;
	sb->s_root_blkno = blkno;

	ret = ocfs2_write_primary_super(ost->ost_fs);
	if (ret) {
		com_err(whoami, ret, "while writing the super block with a "
			"new root directory inode");
		ost->ost_fs->fs_root_blkno = old_root;
		sb->s_root_blkno = old_root;
		goto out;
	}

	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");
		}
	}
}
Exemple #5
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");
		}
	}
}