예제 #1
0
파일: farm.c 프로젝트: yaekumo/sheepdog
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;
}
예제 #2
0
파일: farm.c 프로젝트: yamt/sheepdog
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;
}