xref: /freebsd/sys/fs/tarfs/tarfs.h (revision 66fd12cf4896eb08ad8e7a2627537f84ead84dd3)
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 *
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 *
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