mirror of
git://git.9front.org/plan9front/plan9front
synced 2025-01-12 11:10:06 +00:00
ext4srv: reduce the number of options, align more with existing filesystems
Also provide saner defaults (block size 4k instead of 1k). Cache write back is always enabled now as well.
This commit is contained in:
parent
ce86e64ee0
commit
9ebd6f860e
4 changed files with 126 additions and 159 deletions
|
@ -4,34 +4,29 @@ ext4srv \- ext4 file system
|
|||
.SH SYNOPSIS
|
||||
.B ext4srv
|
||||
[
|
||||
.B -Crs
|
||||
.B -Ss
|
||||
] [
|
||||
.B -f
|
||||
.I file
|
||||
] [
|
||||
.B -g
|
||||
.I groupfile
|
||||
] [
|
||||
.B -R
|
||||
.I uid
|
||||
.B -n
|
||||
.I srvname
|
||||
] [
|
||||
.I service
|
||||
]
|
||||
.PP
|
||||
.B ext4srv
|
||||
.B -M
|
||||
.B -r
|
||||
.I (2|3|4)
|
||||
[
|
||||
.B -L
|
||||
.I label
|
||||
] [
|
||||
.B -b
|
||||
.I blksize
|
||||
] [
|
||||
.B -N
|
||||
.I numinodes
|
||||
] [
|
||||
.B -I
|
||||
.I inodesize
|
||||
] [
|
||||
.B -L
|
||||
.I label
|
||||
]
|
||||
.I device
|
||||
.SH DESCRIPTION
|
||||
.I Ext4srv
|
||||
is a file server that interprets the Linux Second, Third and Fourth
|
||||
|
@ -43,20 +38,20 @@ simultaneously.
|
|||
.PP
|
||||
.I Ext4srv
|
||||
posts a file descriptor named
|
||||
.I service
|
||||
.I srvname
|
||||
(default
|
||||
.BR ext4 )
|
||||
in the
|
||||
.B /srv
|
||||
directory.
|
||||
To access an ext4 file system on a device, use
|
||||
directory. To access an ext4 file system on a device, use
|
||||
.B mount
|
||||
with the
|
||||
.I spec
|
||||
argument
|
||||
(see
|
||||
.IR bind (1))
|
||||
the name of the file holding the raw ext4 file system, typically the disk or partition.
|
||||
the name of the file holding the raw ext4 file system, typically the
|
||||
disk or partition.
|
||||
If
|
||||
.I spec
|
||||
is undefined in the
|
||||
|
@ -68,60 +63,52 @@ as the default name for the device holding the file system.
|
|||
.PP
|
||||
Normally
|
||||
.I ext4srv
|
||||
creates a pipe to act as the communications channel between
|
||||
itself and its clients.
|
||||
creates a pipe to act as the communications channel between itself and
|
||||
its clients.
|
||||
The
|
||||
.B -s
|
||||
flag instructs
|
||||
.I ext4srv
|
||||
to use its standard input and output instead.
|
||||
This flag also prevents the creation of an explicit service file in
|
||||
to use its standard input and output instead. This flag also prevents
|
||||
the creation of an explicit service file in
|
||||
.BR /srv .
|
||||
.PP
|
||||
The
|
||||
.B -r
|
||||
flag (recommended) makes the file system read-only.
|
||||
By default,
|
||||
.I ext4srv
|
||||
will try to parse and use
|
||||
.I /etc/group
|
||||
file for permission checks, if available on the mounted filesystem.
|
||||
The optional
|
||||
.B -g
|
||||
flags specify Unix-format group file that give the mapping between the
|
||||
numeric user- and group-ID numbers in the ext4 file system and the
|
||||
strings reported by Plan 9 status inquiries.
|
||||
flag specifies Unix-format group file that gives the mapping between
|
||||
the numeric user- and group-ID numbers in the Extended file system and
|
||||
the strings reported by Plan 9 status inquiries. The file is assumed
|
||||
to reside on the filesystem where
|
||||
.I ext4srv
|
||||
executable is running, not the one to be mounted.
|
||||
.PP
|
||||
With
|
||||
.B -R
|
||||
option the filesystem can be mounted in "root" mode, allowing full access regardless
|
||||
of permissions. The usual
|
||||
.I uid
|
||||
in this case is
|
||||
.IR 0 .
|
||||
.SH MKFS
|
||||
A different mode of
|
||||
.I ext4srv
|
||||
is enabled with
|
||||
.B -M
|
||||
option that accepts the file system version
|
||||
.RI ( 2
|
||||
for
|
||||
.I ext2
|
||||
and so on).
|
||||
In this mode filesystem is initialized on the specified
|
||||
.I device
|
||||
and all existing data on it is destroyed.
|
||||
.B -S
|
||||
option the filesystem can be mounted in "root" mode, allowing full
|
||||
access, regardless of permissions.
|
||||
.PP
|
||||
Additional options may be specified, for example
|
||||
.B -L
|
||||
may be used to set the filesystem label.
|
||||
With
|
||||
.B -r
|
||||
option the filesystem will be reamed - the old data erased and the
|
||||
file reformatted as specified. An optional label can be specified
|
||||
with
|
||||
.BR -L ,
|
||||
block size (default is 4096 bytes) with
|
||||
.B -b
|
||||
and
|
||||
inode size (default is 256 bytes) with
|
||||
.BR -I .
|
||||
.SH SOURCE
|
||||
.B /sys/src/cmd/ext4srv
|
||||
.SH BUGS
|
||||
Yes.
|
||||
.PP
|
||||
Permission checking is very basic and may not be complete.
|
||||
.SH NOTES
|
||||
Symlinks are not resolved.
|
||||
There may be many bugs.
|
||||
It is advisable to use
|
||||
.I ext4srv
|
||||
in read-only mode whenever possible.
|
||||
.SH BUGS
|
||||
There may be bugs - no refunds.
|
||||
.SH HISTORY
|
||||
.I Ext4srv
|
||||
first appeared in 9front (February, 2024).
|
||||
|
|
|
@ -3,14 +3,10 @@ typedef struct Part Part;
|
|||
|
||||
struct Opts {
|
||||
char *group;
|
||||
int cachewb;
|
||||
int asroot;
|
||||
int rdonly;
|
||||
|
||||
int fstype;
|
||||
int ream;
|
||||
int blksz;
|
||||
int inodesz;
|
||||
u32int ninode;
|
||||
char *label;
|
||||
};
|
||||
|
||||
|
|
|
@ -30,23 +30,17 @@ struct Aux {
|
|||
enum {
|
||||
Adir,
|
||||
Afile,
|
||||
|
||||
Root = 0,
|
||||
};
|
||||
|
||||
static Opts opts = {
|
||||
.group = nil,
|
||||
.cachewb = 0,
|
||||
.asroot = 0,
|
||||
.rdonly = 0,
|
||||
|
||||
.fstype = -1,
|
||||
.blksz = 1024,
|
||||
.label = "",
|
||||
.inodesz = 256,
|
||||
.ninode = 0,
|
||||
};
|
||||
static u32int Root;
|
||||
static u8int zero[65536];
|
||||
static char *srvname = "ext4";
|
||||
static char *srvname;
|
||||
static char *device;
|
||||
static Part *devpart;
|
||||
|
||||
static int
|
||||
haveperm(Aux *a, int p, struct ext4_inode *inodeout)
|
||||
|
@ -115,27 +109,31 @@ haveperm(Aux *a, int p, struct ext4_inode *inodeout)
|
|||
static void
|
||||
rattach(Req *r)
|
||||
{
|
||||
char err[ERRMAX];
|
||||
Aux *a;
|
||||
|
||||
if((a = calloc(1, sizeof(*a))) == nil)
|
||||
respond(r, "memory");
|
||||
else if((a->p = openpart(r->ifcall.aname, &opts)) == nil){
|
||||
free(a);
|
||||
rerrstr(err, sizeof(err));
|
||||
respond(r, err);
|
||||
}else{
|
||||
if(opts.asroot || findgroup(&a->p->groups, r->ifcall.uname, &a->uid) == nil)
|
||||
a->uid = Root;
|
||||
|
||||
incref(a->p);
|
||||
a->type = Adir;
|
||||
a->path = estrdup9p("");
|
||||
r->ofcall.qid = a->p->qidmask;
|
||||
r->fid->qid = a->p->qidmask;
|
||||
r->fid->aux = a;
|
||||
respond(r, nil);
|
||||
if(r->ifcall.aname && *r->ifcall.aname){
|
||||
if((a->p = openpart(r->ifcall.aname, &opts)) == nil){
|
||||
free(a);
|
||||
responderror(r);
|
||||
return;
|
||||
}
|
||||
}else if((a->p = devpart) == nil){
|
||||
respond(r, "no file specified");
|
||||
return;
|
||||
}
|
||||
|
||||
if(opts.asroot || findgroup(&a->p->groups, r->ifcall.uname, &a->uid) == nil)
|
||||
a->uid = Root;
|
||||
|
||||
incref(a->p);
|
||||
a->type = Adir;
|
||||
a->path = estrdup9p("");
|
||||
r->ofcall.qid = a->p->qidmask;
|
||||
r->fid->qid = a->p->qidmask;
|
||||
r->fid->aux = a;
|
||||
respond(r, nil);
|
||||
}
|
||||
|
||||
static u32int
|
||||
|
@ -573,7 +571,7 @@ rwstat(Req *r)
|
|||
|
||||
wrperm = haveperm(a, OWRITE, &inode);
|
||||
uid = ext4_inode_get_uid(&inode);
|
||||
isowner = uid == Root || a->uid == uid;
|
||||
isowner = a->uid == Root || a->uid == uid;
|
||||
|
||||
/* permission to truncate */
|
||||
isdir = ext4_inode_type(a->p->sb, &inode) == EXT4_INODE_MODE_DIRECTORY;
|
||||
|
@ -876,8 +874,9 @@ static Srv fs = {
|
|||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprint(2, "usage: %s [-Crs] [-g groupfile] [-R uid] [srvname]\n", argv0);
|
||||
fprint(2, "mkfs: %s -M (2|3|4) [-L label] [-b blksize] [-N numinodes] [-I inodesize] device\n", argv0);
|
||||
fprint(2,
|
||||
"usage: %s [-Ss] [-f file] [-g groupfile] [-n srvname] [-r (2|3|4)]"
|
||||
" [-b blksize] [-I inodesize] [-L label]\n", argv0);
|
||||
threadexitsall("usage");
|
||||
}
|
||||
|
||||
|
@ -891,20 +890,19 @@ threadmain(int argc, char **argv)
|
|||
rfork(RFNOTEG);
|
||||
|
||||
stdio = 0;
|
||||
device = nil;
|
||||
ARGBEGIN{
|
||||
case 'D':
|
||||
chatty9p++;
|
||||
nomkfs:
|
||||
if(opts.fstype > 0)
|
||||
usage();
|
||||
opts.fstype = 0;
|
||||
break;
|
||||
case 'd':
|
||||
ext4_dmask_set(strtoul(EARGF(usage()), nil, 0));
|
||||
break;
|
||||
case 'C':
|
||||
opts.cachewb = 1;
|
||||
goto nomkfs;
|
||||
case 'f':
|
||||
if(device != nil)
|
||||
usage();
|
||||
device = EARGF(usage());
|
||||
break;
|
||||
case 'g':
|
||||
gr = EARGF(usage());
|
||||
if((f = open(gr, OREAD)) < 0)
|
||||
|
@ -919,70 +917,62 @@ nomkfs:
|
|||
sysfatal("%s: read failed", gr);
|
||||
close(f);
|
||||
opts.group[sz] = 0;
|
||||
goto nomkfs;
|
||||
case 'R':
|
||||
opts.asroot = 1;
|
||||
Root = atoll(EARGF(usage()));
|
||||
goto nomkfs;
|
||||
case 'r':
|
||||
opts.rdonly = 1;
|
||||
goto nomkfs;
|
||||
break;
|
||||
case 'n':
|
||||
if(stdio != 0)
|
||||
usage();
|
||||
srvname = EARGF(usage());
|
||||
break;
|
||||
case 's':
|
||||
stdio = 1;
|
||||
goto nomkfs;
|
||||
case 'M':
|
||||
if(!opts.fstype)
|
||||
usage();
|
||||
opts.fstype = atoi(EARGF(usage()));
|
||||
if(opts.fstype < 2 || opts.fstype > 4)
|
||||
if(srvname != nil)
|
||||
usage();
|
||||
break;
|
||||
case 'S':
|
||||
opts.asroot = 1;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
opts.blksz = atoi(EARGF(usage()));
|
||||
if(opts.blksz != 1024 && opts.blksz != 2048 && opts.blksz != 4096)
|
||||
usage();
|
||||
yesmkfs:
|
||||
if(opts.fstype < 1)
|
||||
usage();
|
||||
break;
|
||||
case 'L':
|
||||
opts.label = EARGF(usage());
|
||||
goto yesmkfs;
|
||||
case 'I':
|
||||
opts.inodesz = atoi(EARGF(usage()));
|
||||
if(opts.inodesz < 128 || ((opts.inodesz-1) & opts.inodesz) != 0)
|
||||
usage();
|
||||
goto yesmkfs;
|
||||
case 'N':
|
||||
opts.ninode = atoi(EARGF(usage()));
|
||||
if(opts.ninode < 1)
|
||||
break;
|
||||
case 'L':
|
||||
opts.label = EARGF(usage());
|
||||
break;
|
||||
case 'r':
|
||||
if(opts.ream > 0)
|
||||
usage();
|
||||
goto yesmkfs;
|
||||
opts.ream = atoi(EARGF(usage()));
|
||||
if(opts.ream < 2 || opts.ream > 4)
|
||||
usage();
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}ARGEND
|
||||
|
||||
if(opts.fstype > 1){
|
||||
if(argc != 1)
|
||||
usage();
|
||||
if(openpart(argv[0], &opts) == nil)
|
||||
sysfatal("%r");
|
||||
closeallparts();
|
||||
threadexitsall(nil);
|
||||
}else{
|
||||
if(!stdio && argc == 1)
|
||||
srvname = *argv;
|
||||
else if(argc != 0)
|
||||
usage();
|
||||
if(argc != 0)
|
||||
usage();
|
||||
|
||||
if(stdio){
|
||||
fs.infd = 0;
|
||||
fs.outfd = 1;
|
||||
threadsrv(&fs);
|
||||
}else
|
||||
threadpostsrv(&fs, srvname);
|
||||
threadexits(nil);
|
||||
if(device == nil && opts.ream > 1)
|
||||
usage();
|
||||
if(device != nil && (devpart = openpart(device, &opts)) == nil)
|
||||
sysfatal("%r");
|
||||
|
||||
if(stdio){
|
||||
fs.infd = 0;
|
||||
fs.outfd = 1;
|
||||
threadsrv(&fs);
|
||||
}else{
|
||||
if(srvname == nil)
|
||||
srvname = "ext4";
|
||||
threadpostsrv(&fs, srvname);
|
||||
}
|
||||
threadexits(nil);
|
||||
}
|
||||
|
|
|
@ -154,16 +154,12 @@ static void *
|
|||
readfile(Part *p, char *path, usize *sz)
|
||||
{
|
||||
usize n, got;
|
||||
char *s, *d;
|
||||
ext4_file f;
|
||||
char *d;
|
||||
int r;
|
||||
|
||||
d = nil;
|
||||
while(*path == '/')
|
||||
path++;
|
||||
s = smprint("/%s", path);
|
||||
r = ext4_fopen2(&p->mp, &f, s, O_RDONLY);
|
||||
free(s);
|
||||
r = ext4_fopen2(&p->mp, &f, path, O_RDONLY);
|
||||
|
||||
if(r == 0){
|
||||
*sz = ext4_fsize(&f);
|
||||
|
@ -203,7 +199,7 @@ mountpart(Part *p, Opts *opts)
|
|||
int r;
|
||||
|
||||
mp = &p->mp;
|
||||
if(ext4_mount(mp, &p->bdev, opts->rdonly) < 0){
|
||||
if(ext4_mount(mp, &p->bdev, 0) < 0){
|
||||
werrstr("mount: %r");
|
||||
goto error;
|
||||
}
|
||||
|
@ -219,8 +215,7 @@ mountpart(Part *p, Opts *opts)
|
|||
werrstr("journal: %r");
|
||||
goto error;
|
||||
}
|
||||
if(opts->cachewb)
|
||||
ext4_cache_write_back(mp, 1);
|
||||
ext4_cache_write_back(mp, 1);
|
||||
|
||||
if(ext4_get_sblock(mp, &p->sb) < 0){
|
||||
werrstr("sblock: %r");
|
||||
|
@ -230,7 +225,7 @@ mountpart(Part *p, Opts *opts)
|
|||
r = 0;
|
||||
if(opts->group != nil){
|
||||
r = loadgroups(&p->groups, opts->group);
|
||||
}else if((gr = readfile(p, "/etc/group", &sz)) != nil){
|
||||
}else if((gr = readfile(p, "etc/group", &sz)) != nil){
|
||||
gr[sz] = 0;
|
||||
r = loadgroups(&p->groups, gr);
|
||||
free(gr);
|
||||
|
@ -307,19 +302,18 @@ openpart(char *dev, Opts *opts)
|
|||
p->partdev = (char*)(p+1) + blksz;
|
||||
strcpy(p->partdev, dev);
|
||||
|
||||
if(opts->fstype > 1){
|
||||
if(opts->ream > 1){
|
||||
memset(&fs, 0, sizeof(fs));
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.block_size = opts->blksz;
|
||||
snprint(info.label, sizeof(info.label), opts->label);
|
||||
info.inode_size = opts->inodesz;
|
||||
info.inodes = opts->ninode;
|
||||
info.journal = opts->fstype > 2;
|
||||
info.journal = opts->ream > 2;
|
||||
for(i = 0; i < 16; i += 4){
|
||||
rn = truerand();
|
||||
memcpy(info.uuid+i, &rn, 4);
|
||||
}
|
||||
if(ext4_mkfs(&fs, &p->bdev, &info, opts->fstype) < 0){
|
||||
if(ext4_mkfs(&fs, &p->bdev, &info, opts->ream) < 0){
|
||||
werrstr("mkfs: %r");
|
||||
goto error;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue