ref: 7288138f121ce4bb74c3678c5f4d3817a68b995f
parent: 52e1939db1bfb60e7c9101c03068f6c2cfa27fa0
author: 9ferno <[email protected]>
date: Tue Nov 8 02:34:26 EST 2022
jumbo writes
--- a/dev.c
+++ b/dev.c
@@ -31,13 +31,19 @@
}
int
-devwrite(u64 blkno, void *b)
+devwrites(u64 blkno, void *b, u64 n)
{
- int n;
+ int wn;
- if((n = pwrite(devfd, b, Rawblocksize, blkno*Rawblocksize)) != Rawblocksize)
+ if((wn = pwrite(devfd, b, n*Rawblocksize, blkno*Rawblocksize)) != n*Rawblocksize)
panic("devwrite failed: %r\n");
- return n;
+ return wn;
+}
+
+int
+devwrite(u64 blkno, void *b)
+{
+ return devwrites(blkno, b, 1);
}
/* obsoleted, a hack for more efficient logging */
--- a/docs/mafs.ms
+++ b/docs/mafs.ms
@@ -1182,25 +1182,20 @@
.fi
.sp
Starting mafs on a 2MB byte file. The below commands create a disk.file to use as a disk. Mount /n/mafs_disk.file for the file system.
-.nf
.sp
+.nf
dd -if /dev/zero -of disk.file -bs 512 -count 4096;
-.br
mount -c <{disk/mafs -s -r mafs_disk.file -m 1 -n mafs_disk.file \\
<[0=1]} /n/mafs_disk.file
.fi
.sp
Starting mafs on a RAM file. The below commands create a ramfs filesystem to use as a disk.
-.nf
.sp
+.nf
ramfs -m /n/mafs_ramfs
-.br
touch /n/mafs_ramfs/file
-.br
dd -if /dev/zero -of /n/mafs_ramfs/file -count 700 -bs 1m
-.br
disk/mafs -r mafs_ramfs_file /n/mafs_ramfs/file
-.br
mount -c /srv/mafs_ramfs_file /n/mafs_ramfs_file
.fi
.sp
--- a/fns.h
+++ b/fns.h
@@ -11,6 +11,7 @@
int devread(u64 blkno, void *b);
u64 devsize(void);
int devwrite(u64 blkno, void *b);
+int devwrites(u64 blkno, void *b, u64 n);
/* show blocks */
void showblock(int fd, u8 *buf);
--- a/writer.c
+++ b/writer.c
@@ -71,39 +71,6 @@
return b;
}
-Wbuf *
-getwrite(void)
-{
- Wbuf *b;
-
- qlock(&drts.lck);
- if(drts.n == 0){
- if(stopwrites){
- qunlock(&drts.lck);
- return nil;
- }
- rsleep(&drts.isempty);
- if(drts.n == 0 && stopwrites){
- qunlock(&drts.lck);
- return nil;
- }
- }
- /* using canwlock() here as getbuf() could
- have wlock()'ed the Iobuf too */
- if(drts.head != nil){
- b = pluck(drts.head);
- if(drts.n == npendingwrites-1)
- rwakeup(&drts.isfull);
- if(chatty9p > 4 && b!=nil){
- dprint("getwrite done b->blkno %llud\n", b->blkno);
- stats();
- }
- }else
- b = nil;
- qunlock(&drts.lck);
- return b;
-}
-
/* the Iobuf should be wlock()'ed at entry */
void
putwrite(Iobuf *b)
@@ -154,33 +121,103 @@
incref(dirties) only happens with a wlock() in putwrite().
*/
void
-dowrite(Wbuf *p)
+dowrite(void)
{
- u64 n;
+ Wbuf *b, *blks[128];
+ u64 prevblkno, startblkno, n, wn, i;
+ u8 full, *jumbo;
- if(chatty9p > 4){
- dprint("dowrite p->blkno %llud\n", p->blkno);
- stats();
+ full = 0;
+ qlock(&drts.lck);
+ if(drts.n == 0){
+ if(stopwrites){
+ qunlock(&drts.lck);
+ return;
+ }
+ rsleep(&drts.isempty);
+ if(drts.n == 0 && stopwrites){
+ qunlock(&drts.lck);
+ return;
+ }
}
- if(chatty9p > 4)
- dprint("dowrite p->blkno %llud locked\n", p->blkno);
- if((n = devwrite(p->blkno, p->payload)) != Rawblocksize){
- dprint("%s\n", errstring[Esystem]);
- panic("error writing block %llud: %llud bytes: %r\n",
- p->blkno, n);
+ /* using canwlock() here as getbuf() could
+ have wlock()'ed the Iobuf too */
+ if(drts.head != nil){
+ if(drts.n == npendingwrites-1)
+ full = 1;
+ if(drts.n > 1){
+ /* trying to write consecutive blocks with a write() call */
+ n = 1;
+ prevblkno = startblkno = drts.head->blkno;
+ for(b = drts.head->next;
+ b != nil && b->blkno == prevblkno+1 && n < 128;
+ b = b->next){
+ prevblkno=b->blkno;
+ n++;
+ }
+ if(n > 1){
+ if(chatty9p > 4){
+ if(b != nil)
+ dprint("getwrite jumbo drts.n %llud > 1 n %llud start %llud next %llud\n",
+ drts.n, n, startblkno, b->blkno);
+ else
+ dprint("getwrite jumbo drts.n %llud > 1 n %llud start %llud\n",
+ drts.n, n, startblkno);
+ }
+ jumbo = emalloc9p(n*Rawblocksize);
+ for(i = 0; i < n; i++){
+ b = pluck(drts.head);
+ memcpy(jumbo+(i*Rawblocksize), b->payload, Rawblocksize);
+ blks[i] = b;
+ if(chatty9p > 4 && b!=nil)
+ dprint("getwrite done b->blkno %llud\n", b->blkno);
+ }
+ if((wn = devwrites(startblkno, jumbo, n)) != n*Rawblocksize){
+ dprint("%s\n", errstring[Esystem]);
+ panic("error writing block %llud: %llud bytes, written %llud: %r\n",
+ b->blkno, n, wn);
+ }
+ for(i = 0; i < n; i++){
+ b = blks[i];
+ blks[i] = 0;
+ if(chatty9p > 4)
+ dprint("dowrite %llud wunlock()'ed\n", b->blkno);
+ decref(&b->iobuf->dirties);
+ freememunit(b->payload);
+ free(b);
+ }
+ free(jumbo);
+ qunlock(&drts.lck);
+ return;
+ }
+ goto single;
+ }else{
+single:
+ b = pluck(drts.head);
+ if(chatty9p > 4 && b!=nil)
+ dprint("getwrite done b->blkno %llud\n", b->blkno);
+ if((n = devwrite(b->blkno, b->payload)) != Rawblocksize){
+ dprint("%s\n", errstring[Esystem]);
+ panic("error writing block %llud: %llud bytes: %r\n",
+ b->blkno, n);
+ }
+ if(chatty9p > 4)
+ dprint("dowrite %llud wunlock()'ed\n", b->blkno);
+ decref(&b->iobuf->dirties);
+ freememunit(b->payload);
+ free(b);
+ }
+ if(full)
+ rwakeup(&drts.isfull);
+ if(chatty9p > 4 && b!=nil)
+ stats();
}
- n = p->blkno;
- if(chatty9p > 4)
- dprint("dowrite %llud wunlock()'ed\n", n);
- decref(&p->iobuf->dirties);
- freememunit(p->payload);
- free(p);
+ qunlock(&drts.lck);
}
void
initwriter(void)
{
- Wbuf *b;
char name[Namelen];
// set the locks used by the Rendezes
@@ -201,9 +238,7 @@
snprint(name, Namelen, "%s writer", service);
procsetname(name);
while(stopwrites == 0 || drts.n > 0){
- b=getwrite();
- if(b != nil)
- dowrite(b);
+ dowrite();
}
if(chatty9p > 4)
dprint("%s process exited\n", name);