コード例 #1
0
ファイル: buffer_file.c プロジェクト: jrwilson/Lily
int
buffer_file_initw (buffer_file_t* bf,
		   bd_t bd)
{
  bf->bd = bd;
  bf->bd_size = buffer_size (bd);
  if (bf->bd_size == -1) {
    return -1;
  }
  bf->capacity = bf->bd_size * pagesize ();
  if (bf->bd_size != 0) {
    bf->ptr = buffer_map (bd);
    if (bf->ptr == 0) {
      return -1;
    }
  }
  else {
    bf->ptr = 0;
  }
  bf->size = sizeof (size_t);
  bf->position = sizeof (size_t);
  bf->can_update = true;

  return 0;
}
コード例 #2
0
ファイル: buffer.hpp プロジェクト: Zoxc/scaled
		T *setup(GLsizeiptr size)
		{
			glGenBuffers(1, &handle);
			bind();
			glBufferData(target, size * sizeof(T), 0, GL_STATIC_DRAW);
			return (T *)buffer_map(target);
		}
コード例 #3
0
ファイル: drmdemo.c プロジェクト: magcius/drmdemo
static gboolean
make_appbuf (AppBuf *appbuf, Device *device, int w, int h)
{
  appbuf->buffer.device = device;
  appbuf->buffer.width = w;
  appbuf->buffer.height = h;
  if (!buffer_new (&appbuf->buffer) || !buffer_map(&appbuf->buffer))
    return FALSE;

  appbuf->surface = cairo_image_surface_create_for_data (appbuf->buffer.pixels,
                                                         CAIRO_FORMAT_ARGB32,
                                                         appbuf->buffer.width,
                                                         appbuf->buffer.height,
                                                         appbuf->buffer.stride);
  appbuf->cr = cairo_create (appbuf->surface);
  return TRUE;
}
コード例 #4
0
ファイル: vga_msg.c プロジェクト: jrwilson/Lily
int
vga_op_list_initr (vga_op_list_t* vol,
		   bd_t bda,
		   bd_t bdb)
{
  if (buffer_file_initr (&vol->bf, bda) != 0) {
    return -1;
  }

  if (buffer_file_read (&vol->bf, &vol->count, sizeof (size_t)) != 0) {
    return -1;
  }

  vol->bdb = bdb;
  vol->bdb_size = buffer_size (bdb);
  vol->ptr = buffer_map (bdb);

  return 0;
}
コード例 #5
0
ファイル: buffer_file.c プロジェクト: jrwilson/Lily
int
buffer_file_initr (buffer_file_t* bf,
		   bd_t bd)
{
  bf->bd = bd;
  bf->bd_size = buffer_size (bd);
  if (bf->bd_size == -1) {
    return -1;
  }
  bf->capacity = bf->bd_size * pagesize ();
  bf->ptr = buffer_map (bd);
  if (bf->ptr == 0) {
    return -1;
  }
  bf->size = *((size_t*)bf->ptr);
  bf->position = sizeof (size_t);
  bf->can_update = false;

  return 0;
}
コード例 #6
0
ファイル: buffer_file.c プロジェクト: jrwilson/Lily
int
buffer_file_write (buffer_file_t* bf,
		   const void* ptr,
		   size_t size)
{
  if (!bf->can_update) {
    return -1;
  }

  size_t new_position = bf->position + size;
  if (new_position < bf->position) {
    /* Overflow. */
    return -1;
  }

  /* Resize if necessary. */
  if (bf->capacity < new_position) {
    buffer_unmap (bf->bd);
    bf->capacity = ALIGN_UP (new_position, pagesize ());
    bf->bd_size = bf->capacity / pagesize ();
    if (buffer_resize (bf->bd, bf->bd_size) != 0) {
      return -1;
    }
    bf->ptr = buffer_map (bf->bd);
    if (bf->ptr == 0) {
      return -1;
    }
  }

  memcpy (bf->ptr + bf->position, ptr, size);
  bf->position = new_position;
  if (bf->position > bf->size) {
    bf->size = bf->position;
    *((size_t*)bf->ptr) = bf->size;
  }

  return 0;
}
コード例 #7
0
ファイル: buffer_file.c プロジェクト: jrwilson/Lily
int
buffer_file_put (buffer_file_t* bf,
		 char c)
{
  if (!bf->can_update) {
    return -1;
  }
  
  size_t new_position = bf->position + 1;
  if (new_position < bf->position) {
    /* Overflow. */
    return -1;
  }
  
  /* Resize if necessary. */
  if (bf->capacity < new_position) {
    buffer_unmap (bf->bd);
    bf->capacity = ALIGN_UP (new_position, pagesize ());
    bf->bd_size = bf->capacity / pagesize ();
    if (buffer_resize (bf->bd, bf->bd_size) != 0) {
      return -1;
    }
    bf->ptr = buffer_map (bf->bd);
    if (bf->ptr == 0) {
      return -1;
    }
  }
  
  *((char*)(bf->ptr + bf->position)) = c;
  bf->position = new_position;
  if (bf->position > bf->size) {
    bf->size = bf->position;
    *((size_t*)bf->ptr) = bf->size;
  }

  return 0;
}
コード例 #8
0
ファイル: buffer.hpp プロジェクト: Zoxc/scaled
		T *map()
		{
			bind();
			return (T *)buffer_map(target);
		}
