static int farm_read(uint64_t oid, struct siocb *iocb) { int i; if (iocb->epoch < sys->epoch) { void *buffer; buffer = read_working_object(oid, iocb->length); if (!buffer) { /* Here if read the object from the targeted epoch failed, * we need to read from the later epoch, because at some epoch * we doesn't write the object to the snapshot, we assume * it in the current local object directory, but maybe * in the next epoch we removed it from the local directory. * in this case, we should try to retrieve object upwards, since. * when the object is to be removed, it will get written to the * snapshot at later epoch. */ for (i = iocb->epoch; i < sys->epoch; i++) { buffer = retrieve_object_from_snap(oid, i); if (buffer) break; } } if (!buffer) return SD_RES_NO_OBJ; memcpy(iocb->buf, buffer, iocb->length); free(buffer); } else { ssize_t size = xpread(iocb->fd, iocb->buf, iocb->length, iocb->offset); if (size != iocb->length) return SD_RES_EIO; } return SD_RES_SUCCESS; }
static int farm_read(uint64_t oid, struct siocb *iocb) { int flags = def_open_flags, fd, ret = SD_RES_SUCCESS; uint32_t epoch = sys_epoch(); char path[PATH_MAX]; ssize_t size; int i; void *buffer; if (iocb->epoch < epoch) { buffer = read_working_object(oid, iocb->offset, iocb->length); if (!buffer) { /* Here if read the object from the targeted epoch failed, * we need to read from the later epoch, because at some epoch * we doesn't write the object to the snapshot, we assume * it in the current local object directory, but maybe * in the next epoch we removed it from the local directory. * in this case, we should try to retrieve object upwards, since. * when the object is to be removed, it will get written to the * snapshot at later epoch. */ for (i = iocb->epoch; i < epoch; i++) { buffer = retrieve_object_from_snap(oid, i); if (buffer) break; } } if (!buffer) return SD_RES_NO_OBJ; memcpy(iocb->buf, buffer, iocb->length); free(buffer); return SD_RES_SUCCESS; } if (!is_data_obj(oid)) flags &= ~O_DIRECT; sprintf(path, "%s%016"PRIx64, obj_path, oid); fd = open(path, flags); if (fd < 0) return err_to_sderr(oid, errno); if (flock(fd, LOCK_SH) < 0) { ret = SD_RES_EIO; eprintf("%m\n"); goto out; } size = xpread(fd, iocb->buf, iocb->length, iocb->offset); if (flock(fd, LOCK_UN) < 0) { ret = SD_RES_EIO; eprintf("%m\n"); goto out; } if (size != iocb->length) { ret = SD_RES_EIO; goto out; } out: close(fd); return ret; }