GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/file_chunk.h
Date: 2024-04-21 02:33:16
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.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 11 FileChunk() : content_hash_(shash::Any(shash::kAny)), offset_(0), size_(0) { }
34 250534 FileChunk(const shash::Any &hash,
35 const off_t offset,
36 250534 const size_t size) :
37 250534 content_hash_(hash),
38 250534 offset_(offset),
39 250534 size_(size) { }
40
41 500616 inline const shash::Any& content_hash() const { return content_hash_; }
42 250143 inline off_t offset() const { return offset_; }
43 250102 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 struct FileChunkReflist {
54 356 FileChunkReflist() : list(NULL)
55 356 , compression_alg(zlib::kZlibDefault)
56 356 , external_data(false) { }
57 2 FileChunkReflist(FileChunkList *l,
58 const PathString &p,
59 zlib::Algorithms alg,
60 bool external)
61 2 : list(l)
62 2 , path(p)
63 2 , 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 struct ChunkFd {
81 344 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 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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 assert(retval == 0);
159 18 }
160
161 18 inline void Unlock() {
162 18 int retval = pthread_mutex_unlock(lock_);
163
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
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_
171