示例#1
0
void do_store(int argc, char **argv)
{
	const char	*usage = "usage: %s inode count\n";
	errcode_t	retval;
	ext2_ino_t	ino;
	ext2_ino_t	count;

	if (argc < 3) {
		printf(usage, argv[0]);
		return;
	}
	if (check_icount(argv[0]))
		return;
	if (parse_inode(argv[0], "inode", argv[1], &ino))
		return;
	if (parse_inode(argv[0], "count", argv[2], &count))
		return;
	if (count > 65535) {
		printf("Count too large.\n");
		return;
	}
	retval = ext2fs_icount_store(test_icount, ino, (__u16) count);
	if (retval) {
		com_err(argv[0], retval,
			"while calling ext2fs_icount_store");
		return;
	}
}
示例#2
0
/*
 * This routine is called when an inode is not connected to the
 * directory tree.
 * 
 * This subroutine returns 1 then the caller shouldn't bother with the
 * rest of the pass 4 tests.
 */
static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
{
	ext2_filsys fs = ctx->fs;
	struct ext2_inode	inode;
	struct problem_context	pctx;

	e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
	clear_problem_context(&pctx);
	pctx.ino = i;
	pctx.inode = &inode;
	
	/*
	 * Offer to delete any zero-length files that does not have
	 * blocks.  If there is an EA block, it might have useful
	 * information, so we won't prompt to delete it, but let it be
	 * reconnected to lost+found.
	 */
	if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
				LINUX_S_ISDIR(inode.i_mode))) {
		if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
			ext2fs_icount_store(ctx->inode_link_info, i, 0);
			inode.i_links_count = 0;
			inode.i_dtime = ctx->now;
			e2fsck_write_inode(ctx, i, &inode,
					   "disconnect_inode");
			/*
			 * Fix up the bitmaps...
			 */
			e2fsck_read_bitmaps(ctx);
			ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
			ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
			ext2fs_inode_alloc_stats2(fs, i, -1,
						  LINUX_S_ISDIR(inode.i_mode));
			return 0;
		}
	}
	
	/*
	 * Prompt to reconnect.
	 */
	if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
		if (e2fsck_reconnect_file(ctx, i))
			ext2fs_unmark_valid(fs);
	} else {
		/*
		 * If we don't attach the inode, then skip the
		 * i_links_test since there's no point in trying to
		 * force i_links_count to zero.
		 */
		ext2fs_unmark_valid(fs);
		return 1;
	}
	return 0;
}
示例#3
0
/*
 * This fuction deallocates an inode
 */
