GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/file_chunk.h
Date: 2026-09-06 02:40:30
Exec Total Coverage
Lines: 27 33 81.8%
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 "bigvector.h"
20 #include "compression/compression.h"
21 #include "crypto/hash.h"
22 #include "shortstring.h"
23 #include "smallhash.h"
24 #include "util/atomic.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 class FileChunk {
32 public:
33 527 FileChunk() : content_hash_(shash::Any(shash::kAny)), offset_(0), size_(0) { }
34 8017807 FileChunk(const shash::Any &hash, const off_t offset, const size_t size)
35 8017807 : content_hash_(hash), offset_(offset), size_(size) { }
36
37 16021452 inline const shash::Any &content_hash() const { return content_hash_; }
38 8005676 inline off_t offset() const { return offset_; }
39 8004792 inline size_t size() const { return size_; }
40
41 protected:
42 shash::Any content_hash_; //!< content hash of the compressed file chunk
43 off_t offset_; //!< byte offset in the uncompressed input file
44 size_t size_; //!< uncompressed size of the data chunk
45 };
46
47 typedef BigVector<FileChunk> FileChunkList;
48
49 struct FileChunkReflist {
50 8420 FileChunkReflist()
51 8420 : list(NULL)
52 8420 , compression_alg(zlib::kZlibDefault)
53 8420 , external_data(false)
54 8420 , volatile_data(false) { }
55 47 FileChunkReflist(FileChunkList *l,
56 const PathString &p,
57 zlib::Algorithms alg,
58 bool external,
59 bool volatil = false)
60 47 : list(l)
61 47 , path(p)
62 47 , compression_alg(alg)
63 47 , external_data(external)
64 47 , volatile_data(volatil) { }
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 bool volatile_data;
74 };
75
76
77 /**
78 * Stores the chunk index of a file descriptor. Needed for the Fuse module
79 * and for libcvmfs.
80 */
81 struct ChunkFd {
82 8156 ChunkFd() : fd(-1), chunk_idx(0) { }
83 int fd; // -1 or pointing to chunk_idx
84 unsigned chunk_idx;
85 };
86
87
88 /**
89 * All chunk related data structures in the Fuse module.
90 */
91 struct ChunkTables {
92 ChunkTables();
93 ~ChunkTables();
94 ChunkTables(const ChunkTables &other);
95 ChunkTables &operator=(const ChunkTables &other);
96 void CopyFrom(const ChunkTables &other);
97 void InitLocks();
98 void InitHashmaps();
99
100 pthread_mutex_t *Handle2Lock(const uint64_t handle) const;
101
102 inline void Lock() {
103 const int retval = pthread_mutex_lock(lock);
104 assert(retval == 0);
105 }
106
107 inline void Unlock() {
108 const int retval = pthread_mutex_unlock(lock);
109 assert(retval == 0);
110 }
111
112 // Version 2 --> 4: add handle2uniqino
113 static const unsigned kVersion = 4;
114
115 int version;
116 static const unsigned kNumHandleLocks = 128;
117 // Versions < 4 of ChunkTables didn't have this map. Therefore, after a
118 // hot patch a handle can be missing from this map. In this case, the fuse
119 // module falls back to the inode passed by the kernel.
120 SmallHashDynamic<uint64_t, uint64_t> handle2uniqino;
121 SmallHashDynamic<uint64_t, ChunkFd> handle2fd;
122 // The file descriptors attached to handles need to be locked.
123 // Using a hash map to survive with a small, fixed number of locks
124 BigVector<pthread_mutex_t *> handle_locks;
125 SmallHashDynamic<uint64_t, FileChunkReflist> inode2chunks;
126 SmallHashDynamic<uint64_t, uint32_t> inode2references;
127 uint64_t next_handle;
128 pthread_mutex_t *lock;
129 };
130
131
132 /**
133 * Connects virtual file descriptors to FileChunkLists. Used by libcvmfs.
134 * Tries to keep the file descriptors small because they need to fit within
135 * 29bit. This class takes the ownership of the FileChunkList objects pointed
136 * to by the elements of fd_table_.
137 */
138 class SimpleChunkTables : SingleCopy {
139 public:
140 /**
141 * While a chunked file is open, a single file descriptor is moved around the
142 * individual chunks.
143 */
144 struct OpenChunks {
145 264 OpenChunks() : chunk_fd(NULL) { }
146 ChunkFd *chunk_fd;
147 FileChunkReflist chunk_reflist;
148 };
149
150 SimpleChunkTables();
151 ~SimpleChunkTables();
152 int Add(FileChunkReflist chunks);
153 OpenChunks Get(int fd);
154 void Release(int fd);
155
156 private:
157 396 inline void Lock() {
158 396 const int retval = pthread_mutex_lock(lock_);
159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 396 times.
396 assert(retval == 0);
160 396 }
161
162 396 inline void Unlock() {
163 396 const int retval = pthread_mutex_unlock(lock_);
164
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 396 times.
396 assert(retval == 0);
165 396 }
166
167 std::vector<OpenChunks> fd_table_;
168 pthread_mutex_t *lock_;
169 };
170
171 #endif // CVMFS_FILE_CHUNK_H_
172