File *getfinaltarget(File *file) { Map *linkmap = newmap(); if (!linkmap) { errorf("Out of memory?\n"); return NULL; } File *target = NULL; while (isstat(file) && islink(file)) { target = gettarget(file); if (!target) { errorf("Cannot determine target of %s for %s\n", getname(file)); break; } if (inmap(linkmap, getinode(target))) { errorf("Symlink loop in %s\n", getname(file)); /* no file to stat, but want to print the name field */ target = NULL; break; } else { set(linkmap, (uintmax_t)getinode(target), NULL); } file = target; } freemap(linkmap); return target; }
arg_t _acct(void) { #ifdef CONFIG_ACCT inoptr inode; if (esuper()) return -1; if (acct_fh != -1) oft_deref(acct_fh); if (fd != -1) { if ((inode = getinode(fd)) == NULLINODE) return -1; if (getmode(inode) != F_REG) { udata.u_error = EINVAL; return -1; } if (inode->c_flags & CRDONLY) { udata.u_error = EROFS; return -1; } acct_fh = udata.u_files[fd]; ++of_tab[acct_fh].o_refs; } return 0; #else udata.u_error = EINVAL; return -1; #endif }
int main() { int fileaddr; scanf("%d", &fileaddr); struct inode* myinode = getinode(); if (fileaddr > myinode->length) { printf("文件地址大于文件长度,退出\n"); exit(1); } int belongblock = (fileaddr/1024); int offset = fileaddr - (belongblock * 1024); int physicblock = 0; if (belongblock == 0) { physicblock = myinode->direct1; } else if (belongblock == 1) { physicblock = myinode->direct2; } else if (belongblock == 2) { physicblock = myinode->direct3; } else if (belongblock >= 3 && belongblock <= 258) { physicblock = myinode->level2node1->block[belongblock - 3]; } else if (belongblock >= 259 && belongblock <= 515) { physicblock = myinode->level2node1->block[belongblock - 259]; } else if (belongblock >= 516) { physicblock = myinode->level3node1->index[(belongblock - 516)/256].block[(belongblock - 516)%256]; } outputcontroll(physicblock, offset, myinode); }
int is_hardlink(filetree_t *checktree, file_t *file) { file_t *dupe; ino_t inode; dev_t device; inode = getinode(file->d_name); device = getdevice(file->d_name); if ((inode == checktree->file->inode) && (device == checktree->file->device)) return 1; if (checktree->file->hasdupes) { dupe = checktree->file->duplicates; do { if ((inode == dupe->inode) && (device == dupe->device)) return 1; dupe = dupe->duplicates; } while (dupe != NULL); } return 0; }
arg_t _ioctl(void) { inoptr ino; uint16_t dev; if ((ino = getinode(fd)) == NULLINODE) return -1; if (!(isdevice(ino))) { udata.u_error = ENOTTY; return -1; } if ((request & IOCTL_SUPER) && esuper()) return -1; if (!(getperm(ino) & OTH_WR)) { udata.u_error = EPERM; return -1; } dev = ino->c_node.i_addr[0]; /* top bit of request is reserved for kernel originated magic */ return d_ioctl(dev, request & 0x7FFF, data); }
struct inode * igetinode(struct vfs *vfsp, dev_t dev, ino_t inode, int *perror) { struct inode *pip, *ip; extern struct osi_dev cacheDev; register int code = 0; *perror = 0; AFS_STATCNT(igetinode); ip = getinode(vfsp, dev, inode, perror); if (ip == NULL) { *perror = BAD_IGET; u.u_error = ENOENT; /* Well... */ return; } if (ip->i_mode == 0) { /* Not an allocated inode */ iforget(ip); u.u_error = ENOENT; return; } if (ip->i_nlink == 0 || (ip->i_mode & IFMT) != IFREG) { iput(ip); u.u_error = ENOENT; return; } return ip; }
void getfilestats(file_t *file) { file->size = filesize(file->d_name); file->inode = getinode(file->d_name); file->device = getdevice(file->d_name); file->mtime = getmtime(file->d_name); }
void initSFS(int dev) { //Assuming only predefined sizes are used char buf[4096]; int i; init_superblock(&sb); write(devfd[dev],(&sb),BLOCK); init_inodetable(&inodetable); //initialising root directory inode head=init_inode(getinode(dev),1,1,BLOCK,IS_DIR,6); //4+2=>read+write tail=head; head->INODE->i_blocks[0]=alloc_data(dev); strcpy(dentry.dirname,"."); dentry.i_node=head->i_node; head->INODE->file_size=sizeof(dentry); write(devfd[dev],head->INODE,sizeof(head->INODE)); for(i=1;i<INODETABSIZE;i++) write(devfd[dev],&inodetable,sizeof(inodetable)); // printf("%d\n",p); bzero(buf,PAGECOMP); write(devfd[dev],buf,PAGECOMP); write(devfd[dev],&dentry,BLOCK); head->offset=sizeof(dentry); for(i=1;i<DATABLOCK;i++) { if(i==DATABLOCK-1) db.next=-1; else db.next=i+1; db.cur=i; write(devfd[dev],&db,BLOCK); } }
/* * Allocate an inode on the disk */ void iput(union dinode *ip, ino_t ino) { union dinodep dp; bread(&disk, part_ofs + fsbtodb(&sblock, cgtod(&sblock, 0)), (char *)&acg, sblock.fs_cgsize); if (acg.cg_magic != CG_MAGIC) { printf("cg 0: bad magic number\n"); exit(31); } acg.cg_cs.cs_nifree--; setbit(cg_inosused(&acg), ino); if (cgput(&disk, &acg) != 0) err(1, "iput: cgput: %s", disk.d_error); sblock.fs_cstotal.cs_nifree--; fscs[0].cs_nifree--; if (getinode(&disk, &dp, ino) == -1) { printf("iput: %s\n", disk.d_error); exit(32); } if (sblock.fs_magic == FS_UFS1_MAGIC) *dp.dp1 = ip->dp1; else *dp.dp2 = ip->dp2; putinode(&disk); }
arg_t _fchown(void) { inoptr ino; if ((ino = getinode(fd)) == NULLINODE) return (-1); return chown_op(ino); }
arg_t _fchdir(void) { inoptr newcwd; if ((newcwd = getinode(fd)) == NULLINODE) return (-1); i_ref(newcwd); return chdiroot_op(newcwd, &udata.u_cwd); }
int16_t _fchmod(void) { inoptr ino; if ((ino = getinode(fd)) == NULLINODE) return (-1); return chmod_op(ino); }
arg_t _fstat(void) { inoptr ino; if ((ino = getinode(fd)) == NULLINODE) return (-1); return stcpy(ino, buf); }
int relink(char *oldfile, char *newfile) { dev_t od; dev_t nd; ino_t oi; ino_t ni; od = getdevice(oldfile); oi = getinode(oldfile); if (link(oldfile, newfile) != 0) return 0; /* make sure we're working with the right file (the one we created) */ nd = getdevice(newfile); ni = getinode(newfile); if (nd != od || oi != ni) return 0; /* file is not what we expected */ return 1; }
arg_t _dup(void) { int8_t newd; if (getinode(oldd) == NULLINODE) return (-1); if ((newd = uf_alloc()) == -1) return (-1); udata.u_files[newd] = udata.u_files[oldd]; ++of_tab[udata.u_files[oldd]].o_refs; return (newd); }
static struct socket *sock_get(int fd, uint8_t *flag) { struct oft *oftp; inoptr ino = getinode(fd); if (ino == NULLINODE) return NULL; if (!issocket(ino)) { udata.u_error = EINVAL; return NULL; } if (flag) { oftp = of_tab + udata.u_files[fd]; *flag = oftp->o_access; } return sockets + ino->c_node.i_nlink; }
int registerfile(filetree_t **branch, file_t *file) { file->size = filesize(file->d_name); file->inode = getinode(file->d_name); *branch = (filetree_t*) malloc(sizeof(filetree_t)); if (*branch == NULL) { errormsg("out of memory!\n"); exit(1); } (*branch)->file = file; (*branch)->left = NULL; (*branch)->right = NULL; return 1; }
/* We copy the 32bit offset in and out rather than passing it as a 32bit OS might */ arg_t _lseek(void) { inoptr ino; struct oft *o; off_t p; off_t n; if (uget(offset, &n, sizeof(n))) return -1; if ((ino = getinode(file)) == NULLINODE) return (-1); if (getmode(ino) == MODE_R(F_PIPE)) { udata.u_error = ESPIPE; return (-1); } o = &of_tab[udata.u_files[file]]; p = o->o_ptr; switch (flag) { case 0: p = n; break; case 1: p += n; break; case 2: p = ino->c_node.i_size + n; break; default: goto bad; } if (p < 0) goto bad; o->o_ptr = p; uput(&p, offset, sizeof(n)); return 0; bad: udata.u_error = EINVAL; return (-1); }
arg_t _dup2(void) { if (getinode(oldd) == NULLINODE) return (-1); if (newd < 0 || newd >= UFTSIZE) { udata.u_error = EBADF; return (-1); } if (udata.u_files[newd] != NO_FILE) doclose(newd); udata.u_files[newd] = udata.u_files[oldd]; ++of_tab[udata.u_files[oldd]].o_refs; return (0); }
arg_t _fcntl(void) { uint8_t *acc; int newd; if (getinode(fd) == NULLINODE) return (-1); acc = &of_tab[udata.u_files[fd]].o_access; switch (request) { case F_SETFL: *acc = (*acc & ~(O_APPEND | O_NDELAY)) | (data & (O_APPEND | O_NDELAY)); return 0; case F_GETFL: return data; case F_GETFD: return udata.u_cloexec & (1 << fd) ? O_CLOEXEC : 0; case F_SETFD: if (data & O_CLOEXEC) udata.u_cloexec |= (1 << fd); else udata.u_cloexec &= (1 << fd); return 0; case F_DUPFD: if ((newd = uf_alloc_n(data)) == -1) return (-1); udata.u_files[newd] = udata.u_files[fd]; ++of_tab[udata.u_files[fd]].o_refs; return 0; default: udata.u_error = EINVAL; return -1; } }
file_t *checkmatch(filetree_t **root, filetree_t *checktree, file_t *file) { int cmpresult; char *crcsignature; off_t fsize; /* If inodes are equal one of the files is a hard link, which is usually not accidental. We don't want to flag them as duplicates, unless the user specifies otherwise. */ if (!ISFLAG(flags, F_CONSIDERHARDLINKS) && getinode(file->d_name) == checktree->file->inode) return NULL; fsize = filesize(file->d_name); if (fsize < checktree->file->size) cmpresult = -1; else if (fsize > checktree->file->size) cmpresult = 1; else { if (checktree->file->crcsignature == NULL) { crcsignature = getcrcsignature(checktree->file->d_name); if (crcsignature == NULL) return NULL; checktree->file->crcsignature = (char*) malloc(strlen(crcsignature)+1); if (checktree->file->crcsignature == NULL) { errormsg("out of memory\n"); exit(1); } strcpy(checktree->file->crcsignature, crcsignature); } if (file->crcsignature == NULL) { crcsignature = getcrcsignature(file->d_name); if (crcsignature == NULL) return NULL; file->crcsignature = (char*) malloc(strlen(crcsignature)+1); if (file->crcsignature == NULL) { errormsg("out of memory\n"); exit(1); } strcpy(file->crcsignature, crcsignature); } cmpresult = strcmp(file->crcsignature, checktree->file->crcsignature); } if (cmpresult < 0) { if (checktree->left != NULL) { return checkmatch(root, checktree->left, file); } else { #ifndef EXPERIMENTAL_RBTREE registerfile(&(checktree->left), file); #else registerfile(root, checktree, TREE_LEFT, file); #endif return NULL; } } else if (cmpresult > 0) { if (checktree->right != NULL) { return checkmatch(root, checktree->right, file); } else { #ifndef EXPERIMENTAL_RBTREE registerfile(&(checktree->right), file); #else registerfile(root, checktree, TREE_RIGHT, file); #endif return NULL; } } else return checktree->file; }
arg_t _flock(void) { inoptr ino; struct oft *o; staticfast uint8_t c; staticfast uint8_t lock; staticfast int self; lock = lockop & ~LOCK_NB; self = 0; if (lock > LOCK_UN) { udata.u_error = EINVAL; return -1; } if ((ino = getinode(file)) == NULLINODE) return -1; o = &of_tab[udata.u_files[file]]; c = ino->c_flags & CFLOCK; /* Upgrades and downgrades. Check if we are in fact doing a no-op */ if (o->o_access & O_FLOCK) { self = 1; /* Shared or exclusive to shared can't block and is easy */ if (lock == LOCK_SH) { if (c == CFLEX) c = 1; goto done; } /* Exclusive to exclusive - no op */ if (c == CFLEX && lock == LOCK_EX) return 0; /* Shared to exclusive - handle via the loop */ } /* Unlock - drop the locks, mark us not a lock holder. Doesn't block */ if (lockop == LOCK_UN) { o->o_access &= ~O_FLOCK; deflock(o); return 0; } do { /* Exclusive lock must have no holders */ if (c == self && lock == LOCK_EX) { c = CFLEX; goto done; } if (c < CFMAX) { c++; goto done; } if (c == CFMAX) { udata.u_error = ENOLCK; return -1; } /* LOCK_NB is defined as O_NDELAY... */ if (psleep_flags(&ino->c_flags, (lockop & LOCK_NB))) return -1; /* locks will hopefully have changed .. */ c = ino->c_flags & CFLOCK; } while (1); done: if (o->o_access & O_FLOCK) deflock(o); ino->c_flags &= ~CFLOCK; ino->c_flags |= c; o->o_access |= O_FLOCK; wakeup(&ino->c_flags); return 0; }
smmap() { #ifdef notdef struct a { caddr_t addr; int len; int prot; int share; int fd; off_t pos; } *uap = (struct a *)u.u_ap; register struct file *fp; register struct inode *ip; register struct fpte *pte; int off; int fv, lv, pm; dev_t dev; int (*mapfun)(); extern struct file *getinode(); fp = getinode(uap->fd); if (fp == NULL) return; ip = (struct inode *)fp->f_data; if ((ip->i_mode & IFMT) != IFCHR) { u.u_error = EINVAL; return; } dev = ip->i_rdev; mapfun = cdevsw[major(dev)].d_mmap; if (mapfun == NULL) { u.u_error = EINVAL; return; } if (((int)uap->addr & CLOFSET) || (uap->len & CLOFSET) || (uap->pos & CLOFSET)) { u.u_error = EINVAL; return; } if ((uap->prot & PROT_WRITE) && (fp->f_flag&FWRITE) == 0) { u.u_error = EINVAL; return; } if ((uap->prot & PROT_READ) && (fp->f_flag&FREAD) == 0) { u.u_error = EINVAL; return; } if (uap->share != MAP_SHARED) { u.u_error = EINVAL; return; } fv = btop(uap->addr); lv = btop(uap->addr + uap->len - 1); if (lv < fv || !isadsv(u.u_procp, fv) || !isadsv(u.u_procp, lv)) { u.u_error = EINVAL; return; } for (off=0; off<uap->len; off += NBPG) { if ((*mapfun)(dev, uap->pos+off, uap->prot) == -1) { u.u_error = EINVAL; return; } } if (uap->prot & PROT_WRITE) pm = PG_UW; else pm = PG_URKR; for (off = 0; off < uap->len; off += NBPG) { pte = (struct fpte *)vtopte(u.u_procp, fv); u.u_procp->p_rssize -= vmemfree(pte, 1); *(int *)pte = pm; pte->pg_v = 1; pte->pg_fod = 1; pte->pg_fileno = uap->fd; pte->pg_blkno = (*mapfun)(dev, uap->pos+off, uap->prot); fv++; } u.u_procp->p_flag |= SPTECHG; u.u_pofile[uap->fd] |= UF_MAPPED; #endif }
int main() { u16 i,iblk; char *loc; u32 *l; GD *gp; INODE *ip; prints("What image: "); gets(kstr); prints("\r\n"); // Read group descriptor block and find inode table getblk(2, buf1); gp = (GD *)buf1; iblk = (u16)gp->bg_inode_table; getblk((u16)iblk, buf1); // read first inode block ip = (INODE *)buf1 + 1; // ip->root inode #2 ( / directory) // Read through directory entries looking for /boot i = findentry((u16)ip->i_block[0], "boot"); // get inode ip = getinode(iblk, i); i = findentry((u16)ip->i_block[0], kstr); // Get inode ip = getinode(iblk, i); // get single indirect blocks getblk((u16)ip->i_block[12], buf2); // Copy file into memory prints("Loading: "); setes(0x1000); loc = 0; i = 0; // Get first 12 blocks while(i < 12 && ip->i_block[i] != 0) { getblk((u16)ip->i_block[i], loc); i++; loc += 1024; putc('.'); } l = buf2; i = 0; while(i < 256 && l[i] > 0) { getblk((u16)(l[i]), loc); i++; loc += 1024; putc('+'); } prints("\n\rReady?\n\r"); getc(); return 1; }
void pass4() { ino_t number; /* True if any reconnect attempt failed, in which case we don't try again. */ int reconn_failed = 0; for (number = ROOTINO; number < maxino; number++) { if (linkfound[number] && inodestate[number] != UNALLOC) { if (linkcount[number] != linkfound[number]) { pinode (0, number, "LINK COUNT %d SHOULD BE %d IN", linkcount[number], linkfound[number]); if (preen || reply ("ADJUST")) { struct dinode dino; getinode (number, &dino); dino.di_nlink = linkfound[number]; write_inode (number, &dino); pfix ("ADJUSTED"); } } } else if (linkfound[number] && inodestate[number] == UNALLOC) { /* This can't happen because we never count links to unallocated nodes. */ errexit ("LINK RECORDED FOR UNALLOCATED NODE"); } else if (!linkfound[number] && inodestate[number] != UNALLOC) { /* No links to allocated node. If the size is zero, then we want to clear it; if the size is positive, then we want to reattach in. */ struct dinode dino; pinode (0, number, "UNREF"); getinode (number, &dino); if (dino.di_size && !reconn_failed) { /* This can't happen for dirctories because pass 3 should already have reset them up. */ if ((DI_MODE (&dino) & IFMT) == IFDIR) errexit ("NO LINKS TO NONZERO DIRECTORY"); if (preen || reply ("RECONNECT")) reconn_failed = !linkup (number, -1); if (! reconn_failed) pfix ("RECONNECTED"); if (preen && reconn_failed) pfail ("RECONNECT FAILED"); } if (dino.di_size == 0 || reconn_failed) { if (reconn_failed && !preen) /* If preening, the previous call to problem is still active (more likely the failure was too severe, and exited). */ problem (0, "RECONNECT FAILED"); if (preen || reply ("CLEAR")) { inodestate[number] = UNALLOC; clear_inode (number, &dino); pfix ("CLEARED"); } } } } }
void registerfile(filetree_t **root, filetree_t *parent, int loc, file_t *file) { filetree_t *node; filetree_t *uncle; file->size = filesize(file->d_name); file->inode = getinode(file->d_name); node = (filetree_t*) malloc(sizeof(filetree_t)); if (node == NULL) { errormsg("out of memory!\n"); exit(1); } node->file = file; node->left = NULL; node->right = NULL; node->parent = parent; node->color = COLOR_RED; if (loc == TREE_ROOT) *root = node; else if (loc == TREE_LEFT) parent->left = node; else parent->right = node; while (node != *root && node->parent->color == COLOR_RED) { if (node->parent->parent == NULL) return; if (node->parent == node->parent->parent->left) { uncle = node->parent->parent->right; if (uncle == NULL) return; if (uncle->color == COLOR_RED) { node->parent->color = COLOR_BLACK; uncle->color = COLOR_BLACK; node->parent->parent->color = COLOR_RED; node = node->parent->parent; } else { if (node == node->parent->right) { node = node->parent; rotate_left(root, node); } node->parent->color = COLOR_BLACK; node->parent->parent->color = COLOR_RED; rotate_right(root, node->parent->parent); } } else { uncle = node->parent->parent->left; if (uncle == NULL) return; if (uncle->color == COLOR_RED) { node->parent->color = COLOR_BLACK; uncle->color = COLOR_BLACK; node->parent->parent->color = COLOR_RED; node = node->parent->parent; } else { if (node == node->parent->right) { node = node->parent; rotate_left(root, node); } node->parent->color = COLOR_BLACK; node->parent->parent->color = COLOR_RED; rotate_right(root, node->parent->parent); } } } (*root)->color = COLOR_BLACK; }