static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
{
    ext2_filsys fs = ctx->fs;
    struct ext2_inode	inode;
    struct problem_context	pctx;

    ext2fs_icount_store(ctx->inode_link_info, ino, 0);
    e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
    inode.i_links_count = 0;
    inode.i_dtime = time(0);
    e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
    clear_problem_context(&pctx);
    pctx.ino = ino;

    /*
     * Fix up the bitmaps...
     */
    e2fsck_read_bitmaps(ctx);
    ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
    ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
    if (ctx->inode_bad_map)
        ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
    ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
    ext2fs_mark_ib_dirty(fs);

    if (!ext2fs_inode_has_valid_blocks(&inode))
        return;

    if (!LINUX_S_ISDIR(inode.i_mode) &&
            (inode.i_size_high || inode.i_size & 0x80000000UL))
        ctx->large_files--;

    if (inode.i_file_acl) {
        ext2fs_unmark_block_bitmap(ctx->block_found_map,
                                   inode.i_file_acl);
        ext2fs_unmark_block_bitmap(fs->block_map, inode.i_file_acl);
    }

    ext2fs_mark_bb_dirty(fs);
    pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
                                         deallocate_inode_block, ctx);
    if (pctx.errcode) {
        fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
        ctx->flags |= E2F_FLAG_ABORT;
        return;
    }
}
示例#4
0
int run_test(int flags, int size, char *dir, struct test_program *prog)
{
	errcode_t	retval;
	ext2_icount_t	icount;
	struct test_program *pc;
	__u16		result;
	int		problem = 0;

	if (dir) {
		retval = ext2fs_create_icount_tdb(test_fs, dir,
						  flags, &icount);
		if (retval) {
			com_err("run_test", retval,
				"while creating icount using tdb");
			exit(1);
		}
	} else {
		retval = ext2fs_create_icount2(test_fs, flags, size, 0,
					       &icount);
		if (retval) {
			com_err("run_test", retval, "while creating icount");
			exit(1);
		}
	}
	for (pc = prog; pc->cmd != EXIT; pc++) {
		switch (pc->cmd) {
		case FETCH:
			printf("icount_fetch(%u) = ", pc->ino);
			break;
		case STORE:
			retval = ext2fs_icount_store(icount, pc->ino, pc->arg);
			if (retval) {
				com_err("run_test", retval,
					"while calling icount_store");
				exit(1);
			}
			printf("icount_store(%u, %u) = ", pc->ino, pc->arg);
			break;
		case INCREMENT:
			retval = ext2fs_icount_increment(icount, pc->ino, 0);
			if (retval) {
				com_err("run_test", retval,
					"while calling icount_increment");
				exit(1);
			}
			printf("icount_increment(%u) = ", pc->ino);
			break;
		case DECREMENT:
			retval = ext2fs_icount_decrement(icount, pc->ino, 0);
			if (retval) {
				com_err("run_test", retval,
					"while calling icount_decrement");
				exit(1);
			}
			printf("icount_decrement(%u) = ", pc->ino);
			break;
		}
		retval = ext2fs_icount_fetch(icount, pc->ino, &result);
		if (retval) {
			com_err("run_test", retval,
				"while calling icount_fetch");
			exit(1);
		}
		printf("%u (%s)\n", result, (result == pc->expected) ?
		       "OK" : "NOT OK");
		if (result != pc->expected)
			problem++;
	}
	printf("icount size is %u\n", ext2fs_get_icount_size(icount));
	retval = ext2fs_icount_validate(icount, stdout);
	if (retval) {
		com_err("run_test", retval, "while calling icount_validate");
		exit(1);
	}
	ext2fs_free_icount(icount);
	return problem;
}
示例#5
0
/*
 * This routine gets the lost_and_found inode, making it a directory
 * if necessary
 */
ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
{
	ext2_filsys fs = ctx->fs;
	ext2_ino_t			ino;
	blk64_t			blk;
	errcode_t		retval;
	struct ext2_inode	inode;
	char *			block;
	static const char	name[] = "lost+found";
	struct 	problem_context	pctx;

	if (ctx->lost_and_found)
		return ctx->lost_and_found;

	clear_problem_context(&pctx);

	retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
			       sizeof(name)-1, 0, &ino);
	if (retval && !fix)
		return 0;
	if (!retval) {
		if (ext2fs_check_directory(fs, ino) == 0) {
			ctx->lost_and_found = ino;
			return ino;
		}

		/* Lost+found isn't a directory! */
		if (!fix)
			return 0;
		pctx.ino = ino;
		if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
			return 0;

		/* OK, unlink the old /lost+found file. */
		pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
		if (pctx.errcode) {
			pctx.str = "ext2fs_unlink";
			fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
			return 0;
		}
		(void) e2fsck_dir_info_set_parent(ctx, ino, 0);
		e2fsck_adjust_inode_count(ctx, ino, -1);
	} else if (retval != EXT2_ET_FILE_NOT_FOUND) {
		pctx.errcode = retval;
		fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
	}
	if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
		return 0;

	/*
	 * Read the inode and block bitmaps in; we'll be messing with
	 * them.
	 */
	e2fsck_read_bitmaps(ctx);

	/*
	 * First, find a free block
	 */
	retval = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
	if (retval) {
		pctx.errcode = retval;
		fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
		return 0;
	}
	ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
	ext2fs_block_alloc_stats2(fs, blk, +1);

	/*
	 * Next find a free inode.
	 */
	retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
				  ctx->inode_used_map, &ino);
	if (retval) {
		pctx.errcode = retval;
		fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
		return 0;
	}
	ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
	ext2fs_mark_inode_bitmap2(ctx->inode_dir_map, ino);
	ext2fs_inode_alloc_stats2(fs, ino, +1, 1);

	/*
	 * Now let's create the actual data block for the inode
	 */
	retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
	if (retval) {
		pctx.errcode = retval;
		fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
		return 0;
	}

	retval = ext2fs_write_dir_block4(fs, blk, block, 0, ino);
	ext2fs_free_mem(&block);
	if (retval) {
		pctx.errcode = retval;
		fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
		return 0;
	}

	/*
	 * Set up the inode structure
	 */
	memset(&inode, 0, sizeof(inode));
	inode.i_mode = 040700;
	inode.i_size = fs->blocksize;
	inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
	inode.i_links_count = 2;
	ext2fs_iblk_set(fs, &inode, 1);
	inode.i_block[0] = blk;

	/*
	 * Next, write out the inode.
	 */
	pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
	if (pctx.errcode) {
		pctx.str = "ext2fs_write_inode";
		fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
		return 0;
	}
	/*
	 * Finally, create the directory link
	 */
	pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
	if (pctx.errcode) {
		pctx.str = "ext2fs_link";
		fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
		return 0;
	}

	/*
	 * Miscellaneous bookkeeping that needs to be kept straight.
	 */
	e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
	e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
	ext2fs_icount_store(ctx->inode_count, ino, 2);
	ext2fs_icount_store(ctx->inode_link_info, ino, 2);
	ctx->lost_and_found = ino;
	quota_data_add(ctx->qctx, &inode, ino, fs->blocksize);
	quota_data_inodes(ctx->qctx, &inode, ino, +1);
