phase2.c phase3.c phase4.c phase5.c phase6.c phase7.c rt.c sb.c \
scan.c versions.c xfs_repair.c
-LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID)
+LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBPTHREAD)
LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG)
LLDFLAGS = -static
#include "dir.h"
#include "dinode.h"
#include "bmap.h"
+#include "protos.h"
static int xfs_acl_valid(xfs_acl_t *aclp);
static int xfs_mac_valid(xfs_mac_label_t *lp);
* freespace map for directory and attribute leaf blocks (1 bit per byte)
* 1 == used, 0 == free
*/
-static da_freemap_t attr_freemap[DA_BMAP_SIZE];
+size_t ts_attr_freemap_size = sizeof(da_freemap_t) * DA_BMAP_SIZE;
/* The block is read in. The magic number and forward / backward
* links are checked by the caller process_leaf_attr.
xfs_attr_leaf_name_local_t *local;
xfs_attr_leaf_name_remote_t *remotep;
int i, start, stop, clearit, usedbs, firstb, thissize;
+ da_freemap_t *attr_freemap = ts_attr_freemap();
clearit = usedbs = 0;
*repair = 0;
* freespace map for directory leaf blocks (1 bit per byte)
* 1 == used, 0 == free
*/
-static da_freemap_t dir_freemap[DA_BMAP_SIZE];
-
-#if 0
-unsigned char *
-alloc_da_freemap(xfs_mount_t *mp)
-{
- unsigned char *freemap;
-
- if ((freemap = malloc(mp->m_sb.sb_blocksize)) == NULL)
- return(NULL);
-
- bzero(freemap, mp->m_sb.sb_blocksize/NBBY);
-
- return(freemap);
-}
-#endif
+size_t ts_dir_freemap_size = sizeof(da_freemap_t) * DA_BMAP_SIZE;
void
init_da_freemap(da_freemap_t *dir_freemap)
}
#endif
-static char dirbuf[64 * 1024];
+size_t ts_dirbuf_size = 64*1024;
/*
* called by both node dir and leaf dir processing routines
char fname[MAXNAMELEN + 1];
da_hole_map_t holemap;
da_hole_map_t bholemap;
-#if 0
- unsigned char *dir_freemap;
-#endif
+ unsigned char *dir_freemap = ts_dir_freemap();
#ifdef XR_DIR_TRACE
fprintf(stderr, "\tprocess_leaf_dir_block - ino %llu\n", ino);
*/
init_da_freemap(dir_freemap);
-#if 0
- /*
- * XXX - alternatively, do this for parallel usage.
- * set up block freespace map. head part of dir leaf block
- * including all entries are packed so we can use sizeof
- * and not worry about alignment.
- */
-
- if ((dir_freemap = alloc_da_freemap(mp)) == NULL) {
- do_error(_("couldn't allocate directory block freemap\n"));
- abort();
- }
-#endif
-
*buf_dirty = 0;
first_used = mp->m_sb.sb_blocksize;
zero_len_entries = 0;
_("- compacting block %u in dir inode %llu\n"),
da_bno, ino);
- new_leaf = (xfs_dir_leafblock_t *) &dirbuf[0];
+ new_leaf = (xfs_dir_leafblock_t *) ts_dirbuf();
/*
* copy leaf block header
EXTERN __uint32_t sb_unit;
EXTERN __uint32_t sb_width;
+extern size_t ts_dirbuf_size;
+extern size_t ts_dir_freemap_size;
+extern size_t ts_attr_freemap_size;
+
#endif /* _XFS_REPAIR_GLOBAL_H */
#include "agheader.h"
#include "protos.h"
#include "err_protos.h"
+#include "pthread.h"
+#include <sys/resource.h>
+
+static pthread_key_t dirbuf_key;
+static pthread_key_t dir_freemap_key;
+static pthread_key_t attr_freemap_key;
+
+static void
+ts_alloc(pthread_key_t key, unsigned n, size_t size)
+{
+ void *voidp;
+ voidp = malloc((n)*(size));
+ if (voidp == NULL) {
+ do_error(_("ts_alloc: cannot allocate thread specific storage\n"));
+ /* NO RETURN */
+ return;
+ }
+ pthread_setspecific(key, voidp);
+}
+
+static void
+ts_init(void)
+{
+ /* create thread specific keys */
+ pthread_key_create(&dirbuf_key, NULL);
+ pthread_key_create(&dir_freemap_key, NULL);
+ pthread_key_create(&attr_freemap_key, NULL);
+
+ /* allocate thread specific storage */
+ ts_alloc(dirbuf_key, 1, ts_dirbuf_size);
+ ts_alloc(dir_freemap_key, 1, ts_dir_freemap_size);
+ ts_alloc(attr_freemap_key, 1, ts_attr_freemap_size);
+}
+
+void *
+ts_dirbuf(void)
+{
+ return pthread_getspecific(dirbuf_key);
+}
+
+void *
+ts_dir_freemap(void)
+{
+ return pthread_getspecific(dir_freemap_key);
+}
+
+void *
+ts_attr_freemap(void)
+{
+ return pthread_getspecific(attr_freemap_key);
+}
+
+static void
+increase_rlimit(void)
+{
+ struct rlimit rl;
+
+ /* Increase limits */
+ if (getrlimit(RLIMIT_FSIZE, &rl) == -1) {
+ perror("getrlimit");
+ fprintf(stderr, "getrlimit(RLIMIT_FSIZE) failed!\n");
+ exit(1);
+ }
+ if (rl.rlim_cur != RLIM_INFINITY) {
+ rl.rlim_max = rl.rlim_cur = RLIM_INFINITY;
+ if (setrlimit(RLIMIT_FSIZE, &rl) == -1) {
+ perror("setrlimit");
+ fprintf(stderr,
+ "setrlimit Failed: current = %lld, max = %lld\n",
+ rl.rlim_cur, rl.rlim_max);
+ exit(1);
+ }
+ }
+}
void
xfs_init(libxfs_init_t *args)
if (!libxfs_init(args))
do_error(_("couldn't initialize XFS library\n"));
+
+ ts_init();
+ increase_rlimit();
}
int find_secondary_sb(xfs_sb_t *sb);
-void get_sb_geometry(fs_geometry_t *geo,
+struct fs_geometry;
+void get_sb_geometry(struct fs_geometry *geo,
xfs_sb_t *sbp);
char *alloc_ag_buf(int size);
void print_inode_list(xfs_agnumber_t i);
char * err_string(int err_code);
+
+extern void *ts_attr_freemap(void);
+extern void *ts_dir_freemap(void);
+extern void *ts_dirbuf(void);
+
xfs_agf_t *agf, xfs_agi_t *agi, xfs_agnumber_t i);
static xfs_mount_t *mp = NULL;
-static xfs_extlen_t bno_agffreeblks;
-static xfs_extlen_t cnt_agffreeblks;
-static xfs_extlen_t bno_agflongest;
-static xfs_extlen_t cnt_agflongest;
-static xfs_agino_t agicount;
-static xfs_agino_t agifreecount;
void
set_mp(xfs_mount_t *mpp)
int isroot
)
{
- xfs_agblock_t b;
+ xfs_agblock_t b, e;
xfs_alloc_block_t *block = (xfs_alloc_block_t *)ablock;
int i;
xfs_alloc_ptr_t *pp;
MAXEXTLEN)
continue;
- bno_agffreeblks +=
+ e = INT_GET(rp[i].ar_startblock, ARCH_CONVERT) +
INT_GET(rp[i].ar_blockcount, ARCH_CONVERT);
- if (INT_GET(rp[i].ar_blockcount, ARCH_CONVERT) >
- bno_agflongest)
- bno_agflongest = INT_GET(rp[i].ar_blockcount,
- ARCH_CONVERT);
for (b = INT_GET(rp[i].ar_startblock, ARCH_CONVERT);
- b < INT_GET(rp[i].ar_startblock, ARCH_CONVERT) +
- INT_GET(rp[i].ar_blockcount, ARCH_CONVERT);
- b++) {
+ b < e; b++) {
if (get_agbno_state(mp, agno, b)
== XR_E_UNKNOWN)
set_agbno_state(mp, agno, b,
xfs_alloc_block_t *block;
xfs_alloc_ptr_t *pp;
xfs_alloc_rec_t *rp;
- xfs_agblock_t b;
+ xfs_agblock_t b, e;
int i;
int hdr_errors;
int numrecs;
MAXEXTLEN)
continue;
- cnt_agffreeblks +=
+ e = INT_GET(rp[i].ar_startblock, ARCH_CONVERT) +
INT_GET(rp[i].ar_blockcount, ARCH_CONVERT);
- if (INT_GET(rp[i].ar_blockcount, ARCH_CONVERT) >
- cnt_agflongest)
- cnt_agflongest = INT_GET(rp[i].ar_blockcount,
- ARCH_CONVERT);
for (b = INT_GET(rp[i].ar_startblock, ARCH_CONVERT);
- b < INT_GET(rp[i].ar_startblock, ARCH_CONVERT) +
- INT_GET(rp[i].ar_blockcount, ARCH_CONVERT);
- b++) {
+ b < e; b++) {
state = get_agbno_state(mp, agno, b);
/*
* no warning messages -- we'll catch
continue;
}
- agicount += XFS_INODES_PER_CHUNK;
- agifreecount +=
- INT_GET(rp[i].ir_freecount, ARCH_CONVERT);
nfree = 0;
/*
int sb_dirty;
int status;
- cnt_agffreeblks = cnt_agflongest = 0;
- bno_agffreeblks = bno_agflongest = 0;
-
agi_dirty = agf_dirty = sb_dirty = 0;
- agicount = agifreecount = 0;
-
sbbuf = libxfs_readbuf(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
XFS_FSS_TO_BB(mp, 1), 0);
if (!sbbuf) {