CernVM-FS  2.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
directory_entry.h
Go to the documentation of this file.
1 
8 #ifndef CVMFS_DIRECTORY_ENTRY_H_
9 #define CVMFS_DIRECTORY_ENTRY_H_
10 
11 #include <sys/types.h>
12 
13 #include <cassert>
14 #include <cstring>
15 #include <string>
16 #include <vector>
17 
18 #include "bigvector.h"
20 #include "crypto/hash.h"
21 #include "shortstring.h"
22 #include "util/platform.h"
23 
24 namespace publish {
25 class SyncItem;
26 class SyncItemNative;
27 class SyncItemTar;
28 class SyncItemDummyDir;
30 }
31 namespace swissknife {
32 class CommandMigrate;
33 }
34 
35 namespace catalog {
36 
37 // Create DirectoryEntries for unit test purposes.
38 class DirectoryEntryTestFactory;
39 
40 class MockCatalogManager;
41 class Catalog;
42 class WritableCatalogManager;
43 
44 template <class CatalogMgrT>
46 typedef uint64_t inode_t;
47 
51 };
52 
60  // For testing the catalog balancing
61  friend class CatalogBalancer<MockCatalogManager>;
62  // Create .cvmfscatalog and .cvmfsautocatalog files
64  // Simplify creation of DirectoryEntry objects for write back
65  friend class publish::SyncItem;
67  friend class publish::SyncItemTar;
70  // Simplify file system like _touch_ of DirectoryEntry objects
71  friend class SqlDirentTouch;
72  // Allow creation of virtual directories and files
73  friend class VirtualCatalog;
74 
75  public:
76  static const inode_t kInvalidInode = 0;
77 
83  struct Difference {
84  static const unsigned int kIdentical = 0x00000;
85  static const unsigned int kName = 0x00001;
86  static const unsigned int kLinkcount = 0x00002;
87  static const unsigned int kSize = 0x00004;
88  static const unsigned int kMode = 0x00008;
89  static const unsigned int kMtime = 0x00010;
90  static const unsigned int kSymlink = 0x00020;
91  static const unsigned int kChecksum = 0x00040;
92  static const unsigned int kHardlinkGroup = 0x00080;
93  static const unsigned int kNestedCatalogTransitionFlags = 0x00100;
94  static const unsigned int kChunkedFileFlag = 0x00200;
95  static const unsigned int kHasXattrsFlag = 0x00400;
96  static const unsigned int kExternalFileFlag = 0x00800;
97  static const unsigned int kBindMountpointFlag = 0x01000;
98  static const unsigned int kHiddenFlag = 0x02000;
99  static const unsigned int kDirectIoFlag = 0x04000;
100  static const unsigned int kUid = 0x08000;
101  static const unsigned int kGid = 0x10000;
102  };
103  typedef unsigned int Differences;
104 
110  , mode_(0)
111  , uid_(0)
112  , gid_(0)
113  , size_(0)
114  , mtime_(0)
115  , mtime_ns_(-1)
116  , linkcount_(1) // generally a normal file has linkcount 1 -> default
117  , has_xattrs_(false)
118  , is_external_file_(false)
119  , is_direct_io_(false)
121  { }
122 
123  inline bool IsRegular() const { return S_ISREG(mode_); }
124  inline bool IsLink() const { return S_ISLNK(mode_); }
125  inline bool IsDirectory() const { return S_ISDIR(mode_); }
126  inline bool IsFifo() const { return S_ISFIFO(mode_); }
127  inline bool IsSocket() const { return S_ISSOCK(mode_); }
128  inline bool IsCharDev() const { return S_ISCHR(mode_); }
129  inline bool IsBlockDev() const { return S_ISBLK(mode_); }
130  inline bool IsSpecial() const {
131  return IsFifo() || IsSocket() || IsCharDev() || IsBlockDev();
132  }
133  inline bool IsExternalFile() const { return is_external_file_; }
134  inline bool IsDirectIo() const { return is_direct_io_; }
135  inline bool HasXattrs() const { return has_xattrs_; }
136  inline bool HasMtimeNs() const { return mtime_ns_ >= 0; }
137 
138  inline inode_t inode() const { return inode_; }
139  inline uint32_t linkcount() const { return linkcount_; }
140  inline NameString name() const { return name_; }
141  inline LinkString symlink() const { return symlink_; }
142  inline time_t mtime() const { return mtime_; }
143  inline int32_t mtime_ns() const { return mtime_ns_; }
144  inline unsigned int mode() const { return mode_; }
145  inline uid_t uid() const { return uid_; }
146  inline gid_t gid() const { return gid_; }
147  inline shash::Any checksum() const { return checksum_; }
148  inline const shash::Any *checksum_ptr() const { return &checksum_; }
150  return checksum_.algorithm;
151  }
152  inline uint64_t size() const {
153  if (IsLink())
154  return symlink().GetLength();
155  if (IsBlockDev() || IsCharDev())
156  return 0;
157  return size_;
158  }
159  inline dev_t rdev() const {
160  if (IsBlockDev() || IsCharDev())
161  return size_;
162  return 1;
163  }
164  inline std::string GetFullPath(const std::string &parent_directory) const {
165  std::string file_path = parent_directory + "/";
166  file_path.append(name().GetChars(), name().GetLength());
167  return file_path;
168  }
169 
170  inline void set_inode(const inode_t inode) { inode_ = inode; }
171  inline void set_linkcount(const uint32_t linkcount) {
172  assert(linkcount > 0);
174  }
175  inline void set_symlink(const LinkString &symlink) {
176  symlink_ = symlink;
177  }
178  inline void set_has_xattrs(const bool has_xattrs) {
179  has_xattrs_ = has_xattrs;
180  }
181 
183  return compression_algorithm_;
184  }
185 
190  inline struct stat GetStatStructure() const {
191  struct stat s;
192  memset(&s, 0, sizeof(s));
193  s.st_dev = 1;
194  s.st_ino = inode_;
195  s.st_mode = mode_;
196  s.st_nlink = linkcount();
197  s.st_uid = uid();
198  s.st_gid = gid();
199  s.st_rdev = rdev();
200  s.st_size = static_cast<off_t>(size());
201  s.st_blksize = 4096; // will be ignored by Fuse
202  s.st_blocks = static_cast<blkcnt_t>(1 + size() / 512);
203  s.st_atime = mtime_;
204  s.st_mtime = mtime_;
205  s.st_ctime = mtime_;
206  if (HasMtimeNs()) {
207 #ifdef __APPLE__
208  s.st_atimespec.tv_nsec = mtime_ns_;
209  s.st_mtimespec.tv_nsec = mtime_ns_;
210  s.st_ctimespec.tv_nsec = mtime_ns_;
211 #else
212  s.st_atim.tv_nsec = mtime_ns_;
213  s.st_mtim.tv_nsec = mtime_ns_;
214  s.st_ctim.tv_nsec = mtime_ns_;
215 #endif
216  }
217  return s;
218  }
219 
220  Differences CompareTo(const DirectoryEntryBase &other) const;
221  inline bool operator ==(const DirectoryEntryBase &other) const {
222  return CompareTo(other) == Difference::kIdentical;
223  }
224  inline bool operator !=(const DirectoryEntryBase &other) const {
225  return !(*this == other);
226  }
227 
228  protected:
229  // Inodes are generated based on the rowid of the entry in the file catalog.
231 
232  // Data from struct stat
234  unsigned int mode_;
235  uid_t uid_;
236  gid_t gid_;
237  uint64_t size_;
238  time_t mtime_;
239  // nanosecond part of the mtime. Only valid if non-negative
240  int32_t mtime_ns_;
242  uint32_t linkcount_;
243  // In order to save memory, we only indicate if a directory entry has custom
244  // extended attributes. Another call to the file catalog is necessary to
245  // get them.
247 
248  // The cryptographic hash is not part of the file system intrinsics, though
249  // it can be computed just using the file contents. We therefore put it in
250  // this base class.
252 
255 
256  // The compression algorithm
258 };
259 
260 
272  // Simplify creation of DirectoryEntry objects
273  friend class SqlLookup;
274  // Simplify write of DirectoryEntry objects in database
275  friend class SqlDirentWrite;
276  // For fixing DirectoryEntry glitches
278  // TODO(rmeusel): remove this dependency
280  // Create DirectoryEntries for unit test purposes.
282 
283  public:
291  inline explicit DirectoryEntry(const DirectoryEntryBase& base)
292  : DirectoryEntryBase(base)
293  , hardlink_group_(0)
294  , is_nested_catalog_root_(false)
296  , is_bind_mountpoint_(false)
297  , is_chunked_file_(false)
298  , is_hidden_(false)
299  , is_negative_(false) { }
300 
301  inline DirectoryEntry()
302  : hardlink_group_(0)
303  , is_nested_catalog_root_(false)
305  , is_bind_mountpoint_(false)
306  , is_chunked_file_(false)
307  , is_hidden_(false)
308  , is_negative_(false) { }
309 
310  inline explicit DirectoryEntry(SpecialDirents special_type)
311  : hardlink_group_(0)
312  , is_nested_catalog_root_(false)
314  , is_bind_mountpoint_(false)
315  , is_chunked_file_(false)
316  , is_hidden_(false)
317  , is_negative_(true) { assert(special_type == kDirentNegative); }
318 
319  inline SpecialDirents GetSpecial() const {
321  }
322 
323  Differences CompareTo(const DirectoryEntry &other) const;
324  inline bool operator ==(const DirectoryEntry &other) const {
325  return CompareTo(other) == Difference::kIdentical;
326  }
327  inline bool operator !=(const DirectoryEntry &other) const {
328  return !(*this == other);
329  }
330 
331  inline bool IsNegative() const { return is_negative_; }
332  inline bool IsNestedCatalogRoot() const { return is_nested_catalog_root_; }
333  inline bool IsNestedCatalogMountpoint() const {
335  }
336  inline bool IsBindMountpoint() const { return is_bind_mountpoint_; }
337  inline bool IsChunkedFile() const { return is_chunked_file_; }
338  inline bool IsHidden() const { return is_hidden_; }
339  inline uint32_t hardlink_group() const { return hardlink_group_; }
340 
341  inline void set_hardlink_group(const uint32_t group) {
342  hardlink_group_ = group;
343  }
344  inline void set_is_nested_catalog_mountpoint(const bool val) {
346  }
347  inline void set_is_nested_catalog_root(const bool val) {
349  }
350  inline void set_is_bind_mountpoint(const bool val) {
351  is_bind_mountpoint_ = val;
352  }
353  inline void set_is_chunked_file(const bool val) {
354  is_chunked_file_ = val;
355  }
356  inline void set_is_hidden(const bool val) {
357  is_hidden_ = val;
358  }
359 
360  private:
365  uint32_t hardlink_group_;
366 
367  // TODO(jblomer): transform into bitfield to save memory
374 };
375 
376 
380 struct StatEntry {
382  struct stat info;
383 
384  StatEntry() { memset(&info, 0, sizeof(info)); }
385  StatEntry(const NameString &n, const struct stat &i) : name(n), info(i) { }
386 };
387 
388 
389 typedef std::vector<DirectoryEntry> DirectoryEntryList;
390 typedef std::vector<DirectoryEntryBase> DirectoryEntryBaseList;
391 // TODO(jblomer): use mmap for large listings
393 
394 } // namespace catalog
395 
396 #endif // CVMFS_DIRECTORY_ENTRY_H_
uint32_t linkcount() const
static const unsigned int kHardlinkGroup
bool IsExternalFile() const
void set_is_bind_mountpoint(const bool val)
struct stat info
DirectoryEntry(SpecialDirents special_type)
bool IsSpecial() const
Differences CompareTo(const DirectoryEntry &other) const
BigVector< StatEntry > StatEntryList
static const unsigned int kHiddenFlag
time_t mtime() const
void set_is_chunked_file(const bool val)
void set_inode(const inode_t inode)
bool IsDirectory() const
static const unsigned int kChecksum
bool IsSocket() const
bool IsHidden() const
bool HasMtimeNs() const
bool IsChunkedFile() const
inode_t inode_
bool is_hidden_
SpecialDirents GetSpecial() const
uint64_t size() const
static const unsigned int kGid
void set_linkcount(const uint32_t linkcount)
DirectoryEntryBase()
void set_is_nested_catalog_root(const bool val)
gid_t gid_
void set_symlink(const LinkString &symlink)
NameString name
static const unsigned int kDirectIoFlag
inode_t inode() const
uint64_t inode_t
assert((mem||(size==0))&&"Out Of Memory")
int32_t mtime_ns_
bool IsDirectIo() const
Algorithms algorithm
Definition: hash.h:125
shash::Any checksum() const
bool has_xattrs_
unsigned int mode() const
uint64_t size_
bool IsNestedCatalogMountpoint() const
Algorithms
Definition: hash.h:41
bool IsNestedCatalogRoot() const
NameString name_
std::vector< DirectoryEntry > DirectoryEntryList
zlib::Algorithms compression_algorithm_
NameString name() const
StatEntry()
bool IsLink() const
Algorithms
Definition: compression.h:44
static const unsigned int kExternalFileFlag
bool HasXattrs() const
friend class DirectoryEntryTestFactory
bool IsRegular() const
bool IsBlockDev() const
static const unsigned int kHasXattrsFlag
static const unsigned int kName
bool IsFifo() const
DirectoryEntry()
uint32_t linkcount_
bool is_nested_catalog_mountpoint_
bool is_external_file_
zlib::Algorithms compression_algorithm() const
void set_has_xattrs(const bool has_xattrs)
Differences CompareTo(const DirectoryEntryBase &other) const
bool is_negative_
bool operator!=(const DirectoryEntry &other) const
LinkString symlink() const
uint32_t hardlink_group_
time_t mtime_
static const unsigned int kNestedCatalogTransitionFlags
static const unsigned int kLinkcount
static const inode_t kInvalidInode
static const unsigned int kMtime
bool IsBindMountpoint() const
shash::Algorithms hash_algorithm() const
bool is_chunked_file_
bool IsCharDev() const
DirectoryEntry(const DirectoryEntryBase &base)
void set_is_hidden(const bool val)
StatEntry(const NameString &n, const struct stat &i)
unsigned int mode_
static const unsigned int kChunkedFileFlag
void set_hardlink_group(const uint32_t group)
static const unsigned int kSymlink
bool operator==(const DirectoryEntryBase &other) const
static const unsigned int kSize
std::string GetFullPath(const std::string &parent_directory) const
bool operator==(const DirectoryEntry &other) const
std::vector< DirectoryEntryBase > DirectoryEntryBaseList
uid_t uid() const
gid_t gid() const
unsigned GetLength() const
Definition: shortstring.h:131
static const unsigned int kMode
shash::Any checksum_
bool is_direct_io_
bool IsNegative() const
bool operator!=(const DirectoryEntryBase &other) const
static const unsigned int kBindMountpointFlag
bool is_nested_catalog_root_
bool is_bind_mountpoint_
int32_t mtime_ns() const
LinkString symlink_
uint32_t hardlink_group() const
static const unsigned int kIdentical
void set_is_nested_catalog_mountpoint(const bool val)
unsigned int Differences
struct stat GetStatStructure() const
dev_t rdev() const
const shash::Any * checksum_ptr() const
static const unsigned int kUid
uid_t uid_