return !dup;
}
+/* Mark an existing directory hashtable entry as junk. */
+static void
+dir_hash_junkit(
+ struct dir_hash_tab *hashtab,
+ xfs_dir2_dataptr_t addr)
+{
+ struct dir_hash_ent *p;
+
+ p = radix_tree_lookup(&hashtab->byaddr, addr);
+ assert(p != NULL);
+
+ p->junkit = 1;
+ p->namebuf[0] = '/';
+}
+
static int
dir_hash_check(
struct dir_hash_tab *hashtab,
return EIO;
}
- if (!(ip->i_df.if_flags & XFS_IFEXTENTS)) {
- error = -libxfs_iread_extents(NULL, ip, XFS_DATA_FORK);
- if (error)
- return error;
- }
+ /* Read extent map. */
+ error = -libxfs_iread_extents(NULL, ip, XFS_DATA_FORK);
+ if (error)
+ return error;
bno = *bnop + 1;
if (!libxfs_iext_lookup_extent(ip, &ip->i_df, bno, &icur, &got))
do_error(_("xfs_trans_reserve returned %d\n"), err);
}
+static inline void
+reset_inode_fields(struct xfs_inode *ip)
+{
+ ip->i_projid = 0;
+ ip->i_disk_size = 0;
+ ip->i_nblocks = 0;
+ ip->i_extsize = 0;
+ ip->i_cowextsize = 0;
+ ip->i_flushiter = 0;
+ ip->i_forkoff = 0;
+ ip->i_diflags = 0;
+ ip->i_diflags2 = 0;
+ ip->i_crtime.tv_sec = 0;
+ ip->i_crtime.tv_nsec = 0;
+}
+
static void
mk_rbmino(xfs_mount_t *mp)
{
error);
}
- memset(&ip->i_d, 0, sizeof(ip->i_d));
+ reset_inode_fields(ip);
VFS_I(ip)->i_mode = S_IFREG;
ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
set_nlink(VFS_I(ip), 1); /* account for sb ptr */
times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD;
- if (xfs_sb_version_has_v3inode(&mp->m_sb)) {
+ if (xfs_has_v3inodes(mp)) {
VFS_I(ip)->i_version = 1;
- ip->i_d.di_flags2 = 0;
+ ip->i_diflags2 = 0;
times |= XFS_ICHGTIME_CREATE;
}
libxfs_trans_ichgtime(tp, ip, times);
/*
* now the ifork
*/
- ip->i_df.if_flags = XFS_IFEXTENTS;
ip->i_df.if_bytes = 0;
ip->i_df.if_u1.if_root = NULL;
- ip->i_d.di_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize;
+ ip->i_disk_size = mp->m_sb.sb_rbmblocks * mp->m_sb.sb_blocksize;
/*
* commit changes
error);
}
- memset(&ip->i_d, 0, sizeof(ip->i_d));
+ reset_inode_fields(ip);
VFS_I(ip)->i_mode = S_IFREG;
ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
set_nlink(VFS_I(ip), 1); /* account for sb ptr */
times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD;
- if (xfs_sb_version_has_v3inode(&mp->m_sb)) {
+ if (xfs_has_v3inodes(mp)) {
VFS_I(ip)->i_version = 1;
- ip->i_d.di_flags2 = 0;
+ ip->i_diflags2 = 0;
times |= XFS_ICHGTIME_CREATE;
}
libxfs_trans_ichgtime(tp, ip, times);
/*
* now the ifork
*/
- ip->i_df.if_flags = XFS_IFEXTENTS;
ip->i_df.if_bytes = 0;
ip->i_df.if_u1.if_root = NULL;
- ip->i_d.di_size = mp->m_rsumsize;
+ ip->i_disk_size = mp->m_rsumsize;
/*
* commit changes
/*
* take care of the core -- initialization from xfs_ialloc()
*/
- memset(&ip->i_d, 0, sizeof(ip->i_d));
+ reset_inode_fields(ip);
VFS_I(ip)->i_mode = mode|S_IFDIR;
ip->i_df.if_format = XFS_DINODE_FMT_EXTENTS;
set_nlink(VFS_I(ip), 2); /* account for . and .. */
times = XFS_ICHGTIME_CHG | XFS_ICHGTIME_MOD;
- if (xfs_sb_version_has_v3inode(&mp->m_sb)) {
+ if (xfs_has_v3inodes(mp)) {
VFS_I(ip)->i_version = 1;
- ip->i_d.di_flags2 = 0;
+ ip->i_diflags2 = 0;
times |= XFS_ICHGTIME_CREATE;
}
libxfs_trans_ichgtime(tp, ip, times);
/*
* now the ifork
*/
- ip->i_df.if_flags = XFS_IFEXTENTS;
ip->i_df.if_bytes = 0;
ip->i_df.if_u1.if_root = NULL;
err = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_rename,
nres, 0, 0, &tp);
if (err)
- do_error(
- _("space reservation failed (%d), filesystem may be out of space\n"),
- err);
+ res_failed(err);
libxfs_trans_ijoin(tp, orphanage_ip, 0);
libxfs_trans_ijoin(tp, ino_p, 0);
ino, nres);
if (err)
do_error(
- _("name create failed in %s (%d), filesystem may be out of space\n"),
- ORPHANAGE, err);
+ _("name create failed in %s (%d)\n"), ORPHANAGE, err);
if (irec)
add_inode_ref(irec, ino_offset);
orphanage_ino, nres);
if (err)
do_error(
- _("creation of .. entry failed (%d), filesystem may be out of space\n"),
- err);
+ _("creation of .. entry failed (%d)\n"), err);
inc_nlink(VFS_I(ino_p));
libxfs_trans_log_inode(tp, ino_p, XFS_ILOG_CORE);
err = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_rename,
nres, 0, 0, &tp);
if (err)
- do_error(
- _("space reservation failed (%d), filesystem may be out of space\n"),
- err);
+ res_failed(err);
libxfs_trans_ijoin(tp, orphanage_ip, 0);
libxfs_trans_ijoin(tp, ino_p, 0);
ino, nres);
if (err)
do_error(
- _("name create failed in %s (%d), filesystem may be out of space\n"),
- ORPHANAGE, err);
+ _("name create failed in %s (%d)\n"), ORPHANAGE, err);
if (irec)
add_inode_ref(irec, ino_offset);
nres);
if (err)
do_error(
- _("name replace op failed (%d), filesystem may be out of space\n"),
- err);
+ _("name replace op failed (%d)\n"), err);
}
err = -libxfs_trans_commit(tp);
err = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_remove,
nres, 0, 0, &tp);
if (err)
- do_error(
- _("space reservation failed (%d), filesystem may be out of space\n"),
- err);
+ res_failed(err);
libxfs_trans_ijoin(tp, orphanage_ip, 0);
libxfs_trans_ijoin(tp, ino_p, 0);
nres);
if (err)
do_error(
- _("name create failed in %s (%d), filesystem may be out of space\n"),
- ORPHANAGE, err);
+ _("name create failed in %s (%d)\n"), ORPHANAGE, err);
ASSERT(err == 0);
set_nlink(VFS_I(ino_p), 1);
nres);
if (error) {
do_warn(
-_("name create failed in ino %" PRIu64 " (%d), filesystem may be out of space\n"),
- ino, error);
+_("name create failed in ino %" PRIu64 " (%d)\n"), ino, error);
goto out_bmap_cancel;
}
_("directory shrink failed (%d)\n"), error);
}
+static inline void
+check_longform_ftype(
+ struct xfs_mount *mp,
+ struct xfs_inode *ip,
+ xfs_dir2_data_entry_t *dep,
+ ino_tree_node_t *irec,
+ int ino_offset,
+ struct dir_hash_tab *hashtab,
+ xfs_dir2_dataptr_t addr,
+ struct xfs_da_args *da,
+ struct xfs_buf *bp)
+{
+ xfs_ino_t inum = be64_to_cpu(dep->inumber);
+ uint8_t dir_ftype;
+ uint8_t ino_ftype;
+
+ if (!xfs_has_ftype(mp))
+ return;
+
+ dir_ftype = libxfs_dir2_data_get_ftype(mp, dep);
+ ino_ftype = get_inode_ftype(irec, ino_offset);
+
+ if (dir_ftype == ino_ftype)
+ return;
+
+ if (no_modify) {
+ do_warn(
+_("would fix ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"),
+ dir_ftype, ino_ftype,
+ ip->i_ino, inum);
+ return;
+ }
+
+ do_warn(
+_("fixing ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"),
+ dir_ftype, ino_ftype,
+ ip->i_ino, inum);
+ libxfs_dir2_data_put_ftype(mp, dep, ino_ftype);
+ libxfs_dir2_data_log_entry(da, bp, dep);
+ dir_hash_update_ftype(hashtab, addr, ino_ftype);
+}
+
/*
* process a data block, also checks for .. entry
* and corrects it to match what we think .. should be
endptr = (char *)blp;
if (endptr > (char *)btp)
endptr = (char *)btp;
- if (xfs_sb_version_hascrc(&mp->m_sb))
+ if (xfs_has_crc(mp))
wantmagic = XFS_DIR3_BLOCK_MAGIC;
else
wantmagic = XFS_DIR2_BLOCK_MAGIC;
} else {
endptr = (char *)d + mp->m_dir_geo->blksize;
- if (xfs_sb_version_hascrc(&mp->m_sb))
+ if (xfs_has_crc(mp))
wantmagic = XFS_DIR3_DATA_MAGIC;
else
wantmagic = XFS_DIR2_DATA_MAGIC;
if (entry_junked(
_("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is not in the the first block"), fname,
inum, ip->i_ino)) {
+ dir_hash_junkit(hashtab, addr);
dep->name[0] = '/';
libxfs_dir2_data_log_entry(&da, bp, dep);
}
}
+
+ if (!nbad)
+ check_longform_ftype(mp, ip, dep, irec,
+ ino_offset, hashtab, addr, &da,
+ bp);
continue;
}
ASSERT(no_modify || libxfs_verify_dir_ino(mp, inum));
if (entry_junked(
_("entry \"%s\" in dir %" PRIu64 " is not the first entry"),
fname, inum, ip->i_ino)) {
+ dir_hash_junkit(hashtab, addr);
dep->name[0] = '/';
libxfs_dir2_data_log_entry(&da, bp, dep);
}
}
+
+ if (!nbad)
+ check_longform_ftype(mp, ip, dep, irec,
+ ino_offset, hashtab, addr, &da,
+ bp);
*need_dot = 0;
continue;
}
continue;
/* validate ftype field if supported */
- if (xfs_sb_version_hasftype(&mp->m_sb)) {
- uint8_t dir_ftype;
- uint8_t ino_ftype;
-
- dir_ftype = libxfs_dir2_data_get_ftype(mp, dep);
- ino_ftype = get_inode_ftype(irec, ino_offset);
-
- if (dir_ftype != ino_ftype) {
- if (no_modify) {
- do_warn(
- _("would fix ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"),
- dir_ftype, ino_ftype,
- ip->i_ino, inum);
- } else {
- do_warn(
- _("fixing ftype mismatch (%d/%d) in directory/child inode %" PRIu64 "/%" PRIu64 "\n"),
- dir_ftype, ino_ftype,
- ip->i_ino, inum);
- libxfs_dir2_data_put_ftype(mp, dep, ino_ftype);
- libxfs_dir2_data_log_entry(&da, bp, dep);
- dir_hash_update_ftype(hashtab, addr,
- ino_ftype);
- }
- }
- }
+ check_longform_ftype(mp, ip, dep, irec, ino_offset, hashtab,
+ addr, &da, bp);
/*
* check easy case first, regular inode, just bump
orphanage_ino = 0;
nbad++;
if (!no_modify) {
+ dir_hash_junkit(hashtab, addr);
dep->name[0] = '/';
libxfs_dir2_data_log_entry(&da, bp, dep);
if (verbose)
if (be64_to_cpu(owner) != ino) {
do_warn(
_("expected owner inode %" PRIu64 ", got %llu, directory block %" PRIu64 "\n"),
- ino, (unsigned long long)be64_to_cpu(owner), bp->b_bn);
+ ino, (unsigned long long)be64_to_cpu(owner), xfs_buf_daddr(bp));
return 1;
}
/* verify block number */
- if (be64_to_cpu(blkno) != bp->b_bn) {
+ if (be64_to_cpu(blkno) != xfs_buf_daddr(bp)) {
do_warn(
_("expected block %" PRIu64 ", got %llu, directory inode %" PRIu64 "\n"),
- bp->b_bn, (unsigned long long)be64_to_cpu(blkno), ino);
+ xfs_buf_daddr(bp), (unsigned long long)be64_to_cpu(blkno), ino);
return 1;
}
/* verify uuid */
if (platform_uuid_compare(uuid, &mp->m_sb.sb_meta_uuid) != 0) {
do_warn(
_("wrong FS UUID, directory inode %" PRIu64 " block %" PRIu64 "\n"),
- ino, bp->b_bn);
+ ino, xfs_buf_daddr(bp));
return 1;
}
struct xfs_da_args args;
*need_dot = 1;
- freetab = malloc(FREETAB_SIZE(ip->i_d.di_size / mp->m_dir_geo->blksize));
+ freetab = malloc(FREETAB_SIZE(ip->i_disk_size / mp->m_dir_geo->blksize));
if (!freetab) {
do_error(_("malloc failed in %s (%" PRId64 " bytes)\n"),
__func__,
- FREETAB_SIZE(ip->i_d.di_size / mp->m_dir_geo->blksize));
+ FREETAB_SIZE(ip->i_disk_size / mp->m_dir_geo->blksize));
exit(1);
}
- freetab->naents = ip->i_d.di_size / mp->m_dir_geo->blksize;
+ freetab->naents = ip->i_disk_size / mp->m_dir_geo->blksize;
freetab->nents = 0;
for (i = 0; i < freetab->naents; i++) {
freetab->ents[i].v = NULLDATAOFF;
bytes_deleted = 0;
max_size = ifp->if_bytes;
- ASSERT(ip->i_d.di_size <= ifp->if_bytes);
+ ASSERT(ip->i_disk_size <= ifp->if_bytes);
/*
* if just rebuild a directory due to a "..", update and return
bad_sfnamelen = 1;
if (i == sfp->count - 1) {
- namelen = ip->i_d.di_size -
+ namelen = ip->i_disk_size -
((intptr_t) &sfep->name[0] -
(intptr_t) sfp);
} else {
}
} else if (no_modify && (intptr_t) sfep - (intptr_t) sfp +
+ libxfs_dir2_sf_entsize(mp, sfp, sfep->namelen)
- > ip->i_d.di_size) {
+ > ip->i_disk_size) {
bad_sfnamelen = 1;
if (i == sfp->count - 1) {
- namelen = ip->i_d.di_size -
+ namelen = ip->i_disk_size -
((intptr_t) &sfep->name[0] -
(intptr_t) sfp);
} else {
}
/* validate ftype field if supported */
- if (xfs_sb_version_hasftype(&mp->m_sb)) {
+ if (xfs_has_ftype(mp)) {
uint8_t dir_ftype;
uint8_t ino_ftype;
if (*ino_dirty && bytes_deleted > 0) {
ASSERT(!no_modify);
libxfs_idata_realloc(ip, -bytes_deleted, XFS_DATA_FORK);
- ip->i_d.di_size -= bytes_deleted;
+ ip->i_disk_size -= bytes_deleted;
}
- if (ip->i_d.di_size != ip->i_df.if_bytes) {
+ if (ip->i_disk_size != ip->i_df.if_bytes) {
ASSERT(ip->i_df.if_bytes == (xfs_fsize_t)
((intptr_t) next_sfep - (intptr_t) sfp));
- ip->i_d.di_size = (xfs_fsize_t)
+ ip->i_disk_size = (xfs_fsize_t)
((intptr_t) next_sfep - (intptr_t) sfp);
do_warn(
_("setting size to %" PRId64 " bytes to reflect junked entries\n"),
- ip->i_d.di_size);
+ ip->i_disk_size);
*ino_dirty = 1;
}
}
add_inode_refchecked(irec, ino_offset);
- hashtab = dir_hash_init(ip->i_d.di_size);
+ hashtab = dir_hash_init(ip->i_disk_size);
/*
* look for bogus entries