Пример #1
0
/**
 * write an existing volume disk header.
 *
 * @param[in] hdr   volume disk header
 * @param[in] dp    disk partition object
 * @param[in] cr    assert if O_CREAT | O_EXCL should be passed to open()
 *
 * @return operation status
 *    @retval 0 success
 *    @retval -1 volume header doesn't exist
 *    @retval EIO failed to write volume header
 *
 * @internal
 */
static afs_int32
_VWriteVolumeDiskHeader(VolumeDiskHeader_t * hdr,
			struct DiskPartition64 * dp,
			int flags)
{
    afs_int32 code = 0;
    int fd;
    char path[MAXPATHLEN];

#ifdef AFS_DEMAND_ATTACH_FS
    /* prevent racing with VGC scanners reading the vol header while we are
     * writing it */
    code = VPartHeaderLock(dp, READ_LOCK);
    if (code) {
	return EIO;
    }
#endif /* AFS_DEMAND_ATTACH_FS */

    flags |= O_RDWR;

    (void)afs_snprintf(path, sizeof(path),
		       "%s/" VFORMAT,
		       VPartitionPath(dp), afs_printable_uint32_lu(hdr->id));
    fd = open(path, flags, 0644);
    if (fd < 0) {
	code = errno;
	Log("_VWriteVolumeDiskHeader: Couldn't open header for volume %lu, "
	    "error = %d\n", afs_printable_uint32_lu(hdr->id), errno);
    } else if (write(fd, hdr, sizeof(*hdr)) != sizeof(*hdr)) {
	Log("_VWriteVolumeDiskHeader: Couldn't write header for volume %lu, "
	    "error = %d\n", afs_printable_uint32_lu(hdr->id), errno);
	code = EIO;
    }

    if (fd >= 0) {
	if (close(fd) != 0) {
	    Log("_VWriteVolumeDiskHeader: Error closing header for volume "
	        "%lu, errno %d\n", afs_printable_uint32_lu(hdr->id), errno);
	}
    }

#ifdef AFS_DEMAND_ATTACH_FS
    VPartHeaderUnlock(dp, READ_LOCK);
#endif /* AFS_DEMAND_ATTACH_FS */

    return code;
}
Пример #2
0
/**
 * handle a single vol header as part of VWalkVolumeHeaders.
 *
 * @param[in] dp      disk partition
 * @param[in] volfunc function to call when a vol header is successfully read
 * @param[in] name    full path name to the .vol header
 * @param[out] hdr    header data read in from the .vol header
 * @param[in] locked  1 if the partition headers are locked, 0 otherwise
 * @param[in] rock    the rock to pass to volfunc
 *
 * @return operation status
 *  @retval 0  success
 *  @retval -1 fatal error, stop scanning
 *  @retval 1  failed to read header
 *  @retval 2  volfunc callback indicated error after header read
 */
static int
_VHandleVolumeHeader(struct DiskPartition64 *dp, VWalkVolFunc volfunc,
                     const char *name, struct VolumeDiskHeader *hdr,
                     int locked, void *rock)
{
    int error = 0;
    FD_t fd;

    if ((fd = OS_OPEN(name, O_RDONLY, 0)) == INVALID_FD
        || OS_READ(fd, hdr, sizeof(*hdr))
        != sizeof(*hdr)
        || hdr->stamp.magic != VOLUMEHEADERMAGIC) {
        error = 1;
    }

    if (fd != INVALID_FD) {
	OS_CLOSE(fd);
    }

#ifdef AFSFS_DEMAND_ATTACH_FS
    if (locked) {
	VPartHeaderUnlock(dp);
    }
#endif /* AFS_DEMAND_ATTACH_FS */

    if (!error && volfunc) {
	/* the volume header seems fine; call the caller-supplied
	 * 'we-found-a-volume-header' function */
	int last = 1;

#ifdef AFS_DEMAND_ATTACH_FS
	if (!locked) {
	    last = 0;
	}
#endif /* AFS_DEMAND_ATTACH_FS */

	error = (*volfunc) (dp, name, hdr, last, rock);
	if (error < 0) {
	    return -1;
	}
	if (error) {
	    error = 2;
	}
    }

#ifdef AFS_DEMAND_ATTACH_FS
    if (error && !locked) {
	int code;
	/* retry reading the volume header under the partition
	 * header lock, just to be safe and ensure we're not
	 * racing something rewriting the vol header */
	code = VPartHeaderLock(dp, WRITE_LOCK);
	if (code) {
	    Log("Error acquiring partition write lock when "
		"looking at header %s\n", name);
	    return -1;
	}

	return _VHandleVolumeHeader(dp, volfunc, name, hdr, 1, rock);
    }
#endif /* AFS_DEMAND_ATTACH_FS */

    return error;
}