fileSys::fileSys(Pdisk& dsk){ disk = dsk; bool flag = false; char tmp; string dat = disk.getDiskName()+".dat"; init(); ifstream file; file.open(dat.c_str()); file.seekg(disk.getBlockSize()-1); for(int i=disk.getBlockSize(); i < (2*disk.getBlockSize()); i++) { file.get(tmp); if(tmp != '#'){ flag = true; break; } } if(flag == true){ // data was found load fs load_fs(); }else{//data was not found make_fs(); fsSynch(); } file.close(); }
int fdelete(char* fn){ struct fs *the_fs = malloc(sizeof(struct fs)); int ret = 0; load_fs(the_fs); if(rem_dir_ent(&the_fs->root_dir, fn)) { ret = NOT_FOUND; }; store_fs(the_fs); free(the_fs); return ret; }
int initser() { now = time(NULL); load_fs(); // 创建线程保存配置信息(当发生变化时,10s保存一次) pthread_create(&fsthid, NULL, fs_thread, NULL); // 创建线程监听dat and drw pthread_create(&drwthid, NULL, drw_thread, NULL); pthread_create(&datthid, NULL, dat_thread, NULL); return 0; }
int load(char* fn, void* data, size_t ds){ struct fs *the_fs = malloc(sizeof(struct fs)); int ret = 5; load_fs(the_fs); struct dir_ent file_ent; if(get_dir_ent(&the_fs->root_dir, fn, &file_ent)) { ret = NOT_FOUND; goto error; } unsigned short addr = file_ent.file_addr; unsigned short next_addr = 0; size_t offset = 0; int cyl, sect; while(!get_next_addr(&the_fs->the_fat, addr, &next_addr) && offset < ds) { cyl = to_cylinder_number(addr); sect = to_sector_number(addr); read_sector(cyl, sect, data + offset); offset += BYTES_PER_SECTOR; addr = next_addr; } if(offset >= ds) { printf("looks like data cant hold the whole file!\n"); goto error; } cyl = to_cylinder_number(addr); sect = to_sector_number(addr); char leftover[BYTES_PER_SECTOR]; read_sector(cyl, sect, leftover); size_t to_read = (ds - offset > BYTES_PER_SECTOR) ? BYTES_PER_SECTOR-1 : ds - offset; memcpy(data + offset, leftover, to_read); ret = 0; error: free(the_fs); return ret; }
int save(char* fn, void* data, size_t ds){ struct fs *the_fs = malloc(sizeof(struct fs)); int ret = 5; load_fs(the_fs); struct dir_ent file_ent; unsigned short n = ds / BYTES_PER_SECTOR + 1; unsigned short *free_sectors = malloc(sizeof(unsigned short) * n); if(!get_dir_ent(&the_fs->root_dir, fn, &file_ent)) { ret = NAME_CONFLICT; goto error; }; if(getn_free_sectors(&the_fs->the_fat, n, free_sectors)) { //printf("Looks like there aren't %d sectors available!\n", n); ret = NO_SPACE; goto error; } // now we actually store our file size_t offset = 0; unsigned short addr, next_addr; int cyl, sect; addr = free_sectors[0]; // set the initial root_dir entry if(set_dir_ent(&the_fs->root_dir, fn, addr)) { printf("So we couldn't find an available space in our root_dir\n"); ret = NO_SPACE; goto error; } for(int i = 0; i < n-1; ++i) { addr = free_sectors[i]; next_addr = free_sectors[i+1]; cyl = to_cylinder_number(addr); sect = to_sector_number(addr); if(set_fat_entry_value(&the_fs->the_fat, addr, next_addr)) { printf("Apparently %d is not a valid address!\n", next_addr); goto error; } if(write_sector(cyl, sect, data + offset)) { printf("Something went wrong with write_sector\n"); goto error; } offset += BYTES_PER_SECTOR; } char leftover[BYTES_PER_SECTOR]; memcpy(leftover, data + offset, ds - offset); addr = free_sectors[n-1]; cyl = to_cylinder_number(addr); sect = to_sector_number(addr); if(set_fat_entry_value(&the_fs->the_fat, addr, END_OF_FILE)) { printf("We couldn't set the last addr to END_OF_FILE!\n"); goto error; } if(write_sector(cyl, sect, leftover)) { printf("Something went wrong with writing the last bit of data!\n"); goto error; } ret = 0; error: store_fs(the_fs); free(the_fs); free(free_sectors); return ret; }
/* * All traps come here. It is slower to have all traps call trap() * rather than directly vectoring the handler. However, this avoids a * lot of code duplication and possible bugs. The only exception is * VectorSYSCALL. * Trap is called with interrupts disabled via interrupt-gates. */ void trap(Ureg* ureg) { int clockintr, i, vno, user; char buf[ERRMAX]; Vctl *ctl, *v; Mach *mach; if(!trapinited){ /* fault386 can give a better error message */ if(ureg->trap == VectorPF) fault386(ureg, nil); panic("trap %lud: not ready", ureg->trap); } m->perf.intrts = perfticks(); user = userureg(ureg); if(user){ up->dbgreg = ureg; cycles(&up->kentry); } clockintr = 0; vno = ureg->trap; if(ctl = vctl[vno]){ if(ctl->isintr){ m->intr++; if(vno >= VectorPIC && vno != VectorSYSCALL) m->lastintr = ctl->irq; } if(ctl->isr) ctl->isr(vno); for(v = ctl; v != nil; v = v->next){ if(v->f) v->f(ureg, v->a); } if(ctl->eoi) ctl->eoi(vno); if(ctl->isintr){ intrtime(m, vno); if(ctl->irq == IrqCLOCK || ctl->irq == IrqTIMER) clockintr = 1; if(up && !clockintr) preempted(); } } else if(vno < nelem(excname) && user){ spllo(); sprint(buf, "sys: trap: %s", excname[vno]); postnote(up, 1, buf, NDebug); } else if(vno >= VectorPIC && vno != VectorSYSCALL){ /* * An unknown interrupt. * Check for a default IRQ7. This can happen when * the IRQ input goes away before the acknowledge. * In this case, a 'default IRQ7' is generated, but * the corresponding bit in the ISR isn't set. * In fact, just ignore all such interrupts. */ /* call all interrupt routines, just in case */ for(i = VectorPIC; i <= MaxIrqLAPIC; i++){ ctl = vctl[i]; if(ctl == nil) continue; if(!ctl->isintr) continue; for(v = ctl; v != nil; v = v->next){ if(v->f) v->f(ureg, v->a); } /* should we do this? */ if(ctl->eoi) ctl->eoi(i); } /* clear the interrupt */ i8259isr(vno); if(0)print("cpu%d: spurious interrupt %d, last %d\n", m->machno, vno, m->lastintr); if(0)if(conf.nmach > 1){ for(i = 0; i < 32; i++){ if(!(active.machs & (1<<i))) continue; mach = MACHP(i); if(m->machno == mach->machno) continue; print(" cpu%d: last %d", mach->machno, mach->lastintr); } print("\n"); } m->spuriousintr++; if(user) kexit(ureg); return; } else{ if(vno == VectorNMI){ /* * Don't re-enable, it confuses the crash dumps. nmienable(); */ iprint("cpu%d: nmi PC %#8.8lux, status %ux\n", m->machno, ureg->pc, inb(0x61)); while(m->machno != 0) ; } if(!user){ void (*pc)(void); ulong *sp; extern void _forkretpopgs(void); extern void _forkretpopfs(void); extern void _forkretpopes(void); extern void _forkretpopds(void); extern void _forkretiret(void); extern void _rdmsrinst(void); extern void _wrmsrinst(void); extern void load_fs(ulong); extern void load_gs(ulong); load_fs(NULLSEL); load_gs(NULLSEL); sp = (ulong*)&ureg->sp; /* kernel stack */ pc = (void*)ureg->pc; if(pc == _forkretpopgs || pc == _forkretpopfs || pc == _forkretpopes || pc == _forkretpopds){ if(vno == VectorGPF || vno == VectorSNP){ sp[0] = NULLSEL; return; } } else if(pc == _forkretiret){ if(vno == VectorGPF || vno == VectorSNP){ sp[1] = UESEL; /* CS */ sp[4] = UDSEL; /* SS */ return; } } else if(pc == _rdmsrinst || pc == _wrmsrinst){ if(vno == VectorGPF){ ureg->bp = -1; ureg->pc += 2; return; } } } dumpregs(ureg); if(!user){ ureg->sp = (ulong)&ureg->sp; _dumpstack(ureg); } if(vno < nelem(excname)) panic("%s", excname[vno]); panic("unknown trap/intr: %d", vno); } splhi(); /* delaysched set because we held a lock or because our quantum ended */ if(up && up->delaysched && clockintr){ sched(); splhi(); } if(user){ if(up->procctl || up->nnote) notify(ureg); kexit(ureg); } }