URI: 
       tsyncarena.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tsyncarena.c (4816B)
       ---
            1 #include "stdinc.h"
            2 #include "dat.h"
            3 #include "fns.h"
            4 
            5 static int        writeclumphead(Arena *arena, u64int aa, Clump *cl);
            6 static int        writeclumpmagic(Arena *arena, u64int aa, u32int magic);
            7 
            8 int
            9 clumpinfocmp(ClumpInfo *c, ClumpInfo *d)
           10 {
           11         return c->type != d->type
           12                 || c->size != d->size
           13                 || c->uncsize != d->uncsize
           14                 || scorecmp(c->score, d->score)!=0;
           15 }
           16 
           17 /*
           18  * synchronize the clump info directory with
           19  * with the clumps actually stored in the arena.
           20  * the directory should be at least as up to date
           21  * as the arena's trailer.
           22  *
           23  * checks/updates at most n clumps.
           24  *
           25  * returns 0 if ok, flags if error occurred
           26  */
           27 int
           28 syncarena(Arena *arena, u32int n, int zok, int fix)
           29 {
           30         ZBlock *lump;
           31         Clump cl;
           32         ClumpInfo ci;
           33         static ClumpInfo zci = { .type = -1 };
           34         u8int score[VtScoreSize];
           35         u64int uncsize, used, aa;
           36         u32int clump, clumps, cclumps, magic;
           37         int err, flush, broken;
           38 
           39         used = arena->memstats.used;
           40         clumps = arena->memstats.clumps;
           41         cclumps = arena->memstats.cclumps;
           42         uncsize = arena->memstats.uncsize;
           43         trace(TraceProc, "syncarena start");
           44         flush = 0;
           45         err = 0;
           46         for(; n; n--){
           47                 aa = arena->memstats.used;
           48                 clump = arena->memstats.clumps;
           49                 magic = clumpmagic(arena, aa);
           50                 if(magic == ClumpFreeMagic)
           51                         break;
           52                 if(magic != arena->clumpmagic){
           53                         fprint(2, "%s: illegal clump magic number=%#8.8ux at clump=%d\n", arena->name, magic, clump);
           54                         /* err |= SyncDataErr; */
           55                         if(fix && writeclumpmagic(arena, aa, ClumpFreeMagic) < 0){
           56                                 fprint(2, "%s: can't write corrected clump free magic: %r", arena->name);
           57                                 err |= SyncFixErr;
           58                         }
           59                         break;
           60                 }
           61 
           62                 broken = 0;
           63                 lump = loadclump(arena, aa, 0, &cl, score, 0);
           64                 if(lump == nil){
           65                         fprint(2, "%s: clump=%d failed to read correctly: %r\n", arena->name, clump);
           66                         break;
           67                 }else if(cl.info.type != VtCorruptType){
           68                         scoremem(score, lump->data, cl.info.uncsize);
           69                         if(scorecmp(cl.info.score, score) != 0){
           70                                 /* ignore partially written block */
           71                                 if(cl.encoding == ClumpENone)
           72                                         break;
           73                                 fprint(2, "%s: clump=%d has mismatched score\n", arena->name, clump);
           74                                 err |= SyncDataErr;
           75                                 broken = 1;
           76                         }else if(vttypevalid(cl.info.type) < 0){
           77                                 fprint(2, "%s: clump=%d has invalid type %d", arena->name, clump, cl.info.type);
           78                                 err |= SyncDataErr;
           79                                 broken = 1;
           80                         }
           81                         if(broken && fix){
           82                                 cl.info.type = VtCorruptType;
           83                                 if(writeclumphead(arena, aa, &cl) < 0){
           84                                         fprint(2, "%s: can't write corrected clump header: %r", arena->name);
           85                                         err |= SyncFixErr;
           86                                 }
           87                         }
           88                 }
           89                 freezblock(lump);
           90                 arena->memstats.used += ClumpSize + cl.info.size;
           91 
           92                 arena->memstats.clumps++;
           93                 if(!broken && readclumpinfo(arena, clump, &ci)<0){
           94                         fprint(2, "%s: arena directory read failed\n", arena->name);
           95                         broken = 1;
           96                 }else if(!broken && clumpinfocmp(&ci, &cl.info)!=0){
           97                         if(clumpinfocmp(&ci, &zci) == 0){
           98                                 err |= SyncCIZero;
           99                                 if(!zok)
          100                                         fprint(2, "%s: unwritten clump info for clump=%d\n", arena->name, clump);
          101                         }else{
          102                                 err |= SyncCIErr;
          103                                 fprint(2, "%s: bad clump info for clump=%d\n", arena->name, clump);
          104                                 fprint(2, "\texpected score=%V type=%d size=%d uncsize=%d\n",
          105                                         cl.info.score, cl.info.type, cl.info.size, cl.info.uncsize);
          106                                 fprint(2, "\tfound score=%V type=%d size=%d uncsize=%d\n",
          107                                         ci.score, ci.type, ci.size, ci.uncsize);
          108                         }
          109                         broken = 1;
          110                 }
          111                 if(broken && fix){
          112                         flush = 1;
          113                         ci = cl.info;
          114                         if(writeclumpinfo(arena, clump, &ci) < 0){
          115                                 fprint(2, "%s: can't write correct clump directory: %r\n", arena->name);
          116                                 err |= SyncFixErr;
          117                         }
          118                 }
          119                 trace(TraceProc, "syncarena unindexed clump %V %d", cl.info.score, arena->memstats.clumps);
          120 
          121                 arena->memstats.uncsize += cl.info.uncsize;
          122                 if(cl.info.size < cl.info.uncsize)
          123                         arena->memstats.cclumps++;
          124         }
          125 
          126         if(flush){
          127                 trace(TraceProc, "syncarena flush");
          128                 arena->wtime = now();
          129                 if(arena->ctime == 0 && arena->memstats.clumps)
          130                         arena->ctime = arena->wtime;
          131                 flushdcache();
          132         }
          133 
          134         if(used != arena->memstats.used
          135         || clumps != arena->memstats.clumps
          136         || cclumps != arena->memstats.cclumps
          137         || uncsize != arena->memstats.uncsize){
          138                 err |= SyncHeader;
          139                 fprint(2, "arena %s: fix=%d flush=%d %lld->%lld %ud->%ud %ud->%ud %lld->%lld\n",
          140                         arena->name,
          141                         fix,
          142                         flush,
          143                         used, arena->memstats.used,
          144                         clumps, arena->memstats.clumps,
          145                         cclumps, arena->memstats.cclumps,
          146                         uncsize, arena->memstats.uncsize);
          147         }
          148 
          149         return err;
          150 }
          151 
          152 static int
          153 writeclumphead(Arena *arena, u64int aa, Clump *cl)
          154 {
          155         ZBlock *zb;
          156         int bad;
          157 
          158         zb = alloczblock(ClumpSize, 0, arena->blocksize);
          159         if(zb == nil)
          160                 return -1;
          161         bad = packclump(cl, zb->data, arena->clumpmagic)<0
          162                 || writearena(arena, aa, zb->data, ClumpSize) != ClumpSize;
          163         freezblock(zb);
          164         return bad ? -1 : 0;
          165 }
          166 
          167 static int
          168 writeclumpmagic(Arena *arena, u64int aa, u32int magic)
          169 {
          170         u8int buf[U32Size];
          171 
          172         packmagic(magic, buf);
          173         return writearena(arena, aa, buf, U32Size) == U32Size;
          174 }