コード例 #9
0
ファイル: sfs_io.c プロジェクト: ChunHungLiu/pikachuos
/*
 * This is much the same as sfs_partialio, but intended for use with
 * metadata (e.g. directory entries). It assumes the objects being
 * handled are smaller than whole blocks, do not cross block
 * boundaries, and originate in the kernel.
 *
 * It is separate from sfs_partialio because, although there is no
 * such code in this version of SFS, it is often desirable when doing
 * more advanced things to handle metadata and user data I/O
 * differently.
 */
int
sfs_metaio(struct sfs_vnode *sv, off_t actualpos, void *data, size_t len,
	   enum uio_rw rw)
{
	struct sfs_fs *sfs = sv->sv_absvn.vn_fs->fs_data;
	struct sfs_dinode *dino;
	off_t endpos;
	uint32_t vnblock;
	uint32_t blockoffset;
	daddr_t diskblock;
	struct buf *iobuf;
	char *ioptr;
	bool doalloc;
	int result;

	KASSERT(lock_do_i_hold(sv->sv_lock));

	/* Figure out which block of the vnode (directory, whatever) this is */
	vnblock = actualpos / SFS_BLOCKSIZE;
	blockoffset = actualpos % SFS_BLOCKSIZE;

	result = sfs_dinode_load(sv);
	if (result) {
		return result;
	}
	dino = sfs_dinode_map(sv);

	/* Get the disk block number */
	doalloc = (rw == UIO_WRITE);
	result = sfs_bmap(sv, vnblock, doalloc, &diskblock);
	if (result) {
		sfs_dinode_unload(sv);
		return result;
	}

	if (diskblock == 0) {
		/* Should only get block 0 back if doalloc is false */
		KASSERT(rw == UIO_READ);

		/* Sparse file, read as zeros. */
		bzero(data, len);
		sfs_dinode_unload(sv);
		return 0;
	}

	/* Read the block */
	result = buffer_read(&sfs->sfs_absfs, diskblock, SFS_BLOCKSIZE,
			     &iobuf);
	if (result) {
		/*
		 * XXX: if we allocated, do we need to discard
		 * the block we allocated? urgh...
		 */
		sfs_dinode_unload(sv);
		return result;
	}


	ioptr = buffer_map(iobuf);
	if (rw == UIO_READ) {
		/* Copy out the selected region */
		memcpy(data, ioptr + blockoffset, len);
	}
	else {
		// Journal this!!!
		ioptr = buffer_map(iobuf);
		void *old_data = ioptr + blockoffset;
		sfs_jphys_write_wrapper(sfs, /*context*/ NULL, 
			jentry_meta_update(	diskblock, 
								blockoffset, 
								len,
								old_data, 
								data));

		/* Update the selected region */
		memcpy(ioptr + blockoffset, data, len);
		buffer_mark_dirty(iobuf);	// Journalled (meta_update)

		/* Update the vnode size if needed */
		endpos = actualpos + len;
		if (endpos > (off_t)dino->sfi_size) {
			sfs_jphys_write_wrapper(sfs, NULL,
				jentry_resize(	sv->sv_ino,	// disk_addr
								dino->sfi_size,	// old_size
								endpos));	// new_size
			dino->sfi_size = endpos;
			sfs_dinode_mark_dirty(sv);
		}
	}

	buffer_release(iobuf);
	sfs_dinode_unload(sv);

	/* Done */
	return 0;
}
コード例 #10
0
ファイル: sfs_io.c プロジェクト: ChunHungLiu/pikachuos
/*
 * Do I/O (either read or write) of a single whole block.
 *
 * Locking: must hold vnode lock. May get/release sfs_freemaplock.
 *
 * Requires up to 2 buffers.
 */
