pub fn write(&mut self, buffer: &[u8], offset: usize) -> Result<usize, &'static str> {

        let block_bounds = BlockBounds::block_bounds(offset, buffer.len(), &self.block_size)?;
        let block_size_in_bytes = self.block_size.block_size_in_bytes;

        // // A write transfer (and a read too) can be broken down into three parts: 
        // // (1) Beginning: the first block, which may only be partially included in the transfer.
        // // (2) Middle: the second block to the second-to-last block, which will be full blocks.
        // // (3) End: the last block, which might be partially covered by the byte buffer.
        // // Only the middle blocks can be blindly written to without first reading the existing blocks' contents.
        // // If the first block or last block is aligned to a block boundary, it can be handled as a middle block.
		let mut src_offset = 0;
		let mut dest_offset = block_bounds.first_block_offset;

		for block_num in block_bounds.range {
			let num_bytes_to_copy = core::cmp::min(block_size_in_bytes - dest_offset, buffer.len() - src_offset);

            let buffer_to_write = if num_bytes_to_copy == block_size_in_bytes {
                // We're overwriting the entire block, so no need to read it first
                (&buffer[src_offset .. (src_offset + num_bytes_to_copy)]).to_vec()
            } else {
                // We're only partially writing to this block, so we need to read the old block first.
                let old_block = BlockCache::read_block(&mut self.cache, block_num)?;
                let mut new_block_contents = old_block.to_vec();
                let overwrite_offset = dest_offset % block_size_in_bytes;
                new_block_contents[overwrite_offset .. (overwrite_offset + num_bytes_to_copy)]
                    .copy_from_slice(&buffer[src_offset .. (src_offset + num_bytes_to_copy)]);
                new_block_contents
            };

            self.cache.write_block(block_num, buffer_to_write.into())?;
            trace!("BlockIo::write(): for block {}, copied bytes from buffer[{}..{}] to block[{}..{}]",
				block_num, src_offset, src_offset + num_bytes_to_copy, dest_offset, dest_offset + num_bytes_to_copy,
			);

			src_offset += num_bytes_to_copy;
			dest_offset = 0;
		}

        Ok(src_offset)
    }
/// Write data from the given `buffer` into this block storage device starting at the given `offset` in bytes.
/// The length of the given `buffer` determines the maximum number of bytes to be written.
/// 
/// Returns the number of bytes that were successfully written to the storage device.
/// 
/// The written blocks will be cached in this `BlockIo` struct to accelerate future storage device access.
/// Currently, we use a *write-through* cache policy,
/// in which the blocks are written directly to the cache and the backing storage device immediately.
Write data from the given `buffer` into this block storage device starting at the given `offset` in bytes.
The length of the given `buffer` determines the maximum number of bytes to be written.

Returns the number of bytes that were successfully written to the storage device.

