patch-2.1.63 linux/fs/ncpfs/ncplib_kernel.c

Next file: linux/fs/ncpfs/ncplib_kernel.h
Previous file: linux/fs/ncpfs/mmap.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.62/linux/fs/ncpfs/ncplib_kernel.c linux/fs/ncpfs/ncplib_kernel.c
@@ -3,9 +3,11 @@
  *
  *  Copyright (C) 1995, 1996 by Volker Lendecke
  *  Modified for big endian by J.F. Chadima and David S. Miller
+ *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
  *
  */
 
+
 #include "ncplib_kernel.h"
 
 static inline int min(int a, int b)
@@ -16,7 +18,7 @@
 static void assert_server_locked(struct ncp_server *server)
 {
 	if (server->lock == 0) {
-		DPRINTK("ncpfs: server not locked!\n");
+		DPRINTK(KERN_DEBUG "ncpfs: server not locked!\n");
 	}
 }
 
@@ -65,7 +67,7 @@
 	int len = strlen(s);
 	assert_server_locked(server);
 	if (len > 255) {
-		DPRINTK("ncpfs: string too long: %s\n", s);
+		DPRINTK(KERN_DEBUG "ncpfs: string too long: %s\n", s);
 		len = 255;
 	}
 	ncp_add_byte(server, len);
@@ -115,8 +117,8 @@
 	return get_unaligned((__u32 *) ncp_reply_data(server, offset));
 }
 
-int ncp_negotiate_buffersize(struct ncp_server *server,
-			     int size, int *target)
+int
+ncp_negotiate_buffersize(struct ncp_server *server, int size, int *target)
 {
 	int result;
 
@@ -133,7 +135,8 @@
 	return 0;
 }
 
