本文整理汇总了C++中EXT2_HAS_RO_COMPAT_FEATURE函数的典型用法代码示例。如果您正苦于以下问题:C++ EXT2_HAS_RO_COMPAT_FEATURE函数的具体用法?C++ EXT2_HAS_RO_COMPAT_FEATURE怎么用?C++ EXT2_HAS_RO_COMPAT_FEATURE使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了EXT2_HAS_RO_COMPAT_FEATURE函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: parse_int_node
static void parse_int_node(ext2_filsys fs,
struct ext2_db_entry2 *db,
struct check_dir_struct *cd,
struct dx_dir_info *dx_dir,
char *block_buf, int failed_csum)
{
struct ext2_dx_root_info *root;
struct ext2_dx_entry *ent;
struct ext2_dx_countlimit *limit;
struct dx_dirblock_info *dx_db;
int i, expect_limit, count;
blk_t blk;
ext2_dirhash_t min_hash = 0xffffffff;
ext2_dirhash_t max_hash = 0;
ext2_dirhash_t hash = 0, prev_hash;
int csum_size = 0;
if (db->blockcnt == 0) {
root = (struct ext2_dx_root_info *) (block_buf + 24);
#ifdef DX_DEBUG
printf("Root node dump:\n");
printf("\t Reserved zero: %u\n", root->reserved_zero);
printf("\t Hash Version: %d\n", root->hash_version);
printf("\t Info length: %d\n", root->info_length);
printf("\t Indirect levels: %d\n", root->indirect_levels);
printf("\t Flags: %d\n", root->unused_flags);
#endif
ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
if (failed_csum &&
(e2fsck_dir_will_be_rehashed(cd->ctx, cd->pctx.ino) ||
fix_problem(cd->ctx, PR_2_HTREE_ROOT_CSUM_INVALID,
&cd->pctx)))
goto clear_and_exit;
} else {
ent = (struct ext2_dx_entry *) (block_buf+8);
if (failed_csum &&
(e2fsck_dir_will_be_rehashed(cd->ctx, cd->pctx.ino) ||
fix_problem(cd->ctx, PR_2_HTREE_NODE_CSUM_INVALID,
&cd->pctx)))
goto clear_and_exit;
}
limit = (struct ext2_dx_countlimit *) ent;
#ifdef DX_DEBUG
printf("Number of entries (count): %d\n",
ext2fs_le16_to_cpu(limit->count));
printf("Number of entries (limit): %d\n",
ext2fs_le16_to_cpu(limit->limit));
#endif
count = ext2fs_le16_to_cpu(limit->count);
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
csum_size = sizeof(struct ext2_dx_tail);
expect_limit = (fs->blocksize -
(csum_size + ((char *) ent - block_buf))) /
sizeof(struct ext2_dx_entry);
if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
goto clear_and_exit;
}
if (count > expect_limit) {
cd->pctx.num = count;
if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
goto clear_and_exit;
count = expect_limit;
}
for (i=0; i < count; i++) {
prev_hash = hash;
hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
#ifdef DX_DEBUG
printf("Entry #%d: Hash 0x%08x, block %u\n", i,
hash, ext2fs_le32_to_cpu(ent[i].block));
#endif
blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
/* Check to make sure the block is valid */
if (blk >= (blk_t) dx_dir->numblocks) {
cd->pctx.blk = blk;
if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
&cd->pctx))
goto clear_and_exit;
continue;
}
if (hash < prev_hash &&
fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
goto clear_and_exit;
dx_db = &dx_dir->dx_block[blk];
if (dx_db->flags & DX_FLAG_REFERENCED) {
dx_db->flags |= DX_FLAG_DUP_REF;
} else {
dx_db->flags |= DX_FLAG_REFERENCED;
dx_db->parent = db->blockcnt;
}
//.........这里部分代码省略.........
示例2: write_bitmaps
static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
{
dgrp_t i;
unsigned int j;
int block_nbytes, inode_nbytes;
unsigned int nbits;
errcode_t retval;
char *block_buf = NULL, *inode_buf = NULL;
int csum_flag = 0;
blk64_t blk;
blk64_t blk_itr = EXT2FS_B2C(fs, fs->super->s_first_data_block);
ext2_ino_t ino_itr = 1;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
if (!(fs->flags & EXT2_FLAG_RW))
return EXT2_ET_RO_FILSYS;
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
csum_flag = 1;
inode_nbytes = block_nbytes = 0;
if (do_block) {
block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8;
retval = io_channel_alloc_buf(fs->io, 0, &block_buf);
if (retval)
goto errout;
memset(block_buf, 0xff, fs->blocksize);
}
if (do_inode) {
inode_nbytes = (size_t)
((EXT2_INODES_PER_GROUP(fs->super)+7) / 8);
retval = io_channel_alloc_buf(fs->io, 0, &inode_buf);
if (retval)
goto errout;
memset(inode_buf, 0xff, fs->blocksize);
}
for (i = 0; i < fs->group_desc_count; i++) {
if (!do_block)
goto skip_block_bitmap;
if (csum_flag && ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT)
)
goto skip_this_block_bitmap;
retval = ext2fs_get_block_bitmap_range2(fs->block_map,
blk_itr, block_nbytes << 3, block_buf);
if (retval)
goto errout;
if (i == fs->group_desc_count - 1) {
/* Force bitmap padding for the last group */
nbits = EXT2FS_NUM_B2C(fs,
((ext2fs_blocks_count(fs->super)
- (__u64) fs->super->s_first_data_block)
% (__u64) EXT2_BLOCKS_PER_GROUP(fs->super)));
if (nbits)
for (j = nbits; j < fs->blocksize * 8; j++)
ext2fs_set_bit(j, block_buf);
}
blk = ext2fs_block_bitmap_loc(fs, i);
if (blk) {
retval = io_channel_write_blk64(fs->io, blk, 1,
block_buf);
if (retval) {
retval = EXT2_ET_BLOCK_BITMAP_WRITE;
goto errout;
}
}
skip_this_block_bitmap:
blk_itr += block_nbytes << 3;
skip_block_bitmap:
if (!do_inode)
continue;
if (csum_flag && ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT)
)
goto skip_this_inode_bitmap;
retval = ext2fs_get_inode_bitmap_range2(fs->inode_map,
ino_itr, inode_nbytes << 3, inode_buf);
if (retval)
goto errout;
blk = ext2fs_inode_bitmap_loc(fs, i);
if (blk) {
retval = io_channel_write_blk64(fs->io, blk, 1,
inode_buf);
if (retval) {
retval = EXT2_ET_INODE_BITMAP_WRITE;
goto errout;
}
}
skip_this_inode_bitmap:
ino_itr += inode_nbytes << 3;
}
//.........这里部分代码省略.........
示例3: check_block_bitmaps
static void check_block_bitmaps(e2fsck_t ctx)
{
ext2_filsys fs = ctx->fs;
blk64_t i;
int *free_array;
int group = 0;
blk_t blocks = 0;
blk_t free_blocks = 0;
int group_free = 0;
int actual, bitmap;
struct problem_context pctx;
int problem, save_problem, fixit, had_problem;
errcode_t retval;
int csum_flag;
int skip_group = 0;
int old_desc_blocks = 0;
int count = 0;
int cmp_block = 0;
int redo_flag = 0;
blk64_t super_blk, old_desc_blk, new_desc_blk;
clear_problem_context(&pctx);
free_array = (int *) e2fsck_allocate_memory(ctx,
fs->group_desc_count * sizeof(int), "free block count array");
if ((fs->super->s_first_data_block <
ext2fs_get_block_bitmap_start2(ctx->block_found_map)) ||
(fs->super->s_blocks_count-1 >
ext2fs_get_block_bitmap_end2(ctx->block_found_map))) {
pctx.num = 1;
pctx.blk = fs->super->s_first_data_block;
pctx.blk2 = fs->super->s_blocks_count -1;
pctx.ino = ext2fs_get_block_bitmap_start2(ctx->block_found_map);
pctx.ino2 = ext2fs_get_block_bitmap_end2(ctx->block_found_map);
fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
ctx->flags |= E2F_FLAG_ABORT; /* fatal */
goto errout;
}
if ((fs->super->s_first_data_block <
ext2fs_get_block_bitmap_start2(fs->block_map)) ||
(fs->super->s_blocks_count-1 >
ext2fs_get_block_bitmap_end2(fs->block_map))) {
pctx.num = 2;
pctx.blk = fs->super->s_first_data_block;
pctx.blk2 = fs->super->s_blocks_count -1;
pctx.ino = ext2fs_get_block_bitmap_start2(fs->block_map);
pctx.ino2 = ext2fs_get_block_bitmap_end2(fs->block_map);
fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
ctx->flags |= E2F_FLAG_ABORT; /* fatal */
goto errout;
}
csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
redo_counts:
had_problem = 0;
save_problem = 0;
pctx.blk = pctx.blk2 = NO_BLK;
if (csum_flag &&
(fs->group_desc[group].bg_flags & EXT2_BG_BLOCK_UNINIT))
skip_group++;
for (i = fs->super->s_first_data_block;
i < fs->super->s_blocks_count;
i++) {
actual = ext2fs_fast_test_block_bitmap2(ctx->block_found_map, i);
if (skip_group) {
if ((i - fs->super->s_first_data_block) %
fs->super->s_blocks_per_group == 0) {
super_blk = 0;
old_desc_blk = 0;
new_desc_blk = 0;
ext2fs_super_and_bgd_loc2(fs, group, &super_blk,
&old_desc_blk, &new_desc_blk, 0);
if (fs->super->s_feature_incompat &
EXT2_FEATURE_INCOMPAT_META_BG)
old_desc_blocks =
fs->super->s_first_meta_bg;
else
old_desc_blocks = fs->desc_blocks +
fs->super->s_reserved_gdt_blocks;
count = 0;
cmp_block = fs->super->s_blocks_per_group;
if (group == (int)fs->group_desc_count - 1)
cmp_block =
fs->super->s_blocks_count %
fs->super->s_blocks_per_group;
}
bitmap = 0;
if ((i == super_blk) ||
(old_desc_blk && old_desc_blocks &&
(i >= old_desc_blk) &&
(i < old_desc_blk + old_desc_blocks)) ||
(new_desc_blk && (i == new_desc_blk)) ||
//.........这里部分代码省略.........
示例4: copy_dir_entries
static errcode_t copy_dir_entries(e2fsck_t ctx,
struct fill_dir_struct *fd,
struct out_dir *outdir)
{
ext2_filsys fs = ctx->fs;
errcode_t retval;
char *block_start;
struct hash_entry *ent;
struct ext2_dir_entry *dirent;
unsigned int rec_len, prev_rec_len, left, slack, offset;
int i;
ext2_dirhash_t prev_hash;
int csum_size = 0;
struct ext2_dir_entry_tail *t;
if (ctx->htree_slack_percentage == 255) {
profile_get_uint(ctx->profile, "options",
"indexed_dir_slack_percentage",
0, 20,
&ctx->htree_slack_percentage);
if (ctx->htree_slack_percentage > 100)
ctx->htree_slack_percentage = 20;
}
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
csum_size = sizeof(struct ext2_dir_entry_tail);
outdir->max = 0;
retval = alloc_size_dir(fs, outdir,
(fd->dir_size / fs->blocksize) + 2);
if (retval)
return retval;
outdir->num = fd->compress ? 0 : 1;
offset = 0;
outdir->hashes[0] = 0;
prev_hash = 1;
if ((retval = get_next_block(fs, outdir, &block_start)))
return retval;
dirent = (struct ext2_dir_entry *) block_start;
prev_rec_len = 0;
rec_len = 0;
left = fs->blocksize - csum_size;
slack = fd->compress ? 12 :
((fs->blocksize - csum_size) * ctx->htree_slack_percentage)/100;
if (slack < 12)
slack = 12;
for (i = 0; i < fd->num_array; i++) {
ent = fd->harray + i;
if (ent->dir->inode == 0)
continue;
rec_len = EXT2_DIR_REC_LEN(ext2fs_dirent_name_len(ent->dir));
if (rec_len > left) {
if (left) {
left += prev_rec_len;
retval = ext2fs_set_rec_len(fs, left, dirent);
if (retval)
return retval;
}
if (csum_size) {
t = EXT2_DIRENT_TAIL(block_start,
fs->blocksize);
ext2fs_initialize_dirent_tail(fs, t);
}
if ((retval = get_next_block(fs, outdir,
&block_start)))
return retval;
offset = 0;
}
left = (fs->blocksize - csum_size) - offset;
dirent = (struct ext2_dir_entry *) (block_start + offset);
if (offset == 0) {
if (ent->hash == prev_hash)
outdir->hashes[outdir->num-1] = ent->hash | 1;
else
outdir->hashes[outdir->num-1] = ent->hash;
}
dirent->inode = ent->dir->inode;
ext2fs_dirent_set_name_len(dirent,
ext2fs_dirent_name_len(ent->dir));
ext2fs_dirent_set_file_type(dirent,
ext2fs_dirent_file_type(ent->dir));
retval = ext2fs_set_rec_len(fs, rec_len, dirent);
if (retval)
return retval;
prev_rec_len = rec_len;
memcpy(dirent->name, ent->dir->name,
ext2fs_dirent_name_len(dirent));
offset += rec_len;
left -= rec_len;
if (left < slack) {
prev_rec_len += left;
retval = ext2fs_set_rec_len(fs, prev_rec_len, dirent);
if (retval)
return retval;
offset += left;
left = 0;
}
prev_hash = ent->hash;
}
//.........这里部分代码省略.........
示例5: ext2_fill_super
//.........这里部分代码省略.........
#ifdef CONFIG_EXT2_FS_XATTR
if (def_mount_opts & EXT2_DEFM_XATTR_USER)
set_opt(sbi->s_mount_opt, XATTR_USER);
#endif
#ifdef CONFIG_EXT2_FS_POSIX_ACL
if (def_mount_opts & EXT2_DEFM_ACL)
set_opt(sbi->s_mount_opt, POSIX_ACL);
#endif
if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC)
set_opt(sbi->s_mount_opt, ERRORS_PANIC);
else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_CONTINUE)
set_opt(sbi->s_mount_opt, ERRORS_CONT);
else
set_opt(sbi->s_mount_opt, ERRORS_RO);
sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
set_opt(sbi->s_mount_opt, RESERVATION);
if (!parse_options ((char *) data, sbi))
goto failed_mount;
sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
MS_POSIXACL : 0);
ext2_xip_verify_sb(sb); /* see if bdev supports xip, unset
EXT2_MOUNT_XIP if not */
if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV &&
(EXT2_HAS_COMPAT_FEATURE(sb, ~0U) ||
EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
EXT2_HAS_INCOMPAT_FEATURE(sb, ~0U)))
printk("EXT2-fs warning: feature flags set on rev 0 fs, "
"running e2fsck is recommended\n");
/*
* Check feature flags regardless of the revision level, since we
* previously didn't change the revision level when setting the flags,
* so there is a chance incompat flags are set on a rev 0 filesystem.
*/
features = EXT2_HAS_INCOMPAT_FEATURE(sb, ~EXT2_FEATURE_INCOMPAT_SUPP);
if (features) {
printk("EXT2-fs: %s: couldn't mount because of "
"unsupported optional features (%x).\n",
sb->s_id, le32_to_cpu(features));
goto failed_mount;
}
if (!(sb->s_flags & MS_RDONLY) &&
(features = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))){
printk("EXT2-fs: %s: couldn't mount RDWR because of "
"unsupported optional features (%x).\n",
sb->s_id, le32_to_cpu(features));
goto failed_mount;
}
blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);
if (ext2_use_xip(sb) && blocksize != PAGE_SIZE) {
if (!silent)
printk("XIP: Unsupported blocksize\n");
goto failed_mount;
}
/* If the blocksize doesn't match, re-read the thing.. */
示例6: compute_sb_data
/*
* This computes the fields of the m_ext2fs structure from the
* data in the ext2fs structure read in.
*/
static int
compute_sb_data(struct vnode *devvp, struct ext2fs *es,
struct m_ext2fs *fs)
{
int db_count, error;
int i;
int logic_sb_block = 1; /* XXX for now */
struct buf *bp;
uint32_t e2fs_descpb;
fs->e2fs_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->e2fs_log_bsize;
fs->e2fs_bsize = 1U << fs->e2fs_bshift;
fs->e2fs_fsbtodb = es->e2fs_log_bsize + 1;
fs->e2fs_qbmask = fs->e2fs_bsize - 1;
fs->e2fs_fsize = EXT2_MIN_FRAG_SIZE << es->e2fs_log_fsize;
if (fs->e2fs_fsize)
fs->e2fs_fpb = fs->e2fs_bsize / fs->e2fs_fsize;
fs->e2fs_bpg = es->e2fs_bpg;
fs->e2fs_fpg = es->e2fs_fpg;
fs->e2fs_ipg = es->e2fs_ipg;
if (es->e2fs_rev == E2FS_REV0) {
fs->e2fs_isize = E2FS_REV0_INODE_SIZE;
} else {
fs->e2fs_isize = es->e2fs_inode_size;
/*
* Simple sanity check for superblock inode size value.
*/
if (EXT2_INODE_SIZE(fs) < E2FS_REV0_INODE_SIZE ||
EXT2_INODE_SIZE(fs) > fs->e2fs_bsize ||
(fs->e2fs_isize & (fs->e2fs_isize - 1)) != 0) {
printf("ext2fs: invalid inode size %d\n",
fs->e2fs_isize);
return (EIO);
}
}
/* Check for extra isize in big inodes. */
if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_EXTRA_ISIZE) &&
EXT2_INODE_SIZE(fs) < sizeof(struct ext2fs_dinode)) {
printf("ext2fs: no space for extra inode timestamps\n");
return (EINVAL);
}
fs->e2fs_ipb = fs->e2fs_bsize / EXT2_INODE_SIZE(fs);
fs->e2fs_itpg = fs->e2fs_ipg / fs->e2fs_ipb;
/* s_resuid / s_resgid ? */
fs->e2fs_gcount = howmany(es->e2fs_bcount - es->e2fs_first_dblock,
EXT2_BLOCKS_PER_GROUP(fs));
e2fs_descpb = fs->e2fs_bsize / sizeof(struct ext2_gd);
db_count = howmany(fs->e2fs_gcount, e2fs_descpb);
fs->e2fs_gdbcount = db_count;
fs->e2fs_gd = malloc(db_count * fs->e2fs_bsize,
M_EXT2MNT, M_WAITOK);
fs->e2fs_contigdirs = malloc(fs->e2fs_gcount *
sizeof(*fs->e2fs_contigdirs), M_EXT2MNT, M_WAITOK | M_ZERO);
/*
* Adjust logic_sb_block.
* Godmar thinks: if the blocksize is greater than 1024, then
* the superblock is logically part of block zero.
*/
if (fs->e2fs_bsize > SBSIZE)
logic_sb_block = 0;
for (i = 0; i < db_count; i++) {
error = bread(devvp,
fsbtodb(fs, logic_sb_block + i + 1),
fs->e2fs_bsize, NOCRED, &bp);
if (error) {
free(fs->e2fs_contigdirs, M_EXT2MNT);
free(fs->e2fs_gd, M_EXT2MNT);
brelse(bp);
return (error);
}
e2fs_cgload((struct ext2_gd *)bp->b_data,
&fs->e2fs_gd[
i * fs->e2fs_bsize / sizeof(struct ext2_gd)],
fs->e2fs_bsize);
brelse(bp);
bp = NULL;
}
/* Initialization for the ext2 Orlov allocator variant. */
fs->e2fs_total_dir = 0;
for (i = 0; i < fs->e2fs_gcount; i++)
fs->e2fs_total_dir += fs->e2fs_gd[i].ext2bgd_ndirs;
if (es->e2fs_rev == E2FS_REV0 ||
!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_LARGEFILE))
fs->e2fs_maxfilesize = 0x7fffffff;
else {
fs->e2fs_maxfilesize = 0xffffffffffff;
if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_HUGE_FILE))
fs->e2fs_maxfilesize = 0x7fffffffffffffff;
}
if (es->e4fs_flags & E2FS_UNSIGNED_HASH) {
fs->e2fs_uhash = 3;
} else if ((es->e4fs_flags & E2FS_SIGNED_HASH) == 0) {
//.........这里部分代码省略.........
示例7: ext2fs_inline_data_convert_dir
static errcode_t ext2fs_inline_data_convert_dir(ext2_filsys fs, ext2_ino_t ino,
char *bbuf, char *ibuf, int size)
{
struct ext2_dir_entry *dir, *dir2;
struct ext2_dir_entry_tail *t;
errcode_t retval;
unsigned int offset, rec_len;
int csum_size = 0;
int filetype = 0;
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
csum_size = sizeof(struct ext2_dir_entry_tail);
/* Create '.' and '..' */
if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
EXT2_FEATURE_INCOMPAT_FILETYPE))
filetype = EXT2_FT_DIR;
/*
* Set up entry for '.'
*/
dir = (struct ext2_dir_entry *) bbuf;
dir->inode = ino;
ext2fs_dirent_set_name_len(dir, 1);
ext2fs_dirent_set_file_type(dir, filetype);
dir->name[0] = '.';
rec_len = (fs->blocksize - csum_size) - EXT2_DIR_REC_LEN(1);
dir->rec_len = EXT2_DIR_REC_LEN(1);
/*
* Set up entry for '..'
*/
dir = (struct ext2_dir_entry *) (bbuf + dir->rec_len);
dir->rec_len = EXT2_DIR_REC_LEN(2);
dir->inode = ext2fs_le32_to_cpu(((__u32 *)ibuf)[0]);
ext2fs_dirent_set_name_len(dir, 2);
ext2fs_dirent_set_file_type(dir, filetype);
dir->name[0] = '.';
dir->name[1] = '.';
/*
* Ajust the last rec_len
*/
offset = EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2);
dir = (struct ext2_dir_entry *) (bbuf + offset);
memcpy(bbuf + offset, ibuf + EXT4_INLINE_DATA_DOTDOT_SIZE,
size - EXT4_INLINE_DATA_DOTDOT_SIZE);
size += EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2) -
EXT4_INLINE_DATA_DOTDOT_SIZE;
do {
dir2 = dir;
retval = ext2fs_get_rec_len(fs, dir, &rec_len);
if (retval)
goto err;
offset += rec_len;
dir = (struct ext2_dir_entry *) (bbuf + offset);
} while (offset < size);
rec_len += fs->blocksize - csum_size - offset;
retval = ext2fs_set_rec_len(fs, rec_len, dir2);
if (retval)
goto err;
if (csum_size) {
t = EXT2_DIRENT_TAIL(bbuf, fs->blocksize);
ext2fs_initialize_dirent_tail(fs, t);
}
err:
return retval;
}
示例8: check_block_bitmaps
static void check_block_bitmaps(e2fsck_t ctx)
{
ext2_filsys fs = ctx->fs;
blk64_t i;
unsigned int *free_array;
int group = 0;
unsigned int blocks = 0;
blk64_t free_blocks = 0;
blk64_t first_free = ext2fs_blocks_count(fs->super);
unsigned int group_free = 0;
int actual, bitmap;
struct problem_context pctx;
int problem, save_problem, fixit, had_problem;
errcode_t retval;
int csum_flag;
int skip_group = 0;
int old_desc_blocks = 0;
int count = 0;
int cmp_block = 0;
int redo_flag = 0;
blk64_t super_blk, old_desc_blk, new_desc_blk;
clear_problem_context(&pctx);
free_array = (unsigned int *) e2fsck_allocate_memory(ctx,
fs->group_desc_count * sizeof(unsigned int), "free block count array");
if ((B2C(fs->super->s_first_data_block) <
ext2fs_get_block_bitmap_start2(ctx->block_found_map)) ||
(B2C(ext2fs_blocks_count(fs->super)-1) >
ext2fs_get_block_bitmap_end2(ctx->block_found_map))) {
pctx.num = 1;
pctx.blk = B2C(fs->super->s_first_data_block);
pctx.blk2 = B2C(ext2fs_blocks_count(fs->super) - 1);
pctx.ino = ext2fs_get_block_bitmap_start2(ctx->block_found_map);
pctx.ino2 = ext2fs_get_block_bitmap_end2(ctx->block_found_map);
fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
ctx->flags |= E2F_FLAG_ABORT; /* fatal */
goto errout;
}
if ((B2C(fs->super->s_first_data_block) <
ext2fs_get_block_bitmap_start2(fs->block_map)) ||
(B2C(ext2fs_blocks_count(fs->super)-1) >
ext2fs_get_block_bitmap_end2(fs->block_map))) {
pctx.num = 2;
pctx.blk = B2C(fs->super->s_first_data_block);
pctx.blk2 = B2C(ext2fs_blocks_count(fs->super) - 1);
pctx.ino = ext2fs_get_block_bitmap_start2(fs->block_map);
pctx.ino2 = ext2fs_get_block_bitmap_end2(fs->block_map);
fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
ctx->flags |= E2F_FLAG_ABORT; /* fatal */
goto errout;
}
csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
redo_counts:
had_problem = 0;
save_problem = 0;
pctx.blk = pctx.blk2 = NO_BLK;
if (csum_flag &&
(ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT)))
skip_group++;
for (i = B2C(fs->super->s_first_data_block);
i < ext2fs_blocks_count(fs->super);
i += EXT2FS_CLUSTER_RATIO(fs)) {
actual = ext2fs_fast_test_block_bitmap2(ctx->block_found_map, i);
if (skip_group) {
if ((B2C(i) - B2C(fs->super->s_first_data_block)) %
fs->super->s_clusters_per_group == 0) {
super_blk = 0;
old_desc_blk = 0;
new_desc_blk = 0;
ext2fs_super_and_bgd_loc2(fs, group, &super_blk,
&old_desc_blk, &new_desc_blk, 0);
if (fs->super->s_feature_incompat &
EXT2_FEATURE_INCOMPAT_META_BG)
old_desc_blocks =
fs->super->s_first_meta_bg;
else
old_desc_blocks = fs->desc_blocks +
fs->super->s_reserved_gdt_blocks;
count = 0;
cmp_block = fs->super->s_clusters_per_group;
if (group == (int)fs->group_desc_count - 1)
cmp_block = EXT2FS_NUM_B2C(fs,
ext2fs_group_blocks_count(fs, group));
}
bitmap = 0;
if (EQ_CLSTR(i, super_blk) ||
(old_desc_blk && old_desc_blocks &&
GE_CLSTR(i, old_desc_blk) &&
LE_CLSTR(i, old_desc_blk + old_desc_blocks-1)) ||
(new_desc_blk && EQ_CLSTR(i, new_desc_blk)) ||
//.........这里部分代码省略.........
示例9: check_inode_bitmaps
static void check_inode_bitmaps(e2fsck_t ctx)
{
ext2_filsys fs = ctx->fs;
ext2_ino_t i;
unsigned int free_inodes = 0;
int group_free = 0;
int dirs_count = 0;
int group = 0;
unsigned int inodes = 0;
ext2_ino_t *free_array;
ext2_ino_t *dir_array;
int actual, bitmap;
errcode_t retval;
struct problem_context pctx;
int problem, save_problem, fixit, had_problem;
int csum_flag;
int skip_group = 0;
int redo_flag = 0;
ext2_ino_t first_free = fs->super->s_inodes_per_group + 1;
clear_problem_context(&pctx);
free_array = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
fs->group_desc_count * sizeof(ext2_ino_t), "free inode count array");
dir_array = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
fs->group_desc_count * sizeof(ext2_ino_t), "directory count array");
if ((1 < ext2fs_get_inode_bitmap_start2(ctx->inode_used_map)) ||
(fs->super->s_inodes_count >
ext2fs_get_inode_bitmap_end2(ctx->inode_used_map))) {
pctx.num = 3;
pctx.blk = 1;
pctx.blk2 = fs->super->s_inodes_count;
pctx.ino = ext2fs_get_inode_bitmap_start2(ctx->inode_used_map);
pctx.ino2 = ext2fs_get_inode_bitmap_end2(ctx->inode_used_map);
fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
ctx->flags |= E2F_FLAG_ABORT; /* fatal */
goto errout;
}
if ((1 < ext2fs_get_inode_bitmap_start2(fs->inode_map)) ||
(fs->super->s_inodes_count >
ext2fs_get_inode_bitmap_end2(fs->inode_map))) {
pctx.num = 4;
pctx.blk = 1;
pctx.blk2 = fs->super->s_inodes_count;
pctx.ino = ext2fs_get_inode_bitmap_start2(fs->inode_map);
pctx.ino2 = ext2fs_get_inode_bitmap_end2(fs->inode_map);
fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
ctx->flags |= E2F_FLAG_ABORT; /* fatal */
goto errout;
}
csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
redo_counts:
had_problem = 0;
save_problem = 0;
pctx.ino = pctx.ino2 = 0;
if (csum_flag &&
(ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT)))
skip_group++;
/* Protect loop from wrap-around if inodes_count is maxed */
for (i = 1; i <= fs->super->s_inodes_count && i > 0; i++) {
bitmap = 0;
if (skip_group &&
i % fs->super->s_inodes_per_group == 1) {
/*
* Current inode is the first inode
* in the current block group.
*/
if (ext2fs_test_inode_bitmap_range(
ctx->inode_used_map, i,
fs->super->s_inodes_per_group)) {
/*
* When the compared inodes in inodes bitmap
* are 0, count the free inode,
* skip the current block group.
*/
first_free = 1;
inodes = fs->super->s_inodes_per_group - 1;
group_free = inodes;
free_inodes += inodes;
i += inodes;
skip_group = 0;
goto do_counts;
}
}
actual = ext2fs_fast_test_inode_bitmap2(ctx->inode_used_map, i);
if (redo_flag)
bitmap = actual;
else if (!skip_group)
bitmap = ext2fs_fast_test_inode_bitmap2(fs->inode_map, i);
if (!actual == !bitmap)
goto do_counts;
if (!actual && bitmap) {
//.........这里部分代码省略.........
示例10: ext2_fill_super
//.........这里部分代码省略.........
if (def_mount_opts & EXT2_DEFM_UID16)
set_opt(sbi->s_mount_opt, NO_UID32);
#ifdef CONFIG_EXT2_FS_XATTR
if (def_mount_opts & EXT2_DEFM_XATTR_USER)
set_opt(sbi->s_mount_opt, XATTR_USER);
#endif
#ifdef CONFIG_EXT2_FS_POSIX_ACL
if (def_mount_opts & EXT2_DEFM_ACL)
set_opt(sbi->s_mount_opt, POSIX_ACL);
#endif
if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC)
set_opt(sbi->s_mount_opt, ERRORS_PANIC);
else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_CONTINUE)
set_opt(sbi->s_mount_opt, ERRORS_CONT);
else
set_opt(sbi->s_mount_opt, ERRORS_RO);
sbi->s_resuid = make_kuid(&init_user_ns, le16_to_cpu(es->s_def_resuid));
sbi->s_resgid = make_kgid(&init_user_ns, le16_to_cpu(es->s_def_resgid));
set_opt(sbi->s_mount_opt, RESERVATION);
if (!parse_options((char *) data, sb))
goto failed_mount;
sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
MS_POSIXACL : 0);
sb->s_iflags |= SB_I_CGROUPWB;
if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV &&
(EXT2_HAS_COMPAT_FEATURE(sb, ~0U) ||
EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
EXT2_HAS_INCOMPAT_FEATURE(sb, ~0U)))
ext2_msg(sb, KERN_WARNING,
"warning: feature flags set on rev 0 fs, "
"running e2fsck is recommended");
/*
* Check feature flags regardless of the revision level, since we
* previously didn't change the revision level when setting the flags,
* so there is a chance incompat flags are set on a rev 0 filesystem.
*/
features = EXT2_HAS_INCOMPAT_FEATURE(sb, ~EXT2_FEATURE_INCOMPAT_SUPP);
if (features) {
ext2_msg(sb, KERN_ERR, "error: couldn't mount because of "
"unsupported optional features (%x)",
le32_to_cpu(features));
goto failed_mount;
}
if (!(sb->s_flags & MS_RDONLY) &&
(features = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))){
ext2_msg(sb, KERN_ERR, "error: couldn't mount RDWR because of "
"unsupported optional features (%x)",
le32_to_cpu(features));
goto failed_mount;
}
blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);
if (sbi->s_mount_opt & EXT2_MOUNT_DAX) {
struct blk_dax_ctl dax = {
.sector = 0,
.size = PAGE_SIZE,
};
if (blocksize != PAGE_SIZE) {
示例11: ext2fs_initialize
errcode_t ext2fs_initialize(const char *name, int flags,
struct ext2_super_block *param,
io_manager manager, ext2_filsys *ret_fs)
{
ext2_filsys fs;
errcode_t retval;
struct ext2_super_block *super;
unsigned int rem;
unsigned int overhead = 0;
unsigned int ipg;
dgrp_t i;
blk64_t free_blocks;
blk_t numblocks;
int rsv_gdt;
int csum_flag;
int bigalloc_flag;
int io_flags;
unsigned reserved_inos;
char *buf = 0;
char c;
double reserved_ratio;
if (!param || !ext2fs_blocks_count(param))
return EXT2_ET_INVALID_ARGUMENT;
retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs);
if (retval)
return retval;
memset(fs, 0, sizeof(struct struct_ext2_filsys));
fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
fs->flags = flags | EXT2_FLAG_RW;
fs->umask = 022;
fs->default_bitmap_type = EXT2FS_BMAP64_RBTREE;
#ifdef WORDS_BIGENDIAN
fs->flags |= EXT2_FLAG_SWAP_BYTES;
#endif
io_flags = IO_FLAG_RW;
if (flags & EXT2_FLAG_EXCLUSIVE)
io_flags |= IO_FLAG_EXCLUSIVE;
if (flags & EXT2_FLAG_DIRECT_IO)
io_flags |= IO_FLAG_DIRECT_IO;
retval = manager->open(name, io_flags, &fs->io);
if (retval)
goto cleanup;
fs->image_io = fs->io;
fs->io->app_data = fs;
retval = ext2fs_get_mem(strlen(name)+1, &fs->device_name);
if (retval)
goto cleanup;
strcpy(fs->device_name, name);
retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &super);
if (retval)
goto cleanup;
fs->super = super;
memset(super, 0, SUPERBLOCK_SIZE);
#define set_field(field, default) (super->field = param->field ? \
param->field : (default))
#define assign_field(field) (super->field = param->field)
super->s_magic = EXT2_SUPER_MAGIC;
super->s_state = EXT2_VALID_FS;
bigalloc_flag = EXT2_HAS_RO_COMPAT_FEATURE(param,
EXT4_FEATURE_RO_COMPAT_BIGALLOC);
assign_field(s_log_block_size);
if (bigalloc_flag) {
set_field(s_log_cluster_size, super->s_log_block_size+4);
if (super->s_log_block_size > super->s_log_cluster_size) {
retval = EXT2_ET_INVALID_ARGUMENT;
goto cleanup;
}
} else
super->s_log_cluster_size = super->s_log_block_size;
set_field(s_first_data_block, super->s_log_cluster_size ? 0 : 1);
set_field(s_max_mnt_count, 0);
set_field(s_errors, EXT2_ERRORS_DEFAULT);
set_field(s_feature_compat, 0);
set_field(s_feature_incompat, 0);
set_field(s_feature_ro_compat, 0);
set_field(s_default_mount_opts, 0);
set_field(s_first_meta_bg, 0);
set_field(s_raid_stride, 0); /* default stride size: 0 */
set_field(s_raid_stripe_width, 0); /* default stripe width: 0 */
set_field(s_log_groups_per_flex, 0);
set_field(s_flags, 0);
assign_field(s_backup_bgs[0]);
assign_field(s_backup_bgs[1]);
if (super->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) {
retval = EXT2_ET_UNSUPP_FEATURE;
goto cleanup;
}
if (super->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
retval = EXT2_ET_RO_UNSUPP_FEATURE;
//.........这里部分代码省略.........
示例12: htree_dump_leaf_node
static void htree_dump_leaf_node(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode *inode,
struct ext2_dx_root_info * rootnode,
blk64_t blk, char *buf)
{
errcode_t errcode;
struct ext2_dir_entry *dirent;
int thislen, col = 0;
unsigned int offset = 0;
char name[EXT2_NAME_LEN + 1];
char tmp[EXT2_NAME_LEN + 64];
blk64_t pblk;
ext2_dirhash_t hash, minor_hash;
unsigned int rec_len;
int hash_alg;
int csum_size = 0;
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
csum_size = sizeof(struct ext2_dir_entry_tail);
errcode = ext2fs_bmap2(fs, ino, inode, buf, 0, blk, 0, &pblk);
if (errcode) {
com_err("htree_dump_leaf_node", errcode,
"while mapping logical block %llu\n", blk);
return;
}
fprintf(pager, "Reading directory block %llu, phys %llu\n", blk, pblk);
errcode = ext2fs_read_dir_block4(current_fs, pblk, buf, 0, ino);
if (errcode) {
com_err("htree_dump_leaf_node", errcode,
"while reading block %llu (%llu)\n",
blk, pblk);
return;
}
hash_alg = rootnode->hash_version;
if ((hash_alg <= EXT2_HASH_TEA) &&
(fs->super->s_flags & EXT2_FLAGS_UNSIGNED_HASH))
hash_alg += 3;
while (offset < fs->blocksize) {
dirent = (struct ext2_dir_entry *) (buf + offset);
errcode = ext2fs_get_rec_len(fs, dirent, &rec_len);
if (errcode) {
com_err("htree_dump_leaf_inode", errcode,
"while getting rec_len for block %lu",
(unsigned long) blk);
return;
}
if (((offset + rec_len) > fs->blocksize) ||
(rec_len < 8) ||
((rec_len % 4) != 0) ||
((((unsigned) dirent->name_len & 0xFF)+8) > rec_len)) {
fprintf(pager, "Corrupted directory block (%llu)!\n",
blk);
break;
}
thislen = dirent->name_len & 0xFF;
strncpy(name, dirent->name, thislen);
name[thislen] = '\0';
errcode = ext2fs_dirhash(hash_alg, name,
thislen, fs->super->s_hash_seed,
&hash, &minor_hash);
if (errcode)
com_err("htree_dump_leaf_node", errcode,
"while calculating hash");
if ((offset == fs->blocksize - csum_size) &&
(dirent->inode == 0) &&
(dirent->rec_len == csum_size) &&
(dirent->name_len == EXT2_DIR_NAME_LEN_CSUM)) {
struct ext2_dir_entry_tail *t;
t = (struct ext2_dir_entry_tail *) dirent;
snprintf(tmp, EXT2_NAME_LEN + 64,
"leaf block checksum: 0x%08x ",
t->det_checksum);
} else {
snprintf(tmp, EXT2_NAME_LEN + 64,
"%u 0x%08x-%08x (%d) %s ",
dirent->inode, hash, minor_hash,
rec_len, name);
}
thislen = strlen(tmp);
if (col + thislen > 80) {
fprintf(pager, "\n");
col = 0;
}
fprintf(pager, "%s", tmp);
col += thislen;
offset += rec_len;
}
fprintf(pager, "\n");
}
示例13: check_dir_block
static int check_dir_block(ext2_filsys fs,
struct ext2_db_entry2 *db,
void *priv_data)
{
struct dx_dir_info *dx_dir;
#ifdef ENABLE_HTREE
struct dx_dirblock_info *dx_db = 0;
#endif /* ENABLE_HTREE */
struct ext2_dir_entry *dirent, *prev;
ext2_dirhash_t hash;
unsigned int offset = 0;
int dir_modified = 0;
int dot_state;
unsigned int rec_len;
blk64_t block_nr = db->blk;
ext2_ino_t ino = db->ino;
ext2_ino_t subdir_parent;
__u16 links;
struct check_dir_struct *cd;
char *buf;
e2fsck_t ctx;
int problem;
struct ext2_dx_root_info *root;
struct ext2_dx_countlimit *limit;
static dict_t de_dict;
struct problem_context pctx;
int dups_found = 0;
int ret;
int dx_csum_size = 0, de_csum_size = 0;
int failed_csum = 0;
int is_leaf = 1;
cd = (struct check_dir_struct *) priv_data;
buf = cd->buf;
ctx = cd->ctx;
if (ctx->flags & E2F_FLAG_SIGNAL_MASK || ctx->flags & E2F_FLAG_RESTART)
return DIRENT_ABORT;
if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
return DIRENT_ABORT;
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) {
dx_csum_size = sizeof(struct ext2_dx_tail);
de_csum_size = sizeof(struct ext2_dir_entry_tail);
}
/*
* Make sure the inode is still in use (could have been
* deleted in the duplicate/bad blocks pass.
*/
if (!(ext2fs_test_inode_bitmap2(ctx->inode_used_map, ino)))
return 0;
cd->pctx.ino = ino;
cd->pctx.blk = block_nr;
cd->pctx.blkcount = db->blockcnt;
cd->pctx.ino2 = 0;
cd->pctx.dirent = 0;
cd->pctx.num = 0;
if (db->blk == 0) {
if (allocate_dir_block(ctx, db, buf, &cd->pctx))
return 0;
block_nr = db->blk;
}
if (db->blockcnt)
dot_state = 2;
else
dot_state = 0;
if (ctx->dirs_to_hash &&
ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
dups_found++;
#if 0
printf("In process_dir_block block %lu, #%d, inode %lu\n", block_nr,
db->blockcnt, ino);
#endif
ehandler_operation(_("reading directory block"));
cd->pctx.errcode = ext2fs_read_dir_block4(fs, block_nr, buf, 0, ino);
ehandler_operation(0);
if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
cd->pctx.errcode = 0; /* We'll handle this ourselves */
else if (cd->pctx.errcode == EXT2_ET_DIR_CSUM_INVALID) {
cd->pctx.errcode = 0; /* We'll handle this ourselves */
failed_csum = 1;
}
if (cd->pctx.errcode) {
char *buf2;
if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
ctx->flags |= E2F_FLAG_ABORT;
return DIRENT_ABORT;
}
ext2fs_new_dir_block(fs, db->blockcnt == 0 ? ino : 0,
EXT2_ROOT_INO, &buf2);
memcpy(buf, buf2, fs->blocksize);
//.........这里部分代码省略.........
示例14: ext2fs_new_dir_block
/*
* Create new directory block
*/
errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
ext2_ino_t parent_ino, char **block)
{
struct ext2_dir_entry *dir = NULL;
errcode_t retval;
char *buf;
int rec_len;
int filetype = 0;
struct ext2_dir_entry_tail *t;
int csum_size = 0;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
retval = ext2fs_get_mem(fs->blocksize, &buf);
if (retval)
return retval;
memset(buf, 0, fs->blocksize);
dir = (struct ext2_dir_entry *) buf;
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
csum_size = sizeof(struct ext2_dir_entry_tail);
retval = ext2fs_set_rec_len(fs, fs->blocksize - csum_size, dir);
if (retval)
return retval;
if (dir_ino) {
if (fs->super->s_feature_incompat &
EXT2_FEATURE_INCOMPAT_FILETYPE)
filetype = EXT2_FT_DIR;
/*
* Set up entry for '.'
*/
dir->inode = dir_ino;
ext2fs_dirent_set_name_len(dir, 1);
ext2fs_dirent_set_file_type(dir, filetype);
dir->name[0] = '.';
rec_len = (fs->blocksize - csum_size) - EXT2_DIR_REC_LEN(1);
dir->rec_len = EXT2_DIR_REC_LEN(1);
/*
* Set up entry for '..'
*/
dir = (struct ext2_dir_entry *) (buf + dir->rec_len);
retval = ext2fs_set_rec_len(fs, rec_len, dir);
if (retval)
return retval;
dir->inode = parent_ino;
ext2fs_dirent_set_name_len(dir, 2);
ext2fs_dirent_set_file_type(dir, filetype);
dir->name[0] = '.';
dir->name[1] = '.';
}
if (csum_size) {
t = EXT2_DIRENT_TAIL(buf, fs->blocksize);
ext2fs_initialize_dirent_tail(fs, t);
}
*block = buf;
return 0;
}
示例15: ext2_remount
static int ext2_remount (struct super_block * sb, int * flags, char * data)
{
struct ext2_sb_info * sbi = EXT2_SB(sb);
struct ext2_super_block * es;
struct ext2_mount_options old_opts;
unsigned long old_sb_flags;
int err;
sync_filesystem(sb);
spin_lock(&sbi->s_lock);
/* Store the old options */
old_sb_flags = sb->s_flags;
old_opts.s_mount_opt = sbi->s_mount_opt;
old_opts.s_resuid = sbi->s_resuid;
old_opts.s_resgid = sbi->s_resgid;
/*
* Allow the "check" option to be passed as a remount option.
*/
if (!parse_options(data, sb)) {
err = -EINVAL;
goto restore_opts;
}
sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
es = sbi->s_es;
if ((sbi->s_mount_opt ^ old_opts.s_mount_opt) & EXT2_MOUNT_DAX) {
ext2_msg(sb, KERN_WARNING, "warning: refusing change of "
"dax flag with busy inodes while remounting");
sbi->s_mount_opt ^= EXT2_MOUNT_DAX;
}
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
spin_unlock(&sbi->s_lock);
return 0;
}
if (*flags & MS_RDONLY) {
if (le16_to_cpu(es->s_state) & EXT2_VALID_FS ||
!(sbi->s_mount_state & EXT2_VALID_FS)) {
spin_unlock(&sbi->s_lock);
return 0;
}
/*
* OK, we are remounting a valid rw partition rdonly, so set
* the rdonly flag and then mark the partition as valid again.
*/
es->s_state = cpu_to_le16(sbi->s_mount_state);
es->s_mtime = cpu_to_le32(get_seconds());
spin_unlock(&sbi->s_lock);
err = dquot_suspend(sb, -1);
if (err < 0) {
spin_lock(&sbi->s_lock);
goto restore_opts;
}
ext2_sync_super(sb, es, 1);
} else {
__le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb,
~EXT2_FEATURE_RO_COMPAT_SUPP);
if (ret) {
ext2_msg(sb, KERN_WARNING,
"warning: couldn't remount RDWR because of "
"unsupported optional features (%x).",
le32_to_cpu(ret));
err = -EROFS;
goto restore_opts;
}
/*
* Mounting a RDONLY partition read-write, so reread and
* store the current valid flag. (It may have been changed
* by e2fsck since we originally mounted the partition.)
*/
sbi->s_mount_state = le16_to_cpu(es->s_state);
if (!ext2_setup_super (sb, es, 0))
sb->s_flags &= ~MS_RDONLY;
spin_unlock(&sbi->s_lock);
ext2_write_super(sb);
dquot_resume(sb, -1);
}
return 0;
restore_opts:
sbi->s_mount_opt = old_opts.s_mount_opt;
sbi->s_resuid = old_opts.s_resuid;
sbi->s_resgid = old_opts.s_resgid;
sb->s_flags = old_sb_flags;
spin_unlock(&sbi->s_lock);
return err;
}