arg_t _getfsys(void) { struct mount *m = fs_tab_get(dev); if (m == NULL || m->m_dev == NO_DEVICE) { udata.u_error = ENXIO; return (-1); } return uput((char *) m->m_fs, (char *) buf, sizeof(struct filesys)); }
/* Validblk panics if the given block number is not a valid * data block for the given device. */ void validblk(uint16_t dev, blkno_t num) { struct mount *mnt; fsptr devptr; mnt = fs_tab_get(dev); if(mnt == NULL || !(devptr = mnt->m_fs) || devptr->s_mounted == 0) { panic("validblk: not mounted"); return; } if(num < devptr->s_isize || num >= devptr->s_fsize) panic("validblk: invalid blk"); }
fsptr getdev(uint16_t dev) { struct mount *mnt; fsptr devfs; time_t t; mnt = fs_tab_get(dev); if (!mnt || !(devfs = mnt->m_fs) || devfs->s_mounted) { panic("getdev: bad dev"); /* Return needed to persuade SDCC all is ok */ return NULL; } rdtime(&t); devfs->s_time = (uint32_t)t; devfs->s_timeh = (uint8_t)(t >> 32); devfs->s_fmod = true; ((bufptr)devfs)->bf_dirty = true; return devfs; }
inoptr kn_open(char *namep, inoptr *parent) { staticfast inoptr wd; /* the directory we are currently searching. */ staticfast inoptr ninode; inoptr temp; staticfast char *name; name = namep; #ifdef DEBUG kprintf("kn_open(\"%s\")\n", name); #endif if(*name == '/') wd = udata.u_root; else wd = udata.u_cwd; i_ref(ninode = wd); i_ref(ninode); for(;;) { if(ninode) magic(ninode); /* cheap way to spot rename inside yourself */ if (udata.u_rename == ninode) udata.u_rename = NULLINODE; /* See if we are at a mount point */ if(ninode) ninode = srch_mt(ninode); while(*name == '/') /* Skip(possibly repeated) slashes */ ++name; if(!*name) /* No more components of path? */ break; if(!ninode){ udata.u_error = ENOENT; goto nodir; } i_deref(wd); wd = ninode; if(getmode(wd) != F_DIR){ udata.u_error = ENOTDIR; goto nodir; } if(!(getperm(wd) & OTH_EX)){ udata.u_error = EPERM; goto nodir; } /* See if we are going up through a mount point */ if((wd == udata.u_root || (wd->c_num == ROOTINODE && wd->c_dev != root_dev)) && name[0] == '.' && name[1] == '.' && (name[2] == '/' || name[2] == '\0')){ if (wd == udata.u_root) { ninode = wd; name += 2; continue; } temp = fs_tab_get(wd->c_dev)->m_fs->s_mntpt; ++temp->c_refs; i_deref(wd); wd = temp; } ninode = srch_dir(wd, name); while(*name != '/' && *name) ++name; } if(parent) *parent = wd; else i_deref(wd); if(!(parent || ninode)) udata.u_error = ENOENT; return ninode; nodir: if(parent) *parent = NULLINODE; i_deref(wd); return NULLINODE; }
inoptr i_open(uint16_t dev, uint16_t ino) { struct dinode *buf; inoptr nindex, j; bool isnew = false; if(!validdev(dev)) panic("i_open: bad dev"); if(!ino){ /* ino==0 means we want a new one */ isnew = true; ino = i_alloc(dev); if(!ino) { udata.u_error = ENOSPC; return NULLINODE; } } /* Maybe make this DEBUG only eventually - the fs_tab_get cost is higher than ideal */ if(ino < ROOTINODE || ino >= (fs_tab_get(dev)->m_fs->s_isize - 2) * 8) { kputs("i_open: bad inode number\n"); return NULLINODE; } nindex = NULLINODE; for(j=i_tab; j<i_tab+ITABSIZE; j++){ if(!j->c_refs) // free slot? nindex = j; if(j->c_dev == dev && j->c_num == ino) { nindex = j; goto found; } } /* Not already in the table. */ if(!nindex){ /* No unrefed slots in inode table */ udata.u_error = ENFILE; return(NULLINODE); } buf =(struct dinode *)bread(dev,(ino>>3)+2, 0); memcpy((char *)&(nindex->c_node), (char *)&(buf[ino & 0x07]), 64); brelse(buf); nindex->c_dev = dev; nindex->c_num = ino; nindex->c_magic = CMAGIC; found: if(isnew) { if(nindex->c_node.i_nlink || nindex->c_node.i_mode & F_MASK) goto badino; } else { if(!(nindex->c_node.i_nlink && nindex->c_node.i_mode & F_MASK)) goto badino; } nindex->c_refs++; return nindex; badino: kputs("i_open: bad disk inode\n"); return NULLINODE; }