#if 0
	printf("/lost+found created; inode #%lu\n", ino);
#endif
	return ino;
}
示例#6
0
/*
 * This makes sure the root inode is present; if not, we ask if the
 * user wants us to create it.  Not creating it is a fatal error.
 */
static void check_root(e2fsck_t ctx)
{
	ext2_filsys fs = ctx->fs;
	blk64_t			blk;
	struct ext2_inode	inode;
	char *			block;
	struct problem_context	pctx;

	clear_problem_context(&pctx);

	if (ext2fs_test_inode_bitmap2(ctx->inode_used_map, EXT2_ROOT_INO)) {
		/*
		 * If the root inode is not a directory, die here.  The
		 * user must have answered 'no' in pass1 when we
		 * offered to clear it.
		 */
		if (!(ext2fs_test_inode_bitmap2(ctx->inode_dir_map,
					       EXT2_ROOT_INO))) {
			fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
			ctx->flags |= E2F_FLAG_ABORT;
		}
		return;
	}

	if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
		fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
		ctx->flags |= E2F_FLAG_ABORT;
		return;
	}

	e2fsck_read_bitmaps(ctx);

	/*
	 * First, find a free block
	 */
	pctx.errcode = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
	if (pctx.errcode) {
		pctx.str = "ext2fs_new_block";
		fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
		ctx->flags |= E2F_FLAG_ABORT;
		return;
	}
	ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
	ext2fs_mark_block_bitmap2(fs->block_map, blk);
	ext2fs_mark_bb_dirty(fs);

	/*
	 * Now let's create the actual data block for the inode
	 */
	pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
					    &block);
	if (pctx.errcode) {
		pctx.str = "ext2fs_new_dir_block";
		fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
		ctx->flags |= E2F_FLAG_ABORT;
		return;
	}

	pctx.errcode = ext2fs_write_dir_block4(fs, blk, block, 0,
					       EXT2_ROOT_INO);
	if (pctx.errcode) {
		pctx.str = "ext2fs_write_dir_block";
		fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
		ctx->flags |= E2F_FLAG_ABORT;
		return;
	}
	ext2fs_free_mem(&block);

	/*
	 * Set up the inode structure
	 */
	memset(&inode, 0, sizeof(inode));
	inode.i_mode = 040755;
	inode.i_size = fs->blocksize;
	inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
	inode.i_links_count = 2;
	ext2fs_iblk_set(fs, &inode, 1);
	inode.i_block[0] = blk;

	/*
	 * Write out the inode.
	 */
	pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
	if (pctx.errcode) {
		pctx.str = "ext2fs_write_inode";
		fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
		ctx->flags |= E2F_FLAG_ABORT;
		return;
	}

	/*
	 * Miscellaneous bookkeeping...
	 */
	e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
	ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
	ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);

	ext2fs_mark_inode_bitmap2(ctx->inode_used_map, EXT2_ROOT_INO);
	ext2fs_mark_inode_bitmap2(ctx->inode_dir_map, EXT2_ROOT_INO);
	ext2fs_mark_inode_bitmap2(fs->inode_map, EXT2_ROOT_INO);
	ext2fs_mark_ib_dirty(fs);
}
示例#7
0
/*
 * This routine gets the lost_and_found inode, making it a directory
 * if necessary
 */
ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
{
	ext2_filsys fs = ctx->fs;
	ext2_ino_t			ino;
	blk64_t			blk;
	errcode_t		retval;
	struct ext2_inode	inode;
	char *			block;
	static const char	name[] = "lost+found";
	struct 	problem_context	pctx;
	int			will_rehash, flags;

	if (ctx->lost_and_found)
		return ctx->lost_and_found;

	clear_problem_context(&pctx);

	will_rehash = e2fsck_dir_will_be_rehashed(ctx, EXT2_ROOT_INO);
	if (will_rehash) {
		flags = ctx->fs->flags;
		ctx->fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
	}
	retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
			       sizeof(name)-1, 0, &ino);
	if (will_rehash)
		ctx->fs->flags = (flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) |
			(ctx->fs->flags & ~EXT2_FLAG_IGNORE_CSUM_ERRORS);
	if (retval && !fix)
		return 0;
	if (!retval) {
		/* Lost+found shouldn't have inline data */
		retval = ext2fs_read_inode(fs, ino, &inode);
		if (fix && retval)
			return 0;

		if (fix && (inode.i_flags & EXT4_INLINE_DATA_FL)) {
			if (!fix_problem(ctx, PR_3_LPF_INLINE_DATA, &pctx))
				return 0;
			goto unlink;
		}

		if (fix && (inode.i_flags & EXT4_ENCRYPT_FL)) {
			if (!fix_problem(ctx, PR_3_LPF_ENCRYPTED, &pctx))
				return 0;
			goto unlink;
		}

		if (ext2fs_check_directory(fs, ino) == 0) {
			ctx->lost_and_found = ino;
			return ino;
		}

		/* Lost+found isn't a directory! */
		if (!fix)
			return 0;
		pctx.ino = ino;
		if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
			return 0;

unlink:
		/* OK, unlink the old /lost+found file. */
		pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
		if (pctx.errcode) {
			pctx.str = "ext2fs_unlink";
			fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
			return 0;
		}
		(void) e2fsck_dir_info_set_parent(ctx, ino, 0);
		e2fsck_adjust_inode_count(ctx, ino, -1);
		/*
		 * If the old lost+found was a directory, we've just
		 * disconnected it from the directory tree, which
		 * means we need to restart the directory tree scan.
		 * The simplest way to do this is restart the whole
		 * e2fsck operation.
		 */
		if (LINUX_S_ISDIR(inode.i_mode))
			ctx->flags |= E2F_FLAG_RESTART;
	} else if (retval != EXT2_ET_FILE_NOT_FOUND) {
		pctx.errcode = retval;
		fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
	}
	if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
		return 0;

	/*
	 * Read the inode and block bitmaps in; we'll be messing with
	 * them.
	 */
	e2fsck_read_bitmaps(ctx);

	/*
	 * First, find a free block
	 */
	if (ctx->lnf_repair_block) {
		blk = ctx->lnf_repair_block;
		ctx->lnf_repair_block = 0;
		goto skip_new_block;
	}
	retval = ext2fs_new_block2(fs, 0, ctx->block_found_map, &blk);
	if (retval == EXT2_ET_BLOCK_ALLOC_FAIL &&
	    fix_problem(ctx, PR_3_LPF_NO_SPACE, &pctx)) {
		fix_problem(ctx, PR_3_NO_SPACE_TO_RECOVER, &pctx);
		ctx->lost_and_found = EXT2_ROOT_INO;
		return 0;
	}
	if (retval) {
		pctx.errcode = retval;
		fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
		return 0;
	}
	ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
