Пример #1
0
void i_deref(inoptr ino)
{
    magic(ino);

    if(!ino->c_refs)
        panic("inode freed.");

    if((ino->c_node.i_mode & F_MASK) == F_PIPE)
        wakeup((char *)ino);

    /* If the inode has no links and no refs, it must have
       its blocks freed. */

    if(!(--ino->c_refs || ino->c_node.i_nlink))
        /*
           SN (mcy)
           */
        if(((ino->c_node.i_mode & F_MASK) == F_REG) ||
                ((ino->c_node.i_mode & F_MASK) == F_DIR) ||
                ((ino->c_node.i_mode & F_MASK) == F_PIPE))
            f_trunc(ino);

    /* If the inode was modified, we must write it to disk. */
    if(!(ino->c_refs) && ino->c_dirty)
    {
        if(!(ino->c_node.i_nlink))
        {
            ino->c_node.i_mode = 0;
            i_free(ino->c_dev, ino->c_num);
        }
        wr_inode(ino);
    }
}
Пример #2
0
inoptr newfile(inoptr pino, char *name)
{
    inoptr nindex;
    uint8_t j;

    /* First see if parent is writeable */
    if(!(getperm(pino) & OTH_WR))
        goto nogood;

    if(!(nindex = i_open(pino->c_dev, 0)))
        goto nogood;

    /* BUG FIX:  user/group setting was missing  SN */
    nindex->c_node.i_uid = udata.u_euid;
    nindex->c_node.i_gid = udata.u_egid;

    nindex->c_node.i_mode = F_REG;   /* For the time being */
    nindex->c_node.i_nlink = 1;
    nindex->c_node.i_size = 0;
    for(j=0; j <20; j++)
        nindex->c_node.i_addr[j] = 0;
    wr_inode(nindex);

    if(!ch_link(pino, "", name, nindex)) {
        i_deref(nindex);
        goto nogood;
    }
    i_deref(pino);
    return nindex;

nogood:
    i_deref(pino);
    return NULLINODE;
}
Пример #3
0
arg_t _link(void)
{
	inoptr ino;
	inoptr ino2;
	inoptr parent2;
	char fname[FILENAME_LEN + 1];

	if (!(ino = n_open(name1, NULLINOPTR)))
		return (-1);

	if (getmode(ino) == F_DIR && esuper())
		goto nogood;

	if (ino->c_node.i_nlink == 0xFFFF) {
		udata.u_error = EMLINK;
		goto nogood;
	}

	/* Make sure file2 doesn't exist, and get its parent */
	if ((ino2 = n_open(name2, &parent2)) != NULL) {
		i_deref(ino2);
		i_deref(parent2);
		udata.u_error = EEXIST;
		goto nogood;
	}

	if (!parent2)
		goto nogood;

	if (ino->c_dev != parent2->c_dev) {
		i_deref(parent2);
		udata.u_error = EXDEV;
		goto nogood;
	}

	filename(name2, fname);

	if (!ch_link(parent2, "", fname, ino)) {
		i_deref(parent2);
		goto nogood;
	}

	/* Update the link count. */
	++ino->c_node.i_nlink;
	wr_inode(ino);
	setftime(ino, C_TIME);

	i_deref(parent2);
	i_deref(ino);
	return 0;

      nogood:
	i_deref(ino);
	return -1;
}
Пример #4
0
uint8_t write_core_image(void)
{
	inoptr parent = NULLINODE;
	inoptr ino;

	udata.u_error = 0;

	/* FIXME: need to think more about the case sp is lala */
	if (uput("core", (uint8_t *)udata.u_syscall_sp - 5, 5))
		return 0;

	ino = n_open((char *)udata.u_syscall_sp - 5, &parent);
	if (ino) {
		i_deref(parent);
		return 0;
	}
	if (parent) {
		i_lock(parent);
		if ((ino = newfile(parent, "core")) != NULL) {
			ino->c_node.i_mode = F_REG | 0400;
			setftime(ino, A_TIME | M_TIME | C_TIME);
			wr_inode(ino);
			f_trunc(ino);
#if 0
	/* FIXME address ranges for different models - move core writer
	   for address spaces into helpers ?  */
			/* FIXME: need to add some arch specific header bits, and
			   also pull stuff like the true sp and registers out of
			   the return stack properly */

			corehdr.ch_base = pagemap_base;
			corehdr.ch_break = udata.u_break;
			corehdr.ch_sp = udata.u_syscall_sp;
			corehdr.ch_top = PROGTOP;
			udata.u_offset = 0;
			udata.u_base = (uint8_t *)&corehdr;
			udata.u_sysio = true;
			udata.u_count = sizeof(corehdr);
			writei(ino, 0);
			udata.u_sysio = false;
			udata.u_base = (uint8_t *)pagemap_base;
			udata.u_count = udata.u_break - pagemap_base;
			writei(ino, 0);
			udata.u_base = udata.u_sp;
			udata.u_count = PROGTOP - (uint32_t)udata.u_sp;
			writei(ino, 0);
#endif
			i_unlock_deref(ino);
			return W_COREDUMP;
		}
	}
	return 0;
}
Пример #5
0
uint8_t write_core_image(void)
{
	inoptr parent = NULLINODE;
	inoptr ino;

	udata.u_error = 0;

	/* FIXME: need to think more about the case sp is lala */
	if (uput("core", udata.u_syscall_sp - 5, 5))
		return 0;

	ino = n_open(udata.u_syscall_sp - 5, &parent);
	if (ino) {
		i_deref(parent);
		return 0;
	}
	if (parent) {
		i_lock(parent);
		if (ino = newfile(parent, "core")) {
			ino->c_node.i_mode = F_REG | 0400;
			setftime(ino, A_TIME | M_TIME | C_TIME);
			wr_inode(ino);
			f_trunc(ino);

			/* FIXME: need to add some arch specific header bits, and
			   also pull stuff like the true sp and registers out of
			   the return stack properly */

			corehdr.ch_base = MAPBASE;
			corehdr.ch_break = udata.u_break;
			corehdr.ch_sp = udata.u_syscall_sp;
			corehdr.ch_top = PROGTOP;
			udata.u_offset = 0;
			udata.u_base = (uint8_t *)&corehdr;
			udata.u_sysio = true;
			udata.u_count = sizeof(corehdr);
			writei(ino, 0);
			udata.u_sysio = false;
			udata.u_base = MAPBASE;
			udata.u_count = udata.u_break - MAPBASE;
			writei(ino, 0);
			udata.u_base = udata.u_sp;
			udata.u_count = PROGTOP - (uint16_t)udata.u_sp;
			writei(ino, 0);
			i_unlock_deref(ino);
			return W_COREDUMP;
		}
	}
	return 0;
}
Пример #6
0
int16_t _sync(void)
{
	inoptr ino;

	/* Write out modified inodes */

	for (ino = i_tab; ino < i_tab + ITABSIZE; ++ino)
		if (ino->c_refs > 0 && ino->c_dirty != 0) {
			wr_inode(ino);
			ino->c_dirty = 0;
		}

        /* This now also indirectly does the superblocks as they
           are buffers that are pinned */
	bufsync();		/* Clear buffer pool */

	return 0;
}
Пример #7
0
arg_t _mknod(void)
{
	inoptr ino;
	inoptr parent;
	char fname[FILENAME_LEN + 1];

	udata.u_error = 0;

	if (!super() && ((mode & F_MASK) != F_PIPE)) {
		udata.u_error = EPERM;
		goto nogood3;
	}
	if ((ino = n_open(name, &parent)) != NULL) {
		udata.u_error = EEXIST;
		goto nogood;
	}

	if (!parent) {
		udata.u_error = ENOENT;
		return (-1);
	}

	filename(name, fname);
	ino = newfile(parent, fname);
	if(!ino)
		goto nogood3;	/* parent inode is derefed in newfile. SN */

	/* Initialize mode and dev */
	ino->c_node.i_mode = mode & ~udata.u_mask;
	ino->c_node.i_addr[0] = isdevice(ino) ? dev : 0;
	setftime(ino, A_TIME | M_TIME | C_TIME);
	wr_inode(ino);

	i_deref(ino);
	return (0);

      nogood:
	i_deref(ino);
	i_deref(parent);
      nogood3:
	return (-1);
}
Пример #8
0
arg_t _open(void)
{
	int8_t uindex;
	int8_t oftindex;
	staticfast inoptr ino;
	int16_t perm;
	staticfast inoptr parent;
	char fname[FILENAME_LEN + 1];
	int trunc;
	int r;
	int w;
	int j;

	parent = NULLINODE;

	trunc = flag & O_TRUNC;
	r = (flag + 1) & 1;
	w = (flag + 1) & 2;

	if (O_ACCMODE(flag) == 3 || (flag & O_BADBITS)) {
		udata.u_error = EINVAL;
		return (-1);
	}
	if ((uindex = uf_alloc()) == -1)
		return (-1);

	if ((oftindex = oft_alloc()) == -1)
		goto nooft;

	ino = n_open(name, &parent);
	if (ino) {
		i_deref(parent);
		/* O_EXCL test */
		if ((flag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) {
			udata.u_error = EEXIST;
			goto idrop;
		}
	} else {
		/* The n_open failed */
		if (udata.u_error == EFAULT)
			goto cantopen;
		/* New file */
		if (!(flag & O_CREAT)) {
			udata.u_error = ENOENT;
			goto cantopen;
		}
		filename(name, fname);
		/* newfile drops parent for us */
		if (parent && (ino = newfile(parent, fname))) {
			ino->c_node.i_mode =
			    (F_REG | (mode & MODE_MASK & ~udata.u_mask));
			setftime(ino, A_TIME | M_TIME | C_TIME);
			wr_inode(ino);
		} else {
			udata.u_error = ENFILE;	/* FIXME, should be set in newfile
						   not bodged to a guessed code */
			goto cantopen;
		}
	}
	/* Book our slot in case we block opening a device */
	of_tab[oftindex].o_inode = ino;

	perm = getperm(ino);
	if ((r && !(perm & OTH_RD)) || (w && !(perm & OTH_WR))) {
		udata.u_error = EACCES;
		goto cantopen;
	}
	if (w) {
		if (getmode(ino) == F_DIR ) {
			udata.u_error = EISDIR;
			goto cantopen;
		}
		if (ino->c_flags & CRDONLY) {
			udata.u_error = EROFS;
			goto cantopen;
		}
	}

	if (isdevice(ino)) {
		inoptr *iptr = &of_tab[oftindex].o_inode;
		/* d_open may block and thus ino may become invalid as may
		   parent (but we don't need it again). It may also be changed
		   by the call to dev_openi */

		if (dev_openi(iptr, flag) != 0)
			goto cantopen;

		/* May have changed */
		/* get the static pointer back in case it changed via dev 
		   usage or just because we blocked */
		ino = *iptr;
	}

	if (trunc && getmode(ino) == F_REG) {
		if (f_trunc(ino))
			goto idrop;
		for (j = 0; j < OFTSIZE; ++j)
			/* Arguably should fix at read/write */
			if (of_tab[j].o_inode == ino)
				of_tab[j].o_ptr = 0;
	}

	udata.u_files[uindex] = oftindex;

	of_tab[oftindex].o_ptr = 0;
	of_tab[oftindex].o_access = flag;	/* Save the low bits only */
	if (flag & O_CLOEXEC)
		udata.u_cloexec |= (1 << oftindex);
	/* FIXME: ATIME ? */

/*
 *         Sleep process if no writer or reader
 */
	if (getmode(ino) == F_PIPE && of_tab[oftindex].o_refs == 1
	    && !(flag & O_NDELAY))
		psleep(ino);

        /* From the moment of the psleep ino is invalid */

	return (uindex);
      idrop:
	i_deref(ino);
      cantopen:
	oft_deref(oftindex);	/* This will call i_deref() */
      nooft:
	udata.u_files[uindex] = NO_FILE;
	return (-1);
}