示例#1
0
/* returns 0 on success, errno on failure */
int
ReallyRead(DirHandle * file, int block, char *data)
{
    FdHandle_t *fdP;
    int code;
    ssize_t nBytes;
    errno = 0;
    fdP = IH_OPEN(file->dirh_handle);
    if (fdP == NULL) {
	code = errno;
	return code;
    }
    if (FDH_SEEK(fdP, ((afs_foff_t)block) * AFS_PAGESIZE, SEEK_SET) < 0) {
	code = errno;
	FDH_REALLYCLOSE(fdP);
	return code;
    }
    nBytes = FDH_READ(fdP, data, (afs_fsize_t) AFS_PAGESIZE);
    if (nBytes != AFS_PAGESIZE) {
	if (nBytes < 0)
	    code = errno;
	else
	    code = EIO;
	FDH_REALLYCLOSE(fdP);
	return code;
    }
    FDH_CLOSE(fdP);
    return 0;
}
示例#2
0
/* returns 0 on success, errno on failure */
int
ReallyRead(DirHandle * file, int block, char *data)
{
    int code;
    FdHandle_t *fdP;

    fdP = IH_OPEN(file->dirh_handle);
    if (fdP == NULL) {
	code = errno;
	ViceLog(0,
		("ReallyRead(): open failed device %X inode %s errno %d\n",
		 file->dirh_handle->ih_dev, PrintInode(NULL,
						       file->dirh_handle->
						       ih_ino), code));
	return code;
    }
    if (FDH_SEEK(fdP, block * PAGESIZE, SEEK_SET) < 0) {
	code = errno;
	ViceLog(0,
		("ReallyRead(): lseek failed device %X inode %s errno %d\n",
		 file->dirh_handle->ih_dev, PrintInode(NULL,
						       file->dirh_handle->
						       ih_ino), code));
	FDH_REALLYCLOSE(fdP);
	return code;
    }
    code = FDH_READ(fdP, data, PAGESIZE);
    if (code != PAGESIZE) {
	if (code < 0)
	    code = errno;
	else
	    code = EIO;
	ViceLog(0,
		("ReallyRead(): read failed device %X inode %s errno %d\n",
		 file->dirh_handle->ih_dev, PrintInode(NULL,
						       file->dirh_handle->
						       ih_ino), code));
	FDH_REALLYCLOSE(fdP);
	return code;
    }
    FDH_CLOSE(fdP);
    return 0;

}
示例#3
0
static int
DumpFile(int dumpfd, int vnode, FdHandle_t * handleP,  struct VnodeDiskObject *v)
{
    int code = 0, failed_seek = 0, failed_write = 0;
    afs_int32 pad = 0;
    afs_int32 offset = 0;
    afs_sfsize_t n, nbytes, howMany, howBig;
    byte *p;
#ifndef AFS_NT40_ENV
    struct afs_stat status;
#endif
    afs_sfsize_t size, tmpsize;
#ifdef	AFS_AIX_ENV
#include <sys/statfs.h>
    struct statfs tstatfs;
#endif

    if (verbose)
	fprintf(stderr, "dumping file for vnode %d\n", vnode);

#ifdef AFS_NT40_ENV
    howBig = _filelength(handleP->fd_fd);
    howMany = 4096;

#else
    afs_fstat(handleP->fd_fd, &status);
    howBig = status.st_size;

#ifdef	AFS_AIX_ENV
    /* Unfortunately in AIX valuable fields such as st_blksize are 
     * gone from the stat structure.
     */
    fstatfs(handleP->fd_fd, &tstatfs);
    howMany = tstatfs.f_bsize;
#else
    howMany = status.st_blksize;
#endif /* AFS_AIX_ENV */
#endif /* AFS_NT40_ENV */


    size = FDH_SIZE(handleP);

    if (verbose)
	fprintf(stderr, "  howBig = %u, howMany = %u, fdh size = %u\n",
		howBig, howMany, size);

#ifdef AFS_LARGEFILE_ENV
    {
	afs_uint32 hi, lo;
	SplitInt64(size, hi, lo);
	if (hi == 0L) {
	    code = DumpInt32(dumpfd, 'f', lo);
	} else {
	    code = DumpDouble(dumpfd, 'h', hi, lo);
	}
    }
#else /* !AFS_LARGEFILE_ENV */
    code = DumpInt32(dumpfd, 'f', size);
#endif /* !AFS_LARGEFILE_ENV */
    if (code) {
	return VOLSERDUMPERROR;
    }

    p = (unsigned char *)malloc(howMany);
    if (!p) {
	fprintf(stderr, "out of memory!\n");
	return VOLSERDUMPERROR;
    }

    /* loop through whole file, while we still have bytes left, and no errors, in chunks of howMany bytes */
    for (nbytes = size; (nbytes && !failed_write); nbytes -= howMany) {
	if (nbytes < howMany)
	    howMany = nbytes;

	/* Read the data - unless we know we can't */
	n = (failed_seek ? 0 : FDH_READ(handleP, p, howMany));

	/* If read any good data and we null padded previously, log the
	 * amount that we had null padded.
	 */
	if ((n > 0) && pad) {
	    fprintf(stderr, "Null padding file %d bytes at offset %u\n", pad,
		    offset);
	    pad = 0;
	}

	/* If didn't read enough data, null padd the rest of the buffer. This
	 * can happen if, for instance, the media has some bad spots. We don't
	 * want to quit the dump, so we start null padding.
	 */
	if (n < howMany) {

		if (verbose) fprintf(stderr, "  read %u instead of %u bytes.\n", n, howMany);

	    /* Record the read error */
	    if (n < 0) {
		n = 0;
		fprintf(stderr, "Error %d reading inode %s for vnode %d\n",
			errno, PrintInode(NULL, handleP->fd_ih->ih_ino),
			vnode);
	    } else if (!pad) {
		fprintf(stderr, "Error reading inode %s for vnode %d\n",
			PrintInode(NULL, handleP->fd_ih->ih_ino), vnode);
	    }

	    /* Pad the rest of the buffer with zeros. Remember offset we started 
	     * padding. Keep total tally of padding.
	     */
	    memset(p + n, 0, howMany - n);
	    if (!pad)
		offset = (howBig - nbytes) + n;
	    pad += (howMany - n);

	    /* Now seek over the data we could not get. An error here means we
	     * can't do the next read.
	     */
	    failed_seek = FDH_SEEK(handleP, ((size - nbytes) + howMany), SEEK_SET);
	    if (failed_seek != ((size - nbytes) + howMany)) {
		if (failed_seek < 0) {
		    fprintf(stderr,
			    "Error %d seeking in inode %s for vnode %d\n",
			    errno, PrintInode(NULL, handleP->fd_ih->ih_ino),
			    vnode);
		} else {
		    fprintf(stderr,
			    "Error seeking in inode %s for vnode %d\n",
			    PrintInode(NULL, handleP->fd_ih->ih_ino), vnode);
		    failed_seek = -1;
		}
	    } else {
		failed_seek = 0;
	    }
	}

	/* Now write the data out */
	if (write(dumpfd, (char *)p, howMany) != howMany)
	    failed_write = VOLSERDUMPERROR;
    }

    if (pad) {			/* Any padding we hadn't reported yet */
	fprintf(stderr, "Null padding file: %d bytes at offset %u\n", pad,
		offset);
    }

    free(p);
    return failed_write;
}