summaryrefslogtreecommitdiffstats
path: root/fs/ncpfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ncpfs')
-rw-r--r--fs/ncpfs/dir.c105
-rw-r--r--fs/ncpfs/file.c3
-rw-r--r--fs/ncpfs/inode.c23
-rw-r--r--fs/ncpfs/ioctl.c4
-rw-r--r--fs/ncpfs/mmap.c4
-rw-r--r--fs/ncpfs/ncp_fs.h98
-rw-r--r--fs/ncpfs/ncp_fs_i.h29
-rw-r--r--fs/ncpfs/ncp_fs_sb.h176
-rw-r--r--fs/ncpfs/ncplib_kernel.c2
-rw-r--r--fs/ncpfs/ncplib_kernel.h18
-rw-r--r--fs/ncpfs/ncpsign_kernel.c1
-rw-r--r--fs/ncpfs/ncpsign_kernel.h2
-rw-r--r--fs/ncpfs/sock.c2
-rw-r--r--fs/ncpfs/symlink.c4
14 files changed, 378 insertions, 93 deletions
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index f22b12e7d33..f6946bb5cb5 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -17,12 +17,11 @@
#include <linux/kernel.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
+#include <linux/namei.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
-#include <linux/ncp_fs.h>
-
-#include "ncplib_kernel.h"
+#include "ncp_fs.h"
static void ncp_read_volume_list(struct file *, void *, filldir_t,
struct ncp_cache_control *);
@@ -74,11 +73,14 @@ const struct inode_operations ncp_dir_inode_operations =
* Dentry operations routines
*/
static int ncp_lookup_validate(struct dentry *, struct nameidata *);
-static int ncp_hash_dentry(struct dentry *, struct qstr *);
-static int ncp_compare_dentry (struct dentry *, struct qstr *, struct qstr *);
-static int ncp_delete_dentry(struct dentry *);
-
-static const struct dentry_operations ncp_dentry_operations =
+static int ncp_hash_dentry(const struct dentry *, const struct inode *,
+ struct qstr *);
+static int ncp_compare_dentry(const struct dentry *, const struct inode *,
+ const struct dentry *, const struct inode *,
+ unsigned int, const char *, const struct qstr *);
+static int ncp_delete_dentry(const struct dentry *);
+
+const struct dentry_operations ncp_dentry_operations =
{
.d_revalidate = ncp_lookup_validate,
.d_hash = ncp_hash_dentry,
@@ -86,14 +88,6 @@ static const struct dentry_operations ncp_dentry_operations =
.d_delete = ncp_delete_dentry,
};
-const struct dentry_operations ncp_root_dentry_operations =
-{
- .d_hash = ncp_hash_dentry,
- .d_compare = ncp_compare_dentry,
- .d_delete = ncp_delete_dentry,
-};
-
-
#define ncp_namespace(i) (NCP_SERVER(i)->name_space[NCP_FINFO(i)->volNumber])
static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator)
@@ -113,10 +107,10 @@ static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator)
#define ncp_preserve_case(i) (ncp_namespace(i) != NW_NS_DOS)
-static inline int ncp_case_sensitive(struct dentry *dentry)
+static inline int ncp_case_sensitive(const struct inode *i)
{
#ifdef CONFIG_NCPFS_NFS_NS
- return ncp_namespace(dentry->d_inode) == NW_NS_NFS;
+ return ncp_namespace(i) == NW_NS_NFS;
#else
return 0;
#endif /* CONFIG_NCPFS_NFS_NS */
@@ -127,14 +121,16 @@ static inline int ncp_case_sensitive(struct dentry *dentry)
* is case-sensitive.
*/
static int
-ncp_hash_dentry(struct dentry *dentry, struct qstr *this)
+ncp_hash_dentry(const struct dentry *dentry, const struct inode *inode,
+ struct qstr *this)
{
- if (!ncp_case_sensitive(dentry)) {
+ if (!ncp_case_sensitive(inode)) {
+ struct super_block *sb = dentry->d_sb;
struct nls_table *t;
unsigned long hash;
int i;
- t = NCP_IO_TABLE(dentry);
+ t = NCP_IO_TABLE(sb);
hash = init_name_hash();
for (i=0; i<this->len ; i++)
hash = partial_name_hash(ncp_tolower(t, this->name[i]),
@@ -145,15 +141,17 @@ ncp_hash_dentry(struct dentry *dentry, struct qstr *this)
}
static int
-ncp_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
+ncp_compare_dentry(const struct dentry *parent, const struct inode *pinode,
+ const struct dentry *dentry, const struct inode *inode,
+ unsigned int len, const char *str, const struct qstr *name)
{
- if (a->len != b->len)
+ if (len != name->len)
return 1;
- if (ncp_case_sensitive(dentry))
- return strncmp(a->name, b->name, a->len);
+ if (ncp_case_sensitive(pinode))
+ return strncmp(str, name->name, len);
- return ncp_strnicmp(NCP_IO_TABLE(dentry), a->name, b->name, a->len);
+ return ncp_strnicmp(NCP_IO_TABLE(pinode->i_sb), str, name->name, len);
}
/*
@@ -162,7 +160,7 @@ ncp_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
* Closing files can be safely postponed until iput() - it's done there anyway.
*/
static int
-ncp_delete_dentry(struct dentry * dentry)
+ncp_delete_dentry(const struct dentry * dentry)
{
struct inode *inode = dentry->d_inode;
@@ -301,6 +299,12 @@ ncp_lookup_validate(struct dentry *dentry, struct nameidata *nd)
int res, val = 0, len;
__u8 __name[NCP_MAXPATHLEN + 1];
+ if (dentry == dentry->d_sb->s_root)
+ return 1;
+
+ if (nd->flags & LOOKUP_RCU)
+ return -ECHILD;
+
parent = dget_parent(dentry);
dir = parent->d_inode;
@@ -384,21 +388,21 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
}
/* If a pointer is invalid, we search the dentry. */
- spin_lock(&dcache_lock);
+ spin_lock(&parent->d_lock);
next = parent->d_subdirs.next;
while (next != &parent->d_subdirs) {
dent = list_entry(next, struct dentry, d_u.d_child);
if ((unsigned long)dent->d_fsdata == fpos) {
if (dent->d_inode)
- dget_locked(dent);
+ dget(dent);
else
dent = NULL;
- spin_unlock(&dcache_lock);
+ spin_unlock(&parent->d_lock);
goto out;
}
next = next->next;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&parent->d_lock);
return NULL;
out:
@@ -592,7 +596,7 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
qname.hash = full_name_hash(qname.name, qname.len);
if (dentry->d_op && dentry->d_op->d_hash)
- if (dentry->d_op->d_hash(dentry, &qname) != 0)
+ if (dentry->d_op->d_hash(dentry, dentry->d_inode, &qname) != 0)
goto end_advance;
newdent = d_lookup(dentry, &qname);
@@ -611,35 +615,12 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
shrink_dcache_parent(newdent);
/*
- * It is not as dangerous as it looks. NetWare's OS2 namespace is
- * case preserving yet case insensitive. So we update dentry's name
- * as received from server. We found dentry via d_lookup with our
- * hash, so we know that hash does not change, and so replacing name
- * should be reasonably safe.
+ * NetWare's OS2 namespace is case preserving yet case
+ * insensitive. So we update dentry's name as received from
+ * server. Parent dir's i_mutex is locked because we're in
+ * readdir.
*/
- if (qname.len == newdent->d_name.len &&
- memcmp(newdent->d_name.name, qname.name, newdent->d_name.len)) {
- struct inode *inode = newdent->d_inode;
-
- /*
- * Inside ncpfs all uses of d_name are either for debugging,
- * or on functions which acquire inode mutex (mknod, creat,
- * lookup). So grab i_mutex here, to be sure. d_path
- * uses dcache_lock when generating path, so we should too.
- * And finally d_compare is protected by dentry's d_lock, so
- * here we go.
- */
- if (inode)
- mutex_lock(&inode->i_mutex);
- spin_lock(&dcache_lock);
- spin_lock(&newdent->d_lock);
- memcpy((char *) newdent->d_name.name, qname.name,
- newdent->d_name.len);
- spin_unlock(&newdent->d_lock);
- spin_unlock(&dcache_lock);
- if (inode)
- mutex_unlock(&inode->i_mutex);
- }
+ dentry_update_name_case(newdent, &qname);
}
if (!newdent->d_inode) {
@@ -649,7 +630,6 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
entry->ino = iunique(dir->i_sb, 2);
inode = ncp_iget(dir->i_sb, entry);
if (inode) {
- newdent->d_op = &ncp_dentry_operations;
d_instantiate(newdent, inode);
if (!hashed)
d_rehash(newdent);
@@ -657,7 +637,7 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
} else {
struct inode *inode = newdent->d_inode;
- mutex_lock(&inode->i_mutex);
+ mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
ncp_update_inode2(inode, entry);
mutex_unlock(&inode->i_mutex);
}
@@ -905,7 +885,6 @@ static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, struc
if (inode) {
ncp_new_dentry(dentry);
add_entry:
- dentry->d_op = &ncp_dentry_operations;
d_add(dentry, inode);
error = 0;
}
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index cb50aaf981d..0ed65e0c3df 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -18,8 +18,7 @@
#include <linux/vmalloc.h>
#include <linux/sched.h>
-#include <linux/ncp_fs.h>
-#include "ncplib_kernel.h"
+#include "ncp_fs.h"
static int ncp_fsync(struct file *file, int datasync)
{
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 8fb93b604e7..00a1d1c3d3a 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -29,12 +29,11 @@
#include <linux/vfs.h>
#include <linux/mount.h>
#include <linux/seq_file.h>
-
-#include <linux/ncp_fs.h>
+#include <linux/namei.h>
#include <net/sock.h>
-#include "ncplib_kernel.h"
+#include "ncp_fs.h"
#include "getopt.h"
#define NCP_DEFAULT_FILE_MODE 0600
@@ -58,11 +57,18 @@ static struct inode *ncp_alloc_inode(struct super_block *sb)
return &ei->vfs_inode;
}
-static void ncp_destroy_inode(struct inode *inode)
+static void ncp_i_callback(struct rcu_head *head)
{
+ struct inode *inode = container_of(head, struct inode, i_rcu);
+ INIT_LIST_HEAD(&inode->i_dentry);
kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
}
+static void ncp_destroy_inode(struct inode *inode)
+{
+ call_rcu(&inode->i_rcu, ncp_i_callback);
+}
+
static void init_once(void *foo)
{
struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
@@ -309,7 +315,12 @@ static void ncp_stop_tasks(struct ncp_server *server) {
sk->sk_write_space = server->write_space;
release_sock(sk);
del_timer_sync(&server->timeout_tm);
- flush_scheduled_work();
+
+ flush_work_sync(&server->rcv.tq);
+ if (sk->sk_socket->type == SOCK_STREAM)
+ flush_work_sync(&server->tx.tq);
+ else
+ flush_work_sync(&server->timeout_tq);
}
static int ncp_show_options(struct seq_file *seq, struct vfsmount *mnt)
@@ -531,6 +542,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
sb->s_blocksize_bits = 10;
sb->s_magic = NCP_SUPER_MAGIC;
sb->s_op = &ncp_sops;
+ sb->s_d_op = &ncp_dentry_operations;
sb->s_bdi = &server->bdi;
server = NCP_SBP(sb);
@@ -710,7 +722,6 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
sb->s_root = d_alloc_root(root_inode);
if (!sb->s_root)
goto out_no_root;
- sb->s_root->d_op = &ncp_root_dentry_operations;
return 0;
out_no_root:
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index d40a547e337..790e92a9ec6 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -20,11 +20,9 @@
#include <linux/vmalloc.h>
#include <linux/sched.h>
-#include <linux/ncp_fs.h>
-
#include <asm/uaccess.h>
-#include "ncplib_kernel.h"
+#include "ncp_fs.h"
/* maximum limit for ncp_objectname_ioctl */
#define NCP_OBJECT_NAME_MAX_LEN 4096
diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c
index 56f5b3a0e1e..a7c07b44b10 100644
--- a/fs/ncpfs/mmap.c
+++ b/fs/ncpfs/mmap.c
@@ -16,12 +16,12 @@
#include <linux/mman.h>
#include <linux/string.h>
#include <linux/fcntl.h>
-#include <linux/ncp_fs.h>
-#include "ncplib_kernel.h"
#include <asm/uaccess.h>
#include <asm/system.h>
+#include "ncp_fs.h"
+
/*
* Fill in the supplied page for mmap
* XXX: how are we excluding truncate/invalidate here? Maybe need to lock
diff --git a/fs/ncpfs/ncp_fs.h b/fs/ncpfs/ncp_fs.h
new file mode 100644
index 00000000000..31831afe1c3
--- /dev/null
+++ b/fs/ncpfs/ncp_fs.h
@@ -0,0 +1,98 @@
+#include <linux/ncp_fs.h>
+#include "ncp_fs_i.h"
+#include "ncp_fs_sb.h"
+
+/* define because it is easy to change PRINTK to {*}PRINTK */
+#define PRINTK(format, args...) printk(KERN_DEBUG format , ## args)
+
+#undef NCPFS_PARANOIA
+#ifdef NCPFS_PARANOIA
+#define PPRINTK(format, args...) PRINTK(format , ## args)
+#else
+#define PPRINTK(format, args...)
+#endif
+
+#ifndef DEBUG_NCP
+#define DEBUG_NCP 0
+#endif
+#if DEBUG_NCP > 0
+#define DPRINTK(format, args...) PRINTK(format , ## args)
+#else
+#define DPRINTK(format, args...)
+#endif
+#if DEBUG_NCP > 1
+#define DDPRINTK(format, args...) PRINTK(format , ## args)
+#else
+#define DDPRINTK(format, args...)
+#endif
+
+#define NCP_MAX_RPC_TIMEOUT (6*HZ)
+
+
+struct ncp_entry_info {
+ struct nw_info_struct i;
+ ino_t ino;
+ int opened;
+ int access;
+ unsigned int volume;
+ __u8 file_handle[6];
+};
+
+static inline struct ncp_server *NCP_SBP(const struct super_block *sb)
+{
+ return sb->s_fs_info;
+}
+
+#define NCP_SERVER(inode) NCP_SBP((inode)->i_sb)
+static inline struct ncp_inode_info *NCP_FINFO(const struct inode *inode)
+{
+ return container_of(inode, struct ncp_inode_info, vfs_inode);
+}
+
+/* linux/fs/ncpfs/inode.c */
+int ncp_notify_change(struct dentry *, struct iattr *);
+struct inode *ncp_iget(struct super_block *, struct ncp_entry_info *);
+void ncp_update_inode(struct inode *, struct ncp_entry_info *);
+void ncp_update_inode2(struct inode *, struct ncp_entry_info *);
+
+/* linux/fs/ncpfs/dir.c */
+extern const struct inode_operations ncp_dir_inode_operations;
+extern const struct file_operations ncp_dir_operations;
+extern const struct dentry_operations ncp_dentry_operations;
+int ncp_conn_logged_in(struct super_block *);
+int ncp_date_dos2unix(__le16 time, __le16 date);
+void ncp_date_unix2dos(int unix_date, __le16 * time, __le16 * date);
+
+/* linux/fs/ncpfs/ioctl.c */
+long ncp_ioctl(struct file *, unsigned int, unsigned long);
+long ncp_compat_ioctl(struct file *, unsigned int, unsigned long);
+
+/* linux/fs/ncpfs/sock.c */
+int ncp_request2(struct ncp_server *server, int function,
+ void* reply, int max_reply_size);
+static inline int ncp_request(struct ncp_server *server, int function) {
+ return ncp_request2(server, function, server->packet, server->packet_size);
+}
+int ncp_connect(struct ncp_server *server);
+int ncp_disconnect(struct ncp_server *server);
+void ncp_lock_server(struct ncp_server *server);
+void ncp_unlock_server(struct ncp_server *server);
+
+/* linux/fs/ncpfs/symlink.c */
+#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
+extern const struct address_space_operations ncp_symlink_aops;
+int ncp_symlink(struct inode*, struct dentry*, const char*);
+#endif
+
+/* linux/fs/ncpfs/file.c */
+extern const struct inode_operations ncp_file_inode_operations;
+extern const struct file_operations ncp_file_operations;
+int ncp_make_open(struct inode *, int);
+
+/* linux/fs/ncpfs/mmap.c */
+int ncp_mmap(struct file *, struct vm_area_struct *);
+
+/* linux/fs/ncpfs/ncplib_kernel.c */
+int ncp_make_closed(struct inode *);
+
+#include "ncplib_kernel.h"
diff --git a/fs/ncpfs/ncp_fs_i.h b/fs/ncpfs/ncp_fs_i.h
new file mode 100644
index 00000000000..4b0bec47784
--- /dev/null
+++ b/fs/ncpfs/ncp_fs_i.h
@@ -0,0 +1,29 @@
+/*
+ * ncp_fs_i.h
+ *
+ * Copyright (C) 1995 Volker Lendecke
+ *
+ */
+
+#ifndef _LINUX_NCP_FS_I
+#define _LINUX_NCP_FS_I
+
+/*
+ * This is the ncpfs part of the inode structure. This must contain
+ * all the information we need to work with an inode after creation.
+ */
+struct ncp_inode_info {
+ __le32 dirEntNum;
+ __le32 DosDirNum;
+ __u8 volNumber;
+ __le32 nwattr;
+ struct mutex open_mutex;
+ atomic_t opened;
+ int access;
+ int flags;
+#define NCPI_KLUDGE_SYMLINK 0x0001
+ __u8 file_handle[6];
+ struct inode vfs_inode;
+};
+
+#endif /* _LINUX_NCP_FS_I */
diff --git a/fs/ncpfs/ncp_fs_sb.h b/fs/ncpfs/ncp_fs_sb.h
new file mode 100644
index 00000000000..4af803f1351
--- /dev/null
+++ b/fs/ncpfs/ncp_fs_sb.h
@@ -0,0 +1,176 @@
+/*
+ * ncp_fs_sb.h
+ *
+ * Copyright (C) 1995, 1996 by Volker Lendecke
+ *
+ */
+
+#ifndef _NCP_FS_SB
+#define _NCP_FS_SB
+
+#include <linux/types.h>
+#include <linux/ncp_mount.h>
+#include <linux/net.h>
+#include <linux/mutex.h>
+#include <linux/backing-dev.h>
+#include <linux/workqueue.h>
+
+#define NCP_DEFAULT_OPTIONS 0 /* 2 for packet signatures */
+
+struct sock;
+
+struct ncp_mount_data_kernel {
+ unsigned long flags; /* NCP_MOUNT_* flags */
+ unsigned int int_flags; /* internal flags */
+#define NCP_IMOUNT_LOGGEDIN_POSSIBLE 0x0001
+ __kernel_uid32_t mounted_uid; /* Who may umount() this filesystem? */
+ struct pid *wdog_pid; /* Who cares for our watchdog packets? */
+ unsigned int ncp_fd; /* The socket to the ncp port */
+ unsigned int time_out; /* How long should I wait after
+ sending a NCP request? */
+ unsigned int retry_count; /* And how often should I retry? */
+ unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
+ __kernel_uid32_t uid;
+ __kernel_gid32_t gid;
+ __kernel_mode_t file_mode;
+ __kernel_mode_t dir_mode;
+ int info_fd;
+};
+
+struct ncp_server {
+
+ struct ncp_mount_data_kernel m; /* Nearly all of the mount data is of
+ interest for us later, so we store
+ it completely. */
+
+ __u8 name_space[NCP_NUMBER_OF_VOLUMES + 2];
+
+ struct file *ncp_filp; /* File pointer to ncp socket */
+ struct socket *ncp_sock;/* ncp socket */
+ struct file *info_filp;
+ struct socket *info_sock;
+
+ u8 sequence;
+ u8 task;
+ u16 connection; /* Remote connection number */
+
+ u8 completion; /* Status message from server */
+ u8 conn_status; /* Bit 4 = 1 ==> Server going down, no
+ requests allowed anymore.
+ Bit 0 = 1 ==> Server is down. */
+
+ int buffer_size; /* Negotiated bufsize */
+
+ int reply_size; /* Size of last reply */
+
+ int packet_size;
+ unsigned char *packet; /* Here we prepare requests and
+ receive replies */
+ unsigned char *txbuf; /* Storage for current request */
+ unsigned char *rxbuf; /* Storage for reply to current request */
+
+ int lock; /* To prevent mismatch in protocols. */
+ struct mutex mutex;
+
+ int current_size; /* for packet preparation */
+ int has_subfunction;
+ int ncp_reply_size;
+
+ int root_setuped;
+ struct mutex root_setup_lock;
+
+ /* info for packet signing */
+ int sign_wanted; /* 1=Server needs signed packets */
+ int sign_active; /* 0=don't do signing, 1=do */
+ char sign_root[8]; /* generated from password and encr. key */
+ char sign_last[16];
+
+ /* Authentication info: NDS or BINDERY, username */
+ struct {
+ int auth_type;
+ size_t object_name_len;
+ void* object_name;
+ int object_type;
+ } auth;
+ /* Password info */
+ struct {
+ size_t len;
+ void* data;
+ } priv;
+ struct rw_semaphore auth_rwsem;
+
+ /* nls info: codepage for volume and charset for I/O */
+ struct nls_table *nls_vol;
+ struct nls_table *nls_io;
+
+ /* maximum age in jiffies */
+ atomic_t dentry_ttl;
+
+ /* miscellaneous */
+ unsigned int flags;
+
+ spinlock_t requests_lock; /* Lock accesses to tx.requests, tx.creq and rcv.creq when STREAM mode */
+
+ void (*data_ready)(struct sock* sk, int len);
+ void (*error_report)(struct sock* sk);
+ void (*write_space)(struct sock* sk); /* STREAM mode only */
+ struct {
+ struct work_struct tq; /* STREAM/DGRAM: data/error ready */
+ struct ncp_request_reply* creq; /* STREAM/DGRAM: awaiting reply from this request */
+ struct mutex creq_mutex; /* DGRAM only: lock accesses to rcv.creq */
+
+ unsigned int state; /* STREAM only: receiver state */
+ struct {
+ __u32 magic __packed;
+ __u32 len __packed;
+ __u16 type __packed;
+ __u16 p1 __packed;
+ __u16 p2 __packed;
+ __u16 p3 __packed;
+ __u16 type2 __packed;
+ } buf; /* STREAM only: temporary buffer */
+ unsigned char* ptr; /* STREAM only: pointer to data */
+ size_t len; /* STREAM only: length of data to receive */
+ } rcv;
+ struct {
+ struct list_head requests; /* STREAM only: queued requests */
+ struct work_struct tq; /* STREAM only: transmitter ready */
+ struct ncp_request_reply* creq; /* STREAM only: currently transmitted entry */
+ } tx;
+ struct timer_list timeout_tm; /* DGRAM only: timeout timer */
+ struct work_struct timeout_tq; /* DGRAM only: associated queue, we run timers from process context */
+ int timeout_last; /* DGRAM only: current timeout length */
+ int timeout_retries; /* DGRAM only: retries left */
+ struct {
+ size_t len;
+ __u8 data[128];
+ } unexpected_packet;
+ struct backing_dev_info bdi;
+};
+
+extern void ncp_tcp_rcv_proc(struct work_struct *work);
+extern void ncp_tcp_tx_proc(struct work_struct *work);
+extern void ncpdgram_rcv_proc(struct work_struct *work);
+extern void ncpdgram_timeout_proc(struct work_struct *work);
+extern void ncpdgram_timeout_call(unsigned long server);
+extern void ncp_tcp_data_ready(struct sock* sk, int len);
+extern void ncp_tcp_write_space(struct sock* sk);
+extern void ncp_tcp_error_report(struct sock* sk);
+
+#define NCP_FLAG_UTF8 1
+
+#define NCP_CLR_FLAG(server, flag) ((server)->flags &= ~(flag))
+#define NCP_SET_FLAG(server, flag) ((server)->flags |= (flag))
+#define NCP_IS_FLAG(server, flag) ((server)->flags & (flag))
+
+static inline int ncp_conn_valid(struct ncp_server *server)
+{
+ return ((server->conn_status & 0x11) == 0);
+}
+
+static inline void ncp_invalidate_conn(struct ncp_server *server)
+{
+ server->conn_status |= 0x01;
+}
+
+#endif
diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c
index a95615a0b6a..981a95617fc 100644
--- a/fs/ncpfs/ncplib_kernel.c
+++ b/fs/ncpfs/ncplib_kernel.c
@@ -11,7 +11,7 @@
-#include "ncplib_kernel.h"
+#include "ncp_fs.h"
static inline void assert_server_locked(struct ncp_server *server)
{
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h
index 3c57eca634c..09881e6aa5a 100644
--- a/fs/ncpfs/ncplib_kernel.h
+++ b/fs/ncpfs/ncplib_kernel.h
@@ -32,8 +32,6 @@
#include <linux/ctype.h>
#endif /* CONFIG_NCPFS_NLS */
-#include <linux/ncp_fs.h>
-
#define NCP_MIN_SYMLINK_SIZE 8
#define NCP_MAX_SYMLINK_SIZE 512
@@ -135,7 +133,7 @@ int ncp__vol2io(struct ncp_server *, unsigned char *, unsigned int *,
const unsigned char *, unsigned int, int);
#define NCP_ESC ':'
-#define NCP_IO_TABLE(dentry) (NCP_SERVER((dentry)->d_inode)->nls_io)
+#define NCP_IO_TABLE(sb) (NCP_SBP(sb)->nls_io)
#define ncp_tolower(t, c) nls_tolower(t, c)
#define ncp_toupper(t, c) nls_toupper(t, c)
#define ncp_strnicmp(t, s1, s2, len) \
@@ -150,15 +148,15 @@ int ncp__io2vol(unsigned char *, unsigned int *,
int ncp__vol2io(unsigned char *, unsigned int *,
const unsigned char *, unsigned int, int);
-#define NCP_IO_TABLE(dentry) NULL
+#define NCP_IO_TABLE(sb) NULL
#define ncp_tolower(t, c) tolower(c)
#define ncp_toupper(t, c) toupper(c)
#define ncp_io2vol(S,m,i,n,k,U) ncp__io2vol(m,i,n,k,U)
#define ncp_vol2io(S,m,i,n,k,U) ncp__vol2io(m,i,n,k,U)
-static inline int ncp_strnicmp(struct nls_table *t, const unsigned char *s1,
- const unsigned char *s2, int len)
+static inline int ncp_strnicmp(const struct nls_table *t,
+ const unsigned char *s1, const unsigned char *s2, int len)
{
while (len--) {
if (tolower(*s1++) != tolower(*s2++))
@@ -193,7 +191,7 @@ ncp_renew_dentries(struct dentry *parent)
struct list_head *next;
struct dentry *dentry;
- spin_lock(&dcache_lock);
+ spin_lock(&parent->d_lock);
next = parent->d_subdirs.next;
while (next != &parent->d_subdirs) {
dentry = list_entry(next, struct dentry, d_u.d_child);
@@ -205,7 +203,7 @@ ncp_renew_dentries(struct dentry *parent)
next = next->next;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&parent->d_lock);
}
static inline void
@@ -215,7 +213,7 @@ ncp_invalidate_dircache_entries(struct dentry *parent)
struct list_head *next;
struct dentry *dentry;
- spin_lock(&dcache_lock);
+ spin_lock(&parent->d_lock);
next = parent->d_subdirs.next;
while (next != &parent->d_subdirs) {
dentry = list_entry(next, struct dentry, d_u.d_child);
@@ -223,7 +221,7 @@ ncp_invalidate_dircache_entries(struct dentry *parent)
ncp_age_dentry(server, dentry);
next = next->next;
}
- spin_unlock(&dcache_lock);
+ spin_unlock(&parent->d_lock);
}
struct ncp_cache_head {
diff --git a/fs/ncpfs/ncpsign_kernel.c b/fs/ncpfs/ncpsign_kernel.c
index d8b2d7e6910..08907599dcd 100644
--- a/fs/ncpfs/ncpsign_kernel.c
+++ b/fs/ncpfs/ncpsign_kernel.c
@@ -11,6 +11,7 @@
#include <linux/string.h>
#include <linux/ncp.h>
#include <linux/bitops.h>
+#include "ncp_fs.h"
#include "ncpsign_kernel.h"
/* i386: 32-bit, little endian, handles mis-alignment */
diff --git a/fs/ncpfs/ncpsign_kernel.h b/fs/ncpfs/ncpsign_kernel.h
index 6451a68381c..d9a1438bb1f 100644
--- a/fs/ncpfs/ncpsign_kernel.h
+++ b/fs/ncpfs/ncpsign_kernel.h
@@ -8,8 +8,6 @@
#ifndef _NCPSIGN_KERNEL_H
#define _NCPSIGN_KERNEL_H
-#include <linux/ncp_fs.h>
-
#ifdef CONFIG_NCPFS_PACKET_SIGNING
void __sign_packet(struct ncp_server *server, const char *data, size_t size, __u32 totalsize, void *sign_buff);
int sign_verify_reply(struct ncp_server *server, const char *data, size_t size, __u32 totalsize, const void *sign_buff);
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c
index 668bd267346..3a1587222c8 100644
--- a/fs/ncpfs/sock.c
+++ b/fs/ncpfs/sock.c
@@ -28,7 +28,7 @@
#include <linux/poll.h>
#include <linux/file.h>
-#include <linux/ncp_fs.h>
+#include "ncp_fs.h"
#include "ncpsign_kernel.h"
diff --git a/fs/ncpfs/symlink.c b/fs/ncpfs/symlink.c
index c634fd17b33..661f861d80c 100644
--- a/fs/ncpfs/symlink.c
+++ b/fs/ncpfs/symlink.c
@@ -25,13 +25,11 @@
#include <linux/errno.h>
#include <linux/fs.h>
-#include <linux/ncp_fs.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/stat.h>
-#include "ncplib_kernel.h"
-
+#include "ncp_fs.h"
/* these magic numbers must appear in the symlink file -- this makes it a bit
more resilient against the magic attributes being set on random files. */