ref: 9ebd6f860e9d551e8b1c8f0a0c62bb4c1aa2c268
parent: ce86e64ee0d3b2e5e44319d654f8a05ca8a47b7e
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sat Apr 27 12:26:55 EDT 2024
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.
--- a/sys/man/4/ext4srv
+++ b/sys/man/4/ext4srv
@@ -4,34 +4,29 @@
.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,13 +38,12 @@
.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
@@ -56,7 +50,8 @@
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 @@
.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).
--- a/sys/src/cmd/ext4srv/common.h
+++ b/sys/src/cmd/ext4srv/common.h
@@ -3,14 +3,10 @@
struct Opts {
char *group;
- int cachewb;
int asroot;
- int rdonly;
-
- int fstype;
+ int ream;
int blksz;
int inodesz;
- u32int ninode;
char *label;
};
--- a/sys/src/cmd/ext4srv/ext4srv.c
+++ b/sys/src/cmd/ext4srv/ext4srv.c
@@ -30,23 +30,17 @@
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 @@
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 @@
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 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 @@
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 @@
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)
+ if(srvname != nil)
usage();
- opts.fstype = atoi(EARGF(usage()));
- if(opts.fstype < 2 || opts.fstype > 4)
- 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);
}
--- a/sys/src/cmd/ext4srv/part.c
+++ b/sys/src/cmd/ext4srv/part.c
@@ -154,16 +154,12 @@
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 @@
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 @@
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 @@
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 @@
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;
}