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
- Lines: 512
- Date:
Wed Nov 12 11:10:40 1997
- Orig file:
v2.1.62/linux/fs/ncpfs/ncplib_kernel.c
- Orig date:
Fri Apr 4 08:52:24 1997
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