A few corrections for ramfs(4): - when wstat sets file length to zero, truncate the file instead of crashing - when wstat changes file mtime, don't ignore the request - on attempt to remove a nonexistent file, respond with Enotexist instead of Eperm - don't impose a static limit on the number of allocated files Reference: /n/sources/patch/ramfs-fixes Date: Mon May 30 14:53:35 CES 2016 Signed-off-by: miller@hamnavoe.com --- /sys/src/cmd/ramfs.c Mon May 30 14:53:10 2016 +++ /sys/src/cmd/ramfs.c Mon May 30 14:53:07 2016 @@ -13,7 +13,7 @@ enum { OPERM = 0x3, /* mask of all permission types in open mode */ - Nram = 4096, + Nram = 1024, Maxsize = 768*1024*1024, Maxfdata = 8192, Maxulong= (1ULL << 32) - 1, @@ -62,7 +62,8 @@ ulong path; /* incremented for each new file */ Fid *fids; -Ram ram[Nram]; +Ram *ram; +int maxnram = Nram; int nram; int mfd[2]; char *user; @@ -82,6 +83,7 @@ char *estrdup(char*); void usage(void); int perm(Fid*, Ram*, int); +Ram *ramexpand(Ram*); char *rflush(Fid*), *rversion(Fid*), *rauth(Fid*), *rattach(Fid*), *rwalk(Fid*), @@ -209,6 +211,7 @@ user = getuser(); notify(notifyf); + ram = emalloc(maxnram*sizeof(Ram)); nram = 1; r = &ram[0]; r->busy = 1; @@ -459,7 +462,7 @@ if(strcmp((char*)name, r->name)==0) return Einuse; for(r=ram; r->busy; r++) - if(r == &ram[Nram-1]) + if(r == &ram[maxnram-1] && (r = ramexpand(r)) == nil) return "no free ram resources"; r->busy = 1; r->qid.path = ++path; @@ -637,6 +640,8 @@ f->open = 0; r = f->ram; f->ram = 0; + if(r->busy == 0) + return Enotexist; if(r->qid.path == 0 || !perm(f, &ram[r->parent], Pwrite)) return Eperm; ram[r->parent].mtime = time(0); @@ -686,10 +691,11 @@ } /* - * To change mode, must be owner or group leader. + * To change mode or mtime, must be owner or group leader. * Because of lack of users file, leader=>group itself. */ - if(dir.mode!=~0 && r->perm!=dir.mode){ + if(dir.mode!=~0 && r->perm!=dir.mode || + dir.mtime!=~0 && dir.mtime!=r->mtime){ if(strcmp(f->user, r->user) != 0) if(strcmp(f->user, r->group) != 0) return Enotowner; @@ -717,6 +723,8 @@ dir.mode |= r->perm&DMDIR; r->perm = dir.mode; } + if(dir.mtime != ~0) + r->mtime = dir.mtime; if(dir.name[0] != '\0'){ free(r->name); r->name = estrdup(dir.name); @@ -857,6 +865,26 @@ return 0; } +Ram* +ramexpand(Ram *r) +{ + Ram *newram; + Fid *f; + uintptr offs; + + newram = (Ram*)realloc(ram, (maxnram+Nram)*sizeof(Ram)); + if(newram == nil) + return nil; + memset(newram + maxnram, 0, Nram*sizeof(Ram)); + offs = (uintptr)newram - (uintptr)ram; + for(f = fids; f; f = f->next) + if(f->busy && f->ram != nil) + f->ram = (Ram*)((uintptr)f->ram + offs); + maxnram += Nram; + ram = newram; + return (Ram*)((uintptr)r + offs); +} + void error(char *s) { @@ -880,7 +908,7 @@ erealloc(void *p, ulong n) { p = realloc(p, n); - if(!p) + if(n != 0 && !p) error("out of memory"); return p; }