-int ncp_get_volume_info_with_number(struct ncp_server *server, int n,
+int
+ncp_get_volume_info_with_number(struct ncp_server *server, int n,
 				    struct ncp_volume_info *target)
 {
 	int result;
@@ -143,8 +146,7 @@
 	ncp_add_byte(server, n);
 
 	if ((result = ncp_request(server, 22)) != 0) {
-		ncp_unlock_server(server);
-		return result;
+		goto out;
 	}
 	target->total_blocks = ncp_reply_dword(server, 0);
 	target->free_blocks = ncp_reply_dword(server, 4);
@@ -156,18 +158,21 @@
 
 	memset(&(target->volume_name), 0, sizeof(target->volume_name));
 
+	result = -EIO;
 	len = ncp_reply_byte(server, 29);
 	if (len > NCP_VOLNAME_LEN) {
-		DPRINTK("ncpfs: volume name too long: %d\n", len);
-		ncp_unlock_server(server);
-		return -EIO;
+		DPRINTK(KERN_DEBUG "ncpfs: volume name too long: %d\n", len);
+		goto out;
 	}
 	memcpy(&(target->volume_name), ncp_reply_data(server, 30), len);
+	result = 0;
+out:
 	ncp_unlock_server(server);
-	return 0;
+	return result;
 }
 
-int ncp_close_file(struct ncp_server *server, const char *file_id)
+int
+ncp_close_file(struct ncp_server *server, const char *file_id)
 {
 	int result;
 
@@ -180,10 +185,25 @@
 	return result;
 }
 
-static void ncp_add_handle_path(struct ncp_server *server,
-				__u8 vol_num,
-				__u32 dir_base, int have_dir_base,
-				char *path)
+/*
+ * Called with the superblock locked.
+ */
+int
+ncp_make_closed(struct inode *inode)
+{
+	int err;
+	NCP_FINFO(inode)->opened = 0;
+	err = ncp_close_file(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle);
+#ifdef NCPFS_PARANOIA
+if (!err)
+printk(KERN_DEBUG "ncp_make_closed: volnum=%d, dirent=%u, error=%d\n",
+NCP_FINFO(inode)->volNumber, NCP_FINFO(inode)->dirEntNum, err);
+#endif
+	return err;
+}
+
+static void ncp_add_handle_path(struct ncp_server *server, __u8 vol_num,
+				__u32 dir_base, int have_dir_base, char *path)
 {
 	ncp_add_byte(server, vol_num);
 	ncp_add_dword(server, dir_base);
@@ -213,34 +233,40 @@
 	return;
 }
 
-int ncp_obtain_info(struct ncp_server *server,
-		    __u8 vol_num, __u32 dir_base,
-		    char *path,	/* At most 1 component */
-		    struct nw_info_struct *target)
+/*
+ * Returns information for a (one-component) name relative to
+ * the specified directory.
+ */
+int ncp_obtain_info(struct ncp_server *server, struct inode *dir, char *path,
+			struct nw_info_struct *target)
 {
+	__u8  volnum = NCP_FINFO(dir)->volNumber;
+	__u32 dirent = NCP_FINFO(dir)->dirEntNum;
 	int result;
 
 	if (target == NULL) {
+		printk(KERN_ERR "ncp_obtain_info: invalid call\n");
 		return -EINVAL;
 	}
 	ncp_init_request(server);
 	ncp_add_byte(server, 6);	/* subfunction */
-	ncp_add_byte(server, server->name_space[vol_num]);
-	ncp_add_byte(server, server->name_space[vol_num]);
+	ncp_add_byte(server, server->name_space[volnum]);
+	ncp_add_byte(server, server->name_space[volnum]); /* N.B. twice ?? */
 	ncp_add_word(server, htons(0xff00));	/* get all */
 	ncp_add_dword(server, RIM_ALL);
-	ncp_add_handle_path(server, vol_num, dir_base, 1, path);
+	ncp_add_handle_path(server, volnum, dirent, 1, path);
 
-	if ((result = ncp_request(server, 87)) != 0) {
-		ncp_unlock_server(server);
-		return result;
-	}
+	if ((result = ncp_request(server, 87)) != 0)
+		goto out;
 	ncp_extract_file_info(ncp_reply_data(server, 0), target);
+
+out:
 	ncp_unlock_server(server);
-	return 0;
+	return result;
 }
 
-static inline int ncp_has_os2_namespace(struct ncp_server *server, __u8 volume)
+static inline int
+ncp_has_os2_namespace(struct ncp_server *server, __u8 volume)
 {
 	int result;
 	__u8 *namespace;
@@ -253,34 +279,36 @@
 
 	if ((result = ncp_request(server, 87)) != 0) {
 		ncp_unlock_server(server);
-		return 0;
+		return 0; /* not result ?? */
 	}
 	no_namespaces = ncp_reply_word(server, 0);
 	namespace = ncp_reply_data(server, 2);
 
+	result = 1;
 	while (no_namespaces > 0) {
-		DPRINTK("get_namespaces: found %d on %d\n", *namespace, volume);
+		DPRINTK(KERN_DEBUG "get_namespaces: found %d on %d\n", *namespace, volume);
 
 		if (*namespace == 4) {
-			DPRINTK("get_namespaces: found OS2\n");
-			ncp_unlock_server(server);
-			return 1;
+			DPRINTK(KERN_DEBUG "get_namespaces: found OS2\n");
+			goto out;
 		}
 		namespace += 1;
 		no_namespaces -= 1;
 	}
+	result = 0;
+out:
 	ncp_unlock_server(server);
-	return 0;
+	return result;
 }
 
-int ncp_lookup_volume(struct ncp_server *server,
-		      char *volname,
+int 
+ncp_lookup_volume(struct ncp_server *server, char *volname,
 		      struct nw_info_struct *target)
 {
 	int result;
 	int volnum;
 
-	DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname);
+	DPRINTK(KERN_DEBUG "ncp_lookup_volume: looking up vol %s\n", volname);
 
 	ncp_init_request(server);
 	ncp_add_byte(server, 22);	/* Subfunction: Generate dir handle */
@@ -306,7 +334,7 @@
 
 	server->name_space[volnum] = ncp_has_os2_namespace(server, volnum) ? 4 : 0;
 
-	DPRINTK("lookup_vol: namespace[%d] = %d\n",
+	DPRINTK(KERN_DEBUG "lookup_vol: namespace[%d] = %d\n",
 		volnum, server->name_space[volnum]);
 
 	target->nameLen = strlen(volname);
@@ -316,22 +344,22 @@
 }
 
 int ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
-				       struct nw_info_struct *file,
-				       __u32 info_mask,
+					struct inode *dir, __u32 info_mask,
 				       struct nw_modify_dos_info *info)
 {
+	__u8  volnum = NCP_FINFO(dir)->volNumber;
+	__u32 dirent = NCP_FINFO(dir)->dirEntNum;
 	int result;
 
 	ncp_init_request(server);
 	ncp_add_byte(server, 7);	/* subfunction */
-	ncp_add_byte(server, server->name_space[file->volNumber]);
+	ncp_add_byte(server, server->name_space[volnum]);
 	ncp_add_byte(server, 0);	/* reserved */
 	ncp_add_word(server, htons(0x0680));	/* search attribs: all */
 
 	ncp_add_dword(server, info_mask);
 	ncp_add_mem(server, info, sizeof(*info));
-	ncp_add_handle_path(server, file->volNumber,
-			    file->dirEntNum, 1, NULL);
+	ncp_add_handle_path(server, volnum, dirent, 1, NULL);
 
 	result = ncp_request(server, 87);
 	ncp_unlock_server(server);
@@ -339,17 +367,18 @@
 }
 
 int ncp_del_file_or_subdir(struct ncp_server *server,
-			   struct nw_info_struct *dir, char *name)
+			   struct inode *dir, char *name)
 {
+	__u8  volnum = NCP_FINFO(dir)->volNumber;
+	__u32 dirent = NCP_FINFO(dir)->dirEntNum;
 	int result;
 
 	ncp_init_request(server);
 	ncp_add_byte(server, 8);	/* subfunction */
-	ncp_add_byte(server, server->name_space[dir->volNumber]);
+	ncp_add_byte(server, server->name_space[volnum]);
 	ncp_add_byte(server, 0);	/* reserved */
 	ncp_add_word(server, ntohs(0x0680));	/* search attribs: all */
-	ncp_add_handle_path(server, dir->volNumber,
-			    dir->dirEntNum, 1, name);
+	ncp_add_handle_path(server, volnum, dirent, 1, name);
 
 	result = ncp_request(server, 87);
 	ncp_unlock_server(server);
@@ -367,22 +396,29 @@
 /* If both dir and name are NULL, then in target there's already a
    looked-up entry that wants to be opened. */
 int ncp_open_create_file_or_subdir(struct ncp_server *server,
-				   struct nw_info_struct *dir, char *name,
+				   struct inode *dir, char *name,
 				   int open_create_mode,
 				   __u32 create_attributes,
 				   int desired_acc_rights,
 				   struct nw_file_info *target)
 {
-	int result;
 	__u16 search_attribs = ntohs(0x0600);
-	__u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber;
+	__u8  volnum = target->i.volNumber;
+	__u32 dirent = target->i.dirEntNum;
+	int result;
+
+	if (dir)
+	{
+		volnum = NCP_FINFO(dir)->volNumber;
+		dirent = NCP_FINFO(dir)->dirEntNum;
+	}
 
 	if ((create_attributes & aDIR) != 0) {
 		search_attribs |= ntohs(0x0080);
 	}
 	ncp_init_request(server);
 	ncp_add_byte(server, 1);	/* subfunction */
-	ncp_add_byte(server, server->name_space[volume]);
+	ncp_add_byte(server, server->name_space[volnum]);
 	ncp_add_byte(server, open_create_mode);
 	ncp_add_word(server, search_attribs);
 	ncp_add_dword(server, RIM_ALL);
@@ -390,53 +426,47 @@
 	/* The desired acc rights seem to be the inherited rights mask
 	   for directories */
 	ncp_add_word(server, desired_acc_rights);
+	ncp_add_handle_path(server, volnum, dirent, 1, name);
 
-	if (dir != NULL) {
-		ncp_add_handle_path(server, volume, dir->dirEntNum, 1, name);
-	} else {
-		ncp_add_handle_path(server, volume, target->i.dirEntNum,
-				    1, NULL);
-	}
-
-	if ((result = ncp_request(server, 87)) != 0) {
-		ncp_unlock_server(server);
-		return result;
-	}
+	if ((result = ncp_request(server, 87)) != 0)
+		goto out;
 	target->opened = 1;
 	target->server_file_handle = ncp_reply_dword(server, 0);
 	target->open_create_action = ncp_reply_byte(server, 4);
 
 	if (dir != NULL) {
 		/* in target there's a new finfo to fill */
-		ncp_extract_file_info(ncp_reply_data(server, 5), &(target->i));
+		ncp_extract_file_info(ncp_reply_data(server, 6), &(target->i));
 	}
 	ConvertToNWfromDWORD(target->server_file_handle, target->file_handle);
 
+out:
 	ncp_unlock_server(server);
-	return 0;
+	return result;
 }
 
-
-int ncp_initialize_search(struct ncp_server *server,
-			  struct nw_info_struct *dir,
-			  struct nw_search_sequence *target)
+int
+ncp_initialize_search(struct ncp_server *server, struct inode *dir,
+			struct nw_search_sequence *target)
 {
+	__u8  volnum = NCP_FINFO(dir)->volNumber;
+	__u32 dirent = NCP_FINFO(dir)->dirEntNum;
 	int result;
 
 	ncp_init_request(server);
 	ncp_add_byte(server, 2);	/* subfunction */
-	ncp_add_byte(server, server->name_space[dir->volNumber]);
+	ncp_add_byte(server, server->name_space[volnum]);
 	ncp_add_byte(server, 0);	/* reserved */
-	ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, NULL);
+	ncp_add_handle_path(server, volnum, dirent, 1, NULL);
 
-	if ((result = ncp_request(server, 87)) != 0) {
-		ncp_unlock_server(server);
-		return result;
-	}
+	result = ncp_request(server, 87);
+	if (result)
+		goto out;
 	memcpy(target, ncp_reply_data(server, 0), sizeof(*target));
 
+out:
 	ncp_unlock_server(server);
-	return 0;
+	return result;
 }
 
 /* Search for everything */
