Exemple #1
0
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;
}
Exemple #2
0
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);

}
Exemple #4
0
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;
}
Exemple #5
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);
}
Exemple #6
0
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;
}
Exemple #7
0
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);
}
Exemple #8
0
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);
    }
}
Exemple #9
0
/*
 * 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);
}
Exemple #10
0
arg_t _fchown(void)
{
	inoptr ino;

	if ((ino = getinode(fd)) == NULLINODE)
		return (-1);
	return chown_op(ino);
}
Exemple #11
0
arg_t _fchdir(void)
{
	inoptr newcwd;

	if ((newcwd = getinode(fd)) == NULLINODE)
		return (-1);
	i_ref(newcwd);
	return chdiroot_op(newcwd, &udata.u_cwd);
}
Exemple #12
0
int16_t _fchmod(void)
{
	inoptr ino;

	if ((ino = getinode(fd)) == NULLINODE)
		return (-1);

	return chmod_op(ino);
}
Exemple #13
0
arg_t _fstat(void)
{
	inoptr ino;

	if ((ino = getinode(fd)) == NULLINODE)
		return (-1);

	return stcpy(ino, buf);
}
Exemple #14
0
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;
}
Exemple #15
0
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);
}
Exemple #16
0
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;
}
Exemple #17
0
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;
}
Exemple #18
0
/* 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);

}
Exemple #19
0
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);
}
Exemple #20
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;
	}
}
Exemple #21
0
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;
}
Exemple #22
0
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;
}
Exemple #23
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
}
Exemple #24
0
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;
}  
Exemple #25
0
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");
		}
	    }
	}
    }
}      
Exemple #26
0
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;
}