Example #1
0
/*
 * Writes to a file.
 */
PUBLIC ssize_t sys_write(int fd, const void *buf, size_t n)
{
	dev_t dev;         /* Device number.          */
	struct file *f;    /* File.                   */
	struct inode *i;   /* Inode.                  */
	ssize_t count = 0; /* Bytes actually written. */
	
	/* Invalid file descriptor. */
	if ((fd < 0) || (fd >= OPEN_MAX) || ((f = curr_proc->ofiles[fd]) == NULL))
		return (-EBADF);
	
	/* File not opened for writing. */
	if (ACCMODE(f->oflag) == O_RDONLY)
		return (-EBADF);
	
	/* Invalid buffer. */
	if (!chkmem(buf, n, MAY_READ))
		return (-EINVAL);
	
	i = f->inode;
	
	/* Append mode. */
	if (f->oflag & O_APPEND)
		f->pos = i->size;
	
	/* Character special file. */
	if (S_ISCHR(i->mode))
	{
		dev = i->blocks[0];
		count = cdev_write(dev, buf, n);
		return (count);
	}
	
	/* Block special file. */
	else if (S_ISBLK(i->mode))
	{
		dev = i->blocks[0];
		count = bdev_write(dev, buf, n, f->pos);
	}
	
	/* Pipe file. */
	else if (S_ISFIFO(i->mode))
	{
		kprintf("write to pipe");
		count = pipe_write(i, buf, n);
	}
	
	/* Regular file. */
	else if (S_ISREG(i->mode))
		count = file_write(i, buf, n, f->pos);

	/* Failed to write. */
	if (count < 0)
		return (curr_proc->errno);
	
	f->pos += count;
	
	return (count);
	
}
Example #2
0
/*===========================================================================*
 *				rw_block				     *
 *===========================================================================*/
static void rw_block(
  register struct buf *bp,	/* buffer pointer */
  int rw_flag 			/* READING or WRITING */
)
{
/* Read or write a disk block. This is the only routine in which actual disk
 * I/O is invoked. If an error occurs, a message is printed here, but the error
 * is not reported to the caller.  If the error occurred while purging a block
 * from the cache, it is not clear what the caller could do about it anyway.
 */
  int r, op_failed = 0;
  u64_t pos;
  dev_t dev;

  if ( (dev = bp->b_dev) != NO_DEV) {
	pos = mul64u(bp->b_blocknr, fs_block_size);
	if (rw_flag == READING)
		r = bdev_read(dev, pos, bp->b_data, fs_block_size,
			BDEV_NOFLAGS);
	else
		r = bdev_write(dev, pos, bp->b_data, fs_block_size,
			BDEV_NOFLAGS);
	if (r < 0) {
		printf("Ext2(%d) I/O error on device %d/%d, block %u\n",
			SELF_E, major(dev), minor(dev), bp->b_blocknr);
		op_failed = 1;
	} else if (r != (ssize_t) fs_block_size) {
		r = END_OF_FILE;
		op_failed = 1;
	}

	if (op_failed) {
		bp->b_dev = NO_DEV;     /* invalidate block */

		/* Report read errors to interested parties. */
		if (rw_flag == READING) rdwt_err = r;

	}
  }

  bp->b_dirt = CLEAN;
}