summaryrefslogtreecommitdiff
path: root/sys/src/cmd/dossrv/iotrack.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2023-04-30 18:44:29 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2023-04-30 18:44:29 +0000
commitd24b5a7a0e45186f13d19ddefde62b0932726e42 (patch)
treea3cfeee8dd915bbd60e9f6be96c7318f81e1dfd1 /sys/src/cmd/dossrv/iotrack.c
parent101b3c2724779fcb0e503ae274abd7b751a3a48f (diff)
dossrv: Implement support for != 512 sector and track sizes
The iotrack buffer layer always assumed 512 byte sector size and 9 sectors per track. To support 4K sector size fats, make the iotrack code deal with it. Instead of the fixed size Track structure, we just allocate the pointers and buffers dynamically, and move the sector size and tack size in the Xfs structure. Tracks can still be reused between differnet file-systems after a purgetrack(). The initial fat header has to be read with devread() instead of getsect() to determine the sector/track size of the file-system.
Diffstat (limited to 'sys/src/cmd/dossrv/iotrack.c')
-rw-r--r--sys/src/cmd/dossrv/iotrack.c174
1 files changed, 95 insertions, 79 deletions
diff --git a/sys/src/cmd/dossrv/iotrack.c b/sys/src/cmd/dossrv/iotrack.c
index 6081a5509..f1833ae56 100644
--- a/sys/src/cmd/dossrv/iotrack.c
+++ b/sys/src/cmd/dossrv/iotrack.c
@@ -4,6 +4,9 @@
#include "dat.h"
#include "fns.h"
+static MLock freelock;
+static Iosect * freelist;
+
#define HIOB 31 /* a prime */
#define NIOBUF 80
@@ -19,6 +22,10 @@ static Iotrack iobuf[NIOBUF]; /* the real ones */
#define TOFRONT(h, p) ((h)->next != (p) && (UNLINK(p, next, prev), LINK(h,p, next, prev)))
+static Iotrack *getiotrack(Xfs*, vlong);
+static Iosect *getiosect(Xfs*, vlong, int);
+static void purgetrack(Iotrack*);
+
Iosect *
getsect(Xfs *xf, vlong addr)
{
@@ -31,19 +38,21 @@ getosect(Xfs *xf, vlong addr)
return getiosect(xf, addr, 0);
}
-Iosect *
+static Iosect *
getiosect(Xfs *xf, vlong addr, int rflag)
{
- Iotrack *t;
vlong taddr;
int toff;
+ Iotrack *t;
Iosect *p;
if(addr < 0)
return nil;
- toff = addr % Sect2trk;
+ toff = addr % xf->sect2trk;
taddr = addr - toff;
t = getiotrack(xf, taddr);
+ if(t == nil)
+ return nil;
if(rflag && (t->flags&BSTALE)){
if(tread(t) < 0){
unmlock(&t->lock);
@@ -51,16 +60,31 @@ getiosect(Xfs *xf, vlong addr, int rflag)
}
t->flags &= ~BSTALE;
}
- t->ref++;
- p = t->tp->p[toff];
- if(p == 0){
- p = newsect();
- t->tp->p[toff] = p;
+ p = t->tp[toff];
+ if(p == nil){
+ mlock(&freelock);
+ p = freelist;
+ if(p != nil)
+ freelist = p->next;
+ else {
+ p = malloc(sizeof(Iosect));
+ if(p == nil) {
+ unmlock(&freelock);
+ unmlock(&t->lock);
+ return nil;
+ }
+ }
+ p->next = nil;
+ unmlock(&freelock);
+
p->flags = t->flags&BSTALE;
p->lock.key = 0;
+ p->iobuf = ((uchar*)&t->tp[xf->sect2trk]) + toff*xf->sectsize;
p->t = t;
- p->iobuf = t->tp->buf[toff];
+
+ t->tp[toff] = p;
}
+ t->ref++;
unmlock(&t->lock);
mlock(&p->lock);
return p;
@@ -87,7 +111,7 @@ putsect(Iosect *p)
unmlock(&p->lock);
}
-Iotrack *
+static Iotrack *
getiotrack(Xfs *xf, vlong addr)
{
Iotrack *hp, *p;
@@ -142,8 +166,14 @@ loop:
goto loop;
}
purgetrack(p);
- p->addr = addr;
+ p->tp = malloc(xf->sect2trk*sizeof(Iosect*) + xf->sect2trk*xf->sectsize);
+ if(p->tp == nil){
+ unmlock(&p->lock);
+ return nil;
+ }
+ memset(p->tp, 0, xf->sect2trk*sizeof(Iosect*));
p->xf = xf;
+ p->addr = addr;
p->flags = BSTALE;
out:
mlock(&hp->lock);
@@ -155,39 +185,55 @@ out:
return p;
}
-void
+static void
purgetrack(Iotrack *t)
{
- int i, ref = Sect2trk;
- Iosect *p;
-
- for(i=0; i<Sect2trk; i++){
- p = t->tp->p[i];
- if(p == 0){
- --ref;
- continue;
- }
- if(canmlock(&p->lock)){
- freesect(p);
- --ref;
- t->tp->p[i] = 0;
+ if(t->tp != nil){
+ Xfs *xf = t->xf;
+ int i, ref = xf->sect2trk;
+
+ for(i=0; i<xf->sect2trk; i++){
+ Iosect *p = t->tp[i];
+ if(p == nil){
+ --ref;
+ continue;
+ }
+ if(canmlock(&p->lock)){
+ t->tp[i] = nil;
+
+ mlock(&freelock);
+ p->next = freelist;
+ freelist = p;
+ unmlock(&freelock);
+ --ref;
+ }
}
+ if(t->ref != ref)
+ panic("purgetrack");
+ if(ref != 0)
+ return;
+
+ free(t->tp);
}
- if(t->ref != ref)
- panic("purgetrack");
+ assert(t->ref == 0);
+ t->tp = nil;
+ t->xf = nil;
+ t->addr = -1;
+ t->flags = 0;
}
int
twrite(Iotrack *t)
{
- int i, ref;
+ Xfs *xf = t->xf;
- chat("[twrite %lld...", t->addr);
+ chat("[twrite %lld+%lld...", t->addr, xf->offset);
if(t->flags & BSTALE){
- for(ref=0,i=0; i<Sect2trk; i++)
- if(t->tp->p[i])
+ int i, ref = 0;
+ for(i=0; i<xf->sect2trk; i++)
+ if(t->tp[i] != nil)
++ref;
- if(ref < Sect2trk){
+ if(ref < xf->sect2trk){
if(tread(t) < 0){
chat("error]");
return -1;
@@ -195,7 +241,7 @@ twrite(Iotrack *t)
}else
t->flags &= ~BSTALE;
}
- if(devwrite(t->xf, t->addr, t->tp->buf, Trksize) < 0){
+ if(devwrite(xf, t->addr, (uchar*)&t->tp[xf->sect2trk], xf->sect2trk*xf->sectsize) < 0){
chat("error]");
return -1;
}
@@ -206,33 +252,31 @@ twrite(Iotrack *t)
int
tread(Iotrack *t)
{
+ Xfs *xf = t->xf;
int i, ref = 0;
- uchar buf[Sect2trk][Sectorsize];
- for(i=0; i<Sect2trk; i++)
- if(t->tp->p[i])
+ chat("[tread %lld+%lld...", t->addr, xf->offset);
+ for(i=0; i<xf->sect2trk; i++)
+ if(t->tp[i] != nil)
++ref;
- chat("[tread %lld+%lld...", t->addr, t->xf->offset);
if(ref == 0){
- if(devread(t->xf, t->addr, t->tp->buf, Trksize) < 0){
+ if(devread(xf, t->addr, (uchar*)&t->tp[xf->sect2trk], xf->sect2trk*xf->sectsize) < 0){
chat("error]");
return -1;
}
- chat("done]");
- t->flags &= ~BSTALE;
- return 0;
- }
- if(devread(t->xf, t->addr, buf, Trksize) < 0){
- chat("error]");
- return -1;
- }
- for(i=0; i<Sect2trk; i++)
- if(t->tp->p[i] == 0){
- memmove(t->tp->buf[i], buf[i], Sectorsize);
+ } else {
+ for(i=0; i<xf->sect2trk; i++){
+ if(t->tp[i] != nil)
+ continue;
+ if(devread(xf, t->addr + i, ((uchar*)&t->tp[xf->sect2trk]) + i*xf->sectsize, xf->sectsize) < 0){
+ chat("error]");
+ return -1;
+ }
chat("%d ", i);
}
- chat("done]");
+ }
t->flags &= ~BSTALE;
+ chat("done]");
return 0;
}
@@ -285,34 +329,6 @@ iotrack_init(void)
p->hprev = p->hnext = p;
p->prev = p->next = p;
TOFRONT(mp, p);
- p->tp = sbrk(sizeof(Track));
- memset(p->tp->p, 0, sizeof p->tp->p);
+ purgetrack(p);
}
}
-
-static MLock freelock;
-static Iosect * freelist;
-
-Iosect *
-newsect(void)
-{
- Iosect *p;
-
- mlock(&freelock);
- if(p = freelist) /* assign = */
- freelist = p->next;
- else
- p = malloc(sizeof(Iosect));
- unmlock(&freelock);
- p->next = 0;
- return p;
-}
-
-void
-freesect(Iosect *p)
-{
- mlock(&freelock);
- p->next = freelist;
- freelist = p;
- unmlock(&freelock);
-}