CernVM-FS  2.13.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 } // namespace publish
31 namespace swissknife {
32 class CommandMigrate;
33 class IngestSQL;
34 }
35 
36 namespace catalog {
37 
38 // Create DirectoryEntries for unit test purposes.
39 class DirectoryEntryTestFactory;
40 
41 class MockCatalogManager;
42 class Catalog;
43 class WritableCatalogManager;
44 
45 template<class CatalogMgrT>
47 typedef uint64_t inode_t;
48 
52 };
53 
61  // For testing the catalog balancing
62  friend class CatalogBalancer<MockCatalogManager>;
63  // Create .cvmfscatalog and .cvmfsautocatalog files
65  // Simplify creation of DirectoryEntry objects for write back
66  friend class publish::SyncItem;
68  friend class publish::SyncItemTar;
71  friend class swissknife::IngestSQL; //TODO(vvolkl): can probably avoided with new setters
72  // Simplify file system like _touch_ of DirectoryEntry objects
73  friend class SqlDirentTouch;
74  // Allow creation of virtual directories and files
75  friend class VirtualCatalog;
76 
77  public:
78  static const inode_t kInvalidInode = 0;
79 
85  struct Difference {
86  static const unsigned int kIdentical = 0x00000;
87  static const unsigned int kName = 0x00001;
88  static const unsigned int kLinkcount = 0x00002;
89  static const unsigned int kSize = 0x00004;
90  static const unsigned int kMode = 0x00008;
91  static const unsigned int kMtime = 0x00010;
92  static const unsigned int kSymlink = 0x00020;
93  static const unsigned int kChecksum = 0x00040;
94  static const unsigned int kHardlinkGroup = 0x00080;
95  static const unsigned int kNestedCatalogTransitionFlags = 0x00100;
96  static const unsigned int kChunkedFileFlag = 0x00200;
97  static const unsigned int kHasXattrsFlag = 0x00400;
98  static const unsigned int kExternalFileFlag = 0x00800;
99  static const unsigned int kBindMountpointFlag = 0x01000;
100  static const unsigned int kHiddenFlag = 0x02000;
101  static const unsigned int kDirectIoFlag = 0x04000;
102  static const unsigned int kUid = 0x08000;
103  static const unsigned int kGid = 0x10000;
104  };
105  typedef unsigned int Differences;
106 
112  , mode_(0)
113  , uid_(0)
114  , gid_(0)
115  , size_(0)
116  , mtime_(0)
117  , mtime_ns_(-1)
118  , linkcount_(1) // generally a normal file has linkcount 1 -> default
119  , has_xattrs_(false)
120  , is_external_file_(false)
121  , is_direct_io_(false)
123 
124  inline bool IsRegular() const { return S_ISREG(mode_); }
125  inline bool IsLink() const { return S_ISLNK(mode_); }
126  inline bool IsDirectory() const { return S_ISDIR(mode_); }
127  inline bool IsFifo() const { return S_ISFIFO(mode_); }
128  inline bool IsSocket() const { return S_ISSOCK(mode_); }
129  inline bool IsCharDev() const { return S_ISCHR(mode_); }
130  inline bool IsBlockDev() const { return S_ISBLK(mode_); }
131  inline bool IsSpecial() const {
132  return IsFifo() || IsSocket() || IsCharDev() || IsBlockDev();
133  }
134  inline bool IsExternalFile() const { return is_external_file_; }
135  inline bool IsDirectIo() const { return is_direct_io_; }
136  inline bool HasXattrs() const { return has_xattrs_; }
137  inline bool HasMtimeNs() const { return mtime_ns_ >= 0; }
138 
139  inline inode_t inode() const { return inode_; }
140  inline uint32_t linkcount() const { return linkcount_; }
141  inline NameString name() const { return name_; }
142  inline LinkString symlink() const { return symlink_; }
143  inline time_t mtime() const { return mtime_; }
144  inline int32_t mtime_ns() const { return mtime_ns_; }
145  inline unsigned int mode() const { return mode_; }
146  inline uid_t uid() const { return uid_; }
147  inline gid_t gid() const { return gid_; }
148  inline shash::Any checksum() const { return checksum_; }
149  inline const shash::Any *checksum_ptr() const { return &checksum_; }
151  return checksum_.algorithm;
152  }
153  inline uint64_t size() const {
154  if (IsLink())
155  return symlink().GetLength();
156  if (IsBlockDev() || IsCharDev())
157  return 0;
158  return size_;
159  }
160  inline dev_t rdev() const {
161  if (IsBlockDev() || IsCharDev())
162  return size_;
163  return 1;
164  }
165  inline std::string GetFullPath(const std::string &parent_directory) const {
166  std::string file_path = parent_directory + "/";
167  file_path.append(name().GetChars(), name().GetLength());
168  return file_path;
169  }
170 
171  inline void set_inode(const inode_t inode) { inode_ = inode; }
172  inline void set_linkcount(const uint32_t linkcount) {
173  assert(linkcount > 0);
175  }
176  inline void set_symlink(const LinkString &symlink) { symlink_ = symlink; }
177  inline void set_has_xattrs(const bool has_xattrs) {
178  has_xattrs_ = has_xattrs;
179  }
180 
182  return compression_algorithm_;
183  }
184 
189  inline struct stat GetStatStructure() const {
190  struct stat s;
191  memset(&s, 0, sizeof(s));
192  s.st_dev = 1;
193  s.st_ino = inode_;
194  s.st_mode = mode_;
195  s.st_nlink = linkcount();
196  s.st_uid = uid();
197  s.st_gid = gid();
198  s.st_rdev = rdev();
199  s.st_size = static_cast<off_t>(size());
200  s.st_blksize = 4096; // will be ignored by Fuse
201  s.st_blocks = static_cast<blkcnt_t>(1 + size() / 512);
202  s.st_atime = mtime_;
203  s.st_mtime = mtime_;
204  s.st_ctime = mtime_;
205  if (HasMtimeNs()) {
206 #ifdef __APPLE__
207  s.st_atimespec.tv_nsec = mtime_ns_;
208  s.st_mtimespec.tv_nsec = mtime_ns_;
209  s.st_ctimespec.tv_nsec = mtime_ns_;
210 #else
211  s.st_atim.tv_nsec = mtime_ns_;
212  s.st_mtim.tv_nsec = mtime_ns_;
213  s.st_ctim.tv_nsec = mtime_ns_;
214 #endif
215  }
216  return s;
217  }
218 
219  Differences CompareTo(const DirectoryEntryBase &other) const;
220  inline bool operator==(const DirectoryEntryBase &other) const {
221  return CompareTo(other) == Difference::kIdentical;
222  }
223  inline bool operator!=(const DirectoryEntryBase &other) const {
224  return !(*this == other);
225  }
226 
227  protected:
228  // Inodes are generated based on the rowid of the entry in the file catalog.
230 
231  // Data from struct stat
233  unsigned int mode_;
234  uid_t uid_;
235  gid_t gid_;
236  uint64_t size_;
237  time_t mtime_;
238  // nanosecond part of the mtime. Only valid if non-negative
239  int32_t mtime_ns_;
241  uint32_t linkcount_;
242  // In order to save memory, we only indicate if a directory entry has custom
243  // extended attributes. Another call to the file catalog is necessary to
244  // get them.
246 
247  // The cryptographic hash is not part of the file system intrinsics, though
248  // it can be computed just using the file contents. We therefore put it in
249  // this base class.
251 
254 
255  // The compression algorithm
257 };
258 
259 
271  // Simplify creation of DirectoryEntry objects
272  friend class SqlLookup;
273  // Simplify write of DirectoryEntry objects in database
274  friend class SqlDirentWrite;
275  // For fixing DirectoryEntry glitches
277  // TODO(rmeusel): remove this dependency
279  // Create DirectoryEntries for unit test purposes.
281 
282  public:
290  inline explicit DirectoryEntry(const DirectoryEntryBase &base)
291  : DirectoryEntryBase(base)
292  , hardlink_group_(0)
293  , is_nested_catalog_root_(false)
295  , is_bind_mountpoint_(false)
296  , is_chunked_file_(false)
297  , is_hidden_(false)
298  , is_negative_(false) { }
299 
300  inline DirectoryEntry()
301  : hardlink_group_(0)
302  , is_nested_catalog_root_(false)
304  , is_bind_mountpoint_(false)
305  , is_chunked_file_(false)
306  , is_hidden_(false)
307  , is_negative_(false) { }
308 
309  inline explicit DirectoryEntry(SpecialDirents special_type)
310  : hardlink_group_(0)
311  , is_nested_catalog_root_(false)
313  , is_bind_mountpoint_(false)
314  , is_chunked_file_(false)
315  , is_hidden_(false)
316  , is_negative_(true) {
317  assert(special_type == kDirentNegative);
318  }
319 
320  inline SpecialDirents GetSpecial() const {
322  }
323 
324  Differences CompareTo(const DirectoryEntry &other) const;
325  inline bool operator==(const DirectoryEntry &other) const {
326  return CompareTo(other) == Difference::kIdentical;
327  }
328  inline bool operator!=(const DirectoryEntry &other) const {
329  return !(*this == other);
330  }
331 
332  inline bool IsNegative() const { return is_negative_; }
333  inline bool IsNestedCatalogRoot() const { return is_nested_catalog_root_; }
334  inline bool IsNestedCatalogMountpoint() const {
336  }
337  inline bool IsBindMountpoint() const { return is_bind_mountpoint_; }
338  inline bool IsChunkedFile() const { return is_chunked_file_; }
339  inline bool IsHidden() const { return is_hidden_; }
340  inline uint32_t hardlink_group() const { return hardlink_group_; }
341 
342  inline void set_hardlink_group(const uint32_t group) {
343  hardlink_group_ = group;
344  }
345  inline void set_is_nested_catalog_mountpoint(const bool val) {
347  }
348  inline void set_is_nested_catalog_root(const bool val) {
350  }
351  inline void set_is_bind_mountpoint(const bool val) {
352  is_bind_mountpoint_ = val;
353  }
354  inline void set_is_chunked_file(const bool val) { is_chunked_file_ = val; }
355  inline void set_is_hidden(const bool val) { is_hidden_ = val; }
356 
357  private:
362  uint32_t hardlink_group_;
363 
364  // TODO(jblomer): transform into bitfield to save memory
371 };
372 
373 
377 struct StatEntry {
379  struct stat info;
380 
381  StatEntry() { memset(&info, 0, sizeof(info)); }
382  StatEntry(const NameString &n, const struct stat &i) : name(n), info(i) { }
383 };
384 
385 
386 typedef std::vector<DirectoryEntry> DirectoryEntryList;
387 typedef std::vector<DirectoryEntryBase> DirectoryEntryBaseList;
388 // TODO(jblomer): use mmap for large listings
390 
391 } // namespace catalog
392 
393 #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:122
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_