1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2013 Juniper Networks, Inc.
5 * Copyright (c) 2022-2023 Klara, Inc.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #ifndef _FS_TARFS_TARFS_H_
30 #define _FS_TARFS_TARFS_H_
31
32 #ifndef _KERNEL
33 #error Should only be included by kernel
34 #endif
35
36 MALLOC_DECLARE(M_TARFSMNT);
37 MALLOC_DECLARE(M_TARFSNODE);
38 MALLOC_DECLARE(M_TARFSNAME);
39
40 #ifdef SYSCTL_DECL
41 SYSCTL_DECL(_vfs_tarfs);
42 #endif
43
44 struct componentname;
45 struct mount;
46 struct vnode;
47
48 /*
49 * Internal representation of a tarfs file system node.
50 */
51 struct tarfs_node {
52 TAILQ_ENTRY(tarfs_node) entries;
53 TAILQ_ENTRY(tarfs_node) dirents;
54
55 struct mtx lock;
56
57 struct vnode *vnode;
58 struct tarfs_mount *tmp;
59 __enum_uint8(vtype) type;
60 ino_t ino;
61 off_t offset;
62 size_t size;
63 size_t physize;
64 char *name;
65 size_t namelen;
66
67 /* Node attributes */
68 uid_t uid;
69 gid_t gid;
70 mode_t mode;
71 unsigned int flags;
72 nlink_t nlink;
73 struct timespec atime;
74 struct timespec mtime;
75 struct timespec ctime;
76 struct timespec birthtime;
77 unsigned long gen;
78
79 /* Block map */
80 size_t nblk;
81 struct tarfs_blk *blk;
82
83 struct tarfs_node *parent;
84 union {
85 /* VDIR */
86 struct {
87 TAILQ_HEAD(, tarfs_node) dirhead;
88 off_t lastcookie;
89 struct tarfs_node *lastnode;
90 } dir;
91
92 /* VLNK */
93 struct {
94 char *name;
95 size_t namelen;
96 } link;
97
98 /* VBLK or VCHR */
99 dev_t rdev;
100
101 /* VREG */
102 struct tarfs_node *other;
103 };
104 };
105
106 /*
107 * Entry in sparse file block map.
108 */
109 struct tarfs_blk {
110 off_t i; /* input (physical) offset */
111 off_t o; /* output (logical) offset */
112 size_t l; /* length */
113 };
114
115 /*
116 * Decompression buffer.
117 */
118 #define TARFS_ZBUF_SIZE 1048576
119 struct tarfs_zbuf {
120 u_char buf[TARFS_ZBUF_SIZE];
121 size_t off; /* offset of contents */
122 size_t len; /* length of contents */
123 };
124
125 /*
126 * Internal representation of a tarfs mount point.
127 */
128 struct tarfs_mount {
129 TAILQ_HEAD(, tarfs_node) allnodes;
130 struct mtx allnode_lock;
131
132 struct tarfs_node *root;
133 struct vnode *vp;
134 struct mount *vfs;
135 ino_t ino;
136 struct unrhdr *ino_unr;
137 size_t iosize;
138 size_t nblocks;
139 size_t nfiles;
140 time_t mtime; /* default mtime for directories */
141
142 struct tarfs_zio *zio;
143 struct vnode *znode;
144 };
145
146 struct tarfs_zio {
147 struct tarfs_mount *tmp;
148
149 /* decompression state */
150 #ifdef ZSTDIO
151 struct tarfs_zstd *zstd; /* decompression state (zstd) */
152 #endif
153 off_t ipos; /* current input position */
154 off_t opos; /* current output position */
155
156 /* index of compression frames */
157 unsigned int curidx; /* current index position*/
158 unsigned int nidx; /* number of index entries */
159 unsigned int szidx; /* index capacity */
160 struct tarfs_idx { off_t i, o; } *idx;
161 };
162
163 struct tarfs_fid {
164 u_short len; /* length of data in bytes */
165 u_short data0; /* force alignment */
166 ino_t ino;
167 unsigned long gen;
168 };
169
170 #define TARFS_NODE_LOCK(tnp) \
171 mtx_lock(&(tnp)->lock)
172 #define TARFS_NODE_UNLOCK(tnp) \
173 mtx_unlock(&(tnp)->lock)
174 #define TARFS_ALLNODES_LOCK(tnp) \
175 mtx_lock(&(tmp)->allnode_lock)
176 #define TARFS_ALLNODES_UNLOCK(tnp) \
177 mtx_unlock(&(tmp)->allnode_lock)
178
179 /*
180 * Data and metadata within tar files are aligned on 512-byte boundaries,
181 * to match the block size of the magnetic tapes they were originally
182 * intended for.
183 */
184 #define TARFS_BSHIFT 9
185 #define TARFS_BLOCKSIZE (size_t)(1U << TARFS_BSHIFT)
186 #define TARFS_BLKOFF(l) ((l) % TARFS_BLOCKSIZE)
187 #define TARFS_BLKNUM(l) ((l) >> TARFS_BSHIFT)
188 #define TARFS_SZ2BLKS(sz) (((sz) + TARFS_BLOCKSIZE - 1) / TARFS_BLOCKSIZE)
189
190 /*
191 * Our preferred I/O size.
192 */
193 extern unsigned int tarfs_ioshift;
194 #define TARFS_IOSHIFT_MIN TARFS_BSHIFT
195 #define TARFS_IOSHIFT_DEFAULT PAGE_SHIFT
196 #define TARFS_IOSHIFT_MAX PAGE_SHIFT
197
198 #define TARFS_ROOTINO ((ino_t)3)
199 #define TARFS_ZIOINO ((ino_t)4)
200 #define TARFS_MININO ((ino_t)65535)
201
202 #define TARFS_COOKIE_DOT 0
203 #define TARFS_COOKIE_DOTDOT 1
204 #define TARFS_COOKIE_EOF OFF_MAX
205
206 #define TARFS_ZIO_NAME ".tar"
207 #define TARFS_ZIO_NAMELEN (sizeof(TARFS_ZIO_NAME) - 1)
208
209 extern struct vop_vector tarfs_vnodeops;
210
211 static inline
212 struct tarfs_mount *
MP_TO_TARFS_MOUNT(struct mount * mp)213 MP_TO_TARFS_MOUNT(struct mount *mp)
214 {
215
216 MPASS(mp != NULL && mp->mnt_data != NULL);
217 return (mp->mnt_data);
218 }
219
220 static inline
221 struct tarfs_node *
VP_TO_TARFS_NODE(struct vnode * vp)222 VP_TO_TARFS_NODE(struct vnode *vp)
223 {
224
225 MPASS(vp != NULL && vp->v_data != NULL);
226 return (vp->v_data);
227 }
228
229 int tarfs_alloc_node(struct tarfs_mount *tmp, const char *name,
230 size_t namelen, __enum_uint8(vtype) type, off_t off, size_t sz,
231 time_t mtime, uid_t uid, gid_t gid, mode_t mode,
232 unsigned int flags, const char *linkname, dev_t rdev,
233 struct tarfs_node *parent, struct tarfs_node **node);
234 int tarfs_load_blockmap(struct tarfs_node *tnp, size_t realsize);
235 void tarfs_free_node(struct tarfs_node *tnp);
236 struct tarfs_node *
237 tarfs_lookup_dir(struct tarfs_node *tnp, off_t cookie);
238 struct tarfs_node *
239 tarfs_lookup_node(struct tarfs_node *tnp, struct tarfs_node *f,
240 struct componentname *cnp);
241 int tarfs_read_file(struct tarfs_node *tnp, size_t len, struct uio *uiop);
242
243 int tarfs_io_init(struct tarfs_mount *tmp);
244 int tarfs_io_fini(struct tarfs_mount *tmp);
245 int tarfs_io_read(struct tarfs_mount *tmp, bool raw,
246 struct uio *uiop);
247 ssize_t tarfs_io_read_buf(struct tarfs_mount *tmp, bool raw,
248 void *buf, off_t off, size_t len);
249 unsigned int
250 tarfs_strtofflags(const char *str, char **end);
251
252 #endif /* _FS_TARFS_TARFS_H_ */
253