@@ -457,42 +487,41 @@
 	ncp_add_byte(server, 0xff);	/* following is a wildcard */
 	ncp_add_byte(server, '*');
 
-	if ((result = ncp_request(server, 87)) != 0) {
-		ncp_unlock_server(server);
-		return result;
-	}
+	if ((result = ncp_request(server, 87)) != 0)
+		goto out;
 	memcpy(seq, ncp_reply_data(server, 0), sizeof(*seq));
 	ncp_extract_file_info(ncp_reply_data(server, 10), target);
 
+out:
 	ncp_unlock_server(server);
-	return 0;
+	return result;
 }
 
 int ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
-			  struct nw_info_struct *old_dir, char *old_name,
-			  struct nw_info_struct *new_dir, char *new_name)
+				struct inode *old_dir, char *old_name,
+				struct inode *new_dir, char *new_name)
 {
-	int result;
+	int result = -EINVAL;
 
-	if ((old_dir == NULL) || (old_name == NULL)
-	    || (new_dir == NULL) || (new_name == NULL))
-		return -EINVAL;
+	if ((old_dir == NULL) || (old_name == NULL) ||
+	    (new_dir == NULL) || (new_name == NULL))
+		goto out;
 
 	ncp_init_request(server);
 	ncp_add_byte(server, 4);	/* subfunction */
-	ncp_add_byte(server, server->name_space[old_dir->volNumber]);
+	ncp_add_byte(server, server->name_space[NCP_FINFO(old_dir)->volNumber]);
 	ncp_add_byte(server, 1);	/* rename flag */
 	ncp_add_word(server, ntohs(0x0680));	/* search attributes */
 
 	/* source Handle Path */
-	ncp_add_byte(server, old_dir->volNumber);
-	ncp_add_dword(server, old_dir->dirEntNum);
+	ncp_add_byte(server, NCP_FINFO(old_dir)->volNumber);
+	ncp_add_dword(server, NCP_FINFO(old_dir)->dirEntNum);
 	ncp_add_byte(server, 1);
 	ncp_add_byte(server, 1);	/* 1 source component */
 
 	/* dest Handle Path */
-	ncp_add_byte(server, new_dir->volNumber);
-	ncp_add_dword(server, new_dir->dirEntNum);
+	ncp_add_byte(server, NCP_FINFO(new_dir)->volNumber);
+	ncp_add_dword(server, NCP_FINFO(new_dir)->dirEntNum);
 	ncp_add_byte(server, 1);
 	ncp_add_byte(server, 1);	/* 1 destination component */
 
@@ -503,15 +532,17 @@
 
 	result = ncp_request(server, 87);
 	ncp_unlock_server(server);
+out:
 	return result;
 }
 
 
 /* We have to transfer to/from user space */