skip_new_block:
	ext2fs_block_alloc_stats2(fs, blk, +1);

	/*
	 * Next find a free inode.
	 */
	retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
				  ctx->inode_used_map, &ino);
	if (retval == EXT2_ET_INODE_ALLOC_FAIL &&
	    fix_problem(ctx, PR_3_LPF_NO_SPACE, &pctx)) {
		fix_problem(ctx, PR_3_NO_SPACE_TO_RECOVER, &pctx);
		ctx->lost_and_found = EXT2_ROOT_INO;
		return 0;
	}
	if (retval) {
		pctx.errcode = retval;
		fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
		return 0;
	}
	ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
	ext2fs_mark_inode_bitmap2(ctx->inode_dir_map, ino);
	ext2fs_inode_alloc_stats2(fs, ino, +1, 1);

	/*
	 * Set up the inode structure
	 */
	memset(&inode, 0, sizeof(inode));
	inode.i_mode = 040700;
	inode.i_size = fs->blocksize;
	inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
	inode.i_links_count = 2;
	ext2fs_iblk_set(fs, &inode, 1);
	inode.i_block[0] = blk;

	/*
	 * Next, write out the inode.
	 */
	pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
	if (pctx.errcode) {
		pctx.str = "ext2fs_write_inode";
		fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
		return 0;
	}

	/*
	 * Now let's create the actual data block for the inode.
	 * Due to metadata_csum, the directory block MUST be written
	 * after the inode is written to disk!
	 */
	retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
	if (retval) {
		pctx.errcode = retval;
		fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
		return 0;
	}

	retval = ext2fs_write_dir_block4(fs, blk, block, 0, ino);
	ext2fs_free_mem(&block);
	if (retval) {
		pctx.errcode = retval;
		fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
		return 0;
	}

	/*
	 * Finally, create the directory link
	 */
	pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
	if (pctx.errcode == EXT2_ET_DIR_NO_SPACE) {
		pctx.errcode = ext2fs_expand_dir(fs, EXT2_ROOT_INO);
		if (pctx.errcode)
			goto link_error;
		pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino,
					   EXT2_FT_DIR);
	}
	if (pctx.errcode) {
link_error:
		pctx.str = "ext2fs_link";
		fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
		return 0;
	}

	/*
	 * Miscellaneous bookkeeping that needs to be kept straight.
	 */
	e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
	e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
	ext2fs_icount_store(ctx->inode_count, ino, 2);
	ext2fs_icount_store(ctx->inode_link_info, ino, 2);
	ctx->lost_and_found = ino;
	quota_data_add(ctx->qctx, &inode, ino, fs->blocksize);
	quota_data_inodes(ctx->qctx, &inode, ino, +1);
#if 0
	printf("/lost+found created; inode #%lu\n", ino);
#endif
	return ino;
}