57aa630220
Sponsored by: Juniper Networks, Inc. Sponsored by: Klara, Inc.
253 lines
6.5 KiB
C
253 lines
6.5 KiB
C
/*-
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*
|
|
* Copyright (c) 2013 Juniper Networks, Inc.
|
|
* Copyright (c) 2022-2023 Klara, Inc.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef _FS_TARFS_TARFS_H_
|
|
#define _FS_TARFS_TARFS_H_
|
|
|
|
#ifndef _KERNEL
|
|
#error Should only be included by kernel
|
|
#endif
|
|
|
|
MALLOC_DECLARE(M_TARFSMNT);
|
|
MALLOC_DECLARE(M_TARFSNODE);
|
|
MALLOC_DECLARE(M_TARFSNAME);
|
|
|
|
#ifdef SYSCTL_DECL
|
|
SYSCTL_DECL(_vfs_tarfs);
|
|
#endif
|
|
|
|
struct componentname;
|
|
struct mount;
|
|
struct vnode;
|
|
|
|
/*
|
|
* Internal representation of a tarfs file system node.
|
|
*/
|
|
struct tarfs_node {
|
|
TAILQ_ENTRY(tarfs_node) entries;
|
|
TAILQ_ENTRY(tarfs_node) dirents;
|
|
|
|
struct mtx lock;
|
|
|
|
struct vnode *vnode;
|
|
struct tarfs_mount *tmp;
|
|
enum vtype type;
|
|
ino_t ino;
|
|
off_t offset;
|
|
size_t size;
|
|
size_t physize;
|
|
char *name;
|
|
size_t namelen;
|
|
|
|
/* Node attributes */
|
|
uid_t uid;
|
|
gid_t gid;
|
|
mode_t mode;
|
|
unsigned int flags;
|
|
nlink_t nlink;
|
|
struct timespec atime;
|
|
struct timespec mtime;
|
|
struct timespec ctime;
|
|
struct timespec birthtime;
|
|
unsigned long gen;
|
|
|
|
/* Block map */
|
|
size_t nblk;
|
|
struct tarfs_blk *blk;
|
|
|
|
struct tarfs_node *parent;
|
|
union {
|
|
/* VDIR */
|
|
struct {
|
|
TAILQ_HEAD(, tarfs_node) dirhead;
|
|
off_t lastcookie;
|
|
struct tarfs_node *lastnode;
|
|
} dir;
|
|
|
|
/* VLNK */
|
|
struct {
|
|
char *name;
|
|
size_t namelen;
|
|
} link;
|
|
|
|
/* VBLK or VCHR */
|
|
dev_t rdev;
|
|
|
|
/* VREG */
|
|
struct tarfs_node *other;
|
|
};
|
|
};
|
|
|
|
/*
|
|
* Entry in sparse file block map.
|
|
*/
|
|
struct tarfs_blk {
|
|
off_t i; /* input (physical) offset */
|
|
off_t o; /* output (logical) offset */
|
|
size_t l; /* length */
|
|
};
|
|
|
|
/*
|
|
* Decompression buffer.
|
|
*/
|
|
#define TARFS_ZBUF_SIZE 1048576
|
|
struct tarfs_zbuf {
|
|
u_char buf[TARFS_ZBUF_SIZE];
|
|
size_t off; /* offset of contents */
|
|
size_t len; /* length of contents */
|
|
};
|
|
|
|
/*
|
|
* Internal representation of a tarfs mount point.
|
|
*/
|
|
struct tarfs_mount {
|
|
TAILQ_HEAD(, tarfs_node) allnodes;
|
|
struct mtx allnode_lock;
|
|
|
|
struct tarfs_node *root;
|
|
struct vnode *vp;
|
|
struct mount *vfs;
|
|
ino_t ino;
|
|
struct unrhdr *ino_unr;
|
|
size_t iosize;
|
|
size_t nblocks;
|
|
size_t nfiles;
|
|
time_t mtime; /* default mtime for directories */
|
|
|
|
struct tarfs_zio *zio;
|
|
struct vnode *znode;
|
|
};
|
|
|
|
struct tarfs_zio {
|
|
struct tarfs_mount *tmp;
|
|
|
|
/* decompression state */
|
|
#ifdef ZSTDIO
|
|
struct tarfs_zstd *zstd; /* decompression state (zstd) */
|
|
#endif
|
|
off_t ipos; /* current input position */
|
|
off_t opos; /* current output position */
|
|
|
|
/* index of compression frames */
|
|
unsigned int curidx; /* current index position*/
|
|
unsigned int nidx; /* number of index entries */
|
|
unsigned int szidx; /* index capacity */
|
|
struct tarfs_idx { off_t i, o; } *idx;
|
|
};
|
|
|
|
struct tarfs_fid {
|
|
u_short len; /* length of data in bytes */
|
|
u_short data0; /* force alignment */
|
|
ino_t ino;
|
|
unsigned long gen;
|
|
};
|
|
|
|
#define TARFS_NODE_LOCK(tnp) \
|
|
mtx_lock(&(tnp)->lock)
|
|
#define TARFS_NODE_UNLOCK(tnp) \
|
|
mtx_unlock(&(tnp)->lock)
|
|
#define TARFS_ALLNODES_LOCK(tnp) \
|
|
mtx_lock(&(tmp)->allnode_lock)
|
|
#define TARFS_ALLNODES_UNLOCK(tnp) \
|
|
mtx_unlock(&(tmp)->allnode_lock)
|
|
|
|
/*
|
|
* Data and metadata within tar files are aligned on 512-byte boundaries,
|
|
* to match the block size of the magnetic tapes they were originally
|
|
* intended for.
|
|
*/
|
|
#define TARFS_BSHIFT 9
|
|
#define TARFS_BLOCKSIZE (size_t)(1U << TARFS_BSHIFT)
|
|
#define TARFS_BLKOFF(l) ((l) % TARFS_BLOCKSIZE)
|
|
#define TARFS_BLKNUM(l) ((l) >> TARFS_BSHIFT)
|
|
#define TARFS_SZ2BLKS(sz) (((sz) + TARFS_BLOCKSIZE - 1) / TARFS_BLOCKSIZE)
|
|
|
|
/*
|
|
* Our preferred I/O size.
|
|
*/
|
|
extern unsigned int tarfs_ioshift;
|
|
#define TARFS_IOSHIFT_MIN TARFS_BSHIFT
|
|
#define TARFS_IOSHIFT_DEFAULT PAGE_SHIFT
|
|
#define TARFS_IOSHIFT_MAX PAGE_SHIFT
|
|
|
|
#define TARFS_ROOTINO ((ino_t)3)
|
|
#define TARFS_ZIOINO ((ino_t)4)
|
|
#define TARFS_MININO ((ino_t)65535)
|
|
|
|
#define TARFS_COOKIE_DOT 0
|
|
#define TARFS_COOKIE_DOTDOT 1
|
|
#define TARFS_COOKIE_EOF OFF_MAX
|
|
|
|
#define TARFS_ZIO_NAME ".tar"
|
|
#define TARFS_ZIO_NAMELEN (sizeof(TARFS_ZIO_NAME) - 1)
|
|
|
|
extern struct vop_vector tarfs_vnodeops;
|
|
|
|
static inline
|
|
struct tarfs_mount *
|
|
MP_TO_TARFS_MOUNT(struct mount *mp)
|
|
{
|
|
|
|
MPASS(mp != NULL && mp->mnt_data != NULL);
|
|
return (mp->mnt_data);
|
|
}
|
|
|
|
static inline
|
|
struct tarfs_node *
|
|
VP_TO_TARFS_NODE(struct vnode *vp)
|
|
{
|
|
|
|
MPASS(vp != NULL && vp->v_data != NULL);
|
|
return (vp->v_data);
|
|
}
|
|
|
|
int tarfs_alloc_node(struct tarfs_mount *tmp, const char *name,
|
|
size_t namelen, enum vtype type, off_t off, size_t sz,
|
|
time_t mtime, uid_t uid, gid_t gid, mode_t mode,
|
|
unsigned int flags, const char *linkname, dev_t rdev,
|
|
struct tarfs_node *parent, struct tarfs_node **node);
|
|
int tarfs_load_blockmap(struct tarfs_node *tnp, size_t realsize);
|
|
void tarfs_free_node(struct tarfs_node *tnp);
|
|
struct tarfs_node *
|
|
tarfs_lookup_dir(struct tarfs_node *tnp, off_t cookie);
|
|
struct tarfs_node *
|
|
tarfs_lookup_node(struct tarfs_node *tnp, struct tarfs_node *f,
|
|
struct componentname *cnp);
|
|
int tarfs_read_file(struct tarfs_node *tnp, size_t len, struct uio *uiop);
|
|
|
|
int tarfs_io_init(struct tarfs_mount *tmp);
|
|
int tarfs_io_fini(struct tarfs_mount *tmp);
|
|
int tarfs_io_read(struct tarfs_mount *tmp, bool raw,
|
|
struct uio *uiop);
|
|
ssize_t tarfs_io_read_buf(struct tarfs_mount *tmp, bool raw,
|
|
void *buf, off_t off, size_t len);
|
|
unsigned int
|
|
tarfs_strtofflags(const char *str, char **end);
|
|
|
|
#endif /* _FS_TARFS_TARFS_H_ */
|