1 /* 2 Copyright 2013-2014 EditShare, 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 #include "common/platform.h" 21 22 #include <string.h> 23 #include <sys/stat.h> 24 #include <sys/types.h> 25 #include <unistd.h> 26 27 #include <string> 28 #include <utility> 29 #include <vector> 30 31 #include "common/chunk_with_address_and_label.h" 32 #include "common/exception.h" 33 #include "mount/group_cache.h" 34 #include "mount/lizard_client_context.h" 35 #include "mount/readdata_cache.h" 36 #include "mount/stat_defs.h" 37 #include "protocol/chunkserver_list_entry.h" 38 #include "protocol/lock_info.h" 39 #include "protocol/named_inode_entry.h" 40 41 namespace LizardClient { 42 43 typedef uint32_t Inode; 44 typedef uint32_t JobId; 45 typedef uint32_t NamedInodeOffset; 46 47 struct FsInitParams { 48 static constexpr const char *kDefaultSubfolder = "/"; 49 static constexpr bool kDefaultDoNotRememberPassword = false; 50 static constexpr bool kDefaultDelayedInit = false; 51 #ifdef _WIN32 52 static constexpr unsigned kDefaultReportReservedPeriod = 60; 53 #else 54 static constexpr unsigned kDefaultReportReservedPeriod = 30; 55 #endif 56 static constexpr unsigned kDefaultIoRetries = 30; 57 static constexpr unsigned kDefaultRoundTime = 200; 58 static constexpr unsigned kDefaultChunkserverConnectTo = 2000; 59 static constexpr unsigned kDefaultChunkserverReadTo = 2000; 60 static constexpr unsigned kDefaultChunkserverWaveReadTo = 500; 61 static constexpr unsigned kDefaultChunkserverTotalReadTo = 2000; 62 static constexpr unsigned kDefaultCacheExpirationTime = 300; 63 static constexpr unsigned kDefaultReadaheadMaxWindowSize = 16384; 64 static constexpr bool kDefaultPrefetchXorStripes = false; 65 66 static constexpr float kDefaultBandwidthOveruse = 1.0; 67 static constexpr unsigned kDefaultChunkserverWriteTo = 5000; 68 #ifdef _WIN32 69 static constexpr unsigned kDefaultWriteCacheSize = 50; 70 #else 71 static constexpr unsigned kDefaultWriteCacheSize = 0; 72 #endif 73 static constexpr unsigned kDefaultCachePerInodePercentage = 25; 74 static constexpr unsigned kDefaultWriteWorkers = 10; 75 static constexpr unsigned kDefaultWriteWindowSize = 15; 76 static constexpr unsigned kDefaultSymlinkCacheTimeout = 3600; 77 78 static constexpr bool kDefaultDebugMode = false; 79 static constexpr int kDefaultKeepCache = 0; 80 static constexpr double kDefaultDirentryCacheTimeout = 0.25; 81 static constexpr unsigned kDefaultDirentryCacheSize = 100000; 82 static constexpr double kDefaultEntryCacheTimeout = 0.0; 83 static constexpr double kDefaultAttrCacheTimeout = 1.0; 84 #ifdef __linux__ 85 static constexpr bool kDefaultMkdirCopySgid = true; 86 #else 87 static constexpr bool kDefaultMkdirCopySgid = false; 88 #endif 89 #if defined(DEFAULT_SUGID_CLEAR_MODE_EXT) 90 static constexpr SugidClearMode kDefaultSugidClearMode = SugidClearMode::kExt; 91 #elif defined(DEFAULT_SUGID_CLEAR_MODE_BSD) 92 static constexpr SugidClearMode kDefaultSugidClearMode = SugidClearMode::kBsd; 93 #elif defined(DEFAULT_SUGID_CLEAR_MODE_OSX) 94 static constexpr SugidClearMode kDefaultSugidClearMode = SugidClearMode::kOsx; 95 #else 96 static constexpr SugidClearMode kDefaultSugidClearMode = SugidClearMode::kNever; 97 #endif 98 static constexpr bool kDefaultUseRwLock = true; 99 static constexpr double kDefaultAclCacheTimeout = 1.0; 100 static constexpr unsigned kDefaultAclCacheSize = 1000; 101 static constexpr bool kDefaultVerbose = false; 102 103 // Thank you, GCC 4.6, for no delegating constructors FsInitParamsFsInitParams104 FsInitParams() 105 : bind_host(), host(), port(), meta(false), mountpoint(), subfolder(kDefaultSubfolder), 106 do_not_remember_password(kDefaultDoNotRememberPassword), delayed_init(kDefaultDelayedInit), 107 report_reserved_period(kDefaultReportReservedPeriod), 108 io_retries(kDefaultIoRetries), 109 chunkserver_round_time_ms(kDefaultRoundTime), 110 chunkserver_connect_timeout_ms(kDefaultChunkserverConnectTo), 111 chunkserver_wave_read_timeout_ms(kDefaultChunkserverWaveReadTo), 112 total_read_timeout_ms(kDefaultChunkserverTotalReadTo), 113 cache_expiration_time_ms(kDefaultCacheExpirationTime), 114 readahead_max_window_size_kB(kDefaultReadaheadMaxWindowSize), 115 prefetch_xor_stripes(kDefaultPrefetchXorStripes), 116 bandwidth_overuse(kDefaultBandwidthOveruse), 117 write_cache_size(kDefaultWriteCacheSize), 118 write_workers(kDefaultWriteWorkers), write_window_size(kDefaultWriteWindowSize), 119 chunkserver_write_timeout_ms(kDefaultChunkserverWriteTo), 120 cache_per_inode_percentage(kDefaultCachePerInodePercentage), 121 symlink_cache_timeout_s(kDefaultSymlinkCacheTimeout), 122 debug_mode(kDefaultDebugMode), keep_cache(kDefaultKeepCache), 123 direntry_cache_timeout(kDefaultDirentryCacheTimeout), direntry_cache_size(kDefaultDirentryCacheSize), 124 entry_cache_timeout(kDefaultEntryCacheTimeout), attr_cache_timeout(kDefaultAttrCacheTimeout), 125 mkdir_copy_sgid(kDefaultMkdirCopySgid), sugid_clear_mode(kDefaultSugidClearMode), 126 use_rw_lock(kDefaultUseRwLock), 127 acl_cache_timeout(kDefaultAclCacheTimeout), acl_cache_size(kDefaultAclCacheSize), 128 verbose(kDefaultVerbose) { 129 } 130 FsInitParamsFsInitParams131 FsInitParams(const std::string &bind_host, const std::string &host, const std::string &port, const std::string &mountpoint) 132 : bind_host(bind_host), host(host), port(port), meta(false), mountpoint(mountpoint), subfolder(kDefaultSubfolder), 133 do_not_remember_password(kDefaultDoNotRememberPassword), delayed_init(kDefaultDelayedInit), 134 report_reserved_period(kDefaultReportReservedPeriod), 135 io_retries(kDefaultIoRetries), 136 chunkserver_round_time_ms(kDefaultRoundTime), 137 chunkserver_connect_timeout_ms(kDefaultChunkserverConnectTo), 138 chunkserver_wave_read_timeout_ms(kDefaultChunkserverWaveReadTo), 139 total_read_timeout_ms(kDefaultChunkserverTotalReadTo), 140 cache_expiration_time_ms(kDefaultCacheExpirationTime), 141 readahead_max_window_size_kB(kDefaultReadaheadMaxWindowSize), 142 prefetch_xor_stripes(kDefaultPrefetchXorStripes), 143 bandwidth_overuse(kDefaultBandwidthOveruse), 144 write_cache_size(kDefaultWriteCacheSize), 145 write_workers(kDefaultWriteWorkers), write_window_size(kDefaultWriteWindowSize), 146 chunkserver_write_timeout_ms(kDefaultChunkserverWriteTo), 147 cache_per_inode_percentage(kDefaultCachePerInodePercentage), 148 symlink_cache_timeout_s(kDefaultSymlinkCacheTimeout), 149 debug_mode(kDefaultDebugMode), keep_cache(kDefaultKeepCache), 150 direntry_cache_timeout(kDefaultDirentryCacheTimeout), direntry_cache_size(kDefaultDirentryCacheSize), 151 entry_cache_timeout(kDefaultEntryCacheTimeout), attr_cache_timeout(kDefaultAttrCacheTimeout), 152 mkdir_copy_sgid(kDefaultMkdirCopySgid), sugid_clear_mode(kDefaultSugidClearMode), 153 use_rw_lock(kDefaultUseRwLock), 154 acl_cache_timeout(kDefaultAclCacheTimeout), acl_cache_size(kDefaultAclCacheSize), 155 verbose(kDefaultVerbose) { 156 } 157 158 std::string bind_host; 159 std::string host; 160 std::string port; 161 bool meta; 162 std::string mountpoint; 163 std::string subfolder; 164 std::vector<uint8_t> password_digest; 165 bool do_not_remember_password; 166 bool delayed_init; 167 unsigned report_reserved_period; 168 169 unsigned io_retries; 170 unsigned chunkserver_round_time_ms; 171 unsigned chunkserver_connect_timeout_ms; 172 unsigned chunkserver_wave_read_timeout_ms; 173 unsigned total_read_timeout_ms; 174 unsigned cache_expiration_time_ms; 175 unsigned readahead_max_window_size_kB; 176 bool prefetch_xor_stripes; 177 double bandwidth_overuse; 178 179 unsigned write_cache_size; 180 unsigned write_workers; 181 unsigned write_window_size; 182 unsigned chunkserver_write_timeout_ms; 183 unsigned cache_per_inode_percentage; 184 unsigned symlink_cache_timeout_s; 185 186 bool debug_mode; 187 // NOTICE(sarna): This variable can hold more values than 0-1, don't change it to bool ever. 188 int keep_cache; 189 double direntry_cache_timeout; 190 unsigned direntry_cache_size; 191 double entry_cache_timeout; 192 double attr_cache_timeout; 193 bool mkdir_copy_sgid; 194 SugidClearMode sugid_clear_mode; 195 bool use_rw_lock; 196 double acl_cache_timeout; 197 unsigned acl_cache_size; 198 199 bool verbose; 200 201 std::string io_limits_config_file; 202 }; 203 204 /** 205 * A class that is used for passing information between subsequent calls to the filesystem. 206 * It is created when a file is opened, updated with every use of the file descriptor and 207 * removed when a file is closed. 208 */ 209 struct FileInfo { FileInfoFileInfo210 FileInfo() : flags(), direct_io(), keep_cache(), fh(), lock_owner() {} 211 FileInfoFileInfo212 FileInfo(int flags, unsigned int direct_io, unsigned int keep_cache, uint64_t fh, 213 uint64_t lock_owner) 214 : flags(flags), 215 direct_io(direct_io), 216 keep_cache(keep_cache), 217 fh(fh), 218 lock_owner(lock_owner) { 219 } 220 221 FileInfo(const FileInfo &other) = default; 222 FileInfo(FileInfo &&other) = default; 223 224 FileInfo &operator=(const FileInfo &other) = default; 225 FileInfo &operator=(FileInfo &&other) = default; 226 isValidFileInfo227 bool isValid() const { 228 return fh; 229 } 230 resetFileInfo231 void reset() { 232 *this = FileInfo(); 233 } 234 235 int flags; 236 unsigned int direct_io : 1; 237 unsigned int keep_cache : 1; 238 uint64_t fh; 239 uint64_t lock_owner; 240 }; 241 242 /** 243 * Directory entry parameters, a result of some filesystem operations (lookup, mkdir, 244 * link etc.). 245 */ 246 struct EntryParam { EntryParamEntryParam247 EntryParam() : ino(0), generation(0), attr_timeout(0), entry_timeout(0) { 248 memset(&attr, 0, sizeof(struct stat)); 249 } 250 251 Inode ino; 252 unsigned long generation; 253 struct stat attr; 254 double attr_timeout; 255 double entry_timeout; 256 }; 257 258 /** 259 * A result of setattr and getattr operations 260 */ 261 struct AttrReply { 262 struct stat attr; 263 double attrTimeout; 264 }; 265 266 /** 267 * A result of readdir operation 268 */ 269 struct DirEntry { 270 std::string name; 271 struct stat attr; 272 off_t nextEntryOffset; 273 DirEntryDirEntry274 DirEntry(const std::string n, const struct stat &s, off_t o) : name(n), attr(s), nextEntryOffset(o) {} 275 }; 276 277 /** 278 * A result of getxattr, setxattr and listattr operations 279 */ 280 struct XattrReply { 281 uint32_t valueLength; 282 std::vector<uint8_t> valueBuffer; 283 }; 284 285 /** 286 * An exception that is thrown when a request can't be executed successfully 287 */ 288 struct RequestException : public std::exception { 289 explicit RequestException(int error_code); 290 291 int system_error_code; 292 int lizardfs_error_code; 293 }; 294 295 void updateGroups(Context &ctx); 296 297 // TODO what about this one? Will decide when writing non-fuse client 298 // void fsinit(void *userdata, struct fuse_conn_info *conn); 299 bool isSpecialInode(LizardClient::Inode ino); 300 301 EntryParam lookup(const Context &ctx, Inode parent, const char *name); 302 303 AttrReply getattr(const Context &ctx, Inode ino); 304 305 #define LIZARDFS_SET_ATTR_MODE (1 << 0) 306 #define LIZARDFS_SET_ATTR_UID (1 << 1) 307 #define LIZARDFS_SET_ATTR_GID (1 << 2) 308 #define LIZARDFS_SET_ATTR_SIZE (1 << 3) 309 #define LIZARDFS_SET_ATTR_ATIME (1 << 4) 310 #define LIZARDFS_SET_ATTR_MTIME (1 << 5) 311 #define LIZARDFS_SET_ATTR_ATIME_NOW (1 << 7) 312 #define LIZARDFS_SET_ATTR_MTIME_NOW (1 << 8) 313 AttrReply setattr(const Context &ctx, Inode ino, struct stat *stbuf, int to_set); 314 315 std::string readlink(const Context &ctx, Inode ino); 316 317 EntryParam mknod(const Context &ctx, Inode parent, const char *name, mode_t mode, dev_t rdev); 318 319 EntryParam mkdir(const Context &ctx, Inode parent, const char *name, mode_t mode); 320 321 void unlink(const Context &ctx, Inode parent, const char *name); 322 323 void undel(const Context &ctx, Inode ino); 324 325 void rmdir(const Context &ctx, Inode parent, const char *name); 326 327 EntryParam symlink(const Context &ctx, const char *link, Inode parent, const char *name); 328 329 void rename(const Context &ctx, Inode parent, const char *name, Inode newparent, const char *newname); 330 331 EntryParam link(const Context &ctx, Inode ino, Inode newparent, const char *newname); 332 333 void open(const Context &ctx, Inode ino, FileInfo* fi); 334 335 std::vector<uint8_t> read_special_inode(const Context &ctx, Inode ino, size_t size, off_t off, 336 FileInfo* fi); 337 338 ReadCache::Result read(const Context &ctx, Inode ino, size_t size, off_t off, FileInfo* fi); 339 340 typedef size_t BytesWritten; 341 BytesWritten write(const Context &ctx, Inode ino, const char *buf, size_t size, off_t off, 342 FileInfo* fi); 343 344 void flush(const Context &ctx, Inode ino, FileInfo* fi); 345 346 void release(Inode ino, FileInfo* fi); 347 348 void fsync(const Context &ctx, Inode ino, int datasync, FileInfo* fi); 349 350 void opendir(const Context &ctx, Inode ino); 351 352 std::vector<DirEntry> readdir(const Context &ctx, Inode ino, off_t off, size_t max_entries); 353 354 std::vector<NamedInodeEntry> readreserved(const Context &ctx, NamedInodeOffset offset, NamedInodeOffset max_entries); 355 356 std::vector<NamedInodeEntry> readtrash(const Context &ctx, NamedInodeOffset offset, NamedInodeOffset max_entries); 357 358 void releasedir(Inode ino); 359 360 struct statvfs statfs(const Context &ctx, Inode ino); 361 362 void setxattr(const Context &ctx, Inode ino, const char *name, const char *value, 363 size_t size, int flags, uint32_t position); 364 365 XattrReply getxattr(const Context &ctx, Inode ino, const char *name, size_t size, uint32_t position); 366 367 XattrReply listxattr(const Context &ctx, Inode ino, size_t size); 368 369 void removexattr(const Context &ctx, Inode ino, const char *name); 370 371 void access(const Context &ctx, Inode ino, int mask); 372 373 EntryParam create(const Context &ctx, Inode parent, const char *name, 374 mode_t mode, FileInfo* fi); 375 376 void getlk(const Context &ctx, Inode ino, FileInfo* fi, struct lzfs_locks::FlockWrapper &lock); 377 uint32_t setlk_send(const Context &ctx, Inode ino, FileInfo* fi, struct lzfs_locks::FlockWrapper &lock); 378 void setlk_recv(); 379 uint32_t flock_send(const Context &ctx, Inode ino, FileInfo* fi, int op); 380 void flock_recv(); 381 382 void flock_interrupt(const lzfs_locks::InterruptData &data); 383 void setlk_interrupt(const lzfs_locks::InterruptData &data); 384 385 void remove_file_info(FileInfo *f); 386 void remove_dir_info(FileInfo *f); 387 388 JobId makesnapshot(const Context &ctx, Inode ino, Inode dst_parent, const std::string &dst_name, 389 bool can_overwrite); 390 std::string getgoal(const Context &ctx, Inode ino); 391 void setgoal(const Context &ctx, Inode ino, const std::string &goal_name, uint8_t smode); 392 393 void statfs(uint64_t *totalspace, uint64_t *availspace, uint64_t *trashspace, uint64_t *reservedspace, uint32_t *inodes); 394 395 std::vector<ChunkWithAddressAndLabel> getchunksinfo(const Context &ctx, Inode ino, 396 uint32_t chunk_index, uint32_t chunk_count); 397 398 std::vector<ChunkserverListEntry> getchunkservers(); 399 400 void fs_init(FsInitParams ¶ms); 401 void fs_term(); 402 403 } 404