示例#1
0
文件: ospfsmod.c 项目: qinyiyan/CS111
static ssize_t
ospfs_read(struct file *filp, char __user *buffer, size_t count, loff_t *f_pos)
{
	ospfs_inode_t *oi = ospfs_inode(filp->f_dentry->d_inode->i_ino);
	int retval = 0;
	size_t amount = 0;

	// Make sure we don't read past the end of the file!
	// Change 'count' so we never read past the end of the file.
	if(*f_pos > oi->oi_size)
		return 0;
	//we do not read past the end of the file
	if(*f_pos + count > oi->oi_size)
		count = oi->oi_size - *f_pos;
	/* EXERCISE: Your code here */

	// Copy the data to user block by block
	while (amount < count && retval >= 0) {
		uint32_t blockno = ospfs_inode_blockno(oi, *f_pos);
		uint32_t n;
		char *data;
		//eprintk("reading!!");
		// ospfs_inode_blockno returns 0 on error
		if (blockno == 0) {
			retval = -EIO;
			goto done;
		}

		data = ospfs_block(blockno);
		int offs = *f_pos % OSPFS_BLKSIZE;
		n = OSPFS_BLKSIZE - offs;
		int left = count - amount;
		n = (n > left) ? left : n;
		if(copy_to_user (buffer, data, n))
			//if copy success return 0;
		{
			retval = -EFAULT;
			goto done;
		}
		//to: Destination address, in user space.
 		//from: Source address, in kernel space.
 		//n: Number of bytes to copy.
		// Figure out how much data is left in this block to read.
		// Copy data into user space. Return -EFAULT if unable to write
		// into user space.
		// Use variable 'n' to track number of bytes moved.
		/* EXERCISE: Your code here */
		//retval = -EIO; // Replace these lines
		//goto done;

		buffer += n;
		amount += n;
		*f_pos += n;
	}

    done:
	return (retval >= 0 ? amount : retval);
}
示例#2
0
static ssize_t
ospfs_read(struct file *filp, char __user *buffer, size_t count, loff_t *f_pos)
{
	ospfs_inode_t *oi = ospfs_inode(filp->f_dentry->d_inode->i_ino);
	int retval = 0;
	size_t amount = 0;

	// Make sure we don't read past the end of the file!
	// Change 'count' so we never read past the end of the file.
	/* DONE: Your code here */
	if (count > oi->oi_size - *f_pos) {
		count = oi->oi_size - *f_pos;
	}
	// Copy the data to user block by block
	while (amount < count && retval >= 0) {
		uint32_t blockno = ospfs_inode_blockno(oi, *f_pos);
		uint32_t n;
		char *data;

		// ospfs_inode_blockno returns 0 on error
		if (blockno == 0) {
			retval = -EIO;
			goto done;
		}

		data = ospfs_block(blockno);

		// Figure out how much data is left in this block to read.
		// Copy data into user space. Return -EFAULT if unable to write
		// into user space.
		// Use variable 'n' to track number of bytes moved.

		//goto done;

		long block_pos = *f_pos % OSPFS_BLKSIZE;
		if (count - amount > OSPFS_BLKSIZE - block_pos) {
			n = OSPFS_BLKSIZE - block_pos;
		}
		else {
			n = count - amount;
		}
		retval = copy_to_user(buffer, data + block_pos, n);
		if (retval != 0) {
			return -EFAULT;
		}

		buffer += n;
		amount += n;
		*f_pos += n;
	}

    done:
	return (retval >= 0 ? amount : retval);
}
示例#3
0
文件: ospfsmod.c 项目: bngo92/CS-111
static ssize_t
ospfs_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos)
{
	ospfs_inode_t *oi = ospfs_inode(filp->f_dentry->d_inode->i_ino);
	int retval = 0;
	size_t amount = 0;

	// Support files opened with the O_APPEND flag.  To detect O_APPEND,
	// use struct file's f_flags field and the O_APPEND bit.
	/* EXERCISE: Your code here */
	int append = filp->f_flags & O_APPEND;
	if (append)
		*f_pos = oi->oi_size;
	
	// If the user is writing past the end of the file, change the file's
	// size to accomodate the request.  (Use change_size().)
	/* EXERCISE: Your code here */
	if (count > oi->oi_size - *f_pos) {
		change_size(oi, count + oi->oi_size);
	}

	// Copy data block by block
	while (amount < count && retval >= 0) {
		uint32_t blockno = ospfs_inode_blockno(oi, *f_pos);
		uint32_t n;
		char *data;

		if (blockno == 0) {
			retval = -EIO;
			goto done;
		}
		data = ospfs_block(blockno);
		// Figure out how much data is left in this block to write.
		// Copy data from user space. Return -EFAULT if unable to read
		// read user space.
		// Keep track of the number of bytes moved in 'n'.  
		
		/* EXERCISE: Your code here */
		n = count - amount; //left to write!
		if (n > OSPFS_BLKSIZE)
		    n = OSPFS_BLKSIZE;
		if (copy_from_user(data + *f_pos, buffer, n) != 0)
		{   
		    return -EFAULT;
		}
        
		buffer += n;
		amount += n;
		*f_pos += n;
	}

    done:
	return (retval >= 0 ? amount : retval);
}
示例#4
0
static ssize_t
ospfs_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos)
{
	ospfs_inode_t *oi = ospfs_inode(filp->f_dentry->d_inode->i_ino);
	int retval = 0;
	size_t amount = 0;

	// Support files opened with the O_APPEND flag.  To detect O_APPEND,
	// use struct file's f_flags field and the O_APPEND bit.
	/* EXERCISE: Your code here */

	// If the user is writing past the end of the file, change the file's
	// size to accomodate the request.  (Use change_size().)
	/* EXERCISE: Your code here */

	// Copy data block by block
	while (amount < count && retval >= 0) {
		uint32_t blockno = ospfs_inode_blockno(oi, *f_pos);
		uint32_t n;
		char *data;

		if (blockno == 0) {
			retval = -EIO;
			goto done;
		}

		data = ospfs_block(blockno);
		//unsigned long copy_from_user (	(void *) ,(const void __user *) buffer, unsigned long count);

		//   Returns: a pointer to that block's data
		//to Destination address, in kernel space.
		//from: Source address, in user space.
		//n: Number of bytes to copy.
		// Figure out how much data is left in this block to write.
		// Copy data from user space. Return -EFAULT if unable to read
		// read user space.
		// Keep track of the number of bytes moved in 'n'.
		/* EXERCISE: Your code here */
		retval = -EIO; // Replace these lines
		goto done;

		buffer += n;
		amount += n;
		*f_pos += n;
	}

    done:
	return (retval >= 0 ? amount : retval);
}
示例#5
0
static ssize_t
ospfs_read(struct file *filp, char __user *buffer, size_t count, loff_t *f_pos)
{
	ospfs_inode_t *oi = ospfs_inode(filp->f_dentry->d_inode->i_ino);
	int retval = 0;
	size_t amount = 0;
	/* EXERCISE: Your code here */
	//Never let count request more data than the file size
	if(count > oi->oi_size - *f_pos)
		count = oi->oi_size - *f_pos;

	// Copy the data to user block by block
	while (amount < count && retval >= 0) {
		uint32_t blockno = ospfs_inode_blockno(oi, *f_pos);
		uint32_t n;
		char *data;

		// ospfs_inode_blockno returns 0 on error
		if (blockno == 0) {
			retval = -EIO;
			goto done;
		}

		data = ospfs_block(blockno);

		/* EXERCISE: Your code here */
		//Calulate amount of block left needed to copy
		n = count-amount;
		//Calculate offset of f_pos from a multiple of blocksize
		uint32_t offset = *f_pos % OSPFS_BLKSIZE; 
		if(count-amount > OSPFS_BLKSIZE - offset){
			n = OSPFS_BLKSIZE - offset;
		}
		
		if(copy_to_user(buffer, data + offset, n) != 0){
			//eprintk("Unable to write into user space.\n");
			retval = -EFAULT;
			goto done;		
		}

		buffer += n;
		amount += n;
		*f_pos += n;
	}

    done:
	return (retval >= 0 ? amount : retval);
}
示例#6
0
static inline void *
ospfs_inode_data(ospfs_inode_t *oi, uint32_t offset)
{
	uint32_t blockno = ospfs_inode_blockno(oi, offset);
	return (uint8_t *) ospfs_block(blockno) + (offset % OSPFS_BLKSIZE);
}
示例#7
0
文件: ospfsmod.c 项目: qinyiyan/CS111
static ssize_t
ospfs_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos)
{
	ospfs_inode_t *oi = ospfs_inode(filp->f_dentry->d_inode->i_ino);
	int retval = 0;
	size_t amount = 0;
	//eprintk("writing ~~~~~~~~~~~~~~~~~~");
	// Support files opened with the O_APPEND flag.  To detect O_APPEND,
	// use struct file's f_flags field and the O_APPEND bit.
	/* EXERCISE: Your code here */
	if (filp->f_flags & O_APPEND)	//if has the flag
	{
		*f_pos = oi->oi_size;
	}

	// If the user is writing past the end of the file, change the file's
	// size to accomodate the request.  (Use change_size().)
	/* EXERCISE: Your code here */
	if ((*f_pos+count) > oi->oi_size)
	{
		//static int change_size(ospfs_inode_t *oi, uint32_t want_size);
		int change = change_size(oi, (*f_pos+count));
		if (change < 0)
			goto done;
	}
	// Copy data block by block
	while (amount < count && retval >= 0) {
		uint32_t blockno = ospfs_inode_blockno(oi, *f_pos);
		uint32_t n;
		char *data;

		if (blockno == 0) {
			retval = -EIO;
			goto done;
		}

		data = ospfs_block(blockno);

		// Figure out how much data is left in this block to write.
		// Copy data from user space. Return -EFAULT if unable to read
		// read user space.
		// Keep track of the number of bytes moved in 'n'.
		/* EXERCISE: Your code here */
		//retval = -EIO; // Replace these lines
		//goto done;
		uint32_t blk_left = OSPFS_BLKSIZE - (*f_pos) % OSPFS_BLKSIZE;
		data = data + (*f_pos) % OSPFS_BLKSIZE;
		if (blk_left > (count-amount))
		{
			blk_left = count - amount;
		}
		//unsigned long copy_from_user (void * to,const void __user * from,unsigned long n);
		if (copy_from_user(data,buffer,blk_left)!=0)
			return -EFAULT;

		buffer += n;
		amount += n;
		*f_pos += n;
	}

    done:
	return (retval >= 0 ? amount : retval);
}
示例#8
0
static ssize_t
ospfs_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos)
{
	ospfs_inode_t *oi = ospfs_inode(filp->f_dentry->d_inode->i_ino);
	int retval = 0;
	size_t amount = 0;

	/* EXERCISE: Your code here */
	//Detecting if appending to end of a file
	if(filp->f_flags & O_APPEND)
		*f_pos = oi->oi_size;

	/* EXERCISE: Your code here */
	// If the user is writing past the end of the file, change the file's
	// size to accomodate the request.  (Use change_size().)
	if(count > oi->oi_size - *f_pos)
		retval = change_size(oi, count + *f_pos);

	if(retval < 0){
		//eprintk("Error changing file size.\n");	
		return retval;
	}

	// Copy data block by block
	while(amount < count && retval >= 0){
		uint32_t blockno = ospfs_inode_blockno(oi, *f_pos);
		uint32_t n;
		char *data;

		if (blockno == 0){
			retval = -EIO;
			goto done;
		}

		data = ospfs_block(blockno);

		// Figure out how much data is left in this block to write.
		// Copy data from user space. Return -EFAULT if unable to read
		// read user space.
		// Keep track of the number of bytes moved in 'n'.
		/* EXERCISE: Your code here */

		uint32_t offset = *f_pos % OSPFS_BLKSIZE;
		n = count-amount; 
		if(count-amount > OSPFS_BLKSIZE - offset){
			n = OSPFS_BLKSIZE - offset;
		}	

		if(copy_from_user(data + offset, buffer, n) != 0){
			//eprintk("Unable to read from user space.\n");
			retval = -EFAULT;
			goto done;		
		}
		
		buffer += n;
		amount += n;
		*f_pos += n;
	}

    done:
	return (retval >= 0 ? amount : retval);
}
示例#9
0
文件: ospfsmod.c 项目: Saqib117/Lab-3
static ssize_t
ospfs_read(struct file *filp, char __user *buffer, size_t count, loff_t *f_pos)
{
	ospfs_inode_t *oi = ospfs_inode(filp->f_dentry->d_inode->i_ino);
	int retval = 0;
	size_t amount = 0;

	// Make sure we don't read past the end of the file!
	// Change 'count' so we never read past the end of the file.
	/* EXERCISE: Your code here */
	
	//SQ_additions
	
	if(*f_pos > oi->oi_size) { //check to make sure f_pos is not beyond end of file
		 count = 0;
	} else if (count > oi->oi_size - *f_pos) { // else set count to size of remaining file
		count = oi->oi_size - *f_pos;
	}
	
	//end_SQ_additions
	// Copy the data to user block by block
	while (amount < count && retval >= 0) {
		uint32_t blockno = ospfs_inode_blockno(oi, *f_pos);
		uint32_t n;
		char *data;


		// ospfs_inode_blockno returns 0 on error
		if (blockno == 0) {
			retval = -EIO;
			goto done;
		}

		data = ospfs_block(blockno);

		// Figure out how much data is left in this block to read.
		// Copy data into user space. Return -EFAULT if unable to write
		// into user space.
		// Use variable 'n' to track number of bytes moved.
		/* EXERCISE: Your code here */
	
		n = OSPFS_BLKSIZE - *f_pos % OSPFS_BLKSIZE;
			
		// If in the last block, make sure not to read past
		n = (n > count - amount) ? (count - amount) : n;
			
		if(copy_to_user((void*)buffer, (void*)data, n) != 0) {
		  retval = -EFAULT;
		  goto done;
		}

		/* END of SQ add*/
		//retval = -EIO; // Replace these lines
		//goto done;

		buffer += n;
		amount += n;
		*f_pos += n;
	}

    done:
	return (retval >= 0 ? amount : retval);
}
示例#10
0
static ssize_t
ospfs_write(struct file *filp, const char __user *buffer, size_t count, loff_t *f_pos)
{
	ospfs_inode_t *oi = ospfs_inode(filp->f_dentry->d_inode->i_ino);
	int retval = 0;
	size_t amount = 0;

	if (!count) return 0;
	if (count < 0 ) return -EIO;

	// Support files opened with the O_APPEND flag.  To detect O_APPEND,
	// use struct file's f_flags field and the O_APPEND bit.
	/* DONE: Your code here */
	if ((filp->f_flags & O_APPEND) == O_APPEND) {
		*f_pos = oi->oi_size;
	}

	// If the user is writing past the end of the file, change the file's
	// size to accomodate the request.  (Use change_size().)
	/* DONE: Your code here */
	if (count > oi->oi_size - *f_pos) {
		retval = change_size(oi, *f_pos + count);
		if (retval) return retval;
	}

	// Copy data block by block
	while (amount < count && retval >= 0) {
		uint32_t blockno = ospfs_inode_blockno(oi, *f_pos);
		uint32_t n;
		char *data;

		if (blockno == 0) {
			retval = -EIO;
			goto done;
		}

		data = ospfs_block(blockno);

		// Figure out how much data is left in this block to write.
		// Copy data from user space. Return -EFAULT if unable to
		// read user space.
		// Keep track of the number of bytes moved in 'n'.
		/* DONE: Your code here */
		long block_pos = *f_pos % OSPFS_BLKSIZE;
		// if the amount to write is greater than the amount left in this block
		if (count - amount > OSPFS_BLKSIZE - block_pos) {
			n = OSPFS_BLKSIZE - block_pos;
		}
		// if amt to write is less than amt left
		else {
			n = count - amount;
		}
		retval = copy_from_user(data + block_pos, buffer, n);
		if (retval != 0) {
			return -EFAULT;
		}

		buffer += n;
		amount += n;
		*f_pos += n;
	}

    done:
	return (retval >= 0 ? amount : retval);
}