void write_primary_sb(xfs_sb_t *sbp, int size) { xfs_dsb_t *buf; if (no_modify) return; buf = memalign(libxfs_device_alignment(), size); if (buf == NULL) { do_error(_("failed to memalign superblock buffer\n")); return; } memset(buf, 0, size); if (lseek64(x.dfd, 0LL, SEEK_SET) != 0LL) { free(buf); do_error(_("couldn't seek to offset 0 in filesystem\n")); } libxfs_sb_to_disk(buf, sbp, XFS_SB_ALL_BITS); if (write(x.dfd, buf, size) != size) { free(buf); do_error(_("primary superblock write failed!\n")); } free(buf); }
char * alloc_ag_buf(int size) { char *bp; bp = (char *)memalign(libxfs_device_alignment(), size); if (!bp) do_error(_("could not allocate ag header buffer (%d bytes)\n"), size); return(bp); }
/* XXX: (dgc) Propagate errors, only exit if fail-on-error flag set */ int libxfs_device_zero(struct xfs_buftarg *btp, xfs_daddr_t start, uint len) { xfs_off_t start_offset, end_offset, offset; ssize_t zsize, bytes; char *z; int fd; zsize = min(BDSTRAT_SIZE, BBTOB(len)); if ((z = memalign(libxfs_device_alignment(), zsize)) == NULL) { fprintf(stderr, _("%s: %s can't memalign %d bytes: %s\n"), progname, __FUNCTION__, (int)zsize, strerror(errno)); exit(1); } memset(z, 0, zsize); fd = libxfs_device_to_fd(btp->dev); start_offset = LIBXFS_BBTOOFF64(start); if ((lseek64(fd, start_offset, SEEK_SET)) < 0) { fprintf(stderr, _("%s: %s seek to offset %llu failed: %s\n"), progname, __FUNCTION__, (unsigned long long)start_offset, strerror(errno)); exit(1); } end_offset = LIBXFS_BBTOOFF64(start + len) - start_offset; for (offset = 0; offset < end_offset; ) { bytes = min((ssize_t)(end_offset - offset), zsize); if ((bytes = write(fd, z, bytes)) < 0) { fprintf(stderr, _("%s: %s write failed: %s\n"), progname, __FUNCTION__, strerror(errno)); exit(1); } else if (bytes == 0) { fprintf(stderr, _("%s: %s not progressing?\n"), progname, __FUNCTION__); exit(1); } offset += bytes; } free(z); return 0; }
/* * get a possible superblock -- don't check for internal consistency */ int get_sb(xfs_sb_t *sbp, xfs_off_t off, int size, xfs_agnumber_t agno) { int error, rval; xfs_dsb_t *buf; buf = memalign(libxfs_device_alignment(), size); if (buf == NULL) { do_error( _("error reading superblock %u -- failed to memalign buffer\n"), agno); exit(1); } memset(buf, 0, size); /* try and read it first */ if (lseek64(x.dfd, off, SEEK_SET) != off) { do_warn( _("error reading superblock %u -- seek to offset %" PRId64 " failed\n"), agno, off); return(XR_EOF); } if ((rval = read(x.dfd, buf, size)) != size) { error = errno; do_warn( _("superblock read failed, offset %" PRId64 ", size %d, ag %u, rval %d\n"), off, size, agno, rval); do_error("%s\n", strerror(error)); } libxfs_sb_from_disk(sbp, buf); free(buf); return (verify_sb(sbp, 0)); }
/* * find a secondary superblock, copy it into the sb buffer */ int find_secondary_sb(xfs_sb_t *rsb) { xfs_off_t off; xfs_sb_t *sb; xfs_sb_t bufsb; char *c_bufsb; int done; int i; int dirty; int retval; int bsize; do_warn(_("\nattempting to find secondary superblock...\n")); sb = (xfs_sb_t *)memalign(libxfs_device_alignment(), BSIZE); if (!sb) { do_error( _("error finding secondary superblock -- failed to memalign buffer\n")); exit(1); } memset(&bufsb, 0, sizeof(xfs_sb_t)); retval = 0; dirty = 0; bsize = 0; /* * skip first sector since we know that's bad */ for (done = 0, off = XFS_AG_MIN_BYTES; !done ; off += bsize) { /* * read disk 1 MByte at a time. */ if (lseek64(x.dfd, off, SEEK_SET) != off) { done = 1; } if (!done && (bsize = read(x.dfd, sb, BSIZE)) <= 0) { done = 1; } do_warn("."); /* * check the buffer 512 bytes at a time since * we don't know how big the sectors really are. */ for (i = 0; !done && i < bsize; i += BBSIZE) { c_bufsb = (char *)sb + i; libxfs_sb_from_disk(&bufsb, (xfs_dsb_t *)c_bufsb); if (verify_sb(&bufsb, 0) != XR_OK) continue; do_warn(_("found candidate secondary superblock...\n")); /* * found one. now verify it by looking * for other secondaries. */ memmove(rsb, &bufsb, sizeof(xfs_sb_t)); rsb->sb_inprogress = 0; clear_sunit = 1; if (verify_set_primary_sb(rsb, 0, &dirty) == XR_OK) { do_warn( _("verified secondary superblock...\n")); done = 1; retval = 1; } else { do_warn( _("unable to verify superblock, continuing...\n")); } } } free(sb); return(retval); }