Merge of master-melb:xfs-cmds:29142a by kenmcd.
Minore cleanup
dinode.c dir.c dir2.c dir_stack.c globals.c incore.c \
incore_bmc.c init.c incore_ext.c incore_ino.c phase1.c \
phase2.c phase3.c phase4.c phase5.c phase6.c phase7.c rt.c sb.c \
- progress.c prefetch.c scan.c versions.c xfs_repair.c threads.c
+ progress.c prefetch.c scan.c threads.c versions.c xfs_repair.c
LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBPTHREAD) $(LIBRT)
LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG)
do_warn(_("would correct imap\n"));
}
set_inode_used(ino_rec, irec_offset);
+
+ /*
+ * store on-disk nlink count for comparing in phase 7
+ */
+ set_inode_disk_nlinks(ino_rec, irec_offset,
+ dino->di_core.di_version > XFS_DINODE_VERSION_1
+ ? be32_to_cpu(dino->di_core.di_nlink)
+ : be16_to_cpu(dino->di_core.di_onlink));
+
} else {
set_inode_free(ino_rec, irec_offset);
}
/* inode tree records have full or partial backptr fields ? */
-EXTERN int full_backptrs; /*
- * if 1, use backptrs_t component
- * of ino_un union, if 0, use
- * parent_list_t component. see
- * incore.h for more details
- */
+EXTERN int full_ino_ex_data;/*
+ * if 1, use ino_ex_data_t component
+ * of ino_un union, if 0, use
+ * parent_list_t component. see
+ * incore.h for more details
+ */
#define ORPHANAGE "lost+found"
typedef xfs_ino_t parent_entry_t;
+struct nlink_ops;
+
typedef struct parent_list {
__uint64_t pmask;
parent_entry_t *pentries;
#endif
} parent_list_t;
-typedef struct backptrs {
+typedef struct ino_ex_data {
__uint64_t ino_reached; /* bit == 1 if reached */
__uint64_t ino_processed; /* reference checked bit mask */
- __uint32_t nlinks[XFS_INODES_PER_CHUNK];
parent_list_t *parents;
-} backptrs_t;
+ __uint8_t *counted_nlinks;/* counted nlinks in P6 */
+} ino_ex_data_t;
typedef struct ino_tree_node {
avlnode_t avl_node;
xfs_inofree_t ir_free; /* inode free bit mask */
__uint64_t ino_confirmed; /* confirmed bitmask */
__uint64_t ino_isa_dir; /* bit == 1 if a directory */
+ struct nlink_ops *nlinkops; /* pointer to current nlink ops */
+ __uint8_t *disk_nlinks; /* on-disk nlinks, set in P3 */
union {
- backptrs_t *backptrs;
- parent_list_t *plist;
+ ino_ex_data_t *ex_data; /* phases 6,7 */
+ parent_list_t *plist; /* phases 2-5 */
} ino_un;
} ino_tree_node_t;
+typedef struct nlink_ops {
+ const int nlink_size;
+ void (*disk_nlink_set)(ino_tree_node_t *, int, __uint32_t);
+ __uint32_t (*disk_nlink_get)(ino_tree_node_t *, int);
+ __uint32_t (*counted_nlink_get)(ino_tree_node_t *, int);
+ __uint32_t (*counted_nlink_inc)(ino_tree_node_t *, int);
+ __uint32_t (*counted_nlink_dec)(ino_tree_node_t *, int);
+} nlink_ops_t;
+
+
#define INOS_PER_IREC (sizeof(__uint64_t) * NBBY)
-void add_ino_backptrs(xfs_mount_t *mp);
+void add_ino_ex_data(xfs_mount_t *mp);
/*
* return an inode record to the free inode record pool
#define XFS_INOPROC_MASKN(i,n) ((__uint64_t)((1 << (n)) - 1) << (i))
#define XFS_INOPROC_IS_PROC(rp, i) \
- (((rp)->ino_un.backptrs->ino_processed & XFS_INOPROC_MASK((i))) == 0LL \
+ (((rp)->ino_un.ex_data->ino_processed & XFS_INOPROC_MASK((i))) == 0LL \
? 0 : 1)
#define XFS_INOPROC_SET_PROC(rp, i) \
- ((rp)->ino_un.backptrs->ino_processed |= XFS_INOPROC_MASK((i)))
+ ((rp)->ino_un.ex_data->ino_processed |= XFS_INOPROC_MASK((i)))
/*
#define XFS_INOPROC_CLR_PROC(rp, i) \
- ((rp)->ino_un.backptrs->ino_processed &= ~XFS_INOPROC_MASK((i)))
+ ((rp)->ino_un.ex_data->ino_processed &= ~XFS_INOPROC_MASK((i)))
*/
/*
#define XFS_INO_RCHD_MASK(i) ((__uint64_t)1 << (i))
#define XFS_INO_RCHD_IS_RCHD(rp, i) \
- (((rp)->ino_un.backptrs->ino_reached & XFS_INO_RCHD_MASK((i))) == 0LL \
+ (((rp)->ino_un.ex_data->ino_reached & XFS_INO_RCHD_MASK((i))) == 0LL \
? 0 : 1)
#define XFS_INO_RCHD_SET_RCHD(rp, i) \
- ((rp)->ino_un.backptrs->ino_reached |= XFS_INO_RCHD_MASK((i)))
+ ((rp)->ino_un.ex_data->ino_reached |= XFS_INO_RCHD_MASK((i)))
#define XFS_INO_RCHD_CLR_RCHD(rp, i) \
- ((rp)->ino_un.backptrs->ino_reached &= ~XFS_INO_RCHD_MASK((i)))
+ ((rp)->ino_un.ex_data->ino_reached &= ~XFS_INO_RCHD_MASK((i)))
/*
* set/clear/test is inode a directory inode
*/
static inline int
is_inode_reached(ino_tree_node_t *ino_rec, int ino_offset)
{
- ASSERT(ino_rec->ino_un.backptrs != NULL);
+ ASSERT(ino_rec->ino_un.ex_data != NULL);
return(XFS_INO_RCHD_IS_RCHD(ino_rec, ino_offset));
}
static inline void
add_inode_reached(ino_tree_node_t *ino_rec, int ino_offset)
{
- ASSERT(ino_rec->ino_un.backptrs != NULL);
+ ASSERT(ino_rec->ino_un.ex_data != NULL);
- ino_rec->ino_un.backptrs->nlinks[ino_offset]++;
+ (*ino_rec->nlinkops->counted_nlink_inc)(ino_rec, ino_offset);
XFS_INO_RCHD_SET_RCHD(ino_rec, ino_offset);
ASSERT(is_inode_reached(ino_rec, ino_offset));
static inline void
add_inode_ref(ino_tree_node_t *ino_rec, int ino_offset)
{
- ASSERT(ino_rec->ino_un.backptrs != NULL);
+ ASSERT(ino_rec->ino_un.ex_data != NULL);
- ino_rec->ino_un.backptrs->nlinks[ino_offset]++;
+ (*ino_rec->nlinkops->counted_nlink_inc)(ino_rec, ino_offset);
}
static inline void
drop_inode_ref(ino_tree_node_t *ino_rec, int ino_offset)
{
- ASSERT(ino_rec->ino_un.backptrs != NULL);
- ASSERT(ino_rec->ino_un.backptrs->nlinks[ino_offset] > 0);
+ ASSERT(ino_rec->ino_un.ex_data != NULL);
- if (--ino_rec->ino_un.backptrs->nlinks[ino_offset] == 0)
+ if ((*ino_rec->nlinkops->counted_nlink_dec)(ino_rec, ino_offset) == 0)
XFS_INO_RCHD_CLR_RCHD(ino_rec, ino_offset);
}
static inline int
is_inode_referenced(ino_tree_node_t *ino_rec, int ino_offset)
{
- ASSERT(ino_rec->ino_un.backptrs != NULL);
- return(ino_rec->ino_un.backptrs->nlinks[ino_offset] > 0);
+ ASSERT(ino_rec->ino_un.ex_data != NULL);
+
+ return (*ino_rec->nlinkops->counted_nlink_get)(ino_rec, ino_offset) > 0;
}
static inline __uint32_t
num_inode_references(ino_tree_node_t *ino_rec, int ino_offset)
{
- ASSERT(ino_rec->ino_un.backptrs != NULL);
- return(ino_rec->ino_un.backptrs->nlinks[ino_offset]);
+ ASSERT(ino_rec->ino_un.ex_data != NULL);
+
+ return (*ino_rec->nlinkops->counted_nlink_get)(ino_rec, ino_offset);
+}
+
+static inline void
+set_inode_disk_nlinks(ino_tree_node_t *ino_rec, int ino_offset, __uint32_t nlinks)
+{
+ (*ino_rec->nlinkops->disk_nlink_set)(ino_rec, ino_offset, nlinks);
+}
+
+static inline __uint32_t
+get_inode_disk_nlinks(ino_tree_node_t *ino_rec, int ino_offset)
+{
+ return (*ino_rec->nlinkops->disk_nlink_get)(ino_rec, ino_offset);
}
/*
*/
void set_inode_parent(ino_tree_node_t *irec, int ino_offset,
xfs_ino_t ino);
-#if 0
-void clear_inode_parent(ino_tree_node_t *irec, int offset);
-#endif
xfs_ino_t get_inode_parent(ino_tree_node_t *irec, int ino_offset);
/*
static ino_flist_t ino_flist; /* free list must be initialized before use */
+/* memory optimised nlink counting for all inodes */
+
+static void nlink_grow_8_to_16(ino_tree_node_t *irec);
+static void nlink_grow_16_to_32(ino_tree_node_t *irec);
+
+static void
+disk_nlink_32_set(ino_tree_node_t *irec, int ino_offset, __uint32_t nlinks)
+{
+ ((__uint32_t*)irec->disk_nlinks)[ino_offset] = nlinks;
+}
+
+static __uint32_t
+disk_nlink_32_get(ino_tree_node_t *irec, int ino_offset)
+{
+ return ((__uint32_t*)irec->disk_nlinks)[ino_offset];
+}
+
+static __uint32_t
+counted_nlink_32_get(ino_tree_node_t *irec, int ino_offset)
+{
+ return ((__uint32_t*)irec->ino_un.ex_data->counted_nlinks)[ino_offset];
+}
+
+static __uint32_t
+counted_nlink_32_inc(ino_tree_node_t *irec, int ino_offset)
+{
+ return ++(((__uint32_t*)irec->ino_un.ex_data->counted_nlinks)[ino_offset]);
+}
+
+static __uint32_t
+counted_nlink_32_dec(ino_tree_node_t *irec, int ino_offset)
+{
+ __uint32_t *nlinks = (__uint32_t*)irec->ino_un.ex_data->counted_nlinks;
+
+ ASSERT(nlinks[ino_offset] > 0);
+ return --(nlinks[ino_offset]);
+}
+
+
+static void
+disk_nlink_16_set(ino_tree_node_t *irec, int ino_offset, __uint32_t nlinks)
+{
+ if (nlinks >= 0x10000) {
+ nlink_grow_16_to_32(irec);
+ disk_nlink_32_set(irec, ino_offset, nlinks);
+ } else
+ ((__uint16_t*)irec->disk_nlinks)[ino_offset] = nlinks;
+}
+
+static __uint32_t
+disk_nlink_16_get(ino_tree_node_t *irec, int ino_offset)
+{
+ return ((__uint16_t*)irec->disk_nlinks)[ino_offset];
+}
+
+static __uint32_t
+counted_nlink_16_get(ino_tree_node_t *irec, int ino_offset)
+{
+ return ((__uint16_t*)irec->ino_un.ex_data->counted_nlinks)[ino_offset];
+}
+
+static __uint32_t
+counted_nlink_16_inc(ino_tree_node_t *irec, int ino_offset)
+{
+ __uint16_t *nlinks = (__uint16_t*)irec->ino_un.ex_data->counted_nlinks;
+
+ if (nlinks[ino_offset] == 0xffff) {
+ nlink_grow_16_to_32(irec);
+ return counted_nlink_32_inc(irec, ino_offset);
+ }
+ return ++(nlinks[ino_offset]);
+}
+
+static __uint32_t
+counted_nlink_16_dec(ino_tree_node_t *irec, int ino_offset)
+{
+ __uint16_t *nlinks = (__uint16_t*)irec->ino_un.ex_data->counted_nlinks;
+
+ ASSERT(nlinks[ino_offset] > 0);
+ return --(nlinks[ino_offset]);
+}
+
+
+static void
+disk_nlink_8_set(ino_tree_node_t *irec, int ino_offset, __uint32_t nlinks)
+{
+ if (nlinks >= 0x100) {
+ nlink_grow_8_to_16(irec);
+ disk_nlink_16_set(irec, ino_offset, nlinks);
+ } else
+ irec->disk_nlinks[ino_offset] = nlinks;
+}
+
+static __uint32_t
+disk_nlink_8_get(ino_tree_node_t *irec, int ino_offset)
+{
+ return irec->disk_nlinks[ino_offset];
+}
+
+static __uint32_t
+counted_nlink_8_get(ino_tree_node_t *irec, int ino_offset)
+{
+ return irec->ino_un.ex_data->counted_nlinks[ino_offset];
+}
+
+static __uint32_t
+counted_nlink_8_inc(ino_tree_node_t *irec, int ino_offset)
+{
+ if (irec->ino_un.ex_data->counted_nlinks[ino_offset] == 0xff) {
+ nlink_grow_8_to_16(irec);
+ return counted_nlink_16_inc(irec, ino_offset);
+ }
+ return ++(irec->ino_un.ex_data->counted_nlinks[ino_offset]);
+}
+
+static __uint32_t
+counted_nlink_8_dec(ino_tree_node_t *irec, int ino_offset)
+{
+ ASSERT(irec->ino_un.ex_data->counted_nlinks[ino_offset] > 0);
+ return --(irec->ino_un.ex_data->counted_nlinks[ino_offset]);
+}
+
+
+static nlink_ops_t nlinkops[] = {
+ {sizeof(__uint8_t) * XFS_INODES_PER_CHUNK,
+ disk_nlink_8_set, disk_nlink_8_get,
+ counted_nlink_8_get, counted_nlink_8_inc, counted_nlink_8_dec},
+ {sizeof(__uint16_t) * XFS_INODES_PER_CHUNK,
+ disk_nlink_16_set, disk_nlink_16_get,
+ counted_nlink_16_get, counted_nlink_16_inc, counted_nlink_16_dec},
+ {sizeof(__uint32_t) * XFS_INODES_PER_CHUNK,
+ disk_nlink_32_set, disk_nlink_32_get,
+ counted_nlink_32_get, counted_nlink_32_inc, counted_nlink_32_dec},
+};
+
+static void
+nlink_grow_8_to_16(ino_tree_node_t *irec)
+{
+ __uint16_t *new_nlinks;
+ int i;
+
+ new_nlinks = malloc(sizeof(__uint16_t) * XFS_INODES_PER_CHUNK);
+ if (new_nlinks == NULL)
+ do_error(_("could not allocate expanded nlink array\n"));
+ for (i = 0; i < XFS_INODES_PER_CHUNK; i++)
+ new_nlinks[i] = irec->disk_nlinks[i];
+ free(irec->disk_nlinks);
+ irec->disk_nlinks = (__uint8_t*)new_nlinks;
+
+ if (full_ino_ex_data) {
+ new_nlinks = malloc(sizeof(__uint16_t) * XFS_INODES_PER_CHUNK);
+ if (new_nlinks == NULL)
+ do_error(_("could not allocate expanded nlink array\n"));
+ for (i = 0; i < XFS_INODES_PER_CHUNK; i++)
+ new_nlinks[i] = irec->ino_un.ex_data->counted_nlinks[i];
+ free(irec->ino_un.ex_data->counted_nlinks);
+ irec->ino_un.ex_data->counted_nlinks = (__uint8_t*)new_nlinks;
+ }
+ irec->nlinkops = &nlinkops[1];
+}
+
+static void
+nlink_grow_16_to_32(ino_tree_node_t *irec)
+{
+ __uint32_t *new_nlinks;
+ int i;
+
+ new_nlinks = malloc(sizeof(__uint32_t) * XFS_INODES_PER_CHUNK);
+ if (new_nlinks == NULL)
+ do_error(_("could not allocate expanded nlink array\n"));
+ for (i = 0; i < XFS_INODES_PER_CHUNK; i++)
+ new_nlinks[i] = ((__int16_t*)&irec->disk_nlinks)[i];
+ free(irec->disk_nlinks);
+ irec->disk_nlinks = (__uint8_t*)new_nlinks;
+
+ if (full_ino_ex_data) {
+ new_nlinks = malloc(sizeof(__uint32_t) * XFS_INODES_PER_CHUNK);
+ if (new_nlinks == NULL)
+ do_error(_("could not allocate expanded nlink array\n"));
+ for (i = 0; i < XFS_INODES_PER_CHUNK; i++)
+ new_nlinks[i] = ((__int16_t*)&irec->ino_un.ex_data->counted_nlinks)[i];
+ free(irec->ino_un.ex_data->counted_nlinks);
+ irec->ino_un.ex_data->counted_nlinks = (__uint8_t*)new_nlinks;
+ }
+ irec->nlinkops = &nlinkops[2];
+}
+
/*
* next is the uncertain inode list -- a sorted (in ascending order)
* list of inode records sorted on the starting inode number. There
*/
/* ARGSUSED */
static ino_tree_node_t *
-mk_ino_tree_nodes(xfs_agino_t starting_ino)
+mk_ino_tree_nodes(
+ xfs_agino_t starting_ino)
{
- int i;
- ino_tree_node_t *new;
- avlnode_t *node;
+ int i;
+ ino_tree_node_t *ino_rec;
+ avlnode_t *node;
PREPAIR_RW_WRITE_LOCK(&ino_flist_lock);
if (ino_flist.cnt == 0) {
ASSERT(ino_flist.list == NULL);
- if ((new = malloc(sizeof(ino_tree_node_t[ALLOC_NUM_INOS])))
+ if ((ino_rec = malloc(sizeof(ino_tree_node_t[ALLOC_NUM_INOS])))
== NULL)
do_error(_("inode map malloc failed\n"));
for (i = 0; i < ALLOC_NUM_INOS; i++) {
- new->avl_node.avl_nextino =
+ ino_rec->avl_node.avl_nextino =
(avlnode_t *) ino_flist.list;
- ino_flist.list = new;
+ ino_flist.list = ino_rec;
ino_flist.cnt++;
- new++;
+ ino_rec++;
}
}
ASSERT(ino_flist.list != NULL);
- new = ino_flist.list;
- ino_flist.list = (ino_tree_node_t *) new->avl_node.avl_nextino;
+ ino_rec = ino_flist.list;
+ ino_flist.list = (ino_tree_node_t *) ino_rec->avl_node.avl_nextino;
ino_flist.cnt--;
- node = &new->avl_node;
+ node = &ino_rec->avl_node;
node->avl_nextino = node->avl_forw = node->avl_back = NULL;
PREPAIR_RW_UNLOCK(&ino_flist_lock);
/* initialize node */
- new->ino_startnum = 0;
- new->ino_confirmed = 0;
- new->ino_isa_dir = 0;
- new->ir_free = (xfs_inofree_t) - 1;
- new->ino_un.backptrs = NULL;
+ ino_rec->ino_startnum = 0;
+ ino_rec->ino_confirmed = 0;
+ ino_rec->ino_isa_dir = 0;
+ ino_rec->ir_free = (xfs_inofree_t) - 1;
+ ino_rec->ino_un.ex_data = NULL;
+ ino_rec->nlinkops = &nlinkops[0];
+ ino_rec->disk_nlinks = calloc(1, nlinkops[0].nlink_size);
+ if (ino_rec->disk_nlinks == NULL)
+ do_error(_("could not allocate nlink array\n"));
- return(new);
+ return(ino_rec);
}
/*
ino_flist.list = ino_rec;
ino_flist.cnt++;
- if (ino_rec->ino_un.backptrs != NULL) {
- if (full_backptrs && ino_rec->ino_un.backptrs->parents != NULL)
- free(ino_rec->ino_un.backptrs->parents);
- if (ino_rec->ino_un.plist != NULL)
- free(ino_rec->ino_un.plist);
+ free(ino_rec->disk_nlinks);
+
+ if (ino_rec->ino_un.ex_data != NULL) {
+ if (full_ino_ex_data) {
+ free(ino_rec->ino_un.ex_data->parents);
+ free(ino_rec->ino_un.ex_data->counted_nlinks);
+ }
+ free(ino_rec->ino_un.ex_data);
+
}
PREPAIR_RW_UNLOCK(&ino_flist_lock);
__uint64_t bitmask;
parent_entry_t *tmp;
- ASSERT(full_backptrs == 0);
+ ASSERT(full_ino_ex_data == 0);
if (irec->ino_un.plist == NULL) {
irec->ino_un.plist =
int i;
int target;
- if (full_backptrs)
- ptbl = irec->ino_un.backptrs->parents;
+ if (full_ino_ex_data)
+ ptbl = irec->ino_un.ex_data->parents;
else
ptbl = irec->ino_un.plist;
return(0LL);
}
-backptrs_t *
-get_backptr(void)
+static void
+alloc_ex_data(ino_tree_node_t *irec)
{
- backptrs_t *ptr;
+ parent_list_t *ptbl;
- if ((ptr = malloc(sizeof(backptrs_t))) == NULL)
- do_error(_("could not malloc back pointer table\n"));
+ ptbl = irec->ino_un.plist;
+ irec->ino_un.ex_data = (ino_ex_data_t *)calloc(1, sizeof(ino_ex_data_t));
+ if (irec->ino_un.ex_data == NULL)
+ do_error(_("could not malloc inode extra data\n"));
- bzero(ptr, sizeof(backptrs_t));
+ irec->ino_un.ex_data->parents = ptbl;
+ irec->ino_un.ex_data->counted_nlinks = calloc(1, irec->nlinkops->nlink_size);
- return(ptr);
+ if (irec->ino_un.ex_data->counted_nlinks == NULL)
+ do_error(_("could not malloc inode extra data\n"));
}
void
-add_ino_backptrs(xfs_mount_t *mp)
+add_ino_ex_data(xfs_mount_t *mp)
{
-#ifdef XR_BCKPTR_DBG
- xfs_ino_t ino;
- int j, k;
-#endif /* XR_BCKPTR_DBG */
- ino_tree_node_t *ino_rec;
- parent_list_t *tmp;
- xfs_agnumber_t i;
+ ino_tree_node_t *ino_rec;
+ xfs_agnumber_t i;
for (i = 0; i < mp->m_sb.sb_agcount; i++) {
ino_rec = findfirst_inode_rec(i);
while (ino_rec != NULL) {
- tmp = ino_rec->ino_un.plist;
- ino_rec->ino_un.backptrs = get_backptr();
- ino_rec->ino_un.backptrs->parents = tmp;
-
-#ifdef XR_BCKPTR_DBG
- if (tmp != NULL) {
- k = 0;
- for (j = 0; j < XFS_INODES_PER_CHUNK; j++) {
- ino = XFS_AGINO_TO_INO(mp, i,
- ino_rec->ino_startnum + j);
- if (ino == 25165846) {
- do_warn("THERE 1 !!!\n");
- }
- if (tmp->pentries[j] != 0) {
- k++;
- do_warn(
- "inode %llu - parent %llu\n",
- ino,
- tmp->pentries[j]);
- if (ino == 25165846) {
- do_warn("THERE!!!\n");
- }
- }
- }
-
- if (k != tmp->cnt) {
- do_warn(
- "ERROR - count = %d, counted %d\n",
- tmp->cnt, k);
- }
- }
-#endif /* XR_BCKPTR_DBG */
+ alloc_ex_data(ino_rec);
ino_rec = next_ino_rec(ino_rec);
}
}
-
- full_backptrs = 1;
-
- return;
+ full_ino_ex_data = 1;
}
static __psunsigned_t
bzero(last_rec, sizeof(ino_tree_node_t *) * agcount);
- full_backptrs = 0;
+ full_ino_ex_data = 0;
return;
}
static int
dir_hash_add(
dir_hash_tab_t *hashtab,
- __uint32_t addr,
+ __uint32_t addr,
xfs_ino_t inum,
int namelen,
uchar_t *name)
dir_hash_ent_t *p;
int dup;
short junk;
-
+
ASSERT(!hashtab->names_duped);
-
+
junk = name[0] == '/';
byaddr = DIR_HASH_FUNC(hashtab, addr);
dup = 0;
hash = libxfs_da_hashname(name, namelen);
byhash = DIR_HASH_FUNC(hashtab, hash);
- /*
+ /*
* search hash bucket for existing name.
*/
for (p = hashtab->byhash[byhash]; p; p = p->nextbyhash) {
}
}
}
-
+
if ((p = malloc(sizeof(*p))) == NULL)
do_error(_("malloc failed in dir_hash_add (%u bytes)\n"),
sizeof(*p));
-
+
p->nextbyaddr = hashtab->byaddr[byaddr];
hashtab->byaddr[byaddr] = p;
- if (hashtab->last)
+ if (hashtab->last)
hashtab->last->nextbyorder = p;
else
hashtab->first = p;
p->nextbyorder = NULL;
hashtab->last = p;
-
+
if (!(p->junkit = junk)) {
p->hashval = hash;
p->nextbyhash = hashtab->byhash[byhash];
p->seen = 0;
p->namelen = namelen;
p->name = name;
-
+
return !dup;
}
/*
- * checks to see if any data entries are not in the leaf blocks
+ * checks to see if any data entries are not in the leaf blocks
*/
static int
dir_hash_unseen(
if ((hashtab = calloc(DIR_HASH_TAB_SIZE(hsize), 1)) == NULL)
do_error(_("calloc failed in dir_hash_init\n"));
hashtab->size = hsize;
- hashtab->byhash = (dir_hash_ent_t**)((char *)hashtab +
+ hashtab->byhash = (dir_hash_ent_t**)((char *)hashtab +
sizeof(dir_hash_tab_t));
- hashtab->byaddr = (dir_hash_ent_t**)((char *)hashtab +
+ hashtab->byaddr = (dir_hash_ent_t**)((char *)hashtab +
sizeof(dir_hash_tab_t) + sizeof(dir_hash_ent_t*) * hsize);
return hashtab;
}
{
uchar_t *name;
dir_hash_ent_t *p;
-
+
if (hashtab->names_duped)
return;
-
+
for (p = hashtab->first; p; p = p->nextbyorder) {
name = malloc(p->namelen);
memcpy(name, p->name, p->namelen);
/*
* check for duplicate names in directory.
- */
- if (!dir_hash_add(hashtab, (da_bno << mp->m_sb.sb_blocklog) +
- entry->nameidx,
+ */
+ if (!dir_hash_add(hashtab, (da_bno << mp->m_sb.sb_blocklog) +
+ entry->nameidx,
lino, entry->namelen, namest->name)) {
do_warn(
_("entry \"%s\" (ino %llu) in dir %llu is a duplicate name"),
}
if (!skipit)
- lf_block_dir_entry_check(mp, ino, leaf, &dirty,
- num_illegal, need_dot, stack, irec,
+ lf_block_dir_entry_check(mp, ino, leaf, &dirty,
+ num_illegal, need_dot, stack, irec,
ino_offset, hashtab, da_bno);
da_bno = INT_GET(leaf->hdr.info.forw, ARCH_CONVERT);
* lost+found on the next run
*/
-static void
+static void
longform_dir2_rebuild(
xfs_mount_t *mp,
xfs_ino_t ino,
dir_hash_ent_t *p;
int committed;
int done;
-
- /*
+
+ /*
* trash directory completely and rebuild from scratch using the
* name/inode pairs in the hash table
*/
-
+
do_warn(_("rebuilding directory inode %llu\n"), ino);
-
- /*
+
+ /*
* first attempt to locate the parent inode, if it can't be found,
- * we'll use the lost+found inode
+ * we'll use the lost+found inode
*/
byhash = DIR_HASH_FUNC(hashtab, libxfs_da_hashname((uchar_t*)"..", 2));
parentino = orphanage_ino;
}
XFS_BMAP_INIT(&flist, &firstblock);
-
+
tp = libxfs_trans_alloc(mp, 0);
nres = XFS_REMOVE_SPACE_RES(mp);
error = libxfs_trans_reserve(tp, nres, XFS_REMOVE_LOG_RES(mp), 0,
res_failed(error);
libxfs_trans_ijoin(tp, ip, 0);
libxfs_trans_ihold(tp, ip);
-
- if ((error = libxfs_bmap_last_offset(tp, ip, &lastblock,
+
+ if ((error = libxfs_bmap_last_offset(tp, ip, &lastblock,
XFS_DATA_FORK)))
- do_error(_("xfs_bmap_last_offset failed -- error - %d\n"),
+ do_error(_("xfs_bmap_last_offset failed -- error - %d\n"),
error);
-
+
/* re-init the directory to shortform */
if ((error = libxfs_trans_iget(mp, tp, parentino, 0, 0, &pip))) {
do_warn(
}
/* free all data, leaf, node and freespace blocks */
-
- if ((error = libxfs_bunmapi(tp, ip, 0, lastblock,
+
+ if ((error = libxfs_bunmapi(tp, ip, 0, lastblock,
XFS_BMAPI_METADATA, 0, &firstblock, &flist,
&done))) {
do_warn(_("xfs_bunmapi failed -- error - %d\n"), error);
XFS_TRANS_ABORT);
return;
}
-
+
ASSERT(done);
libxfs_dir2_init(tp, ip, pip);
-
+
error = libxfs_bmap_finish(&tp, &flist, firstblock, &committed);
-
- libxfs_trans_commit(tp,
+
+ libxfs_trans_commit(tp,
XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0);
-
+
/* go through the hash list and re-add the inodes */
for (p = hashtab->first; p; p = p->nextbyorder) {
-
- if (p->name[0] == '/' || (p->name[0] == '.' && (p->namelen == 1
+
+ if (p->name[0] == '/' || (p->name[0] == '.' && (p->namelen == 1
|| (p->namelen == 2 && p->name[1] == '.'))))
continue;
-
+
tp = libxfs_trans_alloc(mp, 0);
nres = XFS_CREATE_SPACE_RES(mp, p->namelen);
- if ((error = libxfs_trans_reserve(tp, nres,
+ if ((error = libxfs_trans_reserve(tp, nres,
XFS_CREATE_LOG_RES(mp), 0,
XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT))) {
do_warn(
XFS_BMAP_INIT(&flist, &firstblock);
if ((error = libxfs_dir2_createname(tp, ip, (uchar_t *)p->name,
- p->namelen, p->inum, &firstblock, &flist,
+ p->namelen, p->inum, &firstblock, &flist,
nres))) {
do_warn(
_("name create failed in ino %llu (%d), filesystem may be out of space\n"),
break;
}
- if ((error = libxfs_bmap_finish(&tp, &flist, firstblock,
+ if ((error = libxfs_bmap_finish(&tp, &flist, firstblock,
&committed))) {
do_warn(
_("bmap finish failed (%d), filesystem may be out of space\n"),
XFS_TRANS_ABORT);
break;
}
-
- libxfs_trans_commit(tp,
+
+ libxfs_trans_commit(tp,
XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_SYNC, 0);
}
}
ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
inum = INT_GET(dep->inumber, ARCH_CONVERT);
lastfree = 0;
- if (!dir_hash_add(hashtab, addr, inum, dep->namelen,
+ if (!dir_hash_add(hashtab, addr, inum, dep->namelen,
dep->name)) {
do_warn(
_("entry \"%s\" (ino %llu) in dir %llu is a duplicate name"),
xfs_fileoff_t next_da_bno;
int seeval = 0;
int used;
-
+
for (da_bno = mp->m_dirleafblk, next_da_bno = 0;
next_da_bno != NULLFILEOFF && da_bno < mp->m_dirfreeblk;
da_bno = (xfs_dablk_t)next_da_bno) {
next_da_bno = da_bno + mp->m_dirblkfsbs - 1;
- if (libxfs_bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK))
+ if (libxfs_bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK))
break;
if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bp,
XFS_DATA_FORK)) {
seeval = dir_hash_see_all(hashtab, leaf->ents, INT_GET(leaf->hdr.count, ARCH_CONVERT),
INT_GET(leaf->hdr.stale, ARCH_CONVERT));
libxfs_da_brelse(NULL, bp);
- if (seeval != DIR_HASH_CK_OK)
+ if (seeval != DIR_HASH_CK_OK)
return 1;
}
- if (dir_hash_check(hashtab, ip, seeval))
+ if (dir_hash_check(hashtab, ip, seeval))
return 1;
-
+
for (da_bno = mp->m_dirfreeblk, next_da_bno = 0;
next_da_bno != NULLFILEOFF;
da_bno = (xfs_dablk_t)next_da_bno) {
next_da_bno = da_bno + mp->m_dirblkfsbs - 1;
- if (libxfs_bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK))
+ if (libxfs_bmap_next_offset(NULL, ip, &next_da_bno, XFS_DATA_FORK))
break;
if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bp,
XFS_DATA_FORK)) {
/* more data blocks than expected */
num_bps = db + 1;
bplist = realloc(bplist, num_bps * sizeof(xfs_dabuf_t*));
- if (!bplist)
+ if (!bplist)
do_error(
_("realloc failed in longform_dir2_entry_check (%u bytes)\n"),
num_bps * sizeof(xfs_dabuf_t*));
}
- if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bplist[db],
+ if (libxfs_da_read_bufr(NULL, ip, da_bno, -1, &bplist[db],
XFS_DATA_FORK)) {
do_warn(_(
"can't read data block %u for directory inode %llu\n"),
block = bplist[0]->data;
btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
blp = XFS_DIR2_BLOCK_LEAF_P(btp);
- seeval = dir_hash_see_all(hashtab, blp,
- INT_GET(btp->count, ARCH_CONVERT),
+ seeval = dir_hash_see_all(hashtab, blp,
+ INT_GET(btp->count, ARCH_CONVERT),
INT_GET(btp->stale, ARCH_CONVERT));
if (dir_hash_check(hashtab, ip, seeval))
fixit |= 1;
}
if (!no_modify && fixit) {
dir_hash_dup_names(hashtab);
- for (i = 0; i < freetab->naents; i++)
+ for (i = 0; i < freetab->naents; i++)
if (bplist[i])
libxfs_da_brelse(NULL, bplist[i]);
longform_dir2_rebuild(mp, ino, ip, hashtab);
*num_illegal = 0;
} else {
- for (i = 0; i < freetab->naents; i++)
+ for (i = 0; i < freetab->naents; i++)
if (bplist[i])
libxfs_da_brelse(NULL, bplist[i]);
}
-
+
free(bplist);
free(freetab);
}
ASSERT(irec != NULL);
ino_offset = XFS_INO_TO_AGINO(mp, lino) - irec->ino_startnum;
-
+
/*
* if it's a free inode, blow out the entry.
* by now, any inode that we think is free
do_warn(_("would junk entry \"%s\"\n"),
fname);
}
- } else if (!dir_hash_add(hashtab,
+ } else if (!dir_hash_add(hashtab,
(xfs_dir2_dataptr_t)(sf_entry - &sf->list[0]),
lino, sf_entry->namelen, sf_entry->name)) {
/*
* check for duplicate names in directory.
- */
+ */
do_warn(
_("entry \"%s\" (ino %llu) in dir %llu is a duplicate name"),
fname, lino, ino);
lino, sfep->namelen, sfep->name)) {
/*
* check for duplicate names in directory.
- */
+ */
do_warn(
_("entry \"%s\" (ino %llu) in dir %llu is a duplicate name"),
fname, lino, ino);
incore_ext_teardown(mp);
- add_ino_backptrs(mp);
+ add_ino_ex_data(mp);
/*
* verify existence of root directory - if we have to
}
do_log(_(" - traversals finished ... \n"));
-
+
/* flush all dirty data before doing lost+found search */
libxfs_bcache_flush();
-
+
do_log(_(" - moving disconnected inodes to lost+found ... \n"));
/*
#include "threads.h"
/* dinoc is a pointer to the IN-CORE dinode core */
-void
-set_nlinks(xfs_dinode_core_t *dinoc,
- xfs_ino_t ino,
- __uint32_t nrefs,
- int *dirty)
+static void
+set_nlinks(
+ xfs_dinode_core_t *dinoc,
+ xfs_ino_t ino,
+ __uint32_t nrefs,
+ int *dirty)
{
- if (!no_modify) {
- if (dinoc->di_nlink != nrefs) {
- *dirty = 1;
- do_warn(
- _("resetting inode %llu nlinks from %d to %d\n"),
- ino, dinoc->di_nlink, nrefs);
+ if (dinoc->di_nlink == nrefs)
+ return;
- if (nrefs > XFS_MAXLINK_1) {
- ASSERT(fs_inode_nlink);
- do_warn(
+ if (!no_modify) {
+ *dirty = 1;
+ do_warn(_("resetting inode %llu nlinks from %d to %d\n"),
+ ino, dinoc->di_nlink, nrefs);
+
+ if (nrefs > XFS_MAXLINK_1) {
+ ASSERT(fs_inode_nlink);
+ do_warn(
_("nlinks %d will overflow v1 ino, ino %llu will be converted to version 2\n"),
- nrefs, ino);
+ nrefs, ino);
- }
- dinoc->di_nlink = nrefs;
}
+ dinoc->di_nlink = nrefs;
} else {
- if (dinoc->di_nlink != nrefs)
+ do_warn(_("would have reset inode %llu nlinks from %d to %d\n"),
+ ino, dinoc->di_nlink, nrefs);
+ }
+}
+
+static void
+update_inode_nlinks(
+ xfs_mount_t *mp,
+ xfs_ino_t ino,
+ __uint32_t nlinks)
+{
+ xfs_trans_t *tp;
+ xfs_inode_t *ip;
+ int error;
+ int dirty;
+
+ tp = libxfs_trans_alloc(mp, XFS_TRANS_REMOVE);
+
+ error = libxfs_trans_reserve(tp, (no_modify ? 0 : 10),
+ XFS_REMOVE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES,
+ XFS_REMOVE_LOG_COUNT);
+
+ ASSERT(error == 0);
+
+ error = libxfs_trans_iget(mp, tp, ino, 0, 0, &ip);
+
+ if (error) {
+ if (!no_modify)
+ do_error(_("couldn't map inode %llu, err = %d\n"),
+ ino, error);
+ else {
do_warn(
- _("would have reset inode %llu nlinks from %d to %d\n"),
- ino, dinoc->di_nlink, nrefs);
+ _("couldn't map inode %llu, err = %d, can't compare link counts\n"),
+ ino, error);
+ return;
+ }
+ }
+
+ dirty = 0;
+
+ /*
+ * compare and set links for all inodes
+ * but the lost+found inode. we keep
+ * that correct as we go.
+ */
+ if (ino != orphanage_ino)
+ set_nlinks(&ip->i_d, ino, nlinks, &dirty);
+
+ if (!dirty) {
+ libxfs_trans_iput(tp, ip, 0);
+ libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES);
+ } else {
+ libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+ /*
+ * no need to do a bmap finish since
+ * we're not allocating anything
+ */
+ ASSERT(error == 0);
+ error = libxfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES |
+ XFS_TRANS_SYNC, NULL);
+
+ ASSERT(error == 0);
}
}
-void
+static void
phase7_alt_function(xfs_mount_t *mp, xfs_agnumber_t agno)
{
- register ino_tree_node_t *irec;
+ ino_tree_node_t *irec;
int j;
- int chunk_dirty;
- int inode_dirty;
- xfs_ino_t ino;
__uint32_t nrefs;
- xfs_agblock_t agbno;
- xfs_dinode_t *dip;
- ino_tree_node_t *ino_ra;
- xfs_buf_t *bp;
-
- if (verbose)
- do_log(_(" - agno = %d\n"), agno);
-
- ino_ra = prefetch_inode_chunks(mp, agno, NULL);
/*
- * read on-disk inodes in chunks. then,
- * look at each on-disk inode 1 at a time.
- * if the number of links is bad, reset it.
+ * using the nlink values memorised during phase3/4, compare to the
+ * nlink counted in phase 6, and if different, update on-disk.
*/
irec = findfirst_inode_rec(agno);
while (irec != NULL) {
-
- if (ino_ra && (irec->ino_startnum >= ino_ra->ino_startnum))
- ino_ra = prefetch_inode_chunks(mp, agno, ino_ra);
-
- agbno = XFS_AGINO_TO_AGBNO(mp, irec->ino_startnum);
- bp = libxfs_readbuf(mp->m_dev,
- XFS_AGB_TO_DADDR(mp, agno, agbno),
- XFS_FSB_TO_BB(mp, XFS_IALLOC_BLOCKS(mp)), 0);
- if (bp == NULL) {
- if (!no_modify) {
- do_error(
- _("cannot read inode %llu, disk block %lld, cnt %d\n"),
- XFS_AGINO_TO_INO(mp, agno, irec->ino_startnum),
- XFS_AGB_TO_DADDR(mp, agno, agbno),
- (int)XFS_FSB_TO_BB(mp, XFS_IALLOC_BLOCKS(mp)));
- /* NOT REACHED */
- }
- do_warn(
- _("cannot read inode %llu, disk block %lld, cnt %d\n"),
- XFS_AGINO_TO_INO(mp, agno, irec->ino_startnum),
- XFS_AGB_TO_DADDR(mp, agno, agbno),
- (int)XFS_FSB_TO_BB(mp, XFS_IALLOC_BLOCKS(mp)));
-
- irec = next_ino_rec(irec);
- continue; /* while */
- }
- chunk_dirty = 0;
for (j = 0; j < XFS_INODES_PER_CHUNK; j++) {
assert(is_inode_confirmed(irec, j));
continue;
assert(no_modify || is_inode_reached(irec, j));
- assert(no_modify ||
- is_inode_referenced(irec, j));
+ assert(no_modify || is_inode_referenced(irec, j));
nrefs = num_inode_references(irec, j);
- ino = XFS_AGINO_TO_INO(mp, agno,
- irec->ino_startnum + j);
-
- dip = (xfs_dinode_t *)(XFS_BUF_PTR(bp) +
- (j << mp->m_sb.sb_inodelog));
-
- inode_dirty = 0;
-
- /* Swap the fields we care about to native format */
- dip->di_core.di_magic = INT_GET(dip->di_core.di_magic,
- ARCH_CONVERT);
- dip->di_core.di_onlink = INT_GET(dip->di_core.di_onlink,
- ARCH_CONVERT);
- if (INT_GET(dip->di_core.di_version, ARCH_CONVERT) ==
- XFS_DINODE_VERSION_1)
- dip->di_core.di_nlink = dip->di_core.di_onlink;
- else
- dip->di_core.di_nlink =
- INT_GET(dip->di_core.di_nlink,
- ARCH_CONVERT);
-
- if (dip->di_core.di_magic != XFS_DINODE_MAGIC) {
- if (!no_modify) {
- do_error(
- _("ino: %llu, bad d_inode magic saw: (0x%x) expecting (0x%x)\n"),
- ino, dip->di_core.di_magic, XFS_DINODE_MAGIC);
- /* NOT REACHED */
- }
- do_warn(
- _("ino: %llu, bad d_inode magic saw: (0x%x) expecting (0x%x)\n"),
- ino, dip->di_core.di_magic, XFS_DINODE_MAGIC);
- continue;
- }
- /*
- * compare and set links for all inodes
- * but the lost+found inode. we keep
- * that correct as we go.
- */
- if (dip->di_core.di_nlink != nrefs) {
- if (ino != orphanage_ino) {
- set_nlinks(&dip->di_core, ino,
- nrefs, &inode_dirty);
- }
- }
-
- /* Swap the fields back */
- dip->di_core.di_magic = INT_GET(dip->di_core.di_magic,
- ARCH_CONVERT);
- if (inode_dirty && INT_GET(dip->di_core.di_version,
- ARCH_CONVERT) == XFS_DINODE_VERSION_1) {
- if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) {
- ASSERT(dip->di_core.di_nlink <=
- XFS_MAXLINK_1);
- INT_SET(dip->di_core.di_onlink,
- ARCH_CONVERT,
- dip->di_core.di_nlink);
- dip->di_core.di_nlink =
- INT_GET(dip->di_core.di_nlink,
- ARCH_CONVERT);
- } else {
- /* superblock support v2 nlinks */
- INT_SET(dip->di_core.di_version,
- ARCH_CONVERT, XFS_DINODE_VERSION_2);
- dip->di_core.di_nlink =
- INT_GET(dip->di_core.di_nlink,
- ARCH_CONVERT);
- dip->di_core.di_onlink = 0;
- memset(&(dip->di_core.di_pad[0]), 0,
- sizeof(dip->di_core.di_pad));
- }
- } else {
- dip->di_core.di_nlink =
- INT_GET(dip->di_core.di_nlink,
- ARCH_CONVERT);
- dip->di_core.di_onlink =
- INT_GET(dip->di_core.di_onlink,
- ARCH_CONVERT);
- }
- chunk_dirty |= inode_dirty;
+ if (get_inode_disk_nlinks(irec, j) != nrefs)
+ update_inode_nlinks(mp, XFS_AGINO_TO_INO(mp,
+ agno, irec->ino_startnum + j),
+ nrefs);
}
-
- if (chunk_dirty)
- libxfs_writebuf(bp, 0);
- else
- libxfs_putbuf(bp);
-
irec = next_ino_rec(irec);
PROG_RPT_INC(prog_rpt_done[agno], XFS_INODES_PER_CHUNK);
}
}
-void
+static void
phase7_alt(xfs_mount_t *mp)
{
int i;
set_progress_msg(no_modify ? PROGRESS_FMT_VRFY_LINK : PROGRESS_FMT_CORR_LINK,
(__uint64_t) mp->m_sb.sb_icount);
- libxfs_bcache_purge();
for (i = 0; i < glob_agcount; i++) {
queue_work(phase7_alt_function, mp, i);
phase7(xfs_mount_t *mp)
{
ino_tree_node_t *irec;
- xfs_inode_t *ip;
- xfs_trans_t *tp;
int i;
int j;
- int error;
- int dirty;
- xfs_ino_t ino;
__uint32_t nrefs;
if (!no_modify)
else
do_log(_("Phase 7 - verify link counts...\n"));
-
if (do_prefetch) {
phase7_alt(mp);
return;
}
- tp = libxfs_trans_alloc(mp, XFS_TRANS_REMOVE);
-
- error = libxfs_trans_reserve(tp, (no_modify ? 0 : 10),
- XFS_REMOVE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES,
- XFS_REMOVE_LOG_COUNT);
-
- ASSERT(error == 0);
-
/*
- * for each ag, look at each inode 1 at a time using the
- * sim code. if the number of links is bad, reset it,
- * log the inode core, commit the transaction, and
- * allocate a new transaction
+ * for each ag, look at each inode 1 at a time. If the number of
+ * links is bad, reset it, log the inode core, commit the transaction
*/
for (i = 0; i < glob_agcount; i++) {
irec = findfirst_inode_rec(i);
nrefs = num_inode_references(irec, j);
- ino = XFS_AGINO_TO_INO(mp, i,
- irec->ino_startnum + j);
-
- error = libxfs_trans_iget(mp, tp, ino, 0, 0, &ip);
-
- if (error) {
- if (!no_modify)
- do_error(
- _("couldn't map inode %llu, err = %d\n"),
- ino, error);
- else {
- do_warn(
- _("couldn't map inode %llu, err = %d, can't compare link counts\n"),
- ino, error);
- continue;
- }
- }
-
- dirty = 0;
-
- /*
- * compare and set links for all inodes
- * but the lost+found inode. we keep
- * that correct as we go.
- */
- if (ino != orphanage_ino)
- set_nlinks(&ip->i_d, ino, nrefs,
- &dirty);
-
- if (!dirty) {
- libxfs_trans_iput(tp, ip, 0);
- } else {
- libxfs_trans_log_inode(tp, ip,
- XFS_ILOG_CORE);
- /*
- * no need to do a bmap finish since
- * we're not allocating anything
- */
- ASSERT(error == 0);
- error = libxfs_trans_commit(tp,
- XFS_TRANS_RELEASE_LOG_RES|
- XFS_TRANS_SYNC, NULL);
-
- ASSERT(error == 0);
-
- tp = libxfs_trans_alloc(mp,
- XFS_TRANS_REMOVE);
-
- error = libxfs_trans_reserve(tp,
- (no_modify ? 0 : 10),
- XFS_REMOVE_LOG_RES(mp),
- 0, XFS_TRANS_PERM_LOG_RES,
- XFS_REMOVE_LOG_COUNT);
- ASSERT(error == 0);
- }
+ if (get_inode_disk_nlinks(irec, j) != nrefs)
+ update_inode_nlinks(mp,
+ XFS_AGINO_TO_INO(mp, i,
+ irec->ino_startnum + j),
+ nrefs);
}
irec = next_ino_rec(irec);
}
}
-
- /*
- * always have one unfinished transaction coming out
- * of the loop. cancel it.
- */
- libxfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES);
}
isa_file = 0;
zap_log = 0;
dumpcore = 0;
- full_backptrs = 0;
+ full_ino_ex_data = 0;
delete_attr_ok = 1;
force_geo = 0;
assume_xfs = 0;
case 't':
report_interval = (int) strtol(optarg, 0, 0);
break;
-
+
case '?':
usage();
}
/* XXX: nathans - something in phase4 ain't playing by */
/* the buffer cache rules.. why doesn't IRIX hit this? */
- libxfs_bcache_purge();
+ libxfs_bcache_flush();
if (no_modify)
printf(_("No modify flag set, skipping phase 5\n"));
phase6(mp);
timestamp(PHASE_END, 6, NULL);
+ libxfs_bcache_flush();
+
phase7(mp);
timestamp(PHASE_END, 7, NULL);
} else {