void xfs_init(libxfs_init_t *args) { memset(args, 0, sizeof(libxfs_init_t)); if (isa_file) { args->disfile = 1; args->dname = fs_name; args->volname = NULL; } else { args->disfile = 0; args->volname = fs_name; args->dname = NULL; } if (log_spec) { /* External log specified */ args->logname = log_name; args->lisfile = (isa_file?1:0); /* XXX assume data file also means log file */ /* REVISIT: Need to do fs sanity / log validity checking */ } if (rt_spec) { /* RT device specified */ args->rtname = rt_name; args->risfile = (isa_file?1:0); /* XXX assume data file also means rt file */ } args->usebuflock = do_prefetch; args->setblksize = 0; args->isdirect = LIBXFS_DIRECT; if (no_modify) args->isreadonly = (LIBXFS_ISREADONLY | LIBXFS_ISINACTIVE); else if (dangerously) args->isreadonly = (LIBXFS_ISINACTIVE | LIBXFS_DANGEROUSLY); else args->isreadonly = LIBXFS_EXCLUSIVELY; if (!libxfs_init(args)) { /* would -d be an option? */ if (!no_modify && !dangerously) { args->isreadonly = (LIBXFS_ISINACTIVE | LIBXFS_DANGEROUSLY); if (libxfs_init(args)) fprintf(stderr, _("Unmount or use the dangerous (-d) option to repair a read-only mounted filesystem\n")); } do_error(_("couldn't initialize XFS library\n")); } ts_create(); increase_rlimit(); pftrace_init(); }
xfs_mount_t *mount_xfs(char *progname, char *source_name) { xfs_mount_t *mp; xfs_buf_t *sbp; xfs_sb_t *sb; libxfs_init_t xargs; xfs_mount_t *mbuf = (xfs_mount_t *)malloc(sizeof(xfs_mount_t)); /* prepare the libxfs_init structure */ memset(&xargs, 0, sizeof(xargs)); xargs.isdirect = LIBXFS_DIRECT; xargs.isreadonly = LIBXFS_ISREADONLY; if (1) { xargs.dname = source_name; xargs.disfile = 1; } else xargs.volname = source_name; if (!libxfs_init(&xargs)) { do_log(_("%s: couldn't initialize XFS library\n" "%s: Aborting.\n"), progname, progname); return NULL; } /* prepare the mount structure */ sbp = libxfs_readbuf(xargs.ddev, XFS_SB_DADDR, 1, 0); memset(mbuf, 0, sizeof(xfs_mount_t)); sb = &(mbuf->m_sb); libxfs_sb_from_disk(sb, XFS_BUF_TO_SBP(sbp)); mp = libxfs_mount(mbuf, sb, xargs.ddev, xargs.logdev, xargs.rtdev, 1); if (mp == NULL) { do_log(_("%s: %s filesystem failed to initialize\n" "%s: Aborting.\n"), progname, source_name, progname); return NULL; } else if (mp->m_sb.sb_inprogress) { do_log(_("%s %s filesystem failed to initialize\n" "%s: Aborting.\n"), progname, source_name, progname); return NULL; } else if (mp->m_sb.sb_logstart == 0) { do_log(_("%s: %s has an external log.\n%s: Aborting.\n"), progname, source_name, progname); return NULL; } else if (mp->m_sb.sb_rextents != 0) { do_log(_("%s: %s has a real-time section.\n" "%s: Aborting.\n"), progname, source_name, progname); return NULL; } return mp; }
int main(int argc, char **argv) { int i, j; int howfar = 0; int open_flags; xfs_off_t pos, end_pos; size_t length; int c, first_residue, tmp_residue; __uint64_t size, sizeb; __uint64_t numblocks = 0; int wblocks = 0; int num_threads = 0; struct dioattr d; int wbuf_size; int wbuf_align; int wbuf_miniosize; int source_is_file = 0; int buffered_output = 0; int duplicate = 0; uint btree_levels, current_level; ag_header_t ag_hdr; xfs_mount_t *mp; xfs_mount_t mbuf; xfs_buf_t *sbp; xfs_sb_t *sb; xfs_agnumber_t num_ags, agno; xfs_agblock_t bno; xfs_daddr_t begin, next_begin, ag_begin, new_begin, ag_end; struct xfs_btree_block *block; xfs_alloc_ptr_t *ptr; xfs_alloc_rec_t *rec_ptr; extern char *optarg; extern int optind; libxfs_init_t xargs; thread_args *tcarg; struct stat64 statbuf; progname = basename(argv[0]); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); while ((c = getopt(argc, argv, "bdL:V")) != EOF) { switch (c) { case 'b': buffered_output = 1; break; case 'd': duplicate = 1; break; case 'L': logfile_name = optarg; break; case 'V': printf(_("%s version %s\n"), progname, VERSION); exit(0); case '?': usage(); } } if (argc - optind < 2) usage(); if (logfile_name) { logfd = open(logfile_name, O_CREAT|O_WRONLY|O_EXCL, 0600); } else { logfile_name = LOGFILE_NAME; logfd = mkstemp(logfile_name); } if (logfd < 0) { fprintf(stderr, _("%s: couldn't open log file \"%s\"\n"), progname, logfile_name); perror(_("Aborting XFS copy - reason")); exit(1); } if ((logerr = fdopen(logfd, "w")) == NULL) { fprintf(stderr, _("%s: couldn't set up logfile stream\n"), progname); perror(_("Aborting XFS copy - reason")); exit(1); } source_name = argv[optind]; source_fd = -1; optind++; num_targets = argc - optind; if ((target = malloc(sizeof(target_control) * num_targets)) == NULL) { do_log(_("Couldn't allocate target array\n")); die_perror(); } for (i = 0; optind < argc; i++, optind++) { target[i].name = argv[optind]; target[i].fd = -1; target[i].position = -1; target[i].state = INACTIVE; target[i].error = 0; target[i].err_type = 0; } parent_pid = getpid(); if (atexit(killall)) { do_log(_("%s: couldn't register atexit function.\n"), progname); die_perror(); } /* open up source -- is it a file? */ open_flags = O_RDONLY; if ((source_fd = open(source_name, open_flags)) < 0) { do_log(_("%s: couldn't open source \"%s\"\n"), progname, source_name); die_perror(); } if (fstat64(source_fd, &statbuf) < 0) { do_log(_("%s: couldn't stat source \"%s\"\n"), progname, source_name); die_perror(); } if (S_ISREG(statbuf.st_mode)) source_is_file = 1; if (source_is_file && platform_test_xfs_fd(source_fd)) { if (fcntl(source_fd, F_SETFL, open_flags | O_DIRECT) < 0) { do_log(_("%s: Cannot set direct I/O flag on \"%s\".\n"), progname, source_name); die_perror(); } if (xfsctl(source_name, source_fd, XFS_IOC_DIOINFO, &d) < 0) { do_log(_("%s: xfsctl on file \"%s\" failed.\n"), progname, source_name); die_perror(); } wbuf_align = d.d_mem; wbuf_size = MIN(d.d_maxiosz, 1 * 1024 * 1024); wbuf_miniosize = d.d_miniosz; } else { /* set arbitrary I/O params, miniosize at least 1 disk block */ wbuf_align = getpagesize(); wbuf_size = 1 * 1024 * 1024; wbuf_miniosize = -1; /* set after mounting source fs */ } if (!source_is_file) { /* * check to make sure a filesystem isn't mounted * on the device */ if (platform_check_ismounted(source_name, NULL, &statbuf, 0)) { do_log( _("%s: Warning -- a filesystem is mounted on the source device.\n"), progname); do_log( _("\t\tGenerated copies may be corrupt unless the source is\n")); do_log( _("\t\tunmounted or mounted read-only. Copy proceeding...\n")); } } /* prepare the libxfs_init structure */ memset(&xargs, 0, sizeof(xargs)); xargs.isdirect = LIBXFS_DIRECT; xargs.isreadonly = LIBXFS_ISREADONLY; if (source_is_file) { xargs.dname = source_name; xargs.disfile = 1; } else xargs.volname = source_name; if (!libxfs_init(&xargs)) { do_log(_("%s: couldn't initialize XFS library\n" "%s: Aborting.\n"), progname, progname); exit(1); } /* prepare the mount structure */ sbp = libxfs_readbuf(xargs.ddev, XFS_SB_DADDR, 1, 0); memset(&mbuf, 0, sizeof(xfs_mount_t)); sb = &mbuf.m_sb; libxfs_sb_from_disk(sb, XFS_BUF_TO_SBP(sbp)); mp = libxfs_mount(&mbuf, sb, xargs.ddev, xargs.logdev, xargs.rtdev, 1); if (mp == NULL) { do_log(_("%s: %s filesystem failed to initialize\n" "%s: Aborting.\n"), progname, source_name, progname); exit(1); } else if (mp->m_sb.sb_inprogress) { do_log(_("%s %s filesystem failed to initialize\n" "%s: Aborting.\n"), progname, source_name, progname); exit(1); } else if (mp->m_sb.sb_logstart == 0) { do_log(_("%s: %s has an external log.\n%s: Aborting.\n"), progname, source_name, progname); exit(1); } else if (mp->m_sb.sb_rextents != 0) { do_log(_("%s: %s has a real-time section.\n" "%s: Aborting.\n"), progname, source_name, progname); exit(1); } source_blocksize = mp->m_sb.sb_blocksize; source_sectorsize = mp->m_sb.sb_sectsize; if (wbuf_miniosize == -1) wbuf_miniosize = source_sectorsize; ASSERT(source_blocksize % source_sectorsize == 0); ASSERT(source_sectorsize % BBSIZE == 0); if (source_blocksize > source_sectorsize) { /* get number of leftover sectors in last block of ag header */ tmp_residue = ((XFS_AGFL_DADDR(mp) + 1) * source_sectorsize) % source_blocksize; first_residue = (tmp_residue == 0) ? 0 : source_blocksize - tmp_residue; ASSERT(first_residue % source_sectorsize == 0); } else if (source_blocksize == source_sectorsize) { first_residue = 0; } else { do_log(_("Error: filesystem block size is smaller than the" " disk sectorsize.\nAborting XFS copy now.\n")); exit(1); } first_agbno = (((XFS_AGFL_DADDR(mp) + 1) * source_sectorsize) + first_residue) / source_blocksize; ASSERT(first_agbno != 0); ASSERT( ((((XFS_AGFL_DADDR(mp) + 1) * source_sectorsize) + first_residue) % source_blocksize) == 0); /* now open targets */ open_flags = O_RDWR; for (i = 0; i < num_targets; i++) { int write_last_block = 0; if (stat64(target[i].name, &statbuf) < 0) { /* ok, assume it's a file and create it */ do_out(_("Creating file %s\n"), target[i].name); open_flags |= O_CREAT; if (!buffered_output) open_flags |= O_DIRECT; write_last_block = 1; } else if (S_ISREG(statbuf.st_mode)) { open_flags |= O_TRUNC; if (!buffered_output) open_flags |= O_DIRECT; write_last_block = 1; } else { /* * check to make sure a filesystem isn't mounted * on the device */ if (platform_check_ismounted(target[i].name, NULL, &statbuf, 0)) { do_log(_("%s: a filesystem is mounted " "on target device \"%s\".\n" "%s cannot copy to mounted filesystems." " Aborting\n"), progname, target[i].name, progname); exit(1); } } target[i].fd = open(target[i].name, open_flags, 0644); if (target[i].fd < 0) { do_log(_("%s: couldn't open target \"%s\"\n"), progname, target[i].name); die_perror(); } if (write_last_block) { /* ensure regular files are correctly sized */ if (ftruncate64(target[i].fd, mp->m_sb.sb_dblocks * source_blocksize)) { do_log(_("%s: cannot grow data section.\n"), progname); die_perror(); } if (platform_test_xfs_fd(target[i].fd)) { if (xfsctl(target[i].name, target[i].fd, XFS_IOC_DIOINFO, &d) < 0) { do_log( _("%s: xfsctl on \"%s\" failed.\n"), progname, target[i].name); die_perror(); } else { wbuf_align = MAX(wbuf_align, d.d_mem); wbuf_size = MIN(d.d_maxiosz, wbuf_size); wbuf_miniosize = MAX(d.d_miniosz, wbuf_miniosize); } } } else { char *lb[XFS_MAX_SECTORSIZE] = { NULL }; off64_t off; /* ensure device files are sufficiently large */ off = mp->m_sb.sb_dblocks * source_blocksize; off -= sizeof(lb); if (pwrite64(target[i].fd, lb, sizeof(lb), off) < 0) { do_log(_("%s: failed to write last block\n"), progname); do_log(_("\tIs target \"%s\" too small?\n"), target[i].name); die_perror(); } } } /* initialize locks and bufs */ if (pthread_mutex_init(&glob_masks.mutex, NULL) != 0) { do_log(_("Couldn't initialize global thread mask\n")); die_perror(); } glob_masks.num_working = 0; if (wbuf_init(&w_buf, wbuf_size, wbuf_align, wbuf_miniosize, 0) == NULL) { do_log(_("Error initializing wbuf 0\n")); die_perror(); } wblocks = wbuf_size / BBSIZE; if (wbuf_init(&btree_buf, MAX(source_blocksize, wbuf_miniosize), wbuf_align, wbuf_miniosize, 1) == NULL) { do_log(_("Error initializing btree buf 1\n")); die_perror(); } if (pthread_mutex_init(&mainwait,NULL) != 0) { do_log(_("Error creating first semaphore.\n")); die_perror(); exit(1); } /* need to start out blocking */ pthread_mutex_lock(&mainwait); /* set up sigchild signal handler */ signal(SIGCHLD, handler); signal_maskfunc(SIGCHLD, SIG_BLOCK); /* make children */ if ((targ = malloc(num_targets * sizeof(thread_args))) == NULL) { do_log(_("Couldn't malloc space for thread args\n")); die_perror(); exit(1); } for (i = 0, tcarg = targ; i < num_targets; i++, tcarg++) { if (!duplicate) platform_uuid_generate(&tcarg->uuid); else platform_uuid_copy(&tcarg->uuid, &mp->m_sb.sb_uuid); if (pthread_mutex_init(&tcarg->wait, NULL) != 0) { do_log(_("Error creating thread mutex %d\n"), i); die_perror(); exit(1); } /* need to start out blocking */ pthread_mutex_lock(&tcarg->wait); } for (i = 0, tcarg = targ; i < num_targets; i++, tcarg++) { tcarg->id = i; tcarg->fd = target[i].fd; target[i].state = ACTIVE; num_threads++; if (pthread_create(&target[i].pid, NULL, begin_reader, (void *)tcarg)) { do_log(_("Error creating thread for target %d\n"), i); die_perror(); } } ASSERT(num_targets == num_threads); /* set up statistics */ num_ags = mp->m_sb.sb_agcount; init_bar(mp->m_sb.sb_blocksize / BBSIZE * ((__uint64_t)mp->m_sb.sb_dblocks - (__uint64_t)mp->m_sb.sb_fdblocks + 10 * num_ags)); kids = num_targets; block = (struct xfs_btree_block *) btree_buf.data; for (agno = 0; agno < num_ags && kids > 0; agno++) { /* read in first blocks of the ag */ read_ag_header(source_fd, agno, &w_buf, &ag_hdr, mp, source_blocksize, source_sectorsize); /* set the in_progress bit for the first AG */ if (agno == 0) ag_hdr.xfs_sb->sb_inprogress = 1; /* save what we need (agf) in the btree buffer */ memmove(btree_buf.data, ag_hdr.xfs_agf, source_sectorsize); ag_hdr.xfs_agf = (xfs_agf_t *) btree_buf.data; btree_buf.length = source_blocksize; /* write the ag header out */ write_wbuf(); /* traverse btree until we get to the leftmost leaf node */ bno = be32_to_cpu(ag_hdr.xfs_agf->agf_roots[XFS_BTNUM_BNOi]); current_level = 0; btree_levels = be32_to_cpu(ag_hdr.xfs_agf-> agf_levels[XFS_BTNUM_BNOi]); ag_end = XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu(ag_hdr.xfs_agf->agf_length) - 1) + source_blocksize / BBSIZE; for (;;) { /* none of this touches the w_buf buffer */ ASSERT(current_level < btree_levels); current_level++; btree_buf.position = pos = (xfs_off_t) XFS_AGB_TO_DADDR(mp,agno,bno) << BBSHIFT; btree_buf.length = source_blocksize; read_wbuf(source_fd, &btree_buf, mp); block = (struct xfs_btree_block *) ((char *)btree_buf.data + pos - btree_buf.position); ASSERT(be32_to_cpu(block->bb_magic) == XFS_ABTB_MAGIC); if (be16_to_cpu(block->bb_level) == 0) break; ptr = XFS_ALLOC_PTR_ADDR(mp, block, 1, mp->m_alloc_mxr[1]); bno = be32_to_cpu(ptr[0]); } /* align first data copy but don't overwrite ag header */ pos = w_buf.position >> BBSHIFT; length = w_buf.length >> BBSHIFT; next_begin = pos + length; ag_begin = next_begin; ASSERT(w_buf.position % source_sectorsize == 0); /* handle the rest of the ag */ for (;;) { if (be16_to_cpu(block->bb_level) != 0) { do_log( _("WARNING: source filesystem inconsistent.\n")); do_log( _(" A leaf btree rec isn't a leaf. Aborting now.\n")); exit(1); } rec_ptr = XFS_ALLOC_REC_ADDR(mp, block, 1); for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++, rec_ptr++) { /* calculate in daddr's */ begin = next_begin; /* * protect against pathological case of a * hole right after the ag header in a * mis-aligned case */ if (begin < ag_begin) begin = ag_begin; /* * round size up to ensure we copy a * range bigger than required */ sizeb = XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu(rec_ptr->ar_startblock)) - begin; size = roundup(sizeb <<BBSHIFT, wbuf_miniosize); if (size > 0) { /* copy extent */ w_buf.position = (xfs_off_t) begin << BBSHIFT; while (size > 0) { /* * let lower layer do alignment */ if (size > w_buf.size) { w_buf.length = w_buf.size; size -= w_buf.size; sizeb -= wblocks; numblocks += wblocks; } else { w_buf.length = size; numblocks += sizeb; size = 0; } read_wbuf(source_fd, &w_buf, mp); write_wbuf(); w_buf.position += w_buf.length; howfar = bump_bar( howfar, numblocks); } } /* round next starting point down */ new_begin = XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu(rec_ptr->ar_startblock) + be32_to_cpu(rec_ptr->ar_blockcount)); next_begin = rounddown(new_begin, w_buf.min_io_size >> BBSHIFT); } if (be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK) break; /* read in next btree record block */ btree_buf.position = pos = (xfs_off_t) XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu( block->bb_u.s.bb_rightsib)) << BBSHIFT; btree_buf.length = source_blocksize; /* let read_wbuf handle alignment */ read_wbuf(source_fd, &btree_buf, mp); block = (struct xfs_btree_block *) ((char *) btree_buf.data + pos - btree_buf.position); ASSERT(be32_to_cpu(block->bb_magic) == XFS_ABTB_MAGIC); } /* * write out range of used blocks after last range * of free blocks in AG */ if (next_begin < ag_end) { begin = next_begin; sizeb = ag_end - begin; size = roundup(sizeb << BBSHIFT, wbuf_miniosize); if (size > 0) { /* copy extent */ w_buf.position = (xfs_off_t) begin << BBSHIFT; while (size > 0) { /* * let lower layer do alignment */ if (size > w_buf.size) { w_buf.length = w_buf.size; size -= w_buf.size; sizeb -= wblocks; numblocks += wblocks; } else { w_buf.length = size; numblocks += sizeb; size = 0; } read_wbuf(source_fd, &w_buf, mp); write_wbuf(); w_buf.position += w_buf.length; howfar = bump_bar(howfar, numblocks); } } } } if (kids > 0) { if (!duplicate) { /* write a clean log using the specified UUID */ for (j = 0, tcarg = targ; j < num_targets; j++) { w_buf.owner = tcarg; w_buf.length = rounddown(w_buf.size, w_buf.min_io_size); pos = write_log_header( source_fd, &w_buf, mp); end_pos = write_log_trailer( source_fd, &w_buf, mp); w_buf.position = pos; memset(w_buf.data, 0, w_buf.length); while (w_buf.position < end_pos) { do_write(tcarg); w_buf.position += w_buf.length; } tcarg++; } } else { num_ags = 1; } /* reread and rewrite superblocks (UUID and in-progress) */ /* [backwards, so inprogress bit only updated when done] */ for (i = num_ags - 1; i >= 0; i--) { read_ag_header(source_fd, i, &w_buf, &ag_hdr, mp, source_blocksize, source_sectorsize); if (i == 0) ag_hdr.xfs_sb->sb_inprogress = 0; /* do each thread in turn, each has its own UUID */ for (j = 0, tcarg = targ; j < num_targets; j++) { platform_uuid_copy(&ag_hdr.xfs_sb->sb_uuid, &tcarg->uuid); do_write(tcarg); tcarg++; } } bump_bar(100, 0); } check_errors(); killall(); pthread_exit(NULL); /*NOTREACHED*/ return 0; }
static void fs_open(char* device) { int open_flags; struct stat statbuf; int source_is_file = 0; xfs_buf_t *sbp; xfs_sb_t *sb; int tmp_residue; /* open up source -- is it a file? */ open_flags = O_RDONLY; if ((source_fd = open(device, open_flags)) < 0) { log_mesg(0, 1, 1, fs_opt.debug, "Couldn't open source partition %s\n", device); }else{ log_mesg(0, 0, 0, fs_opt.debug, "Open %s successfully", device); } if (fstat(source_fd, &statbuf) < 0) { log_mesg(0, 1, 1, fs_opt.debug, "Couldn't stat source partition\n"); } if (S_ISREG(statbuf.st_mode)){ log_mesg(1, 0, 0, fs_opt.debug, "source is file\n"); source_is_file = 1; } /* prepare the libxfs_init structure */ memset(&xargs, 0, sizeof(xargs)); xargs.isdirect = LIBXFS_DIRECT; xargs.isreadonly = LIBXFS_ISREADONLY; if (source_is_file) { xargs.dname = device; xargs.disfile = 1; } else xargs.volname = device; if (libxfs_init(&xargs) == 0) { log_mesg(0, 1, 1, fs_opt.debug, "libxfs_init error. Please repaire %s partition.\n", device); } /* prepare the mount structure */ sbp = libxfs_readbuf(xargs.ddev, XFS_SB_DADDR, 1, 0); memset(&mbuf, 0, sizeof(xfs_mount_t)); sb = &mbuf.m_sb; libxfs_sb_from_disk(sb, XFS_BUF_TO_SBP(sbp)); mp = libxfs_mount(&mbuf, sb, xargs.ddev, xargs.logdev, xargs.rtdev, 1); if (mp == NULL) { log_mesg(0, 1, 1, fs_opt.debug, "%s filesystem failed to initialize\nAborting.\n", device); } else if (mp->m_sb.sb_inprogress) { log_mesg(0, 1, 1, fs_opt.debug, "%s filesystem failed to initialize\nAborting(inprogress).\n", device); } else if (mp->m_sb.sb_logstart == 0) { log_mesg(0, 1, 1, fs_opt.debug, "%s has an external log.\nAborting.\n", device); } else if (mp->m_sb.sb_rextents != 0) { log_mesg(0, 1, 1, fs_opt.debug, "%s has a real-time section.\nAborting.\n", device); } source_blocksize = mp->m_sb.sb_blocksize; source_sectorsize = mp->m_sb.sb_sectsize; log_mesg(2, 0, 0, fs_opt.debug, "source_blocksize %i source_sectorsize = %i\n", source_blocksize, source_sectorsize); if (source_blocksize > source_sectorsize) { /* get number of leftover sectors in last block of ag header */ tmp_residue = ((XFS_AGFL_DADDR(mp) + 1) * source_sectorsize) % source_blocksize; first_residue = (tmp_residue == 0) ? 0 : source_blocksize - tmp_residue; log_mesg(2, 0, 0, fs_opt.debug, "first_residue %i tmp_residue %i\n", first_residue, tmp_residue); } else if (source_blocksize == source_sectorsize) { first_residue = 0; } else { log_mesg(0, 1, 1, fs_opt.debug, "Error: filesystem block size is smaller than the disk sectorsize.\nAborting XFS copy now.\n"); } /* end of xfs open */ log_mesg(3, 0, 0, fs_opt.debug, "%s: blcos size= %i\n", __FILE__, mp->m_sb.sb_blocksize); log_mesg(3, 0, 0, fs_opt.debug, "%s: total b= %lli\n", __FILE__, mp->m_sb.sb_dblocks); log_mesg(3, 0, 0, fs_opt.debug, "%s: free block= %lli\n", __FILE__, mp->m_sb.sb_fdblocks); log_mesg(3, 0, 0, fs_opt.debug, "%s: used block= %lli\n", __FILE__, (mp->m_sb.sb_dblocks - mp->m_sb.sb_fdblocks)); log_mesg(3, 0, 0, fs_opt.debug, "%s: device size= %lli\n", __FILE__, (mp->m_sb.sb_blocksize * mp->m_sb.sb_dblocks)); }
void init( int argc, char **argv) { xfs_sb_t *sbp; void *bufp = NULL; int c; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); progname = basename(argv[0]); while ((c = getopt(argc, argv, "c:fFip:rxVl:")) != EOF) { switch (c) { case 'c': cmdline = xrealloc(cmdline, (ncmdline+1)*sizeof(char*)); cmdline[ncmdline++] = optarg; break; case 'f': x.disfile = 1; break; case 'F': force = 1; break; case 'i': x.isreadonly = (LIBXFS_ISREADONLY|LIBXFS_ISINACTIVE); break; case 'p': progname = optarg; break; case 'r': x.isreadonly = LIBXFS_ISREADONLY; break; case 'l': x.logname = optarg; break; case 'x': expert_mode = 1; break; case 'V': printf(_("%s version %s\n"), progname, VERSION); exit(0); case '?': usage(); /*NOTREACHED*/ } } if (optind + 1 != argc) { usage(); /*NOTREACHED*/ } fsdevice = argv[optind]; if (!x.disfile) x.volname = fsdevice; else x.dname = fsdevice; if (!libxfs_init(&x)) { fputs(_("\nfatal error -- couldn't initialize XFS library\n"), stderr); exit(1); } if (read_bbs(XFS_SB_DADDR, 1, &bufp, NULL)) { fprintf(stderr, _("%s: %s is invalid (cannot read first 512 " "bytes)\n"), progname, fsdevice); exit(1); } /* copy SB from buffer to in-core, converting architecture as we go */ libxfs_sb_from_disk(&xmount.m_sb, bufp); xfree(bufp); sbp = &xmount.m_sb; if (sbp->sb_magicnum != XFS_SB_MAGIC) { fprintf(stderr, _("%s: %s is not a valid XFS filesystem (unexpected SB magic number 0x%08x)\n"), progname, fsdevice, sbp->sb_magicnum); if (!force) exit(EXIT_FAILURE); } mp = libxfs_mount(&xmount, sbp, x.ddev, x.logdev, x.rtdev, LIBXFS_MOUNT_ROOTINOS | LIBXFS_MOUNT_DEBUGGER); if (!mp) { mp = libxfs_mount(&xmount, sbp, x.ddev, x.logdev, x.rtdev, LIBXFS_MOUNT_DEBUGGER); if (!mp) { fprintf(stderr, _("%s: device %s unusable (not an XFS " "filesystem?)\n"), progname, fsdevice); exit(1); } } blkbb = 1 << mp->m_blkbb_log; push_cur(); init_commands(); init_sig(); }