--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2015 XSky <haomai@xsky.com>
+ *
+ * Author: Haomai Wang <haomaiwang@gmail.com>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef CEPH_COMMON_ALIGN_H
+#define CEPH_COMMON_ALIGN_H
+
+template <typename T>
+inline constexpr T align_up(T v, T align) {
+ return (v + align - 1) & ~(align - 1);
+}
+
+template <typename T>
+inline constexpr T align_down(T v, T align) {
+ return v & ~(align - 1);
+}
+
+#endif /* CEPH_COMMON_ALIGN_H */
virtual int read(uint64_t off, uint64_t len, bufferlist *pbl,
IOContext *ioc, bool buffered) = 0;
+ virtual int read_buffered(uint64_t off, uint64_t len, char *buf) = 0;
virtual int aio_write(uint64_t off, bufferlist& bl,
IOContext *ioc, bool buffered) = 0;
#include "include/stringify.h"
#include "include/types.h"
#include "include/compat.h"
+#include "common/align.h"
#include "common/errno.h"
#include "common/debug.h"
#include "common/Initialize.h"
{
zeros = buffer::create_page_aligned(1048576);
zeros.zero();
-
}
return r;
}
+int NVMEDevice::read_buffered(uint64_t off, uint64_t len, char *buf)
+{
+ dout(5) << __func__ << " " << off << "~" << len << dendl;
+ assert(len > 0);
+ assert(off < size);
+ assert(off + len <= size);
+
+ uint64_t aligned_off = align_down(off, block_size);
+ uint64_t aligned_len = align_up(len, block_size);
+ IOContext ioc(nullptr);
+ Task *t;
+ int r = rte_mempool_get(task_pool, (void **)&t);
+ if (r < 0) {
+ derr << __func__ << " task_pool rte_mempool_get failed" << dendl;
+ return r;
+ }
+ t->start = ceph_clock_now(g_ceph_context);
+ t->buf = rte_malloc(NULL, aligned_len, block_size);
+ if (t->buf == NULL) {
+ derr << __func__ << " task->buf rte_malloc failed" << dendl;
+ r = -ENOMEM;
+ goto out;
+ }
+ t->ctx = ioc;
+ t->command = IOCommand::READ_COMMAND;
+ t->offset = aligned_off;
+ t->len = aligned_len;
+ t->device = this;
+ t->return_code = 1;
+ t->next = t->prev = nullptr;
+ ioc->num_reading.inc();;
+ {
+ Mutex::Locker l(queue_lock);
+ task_queue.push(t);
+ if (queue_empty.read()) {
+ queue_empty.dec();
+ queue_cond.Signal();
+ }
+ }
+
+ {
+ Mutex::Locker l(ioc->lock);
+ while (t->return_code > 0)
+ ioc->cond.Wait(ioc->lock);
+ }
+ memcpy(buf, t->buf+off-aligned_off, len);
+ r = t->return_code;
+ rte_free(t->buf);
+
+ return r;
+}
+
int NVMEDevice::invalidate_cache(uint64_t off, uint64_t len)
{
dout(5) << __func__ << " " << off << "~" << len << dendl;
int aio_zero(uint64_t off, uint64_t len,
IOContext *ioc) override;
int flush() override;
+ int read_buffered(uint64_t off, uint64_t len, char *buf) override;
// for managing buffered readers/writers
int invalidate_cache(uint64_t off, uint64_t len) override;