static
int
sfs_blockio(struct sfs_vnode *sv, struct uio *uio)
{
	struct sfs_fs *sfs = sv->sv_absvn.vn_fs->fs_data;
	struct buf *iobuf;
	void *ioptr;
	daddr_t diskblock;
	uint32_t fileblock;
	int result;
	bool doalloc = (uio->uio_rw==UIO_WRITE);
	unsigned new_checksum = 0;

	KASSERT(lock_do_i_hold(sv->sv_lock));

	/* Get the block number within the file */
	fileblock = uio->uio_offset / SFS_BLOCKSIZE;

	/* Look up the disk block number */
	result = sfs_bmap(sv, fileblock, doalloc, &diskblock);
	if (result) {
		return result;
	}

	if (diskblock == 0) {
		/*
		 * No block - fill with zeros.
		 *
		 * We must be reading, or sfs_bmap would have
		 * allocated a block for us.
		 */
		KASSERT(uio->uio_rw == UIO_READ);
		return uiomovezeros(SFS_BLOCKSIZE, uio);
	}

	if (uio->uio_rw == UIO_READ) {
		result = buffer_read(&sfs->sfs_absfs, diskblock, SFS_BLOCKSIZE,
				     &iobuf);
	}
	else {
		result = buffer_get(&sfs->sfs_absfs, diskblock, SFS_BLOCKSIZE,
				    &iobuf);
	}
	if (result) {
		return result;
	}

	/*
	 * Do the I/O into the buffer.
	 */
	ioptr = buffer_map(iobuf);
	result = uiomove(ioptr, SFS_BLOCKSIZE, uio);
	if (result) {
		buffer_release(iobuf);
		return result;
	}

	if (uio->uio_rw == UIO_WRITE) {
		new_checksum = checksum(ioptr);
		sfs_jphys_write_wrapper(sfs, NULL, 
			jentry_block_write(diskblock, new_checksum, false));
		buffer_mark_valid(iobuf);
		buffer_mark_dirty(iobuf);	// Journalled
	}

	buffer_release(iobuf);
	return 0;
}
コード例 #11
0
ファイル: sfs_io.c プロジェクト: ChunHungLiu/pikachuos
/*
 * Do I/O to a block of a file that doesn't cover the whole block.  We
 * need to read in the original block first, even if we're writing, so
 * we don't clobber the portion of the block we're not intending to
 * write over.
 *
 * SKIPSTART is the number of bytes to skip past at the beginning of
 * the sector; LEN is the number of bytes to actually read or write.
 * UIO is the area to do the I/O into.
 *
 * Requires up to 2 buffers.
 */
static
int
sfs_partialio(struct sfs_vnode *sv, struct uio *uio,
	      uint32_t skipstart, uint32_t len)
{
	struct sfs_fs *sfs = sv->sv_absvn.vn_fs->fs_data;
	struct buf *iobuffer;
	unsigned char *ioptr;
	daddr_t diskblock;
	uint32_t fileblock;
	int result;
	unsigned new_checksum = 0;

	/* Allocate missing blocks if and only if we're writing */
	bool doalloc = (uio->uio_rw==UIO_WRITE);

	KASSERT(lock_do_i_hold(sv->sv_lock));
	KASSERT(skipstart + len <= SFS_BLOCKSIZE);

	/* Compute the block offset of this block in the file */
	fileblock = uio->uio_offset / SFS_BLOCKSIZE;

	/* Get the disk block number */
	result = sfs_bmap(sv, fileblock, doalloc, &diskblock);
	if (result) {
		return result;
	}

	if (diskblock == 0) {
		/*
		 * There was no block mapped at this point in the file.
		 *
		 * We must be reading, or sfs_bmap would have
		 * allocated a block for us.
		 */
		KASSERT(uio->uio_rw == UIO_READ);
		return uiomovezeros(len, uio);
	}
	else {
		/*
		 * Read the block.
		 */
		result = buffer_read(&sfs->sfs_absfs, diskblock, SFS_BLOCKSIZE,
				     &iobuffer);
		if (result) {
			return result;
		}
	}

	/*
	 * Now perform the requested operation into/out of the buffer.
	 */
	ioptr = buffer_map(iobuffer);
	result = uiomove(ioptr+skipstart, len, uio);
	if (result) {
		buffer_release(iobuffer);
		return result;
	}

	/*
	 * If it was a write, mark the modified block dirty and journal
	 */
	if (uio->uio_rw == UIO_WRITE) {
		// Compute checksum and journal
		new_checksum = checksum(ioptr);
		sfs_jphys_write_wrapper(sfs, NULL, 
			jentry_block_write(diskblock, new_checksum, false));

		buffer_mark_dirty(iobuffer);	// Journalled
	}

	buffer_release(iobuffer);
	return 0;
}