-int ncp_read(struct ncp_server *server, const char *file_id,
-	     __u32 offset, __u16 to_read,
-	     char *target, int *bytes_read)
+int
+ncp_read(struct ncp_server *server, const char *file_id,
+	     __u32 offset, __u16 to_read, char *target, int *bytes_read)
 {
+	char *source;
 	int result;
 
 	ncp_init_request(server);
@@ -521,20 +552,23 @@
 	ncp_add_word(server, htons(to_read));
 
 	if ((result = ncp_request(server, 72)) != 0) {
-		ncp_unlock_server(server);
-		return result;
+		goto out;
 	}
 	*bytes_read = ntohs(ncp_reply_word(server, 0));
+	source = ncp_reply_data(server, 2 + (offset & 1));
 
-	copy_to_user(target, ncp_reply_data(server, 2 + (offset & 1)), *bytes_read);
-
+	result = -EFAULT;
+	if (!copy_to_user(target, source, *bytes_read))
+		result = 0;
+out:
 	ncp_unlock_server(server);
-	return 0;
+	return result;
 }
 
-int ncp_write(struct ncp_server *server, const char *file_id,
+int
+ncp_write(struct ncp_server *server, const char *file_id,
 	      __u32 offset, __u16 to_write,
-	      const char *source, int *bytes_written)
+		const char *source, int *bytes_written)
 {
 	int result;
 
@@ -545,12 +579,11 @@
 	ncp_add_word(server, htons(to_write));
 	ncp_add_mem_fromfs(server, source, to_write);
 
-	if ((result = ncp_request(server, 73)) != 0) {
-		ncp_unlock_server(server);
-		return result;
-	}
+	if ((result = ncp_request(server, 73)) != 0)
+		goto out;
 	*bytes_written = to_write;
-
+	result = 0;
+out:
 	ncp_unlock_server(server);
-	return 0;
+	return result;
 }

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