1 /* 2 Copyright 2013-2015 Skytechnology sp. z o.o. 3 4 This file is part of LizardFS. 5 6 LizardFS is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, version 3. 9 10 LizardFS is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with LizardFS. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #pragma once 20 21 #include "common/platform.h" 22 23 #include <cstdint> 24 #include <memory> 25 #include <mutex> 26 #include <vector> 27 28 #include "common/chunk_type_with_address.h" 29 #include "common/slogger.h" 30 31 struct ChunkLocationInfo { 32 typedef std::vector<ChunkTypeWithAddress> ChunkLocations; 33 34 uint64_t chunkId; 35 uint32_t version; 36 uint64_t fileLength; 37 ChunkLocations locations; 38 ChunkLocationInfoChunkLocationInfo39 ChunkLocationInfo() 40 : chunkId(0), 41 version(0), 42 fileLength(0) { 43 } 44 ChunkLocationInfoChunkLocationInfo45 ChunkLocationInfo( 46 const uint64_t chunkId, 47 const uint32_t version, 48 const uint64_t fileLength, 49 const ChunkLocations locations) : 50 chunkId(chunkId), 51 version(version), 52 fileLength(fileLength), 53 locations(locations) { 54 } 55 isEmptyChunkChunkLocationInfo56 bool isEmptyChunk() const { 57 return chunkId == 0; 58 } 59 }; 60 61 // Intended to be instantiated per descriptor. 62 // May cache locations of previously queried chunks. 63 // Thread safe. 64 class ReadChunkLocator { 65 public: 66 ReadChunkLocator(const ReadChunkLocator&) = delete; ReadChunkLocator()67 ReadChunkLocator() {} 68 69 std::shared_ptr<const ChunkLocationInfo> locateChunk(uint32_t inode, uint32_t index); 70 void invalidateCache(uint32_t inode, uint32_t index); 71 72 private: 73 uint32_t inode_; 74 uint32_t index_; 75 76 std::shared_ptr<const ChunkLocationInfo> cache_; 77 std::mutex mutex_; 78 }; 79 80 class WriteChunkLocator { 81 public: WriteChunkLocator()82 WriteChunkLocator() : inode_(0), index_(0), lockId_(0) {} 83 ~WriteChunkLocator()84 virtual ~WriteChunkLocator() { 85 try { 86 if (lockId_) { 87 unlockChunk(); 88 } 89 } catch (Exception& ex) { 90 lzfs_pretty_syslog(LOG_WARNING, 91 "unlocking chunk error, inode: %" PRIu32 ", index: %" PRIu32 " - %s", 92 inode_, index_, ex.what()); 93 } 94 } 95 96 virtual void locateAndLockChunk(uint32_t inode, uint32_t index); 97 virtual void unlockChunk(); 98 chunkIndex()99 uint32_t chunkIndex() { 100 return index_; 101 } 102 updateFileLength(uint64_t fileLength)103 void updateFileLength(uint64_t fileLength) { 104 locationInfo_. fileLength = fileLength; 105 } 106 locationInfo()107 const ChunkLocationInfo& locationInfo() const { 108 return locationInfo_; 109 } 110 111 protected: WriteChunkLocator(uint32_t inode,uint32_t index,uint32_t lockId)112 WriteChunkLocator(uint32_t inode, uint32_t index, uint32_t lockId) 113 : inode_(inode), 114 index_(index), 115 lockId_(lockId) { 116 } 117 118 uint32_t inode_; 119 uint32_t index_; 120 uint32_t lockId_; 121 ChunkLocationInfo locationInfo_; 122 }; 123 124 // Fit for truncating xor chunks down when master, not client, locks a chunk 125 class TruncateWriteChunkLocator : public WriteChunkLocator { 126 public: 127 // Locator is created for single operation TruncateWriteChunkLocator(uint32_t inode,uint32_t index,uint32_t lockId)128 explicit TruncateWriteChunkLocator(uint32_t inode, uint32_t index, uint32_t lockId) 129 : WriteChunkLocator(inode, index, lockId) { 130 } 131 ~TruncateWriteChunkLocator()132 ~TruncateWriteChunkLocator() { 133 // Remove information about the lock to prevent ~WriteChunkLocator from unlocking the chunk 134 lockId_ = 0; 135 } 136 137 // In this case a chunk is unlocked by master so this locator will be simply destroyed unlockChunk()138 void unlockChunk() {} 139 }; 140