GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/file_chunk.h Lines: 24 30 80.0 %
Date: 2019-02-03 02:48:13 Branches: 2 8 25.0 %

Line Branch Exec Source
1
/**
2
 * This file is part of the CernVM File System.
3
 *
4
 * This class implements a data wrapper for single dentries in CVMFS
5
 * Additionally to the normal file meta data it manages some
6
 * bookkeeping data like the associated catalog.
7
 */
8
9
#ifndef CVMFS_FILE_CHUNK_H_
10
#define CVMFS_FILE_CHUNK_H_
11
12
#include <pthread.h>
13
#include <stdint.h>
14
#include <sys/types.h>
15
16
#include <string>
17
#include <vector>
18
19
#include "atomic.h"
20
#include "bigvector.h"
21
#include "compression.h"
22
#include "hash.h"
23
#include "shortstring.h"
24
#include "smallhash.h"
25
#include "util/single_copy.h"
26
27
/**
28
 * Describes a FileChunk as generated from the FileProcessor in collaboration
29
 * with the ChunkGenerator.
30
 */
31
6960
class FileChunk {
32
 public:
33
9
  FileChunk() : content_hash_(shash::Any(shash::kAny)), offset_(0), size_(0) { }
34
1826
  FileChunk(const shash::Any &hash,
35
            const off_t       offset,
36
            const size_t      size) :
37
    content_hash_(hash),
38
    offset_(offset),
39
1826
    size_(size) { }
40
41
1971
  inline const shash::Any& content_hash() const { return content_hash_; }
42
202
  inline off_t             offset()       const { return offset_; }
43
163
  inline size_t            size()         const { return size_; }
44
45
 protected:
46
  shash::Any content_hash_;  //!< content hash of the compressed file chunk
47
  off_t      offset_;        //!< byte offset in the uncompressed input file
48
  size_t     size_;          //!< uncompressed size of the data chunk
49
};
50
51
typedef BigVector<FileChunk> FileChunkList;
52
53
735
struct FileChunkReflist {
54
692
  FileChunkReflist() : list(NULL)
55
                     , compression_alg(zlib::kZlibDefault)
56
692
                     , external_data(false) { }
57
2
  FileChunkReflist(FileChunkList     *l,
58
                   const PathString  &p,
59
                   zlib::Algorithms   alg,
60
                   bool               external)
61
    : list(l)
62
    , path(p)
63
    , compression_alg(alg)
64
2
    , external_data(external) { }
65
66
  unsigned FindChunkIdx(const uint64_t offset);
67
  shash::Any HashChunkList();
68
69
  FileChunkList     *list;
70
  PathString         path;
71
  zlib::Algorithms   compression_alg;
72
  bool               external_data;
73
};
74
75
76
/**
77
 * Stores the chunk index of a file descriptor.  Needed for the Fuse module
78
 * and for libcvmfs.
79
 */
80
672
struct ChunkFd {
81
680
  ChunkFd() : fd(-1), chunk_idx(0) { }
82
  int fd;  // -1 or pointing to chunk_idx
83
  unsigned chunk_idx;
84
};
85
86
87
/**
88
 * All chunk related data structures in the Fuse module.
89
 */
90
struct ChunkTables {
91
  ChunkTables();
92
  ~ChunkTables();
93
  ChunkTables(const ChunkTables &other);
94
  ChunkTables &operator= (const ChunkTables &other);
95
  void CopyFrom(const ChunkTables &other);
96
  void InitLocks();
97
  void InitHashmaps();
98
99
  pthread_mutex_t *Handle2Lock(const uint64_t handle) const;
100
101
  inline void Lock() {
102
    int retval = pthread_mutex_lock(lock);
103
    assert(retval == 0);
104
  }
105
106
  inline void Unlock() {
107
    int retval = pthread_mutex_unlock(lock);
108
    assert(retval == 0);
109
  }
110
111
  // Version 2 --> 4: add handle2uniqino
112
  static const unsigned kVersion = 4;
113
114
  int version;
115
  static const unsigned kNumHandleLocks = 128;
116
  // Versions < 4 of ChunkTables didn't have this map.  Therefore, after a
117
  // hot patch a handle can be missing from this map.  In this case, the fuse
118
  // module falls back to the inode passed by the kernel.
119
  SmallHashDynamic<uint64_t, uint64_t> handle2uniqino;
120
  SmallHashDynamic<uint64_t, ChunkFd> handle2fd;
121
  // The file descriptors attached to handles need to be locked.
122
  // Using a hash map to survive with a small, fixed number of locks
123
  BigVector<pthread_mutex_t *> handle_locks;
124
  SmallHashDynamic<uint64_t, FileChunkReflist> inode2chunks;
125
  SmallHashDynamic<uint64_t, uint32_t> inode2references;
126
  uint64_t next_handle;
127
  pthread_mutex_t *lock;
128
};
129
130
131
/**
132
 * Connects virtual file descriptors to FileChunkLists.  Used by libcvmfs.
133
 * Tries to keep the file descriptors small because they need to fit within
134
 * 29bit.  This class takes the ownership of the FileChunkList objects pointed
135
 * to by the elements of fd_table_.
136
 */
137
class SimpleChunkTables : SingleCopy {
138
 public:
139
  /**
140
   * While a chunked file is open, a single file descriptor is moved around the
141
   * individual chunks.
142
   */
143
45
  struct OpenChunks {
144
12
    OpenChunks() : chunk_fd(NULL) { }
145
    ChunkFd *chunk_fd;
146
    FileChunkReflist chunk_reflist;
147
  };
148
149
  SimpleChunkTables();
150
  ~SimpleChunkTables();
151
  int Add(FileChunkReflist chunks);
152
  OpenChunks Get(int fd);
153
  void Release(int fd);
154
155
 private:
156
18
  inline void Lock() {
157
18
    int retval = pthread_mutex_lock(lock_);
158
18
    assert(retval == 0);
159
18
  }
160
161
18
  inline void Unlock() {
162
18
    int retval = pthread_mutex_unlock(lock_);
163
18
    assert(retval == 0);
164
18
  }
165
166
  std::vector<OpenChunks> fd_table_;
167
  pthread_mutex_t *lock_;
168
};
169
170
#endif  // CVMFS_FILE_CHUNK_H_