ssize_t ih_pread(int fd, void * buf, size_t count, afs_foff_t offset) { afs_foff_t code; code = OS_SEEK(fd, offset, 0); if (code < 0) return code; return OS_READ(fd, buf, count); }
/* fread for buffered I/O handles */ afs_sfsize_t stream_read(void *ptr, afs_fsize_t size, afs_fsize_t nitems, StreamHandle_t * streamP) { afs_fsize_t nbytes, bytesRead, bytesToRead; char *p; /* Need to seek before changing direction */ if (streamP->str_direction == STREAM_DIRECTION_NONE) { streamP->str_direction = STREAM_DIRECTION_READ; streamP->str_bufoff = 0; streamP->str_buflen = 0; } else { assert(streamP->str_direction == STREAM_DIRECTION_READ); } bytesRead = 0; nbytes = size * nitems; p = (char *)ptr; while (nbytes > 0 && !streamP->str_eof) { if (streamP->str_buflen == 0) { streamP->str_bufoff = 0; streamP->str_buflen = OS_READ(streamP->str_fd, streamP->str_buffer, STREAM_HANDLE_BUFSIZE); if (streamP->str_buflen < 0) { streamP->str_error = errno; streamP->str_buflen = 0; bytesRead = 0; break; } else if (streamP->str_buflen == 0) { streamP->str_eof = 1; break; } } bytesToRead = nbytes; if (bytesToRead > streamP->str_buflen) { bytesToRead = streamP->str_buflen; } memcpy(p, streamP->str_buffer + streamP->str_bufoff, bytesToRead); p += bytesToRead; streamP->str_bufoff += bytesToRead; streamP->str_buflen -= bytesToRead; bytesRead += bytesToRead; nbytes -= bytesToRead; } return (bytesRead / size); }
/** * 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; }