The written blocks will be cached in this `BlockIo` struct to accelerate future storage device access.
Currently, we use a *write-through* cache policy,
in which the blocks are written directly to the cache and the backing storage device immediately.
Write data from the given ` buffer ` into this block storage device starting at the given ` offset ` in bytes . The length of the given ` buffer ` determines the maximum number of bytes to be written . Returns the number of bytes that were successfully written to the storage device . The written blocks will be cached in this ` BlockIo ` struct to accelerate future storage device access . Currently we use a * write - through * cache policy in which the blocks are written directly to the cache and the backing storage device immediately .
pub fn write(&mut self, buffer: &[u8], offset: usize) -> Result<usize, &'static str> {
        let block_bounds = BlockBounds::block_bounds(offset, buffer.len(), &self.block_size)?;
        let block_size_in_bytes = self.block_size.block_size_in_bytes;
        // // A write transfer (and a read too) can be broken down into three parts: 
        // // (1) Beginning: the first block, which may only be partially included in the transfer.
        // // (2) Middle: the second block to the second-to-last block, which will be full blocks.
        // // (3) End: the last block, which might be partially covered by the byte buffer.
        // // Only the middle blocks can be blindly written to without first reading the existing blocks' contents.
        // // If the first block or last block is aligned to a block boundary, it can be handled as a middle block.
		let mut src_offset = 0;
		let mut dest_offset = block_bounds.first_block_offset;
		for block_num in block_bounds.range {
			let num_bytes_to_copy = core::cmp::min(block_size_in_bytes - dest_offset, buffer.len() - src_offset);
            let buffer_to_write = if num_bytes_to_copy == block_size_in_bytes {
                // We're overwriting the entire block, so no need to read it first
                (&buffer[src_offset .. (src_offset + num_bytes_to_copy)]).to_vec()
            } else {
                // We're only partially writing to this block, so we need to read the old block first.
                let old_block = BlockCache::read_block(&mut self.cache, block_num)?;
                let mut new_block_contents = old_block.to_vec();
                let overwrite_offset = dest_offset % block_size_in_bytes;
                new_block_contents[overwrite_offset .. (overwrite_offset + num_bytes_to_copy)]
                    .copy_from_slice(&buffer[src_offset .. (src_offset + num_bytes_to_copy)]);
                new_block_contents
            };
            self.cache.write_block(block_num, buffer_to_write.into())?;
            trace!("BlockIo::write(): for block {}, copied bytes from buffer[{}..{}] to block[{}..{}]",
				block_num, src_offset, src_offset + num_bytes_to_copy, dest_offset, dest_offset + num_bytes_to_copy,
			);
			src_offset += num_bytes_to_copy;
			dest_offset = 0;
		}
        Ok(src_offset)
    }
pub fn write ( & mut self , buffer : & [ u8 ] , offset : usize ) -> Result < usize , & ' static str > { let block_bounds = BlockBounds :: block_bounds ( offset , buffer . len ( ) , & self . block_size ) ? ; let block_size_in_bytes = self . block_size . block_size_in_bytes ; // // A write transfer (and a read too) can be broken down into three parts:  // // (1) Beginning: the first block, which may only be partially included in the transfer. // // (2) Middle: the second block to the second-to-last block, which will be full blocks. // // (3) End: the last block, which might be partially covered by the byte buffer. // // Only the middle blocks can be blindly written to without first reading the existing blocks' contents. // // If the first block or last block is aligned to a block boundary, it can be handled as a middle block. let mut src_offset = 0 ; let mut dest_offset = block_bounds . first_block_offset ; for block_num in block_bounds . range { let num_bytes_to_copy = core :: cmp :: min ( block_size_in_bytes - dest_offset , buffer . len ( ) - src_offset ) ; let buffer_to_write = if num_bytes_to_copy == block_size_in_bytes { // We're overwriting the entire block, so no need to read it first ( & buffer [ src_offset .. ( src_offset + num_bytes_to_copy ) ] ) . to_vec ( ) } else { // We're only partially writing to this block, so we need to read the old block first. let old_block = BlockCache :: read_block ( & mut self . cache , block_num ) ? ; let mut new_block_contents = old_block . to_vec ( ) ; let overwrite_offset = dest_offset % block_size_in_bytes ; new_block_contents [ overwrite_offset .. ( overwrite_offset + num_bytes_to_copy ) ] . copy_from_slice ( & buffer [ src_offset .. ( src_offset + num_bytes_to_copy ) ] ) ; new_block_contents } ; self . cache . write_block ( block_num , buffer_to_write . into ( ) ) ? ; trace ! ( " " block_num src_offset src_offset num_bytes_to_copy dest_offset dest_offset num_bytes_to_copy ) ; src_offset += num_bytes_to_copy ; dest_offset = 0 ; } Ok ( src_offset ) }
Write data from the given `buffer` into this block storage device starting at the given `offset` in bytes.
Write data from the given ` buffer ` into this block storage device starting at the given ` offset ` in bytes .
&mut self
buffer
&[u8]
offset
usize