diff options
Diffstat (limited to 'src/libradosstriper/RadosStriperImpl.h')
-rw-r--r-- | src/libradosstriper/RadosStriperImpl.h | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/src/libradosstriper/RadosStriperImpl.h b/src/libradosstriper/RadosStriperImpl.h new file mode 100644 index 000000000..8226a9ba2 --- /dev/null +++ b/src/libradosstriper/RadosStriperImpl.h @@ -0,0 +1,276 @@ +// -*- 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) 2014 Sebastien Ponce <sebastien.ponce@cern.ch> + * + * 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_LIBRADOSSTRIPER_RADOSSTRIPERIMPL_H +#define CEPH_LIBRADOSSTRIPER_RADOSSTRIPERIMPL_H + +#include <string> + +#include <boost/intrusive_ptr.hpp> + +#include "include/rados/librados.h" +#include "include/rados/librados.hpp" +#include "include/radosstriper/libradosstriper.h" +#include "include/radosstriper/libradosstriper.hpp" +#include "MultiAioCompletionImpl.h" + +#include "librados/IoCtxImpl.h" +#include "librados/AioCompletionImpl.h" +#include "common/RefCountedObj.h" +#include "common/ceph_context.h" + +namespace libradosstriper { + +using MultiAioCompletionImplPtr = + boost::intrusive_ptr<MultiAioCompletionImpl>; + +struct RadosStriperImpl { + + /** + * exception wrapper around an error code + */ + struct ErrorCode { + ErrorCode(int error) : m_code(error) {}; + int m_code; + }; + + /* + * Constructor + * @param cluster_name name of the cluster, can be NULL + * @param client_name has 2 meanings depending on cluster_name + * - if cluster_name is null : this is the client id + * - else : this is the full client name in format type.id + */ + RadosStriperImpl(librados::IoCtx& ioctx, librados::IoCtxImpl *ioctx_impl); + /// Destructor + ~RadosStriperImpl() {}; + + // configuration + int setObjectLayoutStripeUnit(unsigned int stripe_unit); + int setObjectLayoutStripeCount(unsigned int stripe_count); + int setObjectLayoutObjectSize(unsigned int object_size); + + // xattrs + int getxattr(const object_t& soid, const char *name, bufferlist& bl); + int setxattr(const object_t& soid, const char *name, bufferlist& bl); + int getxattrs(const object_t& soid, map<string, bufferlist>& attrset); + int rmxattr(const object_t& soid, const char *name); + + // io + int write(const std::string& soid, const bufferlist& bl, size_t len, uint64_t off); + int append(const std::string& soid, const bufferlist& bl, size_t len); + int write_full(const std::string& soid, const bufferlist& bl); + int read(const std::string& soid, bufferlist* pbl, size_t len, uint64_t off); + + // asynchronous io + int aio_write(const std::string& soid, librados::AioCompletionImpl *c, + const bufferlist& bl, size_t len, uint64_t off); + int aio_append(const std::string& soid, librados::AioCompletionImpl *c, + const bufferlist& bl, size_t len); + int aio_write_full(const std::string& soid, librados::AioCompletionImpl *c, + const bufferlist& bl); + int aio_read(const std::string& soid, librados::AioCompletionImpl *c, + bufferlist* pbl, size_t len, uint64_t off); + int aio_read(const std::string& soid, librados::AioCompletionImpl *c, + char* buf, size_t len, uint64_t off); + int aio_flush(); + + // stat, deletion and truncation + int stat(const std::string& soid, uint64_t *psize, time_t *pmtime); + int stat2(const std::string& soid, uint64_t *psize, struct timespec *pts); + template<class TimeType> + struct StatFunction { + typedef int (librados::IoCtxImpl::*Type) (const object_t& oid, + librados::AioCompletionImpl *c, + uint64_t *psize, TimeType *pmtime); + }; + template<class TimeType> + int aio_generic_stat(const std::string& soid, librados::AioCompletionImpl *c, + uint64_t *psize, TimeType *pmtime, + typename StatFunction<TimeType>::Type statFunction); + int aio_stat(const std::string& soid, librados::AioCompletionImpl *c, + uint64_t *psize, time_t *pmtime); + int aio_stat2(const std::string& soid, librados::AioCompletionImpl *c, + uint64_t *psize, struct timespec *pts); + int remove(const std::string& soid, int flags=0); + int trunc(const std::string& soid, uint64_t size); + + // asynchronous remove. Note that the removal is not 100% parallelized : + // the removal of the first rados object of the striped object will be + // done via a syncrhonous call after the completion of all other removals. + // These are done asynchrounously and in parallel + int aio_remove(const std::string& soid, librados::AioCompletionImpl *c, int flags=0); + + // reference counting + void get() { + std::lock_guard l{lock}; + m_refCnt ++ ; + } + void put() { + bool deleteme = false; + lock.lock(); + m_refCnt --; + if (m_refCnt == 0) + deleteme = true; + cond.notify_all(); + lock.unlock(); + if (deleteme) + delete this; + } + + // objectid manipulation + std::string getObjectId(const object_t& soid, long long unsigned objectno); + + // opening and closing of striped objects + void unlockObject(const std::string& soid, + const std::string& lockCookie); + void aio_unlockObject(const std::string& soid, + const std::string& lockCookie, + librados::AioCompletion *c); + + // internal versions of IO method + int write_in_open_object(const std::string& soid, + const ceph_file_layout& layout, + const std::string& lockCookie, + const bufferlist& bl, + size_t len, + uint64_t off); + int aio_write_in_open_object(const std::string& soid, + librados::AioCompletionImpl *c, + const ceph_file_layout& layout, + const std::string& lockCookie, + const bufferlist& bl, + size_t len, + uint64_t off); + int internal_aio_write(const std::string& soid, + MultiAioCompletionImplPtr c, + const bufferlist& bl, + size_t len, + uint64_t off, + const ceph_file_layout& layout); + + int extract_uint32_attr(std::map<std::string, bufferlist> &attrs, + const std::string& key, + ceph_le32 *value); + + int extract_sizet_attr(std::map<std::string, bufferlist> &attrs, + const std::string& key, + size_t *value); + + int internal_get_layout_and_size(const std::string& oid, + ceph_file_layout *layout, + uint64_t *size); + + int internal_aio_remove(const std::string& soid, + MultiAioCompletionImplPtr multi_completion, + int flags=0); + + /** + * opens an existing striped object and takes a shared lock on it + * @return 0 if everything is ok and the lock was taken. -errcode otherwise + * In particulae, if the striped object does not exists, -ENOENT is returned + * In case the return code in not 0, no lock is taken + */ + int openStripedObjectForRead(const std::string& soid, + ceph_file_layout *layout, + uint64_t *size, + std::string *lockCookie); + + /** + * opens an existing striped object, takes a shared lock on it + * and sets its size to the size it will have after the write. + * In case the striped object does not exists, it will create it by + * calling createOrOpenStripedObject. + * @param layout this is filled with the layout of the file + * @param size new size of the file (together with isFileSizeAbsolute) + * In case of success, this is filled with the size of the file before the opening + * @param isFileSizeAbsolute if false, this means that the given size should + * be added to the current file size (append mode) + * @return 0 if everything is ok and the lock was taken. -errcode otherwise + * In case the return code in not 0, no lock is taken + */ + int openStripedObjectForWrite(const std::string& soid, + ceph_file_layout *layout, + uint64_t *size, + std::string *lockCookie, + bool isFileSizeAbsolute); + /** + * creates an empty striped object with the given size and opens it calling + * openStripedObjectForWrite, which implies taking a shared lock on it + * Also deals with the cases where the object was created in the mean time + * @param isFileSizeAbsolute if false, this means that the given size should + * be added to the current file size (append mode). This of course only makes + * sense in case the striped object already exists + * @return 0 if everything is ok and the lock was taken. -errcode otherwise + * In case the return code in not 0, no lock is taken + */ + int createAndOpenStripedObject(const std::string& soid, + ceph_file_layout *layout, + uint64_t size, + std::string *lockCookie, + bool isFileSizeAbsolute); + + /** + * truncates an object synchronously. Should only be called with size < original_size + */ + int truncate(const std::string& soid, + uint64_t original_size, + uint64_t size, + ceph_file_layout &layout); + + /** + * truncates an object asynchronously. Should only be called with size < original_size + * note that the method is not 100% asynchronous, only the removal of rados objects + * is, the (potential) truncation of the rados object residing just at the truncation + * point is synchronous for lack of asynchronous truncation in the rados layer + */ + int aio_truncate(const std::string& soid, + MultiAioCompletionImplPtr c, + uint64_t original_size, + uint64_t size, + ceph_file_layout &layout); + + /** + * grows an object (adding 0s). Should only be called with size > original_size + */ + int grow(const std::string& soid, + uint64_t original_size, + uint64_t size, + ceph_file_layout &layout); + + /** + * creates a unique identifier + */ + static std::string getUUID(); + + CephContext *cct() { + return (CephContext*)m_radosCluster.cct(); + } + + // reference counting + std::condition_variable cond; + int m_refCnt; + std::mutex lock; + + + // Context + librados::Rados m_radosCluster; + librados::IoCtx m_ioCtx; + librados::IoCtxImpl *m_ioCtxImpl; + + // Default layout + ceph_file_layout m_layout; +}; +} +#endif |