patch-2.2.10 linux/fs/ncpfs/file.c

Next file: linux/fs/ncpfs/inode.c
Previous file: linux/fs/ncpfs/dir.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.9/linux/fs/ncpfs/file.c linux/fs/ncpfs/file.c
@@ -21,7 +21,7 @@
 #include <linux/ncp_fs.h>
 #include "ncplib_kernel.h"
 
-static inline int min(int a, int b)
+static inline unsigned int min(unsigned int a, unsigned int b)
 {
 	return a < b ? a : b;
 }
@@ -99,7 +99,10 @@
 	struct inode *inode = dentry->d_inode;
 	size_t already_read = 0;
 	off_t pos;
-	int bufsize, error;
+	size_t bufsize;
+	int error;
+	void* freepage;
+	size_t freelen;
 
 	DPRINTK(KERN_DEBUG "ncp_file_read: enter %s/%s\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name);
@@ -119,10 +122,12 @@
 		goto out;
 	}
 
-	pos = file->f_pos;
+	pos = *ppos;
+/* leave it out on server ...
 	if (pos + count > inode->i_size) {
 		count = inode->i_size - pos;
 	}
+*/
 	error = 0;
 	if (!count)	/* size_t is never < 0 */
 		goto out;
@@ -135,16 +140,24 @@
 
 	bufsize = NCP_SERVER(inode)->buffer_size;
 
+	error = -EIO;
+	freelen = ncp_read_bounce_size(bufsize);
+	freepage = kmalloc(freelen, GFP_NFS);
+	if (!freepage)
+		goto out;
+	error = 0;
 	/* First read in as much as possible for each bufsize. */
 	while (already_read < count) {
 		int read_this_time;
-		int to_read = min(bufsize - (pos % bufsize),
+		size_t to_read = min(bufsize - (pos % bufsize),
 				  count - already_read);
 
-		error = ncp_read(NCP_SERVER(inode),
+		error = ncp_read_bounce(NCP_SERVER(inode),
 			 	NCP_FINFO(inode)->file_handle,
-				pos, to_read, buf, &read_this_time);
+				pos, to_read, buf, &read_this_time, 
+				freepage, freelen);
 		if (error) {
+			kfree(freepage);
 			error = -EIO;	/* This is not exact, i know.. */
 			goto out;
 		}
@@ -152,12 +165,13 @@
 		buf += read_this_time;
 		already_read += read_this_time;
 
-		if (read_this_time < to_read) {
+		if (read_this_time != to_read) {
 			break;
 		}
 	}
+	kfree(freepage);
 
-	file->f_pos = pos;
+	*ppos = pos;
 
 	if (!IS_RDONLY(inode)) {
 		inode->i_atime = CURRENT_TIME;
@@ -176,7 +190,9 @@
 	struct inode *inode = dentry->d_inode;
 	size_t already_written = 0;
 	off_t pos;
-	int bufsize, errno;
+	size_t bufsize;
+	int errno;
+	void* bouncebuffer;
 
 	DPRINTK(KERN_DEBUG "ncp_file_write: enter %s/%s\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name);
@@ -201,7 +217,7 @@
 		printk(KERN_ERR "ncp_file_write: open failed, error=%d\n", errno);
 		return errno;
 	}
-	pos = file->f_pos;
+	pos = *ppos;
 
 	if (file->f_flags & O_APPEND) {
 		pos = inode->i_size;
@@ -210,27 +226,36 @@
 
 	already_written = 0;
 
+	bouncebuffer = kmalloc(bufsize, GFP_NFS);
+	if (!bouncebuffer)
+		return -EIO;	/* -ENOMEM */
 	while (already_written < count) {
 		int written_this_time;
-		int to_write = min(bufsize - (pos % bufsize),
+		size_t to_write = min(bufsize - (pos % bufsize),
 				   count - already_written);
 
-		if (ncp_write(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
-			  pos, to_write, buf, &written_this_time) != 0) {
-			return -EIO;
+		if (copy_from_user(bouncebuffer, buf, to_write)) {
+			errno = -EFAULT;
+			break;
+		}
+		if (ncp_write_kernel(NCP_SERVER(inode), 
+		    NCP_FINFO(inode)->file_handle,
+		    pos, to_write, buf, &written_this_time) != 0) {
+			errno = -EIO;
+			break;
 		}
 		pos += written_this_time;
 		buf += written_this_time;
 		already_written += written_this_time;
 
-		if (written_this_time < to_write) {
+		if (written_this_time != to_write) {
 			break;
 		}
 	}
-
+	kfree(bouncebuffer);
 	inode->i_mtime = inode->i_atime = CURRENT_TIME;
 	
-	file->f_pos = pos;
+	*ppos = pos;
 
 	if (pos > inode->i_size) {
 		inode->i_size = pos;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)