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