patch-2.1.63 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.1.62/linux/fs/ncpfs/file.c linux/fs/ncpfs/file.c
@@ -2,6 +2,7 @@
  *  file.c
  *
  *  Copyright (C) 1995, 1996 by Volker Lendecke
+ *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
  *
  */
 
@@ -29,82 +30,113 @@
 	return 0;
 }
 
-int ncp_make_open(struct inode *i, int right)
+/*
+ * Open a file with the specified read/write mode.
+ */
+int ncp_make_open(struct inode *inode, int right)
 {
-	struct nw_file_info *finfo;
-
-	if (i == NULL) {
-		printk("ncp_make_open: got NULL inode\n");
-		return -EINVAL;
-	}
-	finfo = NCP_FINFO(i);
-
-	DPRINTK("ncp_make_open: dirent->opened = %d\n", finfo->opened);
-
-	lock_super(i->i_sb);
-	if (finfo->opened == 0) {
-		finfo->access = -1;
+	int error, result;
+	int access;
+	struct nw_file_info finfo;
+
+	error = -EINVAL;
+	if (!inode) {
+		printk(KERN_ERR "ncp_make_open: got NULL inode\n");
+		goto out;
+	}
+
+	DPRINTK(KERN_DEBUG "ncp_make_open: opened=%d, volume # %u, dir entry # %u\n",
+		NCP_FINFO(inode)->opened, 
+		NCP_FINFO(inode)->volNumber, 
+		NCP_FINFO(inode)->dirEntNum);
+	error = -EACCES;
+	lock_super(inode->i_sb);
+	if (!NCP_FINFO(inode)->opened) {
+		finfo.i.dirEntNum = NCP_FINFO(inode)->dirEntNum;
+		finfo.i.volNumber = NCP_FINFO(inode)->volNumber;
 		/* tries max. rights */
-		if (ncp_open_create_file_or_subdir(NCP_SERVER(i),
-						   NULL, NULL,
-						   OC_MODE_OPEN, 0,
-						   AR_READ | AR_WRITE,
-						   finfo) == 0) {
-			finfo->access = O_RDWR;
-		} else if (ncp_open_create_file_or_subdir(NCP_SERVER(i),
-							  NULL, NULL,
-							  OC_MODE_OPEN, 0,
-							  AR_READ,
-							  finfo) == 0) {
-			finfo->access = O_RDONLY;
+		finfo.access = O_RDWR;
+		result = ncp_open_create_file_or_subdir(NCP_SERVER(inode),
+					NULL, NULL, OC_MODE_OPEN,
+					0, AR_READ | AR_WRITE, &finfo);
+		if (!result)
+			goto update;
+		finfo.access = O_RDONLY;
+		result = ncp_open_create_file_or_subdir(NCP_SERVER(inode),
+					NULL, NULL, OC_MODE_OPEN,
+					0, AR_READ, &finfo);
+		if (!result) {
+#ifdef NCPFS_PARANOIA
+printk(KERN_DEBUG "ncp_make_open: failed, result=%d\n", result);
+#endif
+			goto out_unlock;
 		}
-	}
-	unlock_super(i->i_sb);
-
-	if (((right == O_RDONLY) && ((finfo->access == O_RDONLY)
-				     || (finfo->access == O_RDWR)))
-	    || ((right == O_WRONLY) && ((finfo->access == O_WRONLY)
-					|| (finfo->access == O_RDWR)))
-	    || ((right == O_RDWR) && (finfo->access == O_RDWR)))
-		return 0;
-
-	return -EACCES;
+		/*
+		 * Update the inode information.
+		 */
+	update:
+		ncp_update_inode(inode, &finfo);
+	}
+
+	access = NCP_FINFO(inode)->access;
+#ifdef NCPFS_PARANOIA
+printk(KERN_DEBUG "ncp_make_open: file open, access=%x\n", access);
+#endif
+	if (((right == O_RDONLY) && ((access == O_RDONLY)
+				     || (access == O_RDWR)))
+	    || ((right == O_WRONLY) && ((access == O_WRONLY)
+					|| (access == O_RDWR)))
+	    || ((right == O_RDWR) && (access == O_RDWR)))
+		error = 0;
+
+out_unlock:
+	unlock_super(inode->i_sb);
+out:
+	return error;
 }
 
-static long ncp_file_read(struct inode *inode, struct file *file, char *buf, unsigned long count)
+static ssize_t
+ncp_file_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 {
-	int bufsize, already_read;
+	struct dentry *dentry = file->f_dentry;
+	struct inode *inode = dentry->d_inode;
+	size_t already_read = 0;
 	off_t pos;
-	int errno;
+	int bufsize, error;
 
-	DPRINTK("ncp_file_read: enter %s\n", NCP_ISTRUCT(inode)->entryName);
+	DPRINTK(KERN_DEBUG "ncp_file_read: enter %s/%s\n",
+		dentry->d_parent->d_name.name, dentry->d_name.name);
 
+	error = -EINVAL;
 	if (inode == NULL) {
-		DPRINTK("ncp_file_read: inode = NULL\n");
-		return -EINVAL;
-	}
-	if (!ncp_conn_valid(NCP_SERVER(inode))) {
-		return -EIO;
+		DPRINTK(KERN_DEBUG "ncp_file_read: inode = NULL\n");
+		goto out;
 	}
+	error = -EIO;
+	if (!ncp_conn_valid(NCP_SERVER(inode)))
+		goto out;
+	error = -EINVAL;
 	if (!S_ISREG(inode->i_mode)) {
-		DPRINTK("ncp_file_read: read from non-file, mode %07o\n",
+		DPRINTK(KERN_DEBUG "ncp_file_read: read from non-file, mode %07o\n",
 			inode->i_mode);
-		return -EINVAL;
+		goto out;
 	}
-	pos = file->f_pos;
 
+	pos = file->f_pos;
 	if (pos + count > inode->i_size) {
 		count = inode->i_size - pos;
 	}
-	if (count <= 0) {
-		return 0;
+	error = 0;
+	if (!count)	/* size_t is never < 0 */
+		goto out;
+
+	error = ncp_make_open(inode, O_RDONLY);
+	if (error) {
+		printk(KERN_ERR "ncp_file_read: open failed, error=%d\n", error);
+		goto out;
 	}
-	if ((errno = ncp_make_open(inode, O_RDONLY)) != 0) {
-		return errno;
-	}
-	bufsize = NCP_SERVER(inode)->buffer_size;
 
-	already_read = 0;
+	bufsize = NCP_SERVER(inode)->buffer_size;
 
 	/* First read in as much as possible for each bufsize. */
 	while (already_read < count) {
@@ -112,9 +144,12 @@
 		int to_read = min(bufsize - (pos % bufsize),
 				  count - already_read);
 
-		if (ncp_read(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
-			     pos, to_read, buf, &read_this_time) != 0) {
-			return -EIO;	/* This is not exact, i know.. */
+		error = ncp_read(NCP_SERVER(inode),
+			 	NCP_FINFO(inode)->file_handle,
+				pos, to_read, buf, &read_this_time);
+		if (error) {
+			error = -EIO;	/* This is not exact, i know.. */
+			goto out;
 		}
 		pos += read_this_time;
 		buf += read_this_time;
@@ -130,38 +165,43 @@
 	if (!IS_RDONLY(inode)) {
 		inode->i_atime = CURRENT_TIME;
 	}
-	mark_inode_dirty(inode);
 	
-	DPRINTK("ncp_file_read: exit %s\n", NCP_ISTRUCT(inode)->entryName);
-
-	return already_read;
+	DPRINTK(KERN_DEBUG "ncp_file_read: exit %s/%s\n",
+		dentry->d_parent->d_name.name, dentry->d_name.name);
+out:
+	return already_read ? already_read : error;
 }
 
-static long ncp_file_write(struct inode *inode, struct file *file, const char *buf,
-			   unsigned long count)
+static ssize_t
+ncp_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 {
-	int bufsize, already_written;
+	struct dentry *dentry = file->f_dentry;
+	struct inode *inode = dentry->d_inode;
+	size_t already_written = 0;
 	off_t pos;
-	int errno;
+	int bufsize, errno;
 
+	DPRINTK(KERN_DEBUG "ncp_file_write: enter %s/%s\n",
+		dentry->d_parent->d_name.name, dentry->d_name.name);
 	if (inode == NULL) {
-		DPRINTK("ncp_file_write: inode = NULL\n");
+		DPRINTK(KERN_DEBUG "ncp_file_write: inode = NULL\n");
 		return -EINVAL;
 	}
-	if (!ncp_conn_valid(NCP_SERVER(inode))) {
-		return -EIO;
-	}
+	errno = -EIO;
+	if (!ncp_conn_valid(NCP_SERVER(inode)))
+		goto out;
 	if (!S_ISREG(inode->i_mode)) {
-		DPRINTK("ncp_file_write: write to non-file, mode %07o\n",
+		DPRINTK(KERN_DEBUG "ncp_file_write: write to non-file, mode %07o\n",
 			inode->i_mode);
 		return -EINVAL;
 	}
-	DPRINTK("ncp_file_write: enter %s\n", NCP_ISTRUCT(inode)->entryName);
 
-	if (count <= 0) {
-		return 0;
-	}
-	if ((errno = ncp_make_open(inode, O_RDWR)) != 0) {
+	errno = 0;
+	if (!count)
+		goto out;
+	errno = ncp_make_open(inode, O_RDWR);
+	if (errno) {
+		printk(KERN_ERR "ncp_file_write: open failed, error=%d\n", errno);
 		return errno;
 	}
 	pos = file->f_pos;
@@ -192,17 +232,17 @@
 	}
 
 	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-	mark_inode_dirty(inode);
 	
 	file->f_pos = pos;
 
 	if (pos > inode->i_size) {
 		inode->i_size = pos;
-		ncp_invalid_dir_cache(NCP_INOP(inode)->dir->inode);
+		ncp_invalid_dir_cache(dentry->d_parent->d_inode);
 	}
-	DPRINTK("ncp_file_write: exit %s\n", NCP_ISTRUCT(inode)->entryName);
-
-	return already_written;
+	DPRINTK(KERN_DEBUG "ncp_file_write: exit %s/%s\n",
+		dentry->d_parent->d_name.name, dentry->d_name.name);
+out:
+	return already_written ? already_written : errno;
 }
 
 static struct file_operations ncp_file_operations =

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov