aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2010-10-28 12:44:56 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-28 12:44:56 -0400
commite4c5bf8e3dca827a1b3a6fac494eae8c74b7e1e7 (patch)
treeea51b391f7d74ca695dcb9f5e46eb02688a92ed9 /fs
parent81280572ca6f54009edfa4deee563e8678784218 (diff)
parenta4ac0d847af9dd34d5953a5e264400326144b6b2 (diff)
Merge 'staging-next' to Linus's tree
This merges the staging-next tree to Linus's tree and resolves some conflicts that were present due to changes in other trees that were affected by files here. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs')
-rw-r--r--fs/Kconfig2
-rw-r--r--fs/Makefile2
-rw-r--r--fs/autofs/Kconfig22
-rw-r--r--fs/autofs/Makefile7
-rw-r--r--fs/autofs/autofs_i.h165
-rw-r--r--fs/autofs/dirhash.c250
-rw-r--r--fs/autofs/init.c52
-rw-r--r--fs/autofs/inode.c288
-rw-r--r--fs/autofs/root.c645
-rw-r--r--fs/autofs/symlink.c26
-rw-r--r--fs/autofs/waitq.c205
-rw-r--r--fs/compat.c31
-rw-r--r--fs/compat_ioctl.c29
-rw-r--r--fs/smbfs/Kconfig56
-rw-r--r--fs/smbfs/Makefile18
-rw-r--r--fs/smbfs/cache.c208
-rw-r--r--fs/smbfs/dir.c696
-rw-r--r--fs/smbfs/file.c454
-rw-r--r--fs/smbfs/getopt.c64
-rw-r--r--fs/smbfs/getopt.h14
-rw-r--r--fs/smbfs/inode.c843
-rw-r--r--fs/smbfs/ioctl.c69
-rw-r--r--fs/smbfs/proc.c3503
-rw-r--r--fs/smbfs/proto.h87
-rw-r--r--fs/smbfs/request.c818
-rw-r--r--fs/smbfs/request.h70
-rw-r--r--fs/smbfs/smb_debug.h34
-rw-r--r--fs/smbfs/smbiod.c344
-rw-r--r--fs/smbfs/sock.c386
-rw-r--r--fs/smbfs/symlink.c68
30 files changed, 4 insertions, 9452 deletions
diff --git a/fs/Kconfig b/fs/Kconfig
index 97673c955484..771f457402d4 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -62,7 +62,6 @@ source "fs/notify/Kconfig"
62 62
63source "fs/quota/Kconfig" 63source "fs/quota/Kconfig"
64 64
65source "fs/autofs/Kconfig"
66source "fs/autofs4/Kconfig" 65source "fs/autofs4/Kconfig"
67source "fs/fuse/Kconfig" 66source "fs/fuse/Kconfig"
68 67
@@ -234,7 +233,6 @@ config NFS_COMMON
234 default y 233 default y
235 234
236source "net/sunrpc/Kconfig" 235source "net/sunrpc/Kconfig"
237source "fs/smbfs/Kconfig"
238source "fs/ceph/Kconfig" 236source "fs/ceph/Kconfig"
239source "fs/cifs/Kconfig" 237source "fs/cifs/Kconfig"
240source "fs/ncpfs/Kconfig" 238source "fs/ncpfs/Kconfig"
diff --git a/fs/Makefile b/fs/Makefile
index 26956fcec917..a7f7cef0c0c8 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -88,7 +88,6 @@ obj-$(CONFIG_NFSD) += nfsd/
88obj-$(CONFIG_LOCKD) += lockd/ 88obj-$(CONFIG_LOCKD) += lockd/
89obj-$(CONFIG_NLS) += nls/ 89obj-$(CONFIG_NLS) += nls/
90obj-$(CONFIG_SYSV_FS) += sysv/ 90obj-$(CONFIG_SYSV_FS) += sysv/
91obj-$(CONFIG_SMB_FS) += smbfs/
92obj-$(CONFIG_CIFS) += cifs/ 91obj-$(CONFIG_CIFS) += cifs/
93obj-$(CONFIG_NCP_FS) += ncpfs/ 92obj-$(CONFIG_NCP_FS) += ncpfs/
94obj-$(CONFIG_HPFS_FS) += hpfs/ 93obj-$(CONFIG_HPFS_FS) += hpfs/
@@ -101,7 +100,6 @@ obj-$(CONFIG_UBIFS_FS) += ubifs/
101obj-$(CONFIG_AFFS_FS) += affs/ 100obj-$(CONFIG_AFFS_FS) += affs/
102obj-$(CONFIG_ROMFS_FS) += romfs/ 101obj-$(CONFIG_ROMFS_FS) += romfs/
103obj-$(CONFIG_QNX4FS_FS) += qnx4/ 102obj-$(CONFIG_QNX4FS_FS) += qnx4/
104obj-$(CONFIG_AUTOFS_FS) += autofs/
105obj-$(CONFIG_AUTOFS4_FS) += autofs4/ 103obj-$(CONFIG_AUTOFS4_FS) += autofs4/
106obj-$(CONFIG_ADFS_FS) += adfs/ 104obj-$(CONFIG_ADFS_FS) += adfs/
107obj-$(CONFIG_FUSE_FS) += fuse/ 105obj-$(CONFIG_FUSE_FS) += fuse/
diff --git a/fs/autofs/Kconfig b/fs/autofs/Kconfig
deleted file mode 100644
index 480e210c83ab..000000000000
--- a/fs/autofs/Kconfig
+++ /dev/null
@@ -1,22 +0,0 @@
1config AUTOFS_FS
2 tristate "Kernel automounter support"
3 depends on BKL # unfixable, just use autofs4
4 help
5 The automounter is a tool to automatically mount remote file systems
6 on demand. This implementation is partially kernel-based to reduce
7 overhead in the already-mounted case; this is unlike the BSD
8 automounter (amd), which is a pure user space daemon.
9
10 To use the automounter you need the user-space tools from the autofs
11 package; you can find the location in <file:Documentation/Changes>.
12 You also want to answer Y to "NFS file system support", below.
13
14 If you want to use the newer version of the automounter with more
15 features, say N here and say Y to "Kernel automounter v4 support",
16 below.
17
18 To compile this support as a module, choose M here: the module will be
19 called autofs.
20
21 If you are not a part of a fairly large, distributed network, you
22 probably do not need an automounter, and can say N here.
diff --git a/fs/autofs/Makefile b/fs/autofs/Makefile
deleted file mode 100644
index 453a60f46d05..000000000000
--- a/fs/autofs/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
1#
2# Makefile for the linux autofs-filesystem routines.
3#
4
5obj-$(CONFIG_AUTOFS_FS) += autofs.o
6
7autofs-objs := dirhash.o init.o inode.o root.o symlink.o waitq.o
diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h
deleted file mode 100644
index 901a3e67ec45..000000000000
--- a/fs/autofs/autofs_i.h
+++ /dev/null
@@ -1,165 +0,0 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * linux/fs/autofs/autofs_i.h
4 *
5 * Copyright 1997-1998 Transmeta Corporation - All Rights Reserved
6 *
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
10 *
11 * ----------------------------------------------------------------------- */
12
13/* Internal header file for autofs */
14
15#include <linux/auto_fs.h>
16
17/* This is the range of ioctl() numbers we claim as ours */
18#define AUTOFS_IOC_FIRST AUTOFS_IOC_READY
19#define AUTOFS_IOC_COUNT 32
20
21#include <linux/kernel.h>
22#include <linux/slab.h>
23#include <linux/time.h>
24#include <linux/string.h>
25#include <linux/wait.h>
26#include <linux/dcache.h>
27#include <linux/namei.h>
28#include <linux/mount.h>
29#include <linux/sched.h>
30
31#include <asm/current.h>
32#include <asm/uaccess.h>
33
34#ifdef DEBUG
35#define DPRINTK(D) (printk D)
36#else
37#define DPRINTK(D) ((void)0)
38#endif
39
40/*
41 * If the daemon returns a negative response (AUTOFS_IOC_FAIL) then the
42 * kernel will keep the negative response cached for up to the time given
43 * here, although the time can be shorter if the kernel throws the dcache
44 * entry away. This probably should be settable from user space.
45 */
46#define AUTOFS_NEGATIVE_TIMEOUT (60*HZ) /* 1 minute */
47
48/* Structures associated with the root directory hash table */
49
50#define AUTOFS_HASH_SIZE 67
51
52struct autofs_dir_ent {
53 int hash;
54 char *name;
55 int len;
56 ino_t ino;
57 struct dentry *dentry;
58 /* Linked list of entries */
59 struct autofs_dir_ent *next;
60 struct autofs_dir_ent **back;
61 /* The following entries are for the expiry system */
62 unsigned long last_usage;
63 struct list_head exp;
64};
65
66struct autofs_dirhash {
67 struct autofs_dir_ent *h[AUTOFS_HASH_SIZE];
68 struct list_head expiry_head;
69};
70
71struct autofs_wait_queue {
72 wait_queue_head_t queue;
73 struct autofs_wait_queue *next;
74 autofs_wqt_t wait_queue_token;
75 /* We use the following to see what we are waiting for */
76 int hash;
77 int len;
78 char *name;
79 /* This is for status reporting upon return */
80 int status;
81 int wait_ctr;
82};
83
84struct autofs_symlink {
85 char *data;
86 int len;
87 time_t mtime;
88};
89
90#define AUTOFS_MAX_SYMLINKS 256
91
92#define AUTOFS_ROOT_INO 1
93#define AUTOFS_FIRST_SYMLINK 2
94#define AUTOFS_FIRST_DIR_INO (AUTOFS_FIRST_SYMLINK+AUTOFS_MAX_SYMLINKS)
95
96#define AUTOFS_SYMLINK_BITMAP_LEN \
97 ((AUTOFS_MAX_SYMLINKS+((sizeof(long)*1)-1))/(sizeof(long)*8))
98
99#define AUTOFS_SBI_MAGIC 0x6d4a556d
100
101struct autofs_sb_info {
102 u32 magic;
103 struct file *pipe;
104 struct pid *oz_pgrp;
105 int catatonic;
106 struct super_block *sb;
107 unsigned long exp_timeout;
108 ino_t next_dir_ino;
109 struct autofs_wait_queue *queues; /* Wait queue pointer */
110 struct autofs_dirhash dirhash; /* Root directory hash */
111 struct autofs_symlink symlink[AUTOFS_MAX_SYMLINKS];
112 unsigned long symlink_bitmap[AUTOFS_SYMLINK_BITMAP_LEN];
113};
114
115static inline struct autofs_sb_info *autofs_sbi(struct super_block *sb)
116{
117 return (struct autofs_sb_info *)(sb->s_fs_info);
118}
119
120/* autofs_oz_mode(): do we see the man behind the curtain? (The
121 processes which do manipulations for us in user space sees the raw
122 filesystem without "magic".) */
123
124static inline int autofs_oz_mode(struct autofs_sb_info *sbi) {
125 return sbi->catatonic || task_pgrp(current) == sbi->oz_pgrp;
126}
127
128/* Hash operations */
129
130void autofs_initialize_hash(struct autofs_dirhash *);
131struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *,struct qstr *);
132void autofs_hash_insert(struct autofs_dirhash *,struct autofs_dir_ent *);
133void autofs_hash_delete(struct autofs_dir_ent *);
134struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *,off_t *,struct autofs_dir_ent *);
135void autofs_hash_dputall(struct autofs_dirhash *);
136void autofs_hash_nuke(struct autofs_sb_info *);
137
138/* Expiration-handling functions */
139
140void autofs_update_usage(struct autofs_dirhash *,struct autofs_dir_ent *);
141struct autofs_dir_ent *autofs_expire(struct super_block *,struct autofs_sb_info *, struct vfsmount *mnt);
142
143/* Operations structures */
144
145extern const struct inode_operations autofs_root_inode_operations;
146extern const struct inode_operations autofs_symlink_inode_operations;
147extern const struct file_operations autofs_root_operations;
148
149/* Initializing function */
150
151int autofs_fill_super(struct super_block *, void *, int);
152void autofs_kill_sb(struct super_block *sb);
153struct inode *autofs_iget(struct super_block *, unsigned long);
154
155/* Queue management functions */
156
157int autofs_wait(struct autofs_sb_info *,struct qstr *);
158int autofs_wait_release(struct autofs_sb_info *,autofs_wqt_t,int);
159void autofs_catatonic_mode(struct autofs_sb_info *);
160
161#ifdef DEBUG
162void autofs_say(const char *name, int len);
163#else
164#define autofs_say(n,l) ((void)0)
165#endif
diff --git a/fs/autofs/dirhash.c b/fs/autofs/dirhash.c
deleted file mode 100644
index e947915109e5..000000000000
--- a/fs/autofs/dirhash.c
+++ /dev/null
@@ -1,250 +0,0 @@
1/* -*- linux-c -*- --------------------------------------------------------- *
2 *
3 * linux/fs/autofs/dirhash.c
4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 *
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
10 *
11 * ------------------------------------------------------------------------- */
12
13#include "autofs_i.h"
14
15/* Functions for maintenance of expiry queue */
16
17static void autofs_init_usage(struct autofs_dirhash *dh,
18 struct autofs_dir_ent *ent)
19{
20 list_add_tail(&ent->exp, &dh->expiry_head);
21 ent->last_usage = jiffies;
22}
23
24static void autofs_delete_usage(struct autofs_dir_ent *ent)
25{
26 list_del(&ent->exp);
27}
28
29void autofs_update_usage(struct autofs_dirhash *dh,
30 struct autofs_dir_ent *ent)
31{
32 autofs_delete_usage(ent); /* Unlink from current position */
33 autofs_init_usage(dh,ent); /* Relink at queue tail */
34}
35
36struct autofs_dir_ent *autofs_expire(struct super_block *sb,
37 struct autofs_sb_info *sbi,
38 struct vfsmount *mnt)
39{
40 struct autofs_dirhash *dh = &sbi->dirhash;
41 struct autofs_dir_ent *ent;
42 unsigned long timeout = sbi->exp_timeout;
43
44 while (1) {
45 struct path path;
46 int umount_ok;
47
48 if ( list_empty(&dh->expiry_head) || sbi->catatonic )
49 return NULL; /* No entries */
50 /* We keep the list sorted by last_usage and want old stuff */
51 ent = list_entry(dh->expiry_head.next, struct autofs_dir_ent, exp);
52 if (jiffies - ent->last_usage < timeout)
53 break;
54 /* Move to end of list in case expiry isn't desirable */
55 autofs_update_usage(dh, ent);
56
57 /* Check to see that entry is expirable */
58 if ( ent->ino < AUTOFS_FIRST_DIR_INO )
59 return ent; /* Symlinks are always expirable */
60
61 /* Get the dentry for the autofs subdirectory */
62 path.dentry = ent->dentry;
63
64 if (!path.dentry) {
65 /* Should only happen in catatonic mode */
66 printk("autofs: dentry == NULL but inode range is directory, entry %s\n", ent->name);
67 autofs_delete_usage(ent);
68 continue;
69 }
70
71 if (!path.dentry->d_inode) {
72 dput(path.dentry);
73 printk("autofs: negative dentry on expiry queue: %s\n",
74 ent->name);
75 autofs_delete_usage(ent);
76 continue;
77 }
78
79 /* Make sure entry is mounted and unused; note that dentry will
80 point to the mounted-on-top root. */
81 if (!S_ISDIR(path.dentry->d_inode->i_mode) ||
82 !d_mountpoint(path.dentry)) {
83 DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
84 continue;
85 }
86 path.mnt = mnt;
87 path_get(&path);
88 if (!follow_down(&path)) {
89 path_put(&path);
90 DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
91 continue;
92 }
93 while (d_mountpoint(path.dentry) && follow_down(&path))
94 ;
95 umount_ok = may_umount(path.mnt);
96 path_put(&path);
97
98 if (umount_ok) {
99 DPRINTK(("autofs: signaling expire on %s\n", ent->name));
100 return ent; /* Expirable! */
101 }
102 DPRINTK(("autofs: didn't expire due to may_umount: %s\n", ent->name));
103 }
104 return NULL; /* No expirable entries */
105}
106
107void autofs_initialize_hash(struct autofs_dirhash *dh) {
108 memset(&dh->h, 0, AUTOFS_HASH_SIZE*sizeof(struct autofs_dir_ent *));
109 INIT_LIST_HEAD(&dh->expiry_head);
110}
111
112struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *dh, struct qstr *name)
113{
114 struct autofs_dir_ent *dhn;
115
116 DPRINTK(("autofs_hash_lookup: hash = 0x%08x, name = ", name->hash));
117 autofs_say(name->name,name->len);
118
119 for ( dhn = dh->h[(unsigned) name->hash % AUTOFS_HASH_SIZE] ; dhn ; dhn = dhn->next ) {
120 if ( name->hash == dhn->hash &&
121 name->len == dhn->len &&
122 !memcmp(name->name, dhn->name, name->len) )
123 break;
124 }
125
126 return dhn;
127}
128
129void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent)
130{
131 struct autofs_dir_ent **dhnp;
132
133 DPRINTK(("autofs_hash_insert: hash = 0x%08x, name = ", ent->hash));
134 autofs_say(ent->name,ent->len);
135
136 autofs_init_usage(dh,ent);
137 if (ent->dentry)
138 dget(ent->dentry);
139
140 dhnp = &dh->h[(unsigned) ent->hash % AUTOFS_HASH_SIZE];
141 ent->next = *dhnp;
142 ent->back = dhnp;
143 *dhnp = ent;
144 if ( ent->next )
145 ent->next->back = &(ent->next);
146}
147
148void autofs_hash_delete(struct autofs_dir_ent *ent)
149{
150 *(ent->back) = ent->next;
151 if ( ent->next )
152 ent->next->back = ent->back;
153
154 autofs_delete_usage(ent);
155
156 if ( ent->dentry )
157 dput(ent->dentry);
158 kfree(ent->name);
159 kfree(ent);
160}
161
162/*
163 * Used by readdir(). We must validate "ptr", so we can't simply make it
164 * a pointer. Values below 0xffff are reserved; calling with any value
165 * <= 0x10000 will return the first entry found.
166 *
167 * "last" can be NULL or the value returned by the last search *if* we
168 * want the next sequential entry.
169 */
170struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *dh,
171 off_t *ptr, struct autofs_dir_ent *last)
172{
173 int bucket, ecount, i;
174 struct autofs_dir_ent *ent;
175
176 bucket = (*ptr >> 16) - 1;
177 ecount = *ptr & 0xffff;
178
179 if ( bucket < 0 ) {
180 bucket = ecount = 0;
181 }
182
183 DPRINTK(("autofs_hash_enum: bucket %d, entry %d\n", bucket, ecount));
184
185 ent = last ? last->next : NULL;
186
187 if ( ent ) {
188 ecount++;
189 } else {
190 while ( bucket < AUTOFS_HASH_SIZE ) {
191 ent = dh->h[bucket];
192 for ( i = ecount ; ent && i ; i-- )
193 ent = ent->next;
194
195 if (ent) {
196 ecount++; /* Point to *next* entry */
197 break;
198 }
199
200 bucket++; ecount = 0;
201 }
202 }
203
204#ifdef DEBUG
205 if ( !ent )
206 printk("autofs_hash_enum: nothing found\n");
207 else {
208 printk("autofs_hash_enum: found hash %08x, name", ent->hash);
209 autofs_say(ent->name,ent->len);
210 }
211#endif
212
213 *ptr = ((bucket+1) << 16) + ecount;
214 return ent;
215}
216
217/* Iterate over all the ents, and remove all dentry pointers. Used on
218 entering catatonic mode, in order to make the filesystem unmountable. */
219void autofs_hash_dputall(struct autofs_dirhash *dh)
220{
221 int i;
222 struct autofs_dir_ent *ent;
223
224 for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
225 for ( ent = dh->h[i] ; ent ; ent = ent->next ) {
226 if ( ent->dentry ) {
227 dput(ent->dentry);
228 ent->dentry = NULL;
229 }
230 }
231 }
232}
233
234/* Delete everything. This is used on filesystem destruction, so we
235 make no attempt to keep the pointers valid */
236void autofs_hash_nuke(struct autofs_sb_info *sbi)
237{
238 int i;
239 struct autofs_dir_ent *ent, *nent;
240
241 for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) {
242 for ( ent = sbi->dirhash.h[i] ; ent ; ent = nent ) {
243 nent = ent->next;
244 if ( ent->dentry )
245 dput(ent->dentry);
246 kfree(ent->name);
247 kfree(ent);
248 }
249 }
250}
diff --git a/fs/autofs/init.c b/fs/autofs/init.c
deleted file mode 100644
index cea5219b4f37..000000000000
--- a/fs/autofs/init.c
+++ /dev/null
@@ -1,52 +0,0 @@
1/* -*- linux-c -*- --------------------------------------------------------- *
2 *
3 * linux/fs/autofs/init.c
4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 *
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
10 *
11 * ------------------------------------------------------------------------- */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include "autofs_i.h"
16
17static int autofs_get_sb(struct file_system_type *fs_type,
18 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
19{
20 return get_sb_nodev(fs_type, flags, data, autofs_fill_super, mnt);
21}
22
23static struct file_system_type autofs_fs_type = {
24 .owner = THIS_MODULE,
25 .name = "autofs",
26 .get_sb = autofs_get_sb,
27 .kill_sb = autofs_kill_sb,
28};
29
30static int __init init_autofs_fs(void)
31{
32 return register_filesystem(&autofs_fs_type);
33}
34
35static void __exit exit_autofs_fs(void)
36{
37 unregister_filesystem(&autofs_fs_type);
38}
39
40module_init(init_autofs_fs);
41module_exit(exit_autofs_fs);
42
43#ifdef DEBUG
44void autofs_say(const char *name, int len)
45{
46 printk("(%d: ", len);
47 while ( len-- )
48 printk("%c", *name++);
49 printk(")\n");
50}
51#endif
52MODULE_LICENSE("GPL");
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
deleted file mode 100644
index e1734f2d6e26..000000000000
--- a/fs/autofs/inode.c
+++ /dev/null
@@ -1,288 +0,0 @@
1/* -*- linux-c -*- --------------------------------------------------------- *
2 *
3 * linux/fs/autofs/inode.c
4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 *
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
10 *
11 * ------------------------------------------------------------------------- */
12
13#include <linux/kernel.h>
14#include <linux/mm.h>
15#include <linux/slab.h>
16#include <linux/file.h>
17#include <linux/parser.h>
18#include <linux/bitops.h>
19#include <linux/magic.h>
20#include "autofs_i.h"
21#include <linux/module.h>
22
23void autofs_kill_sb(struct super_block *sb)
24{
25 struct autofs_sb_info *sbi = autofs_sbi(sb);
26 unsigned int n;
27
28 /*
29 * In the event of a failure in get_sb_nodev the superblock
30 * info is not present so nothing else has been setup, so
31 * just call kill_anon_super when we are called from
32 * deactivate_super.
33 */
34 if (!sbi)
35 goto out_kill_sb;
36
37 if (!sbi->catatonic)
38 autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */
39
40 put_pid(sbi->oz_pgrp);
41
42 autofs_hash_nuke(sbi);
43 for (n = 0; n < AUTOFS_MAX_SYMLINKS; n++) {
44 if (test_bit(n, sbi->symlink_bitmap))
45 kfree(sbi->symlink[n].data);
46 }
47
48 kfree(sb->s_fs_info);
49
50out_kill_sb:
51 DPRINTK(("autofs: shutting down\n"));
52 kill_anon_super(sb);
53}
54
55static const struct super_operations autofs_sops = {
56 .statfs = simple_statfs,
57 .show_options = generic_show_options,
58};
59
60enum {Opt_err, Opt_fd, Opt_uid, Opt_gid, Opt_pgrp, Opt_minproto, Opt_maxproto};
61
62static const match_table_t autofs_tokens = {
63 {Opt_fd, "fd=%u"},
64 {Opt_uid, "uid=%u"},
65 {Opt_gid, "gid=%u"},
66 {Opt_pgrp, "pgrp=%u"},
67 {Opt_minproto, "minproto=%u"},
68 {Opt_maxproto, "maxproto=%u"},
69 {Opt_err, NULL}
70};
71
72static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
73 pid_t *pgrp, int *minproto, int *maxproto)
74{
75 char *p;
76 substring_t args[MAX_OPT_ARGS];
77 int option;
78
79 *uid = current_uid();
80 *gid = current_gid();
81 *pgrp = task_pgrp_nr(current);
82
83 *minproto = *maxproto = AUTOFS_PROTO_VERSION;
84
85 *pipefd = -1;
86
87 if (!options)
88 return 1;
89
90 while ((p = strsep(&options, ",")) != NULL) {
91 int token;
92 if (!*p)
93 continue;
94
95 token = match_token(p, autofs_tokens, args);
96 switch (token) {
97 case Opt_fd:
98 if (match_int(&args[0], &option))
99 return 1;
100 *pipefd = option;
101 break;
102 case Opt_uid:
103 if (match_int(&args[0], &option))
104 return 1;
105 *uid = option;
106 break;
107 case Opt_gid:
108 if (match_int(&args[0], &option))
109 return 1;
110 *gid = option;
111 break;
112 case Opt_pgrp:
113 if (match_int(&args[0], &option))
114 return 1;
115 *pgrp = option;
116 break;
117 case Opt_minproto:
118 if (match_int(&args[0], &option))
119 return 1;
120 *minproto = option;
121 break;
122 case Opt_maxproto:
123 if (match_int(&args[0], &option))
124 return 1;
125 *maxproto = option;
126 break;
127 default:
128 return 1;
129 }
130 }
131 return (*pipefd < 0);
132}
133
134int autofs_fill_super(struct super_block *s, void *data, int silent)
135{
136 struct inode * root_inode;
137 struct dentry * root;
138 struct file * pipe;
139 int pipefd;
140 struct autofs_sb_info *sbi;
141 int minproto, maxproto;
142 pid_t pgid;
143
144 save_mount_options(s, data);
145
146 sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
147 if (!sbi)
148 goto fail_unlock;
149 DPRINTK(("autofs: starting up, sbi = %p\n",sbi));
150
151 s->s_fs_info = sbi;
152 sbi->magic = AUTOFS_SBI_MAGIC;
153 sbi->pipe = NULL;
154 sbi->catatonic = 1;
155 sbi->exp_timeout = 0;
156 autofs_initialize_hash(&sbi->dirhash);
157 sbi->queues = NULL;
158 memset(sbi->symlink_bitmap, 0, sizeof(long)*AUTOFS_SYMLINK_BITMAP_LEN);
159 sbi->next_dir_ino = AUTOFS_FIRST_DIR_INO;
160 s->s_blocksize = 1024;
161 s->s_blocksize_bits = 10;
162 s->s_magic = AUTOFS_SUPER_MAGIC;
163 s->s_op = &autofs_sops;
164 s->s_time_gran = 1;
165 sbi->sb = s;
166
167 root_inode = autofs_iget(s, AUTOFS_ROOT_INO);
168 if (IS_ERR(root_inode))
169 goto fail_free;
170 root = d_alloc_root(root_inode);
171 pipe = NULL;
172
173 if (!root)
174 goto fail_iput;
175
176 /* Can this call block? - WTF cares? s is locked. */
177 if (parse_options(data, &pipefd, &root_inode->i_uid,
178 &root_inode->i_gid, &pgid, &minproto,
179 &maxproto)) {
180 printk("autofs: called with bogus options\n");
181 goto fail_dput;
182 }
183
184 /* Couldn't this be tested earlier? */
185 if (minproto > AUTOFS_PROTO_VERSION ||
186 maxproto < AUTOFS_PROTO_VERSION) {
187 printk("autofs: kernel does not match daemon version\n");
188 goto fail_dput;
189 }
190
191 DPRINTK(("autofs: pipe fd = %d, pgrp = %u\n", pipefd, pgid));
192 sbi->oz_pgrp = find_get_pid(pgid);
193
194 if (!sbi->oz_pgrp) {
195 printk("autofs: could not find process group %d\n", pgid);
196 goto fail_dput;
197 }
198
199 pipe = fget(pipefd);
200
201 if (!pipe) {
202 printk("autofs: could not open pipe file descriptor\n");
203 goto fail_put_pid;
204 }
205
206 if (!pipe->f_op || !pipe->f_op->write)
207 goto fail_fput;
208 sbi->pipe = pipe;
209 sbi->catatonic = 0;
210
211 /*
212 * Success! Install the root dentry now to indicate completion.
213 */
214 s->s_root = root;
215 return 0;
216
217fail_fput:
218 printk("autofs: pipe file descriptor does not contain proper ops\n");
219 fput(pipe);
220fail_put_pid:
221 put_pid(sbi->oz_pgrp);
222fail_dput:
223 dput(root);
224 goto fail_free;
225fail_iput:
226 printk("autofs: get root dentry failed\n");
227 iput(root_inode);
228fail_free:
229 kfree(sbi);
230 s->s_fs_info = NULL;
231fail_unlock:
232 return -EINVAL;
233}
234
235struct inode *autofs_iget(struct super_block *sb, unsigned long ino)
236{
237 unsigned int n;
238 struct autofs_sb_info *sbi = autofs_sbi(sb);
239 struct inode *inode;
240
241 inode = iget_locked(sb, ino);
242 if (!inode)
243 return ERR_PTR(-ENOMEM);
244 if (!(inode->i_state & I_NEW))
245 return inode;
246
247 /* Initialize to the default case (stub directory) */
248
249 inode->i_op = &simple_dir_inode_operations;
250 inode->i_fop = &simple_dir_operations;
251 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
252 inode->i_nlink = 2;
253 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
254
255 if (ino == AUTOFS_ROOT_INO) {
256 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
257 inode->i_op = &autofs_root_inode_operations;
258 inode->i_fop = &autofs_root_operations;
259 goto done;
260 }
261
262 inode->i_uid = inode->i_sb->s_root->d_inode->i_uid;
263 inode->i_gid = inode->i_sb->s_root->d_inode->i_gid;
264
265 if (ino >= AUTOFS_FIRST_SYMLINK && ino < AUTOFS_FIRST_DIR_INO) {
266 /* Symlink inode - should be in symlink list */
267 struct autofs_symlink *sl;
268
269 n = ino - AUTOFS_FIRST_SYMLINK;
270 if (n >= AUTOFS_MAX_SYMLINKS || !test_bit(n,sbi->symlink_bitmap)) {
271 printk("autofs: Looking for bad symlink inode %u\n", (unsigned int) ino);
272 goto done;
273 }
274
275 inode->i_op = &autofs_symlink_inode_operations;
276 sl = &sbi->symlink[n];
277 inode->i_private = sl;
278 inode->i_mode = S_IFLNK | S_IRWXUGO;
279 inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = sl->mtime;
280 inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 0;
281 inode->i_size = sl->len;
282 inode->i_nlink = 1;
283 }
284
285done:
286 unlock_new_inode(inode);
287 return inode;
288}
diff --git a/fs/autofs/root.c b/fs/autofs/root.c
deleted file mode 100644
index 0c4ca81aeaeb..000000000000
--- a/fs/autofs/root.c
+++ /dev/null
@@ -1,645 +0,0 @@
1/* -*- linux-c -*- --------------------------------------------------------- *
2 *
3 * linux/fs/autofs/root.c
4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 *
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
10 *
11 * ------------------------------------------------------------------------- */
12
13#include <linux/capability.h>
14#include <linux/errno.h>
15#include <linux/stat.h>
16#include <linux/slab.h>
17#include <linux/param.h>
18#include <linux/time.h>
19#include <linux/compat.h>
20#include <linux/smp_lock.h>
21#include "autofs_i.h"
22
23static int autofs_root_readdir(struct file *,void *,filldir_t);
24static struct dentry *autofs_root_lookup(struct inode *,struct dentry *, struct nameidata *);
25static int autofs_root_symlink(struct inode *,struct dentry *,const char *);
26static int autofs_root_unlink(struct inode *,struct dentry *);
27static int autofs_root_rmdir(struct inode *,struct dentry *);
28static int autofs_root_mkdir(struct inode *,struct dentry *,int);
29static long autofs_root_ioctl(struct file *,unsigned int,unsigned long);
30#ifdef CONFIG_COMPAT
31static long autofs_root_compat_ioctl(struct file *,unsigned int,unsigned long);
32#endif
33
34const struct file_operations autofs_root_operations = {
35 .llseek = generic_file_llseek,
36 .read = generic_read_dir,
37 .readdir = autofs_root_readdir,
38 .unlocked_ioctl = autofs_root_ioctl,
39#ifdef CONFIG_COMPAT
40 .compat_ioctl = autofs_root_compat_ioctl,
41#endif
42};
43
44const struct inode_operations autofs_root_inode_operations = {
45 .lookup = autofs_root_lookup,
46 .unlink = autofs_root_unlink,
47 .symlink = autofs_root_symlink,
48 .mkdir = autofs_root_mkdir,
49 .rmdir = autofs_root_rmdir,
50};
51
52static int autofs_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
53{
54 struct autofs_dir_ent *ent = NULL;
55 struct autofs_dirhash *dirhash;
56 struct autofs_sb_info *sbi;
57 struct inode * inode = filp->f_path.dentry->d_inode;
58 off_t onr, nr;
59
60 lock_kernel();
61
62 sbi = autofs_sbi(inode->i_sb);
63 dirhash = &sbi->dirhash;
64 nr = filp->f_pos;
65
66 switch(nr)
67 {
68 case 0:
69 if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0)
70 goto out;
71 filp->f_pos = ++nr;
72 /* fall through */
73 case 1:
74 if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0)
75 goto out;
76 filp->f_pos = ++nr;
77 /* fall through */
78 default:
79 while (onr = nr, ent = autofs_hash_enum(dirhash,&nr,ent)) {
80 if (!ent->dentry || d_mountpoint(ent->dentry)) {
81 if (filldir(dirent,ent->name,ent->len,onr,ent->ino,DT_UNKNOWN) < 0)
82 goto out;
83 filp->f_pos = nr;
84 }
85 }
86 break;
87 }
88
89out:
90 unlock_kernel();
91 return 0;
92}
93
94static int try_to_fill_dentry(struct dentry *dentry, struct super_block *sb, struct autofs_sb_info *sbi)
95{
96 struct inode * inode;
97 struct autofs_dir_ent *ent;
98 int status = 0;
99
100 if (!(ent = autofs_hash_lookup(&sbi->dirhash, &dentry->d_name))) {
101 do {
102 if (status && dentry->d_inode) {
103 if (status != -ENOENT)
104 printk("autofs warning: lookup failure on positive dentry, status = %d, name = %s\n", status, dentry->d_name.name);
105 return 0; /* Try to get the kernel to invalidate this dentry */
106 }
107
108 /* Turn this into a real negative dentry? */
109 if (status == -ENOENT) {
110 dentry->d_time = jiffies + AUTOFS_NEGATIVE_TIMEOUT;
111 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
112 return 1;
113 } else if (status) {
114 /* Return a negative dentry, but leave it "pending" */
115 return 1;
116 }
117 status = autofs_wait(sbi, &dentry->d_name);
118 } while (!(ent = autofs_hash_lookup(&sbi->dirhash, &dentry->d_name)));
119 }
120
121 /* Abuse this field as a pointer to the directory entry, used to
122 find the expire list pointers */
123 dentry->d_time = (unsigned long) ent;
124
125 if (!dentry->d_inode) {
126 inode = autofs_iget(sb, ent->ino);
127 if (IS_ERR(inode)) {
128 /* Failed, but leave pending for next time */
129 return 1;
130 }
131 dentry->d_inode = inode;
132 }
133
134 /* If this is a directory that isn't a mount point, bitch at the
135 daemon and fix it in user space */
136 if (S_ISDIR(dentry->d_inode->i_mode) && !d_mountpoint(dentry)) {
137 return !autofs_wait(sbi, &dentry->d_name);
138 }
139
140 /* We don't update the usages for the autofs daemon itself, this
141 is necessary for recursive autofs mounts */
142 if (!autofs_oz_mode(sbi)) {
143 autofs_update_usage(&sbi->dirhash,ent);
144 }
145
146 dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
147 return 1;
148}
149
150
151/*
152 * Revalidate is called on every cache lookup. Some of those
153 * cache lookups may actually happen while the dentry is not
154 * yet completely filled in, and revalidate has to delay such
155 * lookups..
156 */
157static int autofs_revalidate(struct dentry * dentry, struct nameidata *nd)
158{
159 struct inode * dir;
160 struct autofs_sb_info *sbi;
161 struct autofs_dir_ent *ent;
162 int res;
163
164 lock_kernel();
165 dir = dentry->d_parent->d_inode;
166 sbi = autofs_sbi(dir->i_sb);
167
168 /* Pending dentry */
169 if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
170 if (autofs_oz_mode(sbi))
171 res = 1;
172 else
173 res = try_to_fill_dentry(dentry, dir->i_sb, sbi);
174 unlock_kernel();
175 return res;
176 }
177
178 /* Negative dentry.. invalidate if "old" */
179 if (!dentry->d_inode) {
180 unlock_kernel();
181 return (dentry->d_time - jiffies <= AUTOFS_NEGATIVE_TIMEOUT);
182 }
183
184 /* Check for a non-mountpoint directory */
185 if (S_ISDIR(dentry->d_inode->i_mode) && !d_mountpoint(dentry)) {
186 if (autofs_oz_mode(sbi))
187 res = 1;
188 else
189 res = try_to_fill_dentry(dentry, dir->i_sb, sbi);
190 unlock_kernel();
191 return res;
192 }
193
194 /* Update the usage list */
195 if (!autofs_oz_mode(sbi)) {
196 ent = (struct autofs_dir_ent *) dentry->d_time;
197 if (ent)
198 autofs_update_usage(&sbi->dirhash,ent);
199 }
200 unlock_kernel();
201 return 1;
202}
203
204static const struct dentry_operations autofs_dentry_operations = {
205 .d_revalidate = autofs_revalidate,
206};
207
208static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
209{
210 struct autofs_sb_info *sbi;
211 int oz_mode;
212
213 DPRINTK(("autofs_root_lookup: name = "));
214 lock_kernel();
215 autofs_say(dentry->d_name.name,dentry->d_name.len);
216
217 if (dentry->d_name.len > NAME_MAX) {
218 unlock_kernel();
219 return ERR_PTR(-ENAMETOOLONG);/* File name too long to exist */
220 }
221
222 sbi = autofs_sbi(dir->i_sb);
223
224 oz_mode = autofs_oz_mode(sbi);
225 DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, "
226 "oz_mode = %d\n", task_pid_nr(current),
227 task_pgrp_nr(current), sbi->catatonic,
228 oz_mode));
229
230 /*
231 * Mark the dentry incomplete, but add it. This is needed so
232 * that the VFS layer knows about the dentry, and we can count
233 * on catching any lookups through the revalidate.
234 *
235 * Let all the hard work be done by the revalidate function that
236 * needs to be able to do this anyway..
237 *
238 * We need to do this before we release the directory semaphore.
239 */
240 dentry->d_op = &autofs_dentry_operations;
241 dentry->d_flags |= DCACHE_AUTOFS_PENDING;
242 d_add(dentry, NULL);
243
244 mutex_unlock(&dir->i_mutex);
245 autofs_revalidate(dentry, nd);
246 mutex_lock(&dir->i_mutex);
247
248 /*
249 * If we are still pending, check if we had to handle
250 * a signal. If so we can force a restart..
251 */
252 if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
253 /* See if we were interrupted */
254 if (signal_pending(current)) {
255 sigset_t *sigset = &current->pending.signal;
256 if (sigismember (sigset, SIGKILL) ||
257 sigismember (sigset, SIGQUIT) ||
258 sigismember (sigset, SIGINT)) {
259 unlock_kernel();
260 return ERR_PTR(-ERESTARTNOINTR);
261 }
262 }
263 }
264 unlock_kernel();
265
266 /*
267 * If this dentry is unhashed, then we shouldn't honour this
268 * lookup even if the dentry is positive. Returning ENOENT here
269 * doesn't do the right thing for all system calls, but it should
270 * be OK for the operations we permit from an autofs.
271 */
272 if (dentry->d_inode && d_unhashed(dentry))
273 return ERR_PTR(-ENOENT);
274
275 return NULL;
276}
277
278static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
279{
280 struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
281 struct autofs_dirhash *dh = &sbi->dirhash;
282 struct autofs_dir_ent *ent;
283 unsigned int n;
284 int slsize;
285 struct autofs_symlink *sl;
286 struct inode *inode;
287
288 DPRINTK(("autofs_root_symlink: %s <- ", symname));
289 autofs_say(dentry->d_name.name,dentry->d_name.len);
290
291 lock_kernel();
292 if (!autofs_oz_mode(sbi)) {
293 unlock_kernel();
294 return -EACCES;
295 }
296
297 if (autofs_hash_lookup(dh, &dentry->d_name)) {
298 unlock_kernel();
299 return -EEXIST;
300 }
301
302 n = find_first_zero_bit(sbi->symlink_bitmap,AUTOFS_MAX_SYMLINKS);
303 if (n >= AUTOFS_MAX_SYMLINKS) {
304 unlock_kernel();
305 return -ENOSPC;
306 }
307
308 set_bit(n,sbi->symlink_bitmap);
309 sl = &sbi->symlink[n];
310 sl->len = strlen(symname);
311 sl->data = kmalloc(slsize = sl->len+1, GFP_KERNEL);
312 if (!sl->data) {
313 clear_bit(n,sbi->symlink_bitmap);
314 unlock_kernel();
315 return -ENOSPC;
316 }
317
318 ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL);
319 if (!ent) {
320 kfree(sl->data);
321 clear_bit(n,sbi->symlink_bitmap);
322 unlock_kernel();
323 return -ENOSPC;
324 }
325
326 ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL);
327 if (!ent->name) {
328 kfree(sl->data);
329 kfree(ent);
330 clear_bit(n,sbi->symlink_bitmap);
331 unlock_kernel();
332 return -ENOSPC;
333 }
334
335 memcpy(sl->data,symname,slsize);
336 sl->mtime = get_seconds();
337
338 ent->ino = AUTOFS_FIRST_SYMLINK + n;
339 ent->hash = dentry->d_name.hash;
340 memcpy(ent->name, dentry->d_name.name, 1+(ent->len = dentry->d_name.len));
341 ent->dentry = NULL; /* We don't keep the dentry for symlinks */
342
343 autofs_hash_insert(dh,ent);
344
345 inode = autofs_iget(dir->i_sb, ent->ino);
346 if (IS_ERR(inode))
347 return PTR_ERR(inode);
348
349 d_instantiate(dentry, inode);
350 unlock_kernel();
351 return 0;
352}
353
354/*
355 * NOTE!
356 *
357 * Normal filesystems would do a "d_delete()" to tell the VFS dcache
358 * that the file no longer exists. However, doing that means that the
359 * VFS layer can turn the dentry into a negative dentry, which we
360 * obviously do not want (we're dropping the entry not because it
361 * doesn't exist, but because it has timed out).
362 *
363 * Also see autofs_root_rmdir()..
364 */
365static int autofs_root_unlink(struct inode *dir, struct dentry *dentry)
366{
367 struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
368 struct autofs_dirhash *dh = &sbi->dirhash;
369 struct autofs_dir_ent *ent;
370 unsigned int n;
371
372 /* This allows root to remove symlinks */
373 lock_kernel();
374 if (!autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) {
375 unlock_kernel();
376 return -EACCES;
377 }
378
379 ent = autofs_hash_lookup(dh, &dentry->d_name);
380 if (!ent) {
381 unlock_kernel();
382 return -ENOENT;
383 }
384
385 n = ent->ino - AUTOFS_FIRST_SYMLINK;
386 if (n >= AUTOFS_MAX_SYMLINKS) {
387 unlock_kernel();
388 return -EISDIR; /* It's a directory, dummy */
389 }
390 if (!test_bit(n,sbi->symlink_bitmap)) {
391 unlock_kernel();
392 return -EINVAL; /* Nonexistent symlink? Shouldn't happen */
393 }
394
395 dentry->d_time = (unsigned long)(struct autofs_dirhash *)NULL;
396 autofs_hash_delete(ent);
397 clear_bit(n,sbi->symlink_bitmap);
398 kfree(sbi->symlink[n].data);
399 d_drop(dentry);
400
401 unlock_kernel();
402 return 0;
403}
404
405static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry)
406{
407 struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
408 struct autofs_dirhash *dh = &sbi->dirhash;
409 struct autofs_dir_ent *ent;
410
411 lock_kernel();
412 if (!autofs_oz_mode(sbi)) {
413 unlock_kernel();
414 return -EACCES;
415 }
416
417 ent = autofs_hash_lookup(dh, &dentry->d_name);
418 if (!ent) {
419 unlock_kernel();
420 return -ENOENT;
421 }
422
423 if ((unsigned int)ent->ino < AUTOFS_FIRST_DIR_INO) {
424 unlock_kernel();
425 return -ENOTDIR; /* Not a directory */
426 }
427
428 if (ent->dentry != dentry) {
429 printk("autofs_rmdir: odentry != dentry for entry %s\n", dentry->d_name.name);
430 }
431
432 dentry->d_time = (unsigned long)(struct autofs_dir_ent *)NULL;
433 autofs_hash_delete(ent);
434 drop_nlink(dir);
435 d_drop(dentry);
436 unlock_kernel();
437
438 return 0;
439}
440
441static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
442{
443 struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
444 struct autofs_dirhash *dh = &sbi->dirhash;
445 struct autofs_dir_ent *ent;
446 struct inode *inode;
447 ino_t ino;
448
449 lock_kernel();
450 if (!autofs_oz_mode(sbi)) {
451 unlock_kernel();
452 return -EACCES;
453 }
454
455 ent = autofs_hash_lookup(dh, &dentry->d_name);
456 if (ent) {
457 unlock_kernel();
458 return -EEXIST;
459 }
460
461 if (sbi->next_dir_ino < AUTOFS_FIRST_DIR_INO) {
462 printk("autofs: Out of inode numbers -- what the heck did you do??\n");
463 unlock_kernel();
464 return -ENOSPC;
465 }
466 ino = sbi->next_dir_ino++;
467
468 ent = kmalloc(sizeof(struct autofs_dir_ent), GFP_KERNEL);
469 if (!ent) {
470 unlock_kernel();
471 return -ENOSPC;
472 }
473
474 ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL);
475 if (!ent->name) {
476 kfree(ent);
477 unlock_kernel();
478 return -ENOSPC;
479 }
480
481 ent->hash = dentry->d_name.hash;
482 memcpy(ent->name, dentry->d_name.name, 1+(ent->len = dentry->d_name.len));
483 ent->ino = ino;
484 ent->dentry = dentry;
485 autofs_hash_insert(dh,ent);
486
487 inc_nlink(dir);
488
489 inode = autofs_iget(dir->i_sb, ino);
490 if (IS_ERR(inode)) {
491 drop_nlink(dir);
492 return PTR_ERR(inode);
493 }
494
495 d_instantiate(dentry, inode);
496 unlock_kernel();
497
498 return 0;
499}
500
501/* Get/set timeout ioctl() operation */
502#ifdef CONFIG_COMPAT
503static inline int autofs_compat_get_set_timeout(struct autofs_sb_info *sbi,
504 unsigned int __user *p)
505{
506 unsigned long ntimeout;
507
508 if (get_user(ntimeout, p) ||
509 put_user(sbi->exp_timeout / HZ, p))
510 return -EFAULT;
511
512 if (ntimeout > UINT_MAX/HZ)
513 sbi->exp_timeout = 0;
514 else
515 sbi->exp_timeout = ntimeout * HZ;
516
517 return 0;
518}
519#endif
520
521static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi,
522 unsigned long __user *p)
523{
524 unsigned long ntimeout;
525
526 if (get_user(ntimeout, p) ||
527 put_user(sbi->exp_timeout / HZ, p))
528 return -EFAULT;
529
530 if (ntimeout > ULONG_MAX/HZ)
531 sbi->exp_timeout = 0;
532 else
533 sbi->exp_timeout = ntimeout * HZ;
534
535 return 0;
536}
537
538/* Return protocol version */
539static inline int autofs_get_protover(int __user *p)
540{
541 return put_user(AUTOFS_PROTO_VERSION, p);
542}
543
544/* Perform an expiry operation */
545static inline int autofs_expire_run(struct super_block *sb,
546 struct autofs_sb_info *sbi,
547 struct vfsmount *mnt,
548 struct autofs_packet_expire __user *pkt_p)
549{
550 struct autofs_dir_ent *ent;
551 struct autofs_packet_expire pkt;
552
553 memset(&pkt,0,sizeof pkt);
554
555 pkt.hdr.proto_version = AUTOFS_PROTO_VERSION;
556 pkt.hdr.type = autofs_ptype_expire;
557
558 if (!sbi->exp_timeout || !(ent = autofs_expire(sb,sbi,mnt)))
559 return -EAGAIN;
560
561 pkt.len = ent->len;
562 memcpy(pkt.name, ent->name, pkt.len);
563 pkt.name[pkt.len] = '\0';
564
565 if (copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire)))
566 return -EFAULT;
567
568 return 0;
569}
570
571/*
572 * ioctl()'s on the root directory is the chief method for the daemon to
573 * generate kernel reactions
574 */
575static int autofs_do_root_ioctl(struct inode *inode, struct file *filp,
576 unsigned int cmd, unsigned long arg)
577{
578 struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);
579 void __user *argp = (void __user *)arg;
580
581 DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,task_pgrp_nr(current)));
582
583 if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
584 _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT)
585 return -ENOTTY;
586
587 if (!autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN))
588 return -EPERM;
589
590 switch(cmd) {
591 case AUTOFS_IOC_READY: /* Wait queue: go ahead and retry */
592 return autofs_wait_release(sbi,(autofs_wqt_t)arg,0);
593 case AUTOFS_IOC_FAIL: /* Wait queue: fail with ENOENT */
594 return autofs_wait_release(sbi,(autofs_wqt_t)arg,-ENOENT);
595 case AUTOFS_IOC_CATATONIC: /* Enter catatonic mode (daemon shutdown) */
596 autofs_catatonic_mode(sbi);
597 return 0;
598 case AUTOFS_IOC_PROTOVER: /* Get protocol version */
599 return autofs_get_protover(argp);
600#ifdef CONFIG_COMPAT
601 case AUTOFS_IOC_SETTIMEOUT32:
602 return autofs_compat_get_set_timeout(sbi, argp);
603#endif
604 case AUTOFS_IOC_SETTIMEOUT:
605 return autofs_get_set_timeout(sbi, argp);
606 case AUTOFS_IOC_EXPIRE:
607 return autofs_expire_run(inode->i_sb, sbi, filp->f_path.mnt,
608 argp);
609 default:
610 return -ENOSYS;
611 }
612
613}
614
615static long autofs_root_ioctl(struct file *filp,
616 unsigned int cmd, unsigned long arg)
617{
618 int ret;
619
620 lock_kernel();
621 ret = autofs_do_root_ioctl(filp->f_path.dentry->d_inode,
622 filp, cmd, arg);
623 unlock_kernel();
624
625 return ret;
626}
627
628#ifdef CONFIG_COMPAT
629static long autofs_root_compat_ioctl(struct file *filp,
630 unsigned int cmd, unsigned long arg)
631{
632 struct inode *inode = filp->f_path.dentry->d_inode;
633 int ret;
634
635 lock_kernel();
636 if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL)
637 ret = autofs_do_root_ioctl(inode, filp, cmd, arg);
638 else
639 ret = autofs_do_root_ioctl(inode, filp, cmd,
640 (unsigned long)compat_ptr(arg));
641 unlock_kernel();
642
643 return ret;
644}
645#endif
diff --git a/fs/autofs/symlink.c b/fs/autofs/symlink.c
deleted file mode 100644
index 7ce9cb2c9ce2..000000000000
--- a/fs/autofs/symlink.c
+++ /dev/null
@@ -1,26 +0,0 @@
1/* -*- linux-c -*- --------------------------------------------------------- *
2 *
3 * linux/fs/autofs/symlink.c
4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 *
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
10 *
11 * ------------------------------------------------------------------------- */
12
13#include "autofs_i.h"
14
15/* Nothing to release.. */
16static void *autofs_follow_link(struct dentry *dentry, struct nameidata *nd)
17{
18 char *s=((struct autofs_symlink *)dentry->d_inode->i_private)->data;
19 nd_set_link(nd, s);
20 return NULL;
21}
22
23const struct inode_operations autofs_symlink_inode_operations = {
24 .readlink = generic_readlink,
25 .follow_link = autofs_follow_link
26};
diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c
deleted file mode 100644
index be46805972f0..000000000000
--- a/fs/autofs/waitq.c
+++ /dev/null
@@ -1,205 +0,0 @@
1/* -*- linux-c -*- --------------------------------------------------------- *
2 *
3 * linux/fs/autofs/waitq.c
4 *
5 * Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
6 *
7 * This file is part of the Linux kernel and is made available under
8 * the terms of the GNU General Public License, version 2, or at your
9 * option, any later version, incorporated herein by reference.
10 *
11 * ------------------------------------------------------------------------- */
12
13#include <linux/slab.h>
14#include <linux/time.h>
15#include <linux/signal.h>
16#include <linux/file.h>
17#include "autofs_i.h"
18
19/* We make this a static variable rather than a part of the superblock; it
20 is better if we don't reassign numbers easily even across filesystems */
21static autofs_wqt_t autofs_next_wait_queue = 1;
22
23/* These are the signals we allow interrupting a pending mount */
24#define SHUTDOWN_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT))
25
26void autofs_catatonic_mode(struct autofs_sb_info *sbi)
27{
28 struct autofs_wait_queue *wq, *nwq;
29
30 DPRINTK(("autofs: entering catatonic mode\n"));
31
32 sbi->catatonic = 1;
33 wq = sbi->queues;
34 sbi->queues = NULL; /* Erase all wait queues */
35 while ( wq ) {
36 nwq = wq->next;
37 wq->status = -ENOENT; /* Magic is gone - report failure */
38 kfree(wq->name);
39 wq->name = NULL;
40 wake_up(&wq->queue);
41 wq = nwq;
42 }
43 fput(sbi->pipe); /* Close the pipe */
44 sbi->pipe = NULL;
45 autofs_hash_dputall(&sbi->dirhash); /* Remove all dentry pointers */
46}
47
48static int autofs_write(struct file *file, const void *addr, int bytes)
49{
50 unsigned long sigpipe, flags;
51 mm_segment_t fs;
52 const char *data = (const char *)addr;
53 ssize_t wr = 0;
54
55 /** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/
56
57 sigpipe = sigismember(&current->pending.signal, SIGPIPE);
58
59 /* Save pointer to user space and point back to kernel space */
60 fs = get_fs();
61 set_fs(KERNEL_DS);
62
63 while (bytes &&
64 (wr = file->f_op->write(file,data,bytes,&file->f_pos)) > 0) {
65 data += wr;
66 bytes -= wr;
67 }
68
69 set_fs(fs);
70
71 /* Keep the currently executing process from receiving a
72 SIGPIPE unless it was already supposed to get one */
73 if (wr == -EPIPE && !sigpipe) {
74 spin_lock_irqsave(&current->sighand->siglock, flags);
75 sigdelset(&current->pending.signal, SIGPIPE);
76 recalc_sigpending();
77 spin_unlock_irqrestore(&current->sighand->siglock, flags);
78 }
79
80 return (bytes > 0);
81}
82
83static void autofs_notify_daemon(struct autofs_sb_info *sbi, struct autofs_wait_queue *wq)
84{
85 struct autofs_packet_missing pkt;
86
87 DPRINTK(("autofs_wait: wait id = 0x%08lx, name = ", wq->wait_queue_token));
88 autofs_say(wq->name,wq->len);
89
90 memset(&pkt,0,sizeof pkt); /* For security reasons */
91
92 pkt.hdr.proto_version = AUTOFS_PROTO_VERSION;
93 pkt.hdr.type = autofs_ptype_missing;
94 pkt.wait_queue_token = wq->wait_queue_token;
95 pkt.len = wq->len;
96 memcpy(pkt.name, wq->name, pkt.len);
97 pkt.name[pkt.len] = '\0';
98
99 if ( autofs_write(sbi->pipe,&pkt,sizeof(struct autofs_packet_missing)) )
100 autofs_catatonic_mode(sbi);
101}
102
103int autofs_wait(struct autofs_sb_info *sbi, struct qstr *name)
104{
105 struct autofs_wait_queue *wq;
106 int status;
107
108 /* In catatonic mode, we don't wait for nobody */
109 if ( sbi->catatonic )
110 return -ENOENT;
111
112 /* We shouldn't be able to get here, but just in case */
113 if ( name->len > NAME_MAX )
114 return -ENOENT;
115
116 for ( wq = sbi->queues ; wq ; wq = wq->next ) {
117 if ( wq->hash == name->hash &&
118 wq->len == name->len &&
119 wq->name && !memcmp(wq->name,name->name,name->len) )
120 break;
121 }
122
123 if ( !wq ) {
124 /* Create a new wait queue */
125 wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL);
126 if ( !wq )
127 return -ENOMEM;
128
129 wq->name = kmalloc(name->len,GFP_KERNEL);
130 if ( !wq->name ) {
131 kfree(wq);
132 return -ENOMEM;
133 }
134 wq->wait_queue_token = autofs_next_wait_queue++;
135 init_waitqueue_head(&wq->queue);
136 wq->hash = name->hash;
137 wq->len = name->len;
138 wq->status = -EINTR; /* Status return if interrupted */
139 memcpy(wq->name, name->name, name->len);
140 wq->next = sbi->queues;
141 sbi->queues = wq;
142
143 /* autofs_notify_daemon() may block */
144 wq->wait_ctr = 2;
145 autofs_notify_daemon(sbi,wq);
146 } else
147 wq->wait_ctr++;
148
149 /* wq->name is NULL if and only if the lock is already released */
150
151 if ( sbi->catatonic ) {
152 /* We might have slept, so check again for catatonic mode */
153 wq->status = -ENOENT;
154 kfree(wq->name);
155 wq->name = NULL;
156 }
157
158 if ( wq->name ) {
159 /* Block all but "shutdown" signals while waiting */
160 sigset_t sigmask;
161
162 siginitsetinv(&sigmask, SHUTDOWN_SIGS);
163 sigprocmask(SIG_BLOCK, &sigmask, &sigmask);
164
165 interruptible_sleep_on(&wq->queue);
166
167 sigprocmask(SIG_SETMASK, &sigmask, NULL);
168 } else {
169 DPRINTK(("autofs_wait: skipped sleeping\n"));
170 }
171
172 status = wq->status;
173
174 if ( ! --wq->wait_ctr ) /* Are we the last process to need status? */
175 kfree(wq);
176
177 return status;
178}
179
180
181int autofs_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_token, int status)
182{
183 struct autofs_wait_queue *wq, **wql;
184
185 for (wql = &sbi->queues; (wq = *wql) != NULL; wql = &wq->next) {
186 if ( wq->wait_queue_token == wait_queue_token )
187 break;
188 }
189 if ( !wq )
190 return -EINVAL;
191
192 *wql = wq->next; /* Unlink from chain */
193 kfree(wq->name);
194 wq->name = NULL; /* Do not wait on this queue */
195
196 wq->status = status;
197
198 if ( ! --wq->wait_ctr ) /* Is anyone still waiting for this guy? */
199 kfree(wq);
200 else
201 wake_up(&wq->queue);
202
203 return 0;
204}
205
diff --git a/fs/compat.c b/fs/compat.c
index f03abdadc401..52cfeb61da77 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -29,8 +29,6 @@
29#include <linux/vfs.h> 29#include <linux/vfs.h>
30#include <linux/ioctl.h> 30#include <linux/ioctl.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/smb.h>
33#include <linux/smb_mount.h>
34#include <linux/ncp_mount.h> 32#include <linux/ncp_mount.h>
35#include <linux/nfs4_mount.h> 33#include <linux/nfs4_mount.h>
36#include <linux/syscalls.h> 34#include <linux/syscalls.h>
@@ -745,30 +743,6 @@ static void *do_ncp_super_data_conv(void *raw_data)
745 return raw_data; 743 return raw_data;
746} 744}
747 745
748struct compat_smb_mount_data {
749 compat_int_t version;
750 __compat_uid_t mounted_uid;
751 __compat_uid_t uid;
752 __compat_gid_t gid;
753 compat_mode_t file_mode;
754 compat_mode_t dir_mode;
755};
756
757static void *do_smb_super_data_conv(void *raw_data)
758{
759 struct smb_mount_data *s = raw_data;
760 struct compat_smb_mount_data *c_s = raw_data;
761
762 if (c_s->version != SMB_MOUNT_OLDVERSION)
763 goto out;
764 s->dir_mode = c_s->dir_mode;
765 s->file_mode = c_s->file_mode;
766 s->gid = c_s->gid;
767 s->uid = c_s->uid;
768 s->mounted_uid = c_s->mounted_uid;
769 out:
770 return raw_data;
771}
772 746
773struct compat_nfs_string { 747struct compat_nfs_string {
774 compat_uint_t len; 748 compat_uint_t len;
@@ -835,7 +809,6 @@ static int do_nfs4_super_data_conv(void *raw_data)
835 return 0; 809 return 0;
836} 810}
837 811
838#define SMBFS_NAME "smbfs"
839#define NCPFS_NAME "ncpfs" 812#define NCPFS_NAME "ncpfs"
840#define NFS4_NAME "nfs4" 813#define NFS4_NAME "nfs4"
841 814
@@ -870,9 +843,7 @@ asmlinkage long compat_sys_mount(const char __user * dev_name,
870 retval = -EINVAL; 843 retval = -EINVAL;
871 844
872 if (kernel_type && data_page) { 845 if (kernel_type && data_page) {
873 if (!strcmp(kernel_type, SMBFS_NAME)) { 846 if (!strcmp(kernel_type, NCPFS_NAME)) {
874 do_smb_super_data_conv((void *)data_page);
875 } else if (!strcmp(kernel_type, NCPFS_NAME)) {
876 do_ncp_super_data_conv((void *)data_page); 847 do_ncp_super_data_conv((void *)data_page);
877 } else if (!strcmp(kernel_type, NFS4_NAME)) { 848 } else if (!strcmp(kernel_type, NFS4_NAME)) {
878 if (do_nfs4_super_data_conv((void *) data_page)) 849 if (do_nfs4_super_data_conv((void *) data_page))
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index d0ad09d57789..410ed188faa1 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -46,7 +46,6 @@
46#include <linux/videodev.h> 46#include <linux/videodev.h>
47#include <linux/netdevice.h> 47#include <linux/netdevice.h>
48#include <linux/raw.h> 48#include <linux/raw.h>
49#include <linux/smb_fs.h>
50#include <linux/blkdev.h> 49#include <linux/blkdev.h>
51#include <linux/elevator.h> 50#include <linux/elevator.h>
52#include <linux/rtc.h> 51#include <linux/rtc.h>
@@ -558,25 +557,6 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, void __user *argp)
558 557
559#endif /* CONFIG_BLOCK */ 558#endif /* CONFIG_BLOCK */
560 559
561static int do_smb_getmountuid(unsigned int fd, unsigned int cmd,
562 compat_uid_t __user *argp)
563{
564 mm_segment_t old_fs = get_fs();
565 __kernel_uid_t kuid;
566 int err;
567
568 cmd = SMB_IOC_GETMOUNTUID;
569
570 set_fs(KERNEL_DS);
571 err = sys_ioctl(fd, cmd, (unsigned long)&kuid);
572 set_fs(old_fs);
573
574 if (err >= 0)
575 err = put_user(kuid, argp);
576
577 return err;
578}
579
580/* Bluetooth ioctls */ 560/* Bluetooth ioctls */
581#define HCIUARTSETPROTO _IOW('U', 200, int) 561#define HCIUARTSETPROTO _IOW('U', 200, int)
582#define HCIUARTGETPROTO _IOR('U', 201, int) 562#define HCIUARTGETPROTO _IOR('U', 201, int)
@@ -1199,8 +1179,9 @@ COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5)
1199COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS) 1179COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS)
1200COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS) 1180COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS)
1201COMPATIBLE_IOCTL(OSS_GETVERSION) 1181COMPATIBLE_IOCTL(OSS_GETVERSION)
1202/* SMB ioctls which do not need any translations */ 1182/* Raw devices */
1203COMPATIBLE_IOCTL(SMB_IOC_NEWCONN) 1183COMPATIBLE_IOCTL(RAW_SETBIND)
1184COMPATIBLE_IOCTL(RAW_GETBIND)
1204/* Watchdog */ 1185/* Watchdog */
1205COMPATIBLE_IOCTL(WDIOC_GETSUPPORT) 1186COMPATIBLE_IOCTL(WDIOC_GETSUPPORT)
1206COMPATIBLE_IOCTL(WDIOC_GETSTATUS) 1187COMPATIBLE_IOCTL(WDIOC_GETSTATUS)
@@ -1458,10 +1439,6 @@ static long do_ioctl_trans(int fd, unsigned int cmd,
1458 case MTIOCPOS32: 1439 case MTIOCPOS32:
1459 return mt_ioctl_trans(fd, cmd, argp); 1440 return mt_ioctl_trans(fd, cmd, argp);
1460#endif 1441#endif
1461 /* One SMB ioctl needs translations. */
1462#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
1463 case SMB_IOC_GETMOUNTUID_32:
1464 return do_smb_getmountuid(fd, cmd, argp);
1465 /* Serial */ 1442 /* Serial */
1466 case TIOCGSERIAL: 1443 case TIOCGSERIAL:
1467 case TIOCSSERIAL: 1444 case TIOCSSERIAL:
diff --git a/fs/smbfs/Kconfig b/fs/smbfs/Kconfig
deleted file mode 100644
index 2bc24a8c4039..000000000000
--- a/fs/smbfs/Kconfig
+++ /dev/null
@@ -1,56 +0,0 @@
1config SMB_FS
2 tristate "SMB file system support (OBSOLETE, please use CIFS)"
3 depends on BKL # probably unfixable
4 depends on INET
5 select NLS
6 help
7 SMB (Server Message Block) is the protocol Windows for Workgroups
8 (WfW), Windows 95/98, Windows NT and OS/2 Lan Manager use to share
9 files and printers over local networks. Saying Y here allows you to
10 mount their file systems (often called "shares" in this context) and
11 access them just like any other Unix directory. Currently, this
12 works only if the Windows machines use TCP/IP as the underlying
13 transport protocol, and not NetBEUI. For details, read
14 <file:Documentation/filesystems/smbfs.txt> and the SMB-HOWTO,
15 available from <http://www.tldp.org/docs.html#howto>.
16
17 Note: if you just want your box to act as an SMB *server* and make
18 files and printing services available to Windows clients (which need
19 to have a TCP/IP stack), you don't need to say Y here; you can use
20 the program SAMBA (available from <ftp://ftp.samba.org/pub/samba/>)
21 for that.
22
23 General information about how to connect Linux, Windows machines and
24 Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.
25
26 To compile the SMB support as a module, choose M here:
27 the module will be called smbfs. Most people say N, however.
28
29config SMB_NLS_DEFAULT
30 bool "Use a default NLS"
31 depends on SMB_FS
32 help
33 Enabling this will make smbfs use nls translations by default. You
34 need to specify the local charset (CONFIG_NLS_DEFAULT) in the nls
35 settings and you need to give the default nls for the SMB server as
36 CONFIG_SMB_NLS_REMOTE.
37
38 The nls settings can be changed at mount time, if your smbmount
39 supports that, using the codepage and iocharset parameters.
40
41 smbmount from samba 2.2.0 or later supports this.
42
43config SMB_NLS_REMOTE
44 string "Default Remote NLS Option"
45 depends on SMB_NLS_DEFAULT
46 default "cp437"
47 help
48 This setting allows you to specify a default value for which
49 codepage the server uses. If this field is left blank no
50 translations will be done by default. The local codepage/charset
51 default to CONFIG_NLS_DEFAULT.
52
53 The nls settings can be changed at mount time, if your smbmount
54 supports that, using the codepage and iocharset parameters.
55
56 smbmount from samba 2.2.0 or later supports this.
diff --git a/fs/smbfs/Makefile b/fs/smbfs/Makefile
deleted file mode 100644
index 4faf8c4722c3..000000000000
--- a/fs/smbfs/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
1#
2# Makefile for the linux smb-filesystem routines.
3#
4
5obj-$(CONFIG_SMB_FS) += smbfs.o
6
7smbfs-objs := proc.o dir.o cache.o sock.o inode.o file.o ioctl.o getopt.o \
8 symlink.o smbiod.o request.o
9
10# If you want debugging output, you may add these flags to the EXTRA_CFLAGS
11# SMBFS_PARANOIA should normally be enabled.
12
13EXTRA_CFLAGS += -DSMBFS_PARANOIA
14#EXTRA_CFLAGS += -DSMBFS_DEBUG
15#EXTRA_CFLAGS += -DSMBFS_DEBUG_VERBOSE
16#EXTRA_CFLAGS += -DDEBUG_SMB_TIMESTAMP
17#EXTRA_CFLAGS += -Werror
18
diff --git a/fs/smbfs/cache.c b/fs/smbfs/cache.c
deleted file mode 100644
index 8c177eb7e344..000000000000
--- a/fs/smbfs/cache.c
+++ /dev/null
@@ -1,208 +0,0 @@
1/*
2 * cache.c
3 *
4 * Copyright (C) 1997 by Bill Hawes
5 *
6 * Routines to support directory cacheing using the page cache.
7 * This cache code is almost directly taken from ncpfs.
8 *
9 * Please add a note about your changes to smbfs in the ChangeLog file.
10 */
11
12#include <linux/time.h>
13#include <linux/errno.h>
14#include <linux/kernel.h>
15#include <linux/mm.h>
16#include <linux/smb_fs.h>
17#include <linux/pagemap.h>
18#include <linux/net.h>
19
20#include <asm/page.h>
21
22#include "smb_debug.h"
23#include "proto.h"
24
25/*
26 * Force the next attempt to use the cache to be a timeout.
27 * If we can't find the page that's fine, it will cause a refresh.
28 */
29void
30smb_invalid_dir_cache(struct inode * dir)
31{
32 struct smb_sb_info *server = server_from_inode(dir);
33 union smb_dir_cache *cache = NULL;
34 struct page *page = NULL;
35
36 page = grab_cache_page(&dir->i_data, 0);
37 if (!page)
38 goto out;
39
40 if (!PageUptodate(page))
41 goto out_unlock;
42
43 cache = kmap(page);
44 cache->head.time = jiffies - SMB_MAX_AGE(server);
45
46 kunmap(page);
47 SetPageUptodate(page);
48out_unlock:
49 unlock_page(page);
50 page_cache_release(page);
51out:
52 return;
53}
54
55/*
56 * Mark all dentries for 'parent' as invalid, forcing them to be re-read
57 */
58void
59smb_invalidate_dircache_entries(struct dentry *parent)
60{
61 struct smb_sb_info *server = server_from_dentry(parent);
62 struct list_head *next;
63 struct dentry *dentry;
64
65 spin_lock(&dcache_lock);
66 next = parent->d_subdirs.next;
67 while (next != &parent->d_subdirs) {
68 dentry = list_entry(next, struct dentry, d_u.d_child);
69 dentry->d_fsdata = NULL;
70 smb_age_dentry(server, dentry);
71 next = next->next;
72 }
73 spin_unlock(&dcache_lock);
74}
75
76/*
77 * dget, but require that fpos and parent matches what the dentry contains.
78 * dentry is not known to be a valid pointer at entry.
79 */
80struct dentry *
81smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
82{
83 struct dentry *dent = dentry;
84 struct list_head *next;
85
86 if (d_validate(dent, parent)) {
87 if (dent->d_name.len <= SMB_MAXNAMELEN &&
88 (unsigned long)dent->d_fsdata == fpos) {
89 if (!dent->d_inode) {
90 dput(dent);
91 dent = NULL;
92 }
93 return dent;
94 }
95 dput(dent);
96 }
97
98 /* If a pointer is invalid, we search the dentry. */
99 spin_lock(&dcache_lock);
100 next = parent->d_subdirs.next;
101 while (next != &parent->d_subdirs) {
102 dent = list_entry(next, struct dentry, d_u.d_child);
103 if ((unsigned long)dent->d_fsdata == fpos) {
104 if (dent->d_inode)
105 dget_locked(dent);
106 else
107 dent = NULL;
108 goto out_unlock;
109 }
110 next = next->next;
111 }
112 dent = NULL;
113out_unlock:
114 spin_unlock(&dcache_lock);
115 return dent;
116}
117
118
119/*
120 * Create dentry/inode for this file and add it to the dircache.
121 */
122int
123smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
124 struct smb_cache_control *ctrl, struct qstr *qname,
125 struct smb_fattr *entry)
126{
127 struct dentry *newdent, *dentry = filp->f_path.dentry;
128 struct inode *newino, *inode = dentry->d_inode;
129 struct smb_cache_control ctl = *ctrl;
130 int valid = 0;
131 int hashed = 0;
132 ino_t ino = 0;
133
134 qname->hash = full_name_hash(qname->name, qname->len);
135
136 if (dentry->d_op && dentry->d_op->d_hash)
137 if (dentry->d_op->d_hash(dentry, qname) != 0)
138 goto end_advance;
139
140 newdent = d_lookup(dentry, qname);
141
142 if (!newdent) {
143 newdent = d_alloc(dentry, qname);
144 if (!newdent)
145 goto end_advance;
146 } else {
147 hashed = 1;
148 memcpy((char *) newdent->d_name.name, qname->name,
149 newdent->d_name.len);
150 }
151
152 if (!newdent->d_inode) {
153 smb_renew_times(newdent);
154 entry->f_ino = iunique(inode->i_sb, 2);
155 newino = smb_iget(inode->i_sb, entry);
156 if (newino) {
157 smb_new_dentry(newdent);
158 d_instantiate(newdent, newino);
159 if (!hashed)
160 d_rehash(newdent);
161 }
162 } else
163 smb_set_inode_attr(newdent->d_inode, entry);
164
165 if (newdent->d_inode) {
166 ino = newdent->d_inode->i_ino;
167 newdent->d_fsdata = (void *) ctl.fpos;
168 smb_new_dentry(newdent);
169 }
170
171 if (ctl.idx >= SMB_DIRCACHE_SIZE) {
172 if (ctl.page) {
173 kunmap(ctl.page);
174 SetPageUptodate(ctl.page);
175 unlock_page(ctl.page);
176 page_cache_release(ctl.page);
177 }
178 ctl.cache = NULL;
179 ctl.idx -= SMB_DIRCACHE_SIZE;
180 ctl.ofs += 1;
181 ctl.page = grab_cache_page(&inode->i_data, ctl.ofs);
182 if (ctl.page)
183 ctl.cache = kmap(ctl.page);
184 }
185 if (ctl.cache) {
186 ctl.cache->dentry[ctl.idx] = newdent;
187 valid = 1;
188 }
189 dput(newdent);
190
191end_advance:
192 if (!valid)
193 ctl.valid = 0;
194 if (!ctl.filled && (ctl.fpos == filp->f_pos)) {
195 if (!ino)
196 ino = find_inode_number(dentry, qname);
197 if (!ino)
198 ino = iunique(inode->i_sb, 2);
199 ctl.filled = filldir(dirent, qname->name, qname->len,
200 filp->f_pos, ino, DT_UNKNOWN);
201 if (!ctl.filled)
202 filp->f_pos += 1;
203 }
204 ctl.fpos += 1;
205 ctl.idx += 1;
206 *ctrl = ctl;
207 return (ctl.valid || !ctl.filled);
208}
diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c
deleted file mode 100644
index f678d421e541..000000000000
--- a/fs/smbfs/dir.c
+++ /dev/null
@@ -1,696 +0,0 @@
1/*
2 * dir.c
3 *
4 * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
5 * Copyright (C) 1997 by Volker Lendecke
6 *
7 * Please add a note about your changes to smbfs in the ChangeLog file.
8 */
9
10#include <linux/time.h>
11#include <linux/errno.h>
12#include <linux/kernel.h>
13#include <linux/smp_lock.h>
14#include <linux/ctype.h>
15#include <linux/net.h>
16#include <linux/sched.h>
17
18#include <linux/smb_fs.h>
19#include <linux/smb_mount.h>
20#include <linux/smbno.h>
21
22#include "smb_debug.h"
23#include "proto.h"
24
25static int smb_readdir(struct file *, void *, filldir_t);
26static int smb_dir_open(struct inode *, struct file *);
27
28static struct dentry *smb_lookup(struct inode *, struct dentry *, struct nameidata *);
29static int smb_create(struct inode *, struct dentry *, int, struct nameidata *);
30static int smb_mkdir(struct inode *, struct dentry *, int);
31static int smb_rmdir(struct inode *, struct dentry *);
32static int smb_unlink(struct inode *, struct dentry *);
33static int smb_rename(struct inode *, struct dentry *,
34 struct inode *, struct dentry *);
35static int smb_make_node(struct inode *,struct dentry *,int,dev_t);
36static int smb_link(struct dentry *, struct inode *, struct dentry *);
37
38const struct file_operations smb_dir_operations =
39{
40 .llseek = generic_file_llseek,
41 .read = generic_read_dir,
42 .readdir = smb_readdir,
43 .unlocked_ioctl = smb_ioctl,
44 .open = smb_dir_open,
45};
46
47const struct inode_operations smb_dir_inode_operations =
48{
49 .create = smb_create,
50 .lookup = smb_lookup,
51 .unlink = smb_unlink,
52 .mkdir = smb_mkdir,
53 .rmdir = smb_rmdir,
54 .rename = smb_rename,
55 .getattr = smb_getattr,
56 .setattr = smb_notify_change,
57};
58
59const struct inode_operations smb_dir_inode_operations_unix =
60{
61 .create = smb_create,
62 .lookup = smb_lookup,
63 .unlink = smb_unlink,
64 .mkdir = smb_mkdir,
65 .rmdir = smb_rmdir,
66 .rename = smb_rename,
67 .getattr = smb_getattr,
68 .setattr = smb_notify_change,
69 .symlink = smb_symlink,
70 .mknod = smb_make_node,
71 .link = smb_link,
72};
73
74/*
75 * Read a directory, using filldir to fill the dirent memory.
76 * smb_proc_readdir does the actual reading from the smb server.
77 *
78 * The cache code is almost directly taken from ncpfs
79 */
80static int
81smb_readdir(struct file *filp, void *dirent, filldir_t filldir)
82{
83 struct dentry *dentry = filp->f_path.dentry;
84 struct inode *dir = dentry->d_inode;
85 struct smb_sb_info *server = server_from_dentry(dentry);
86 union smb_dir_cache *cache = NULL;
87 struct smb_cache_control ctl;
88 struct page *page = NULL;
89 int result;
90
91 ctl.page = NULL;
92 ctl.cache = NULL;
93
94 VERBOSE("reading %s/%s, f_pos=%d\n",
95 DENTRY_PATH(dentry), (int) filp->f_pos);
96
97 result = 0;
98
99 lock_kernel();
100
101 switch ((unsigned int) filp->f_pos) {
102 case 0:
103 if (filldir(dirent, ".", 1, 0, dir->i_ino, DT_DIR) < 0)
104 goto out;
105 filp->f_pos = 1;
106 /* fallthrough */
107 case 1:
108 if (filldir(dirent, "..", 2, 1, parent_ino(dentry), DT_DIR) < 0)
109 goto out;
110 filp->f_pos = 2;
111 }
112
113 /*
114 * Make sure our inode is up-to-date.
115 */
116 result = smb_revalidate_inode(dentry);
117 if (result)
118 goto out;
119
120
121 page = grab_cache_page(&dir->i_data, 0);
122 if (!page)
123 goto read_really;
124
125 ctl.cache = cache = kmap(page);
126 ctl.head = cache->head;
127
128 if (!PageUptodate(page) || !ctl.head.eof) {
129 VERBOSE("%s/%s, page uptodate=%d, eof=%d\n",
130 DENTRY_PATH(dentry), PageUptodate(page),ctl.head.eof);
131 goto init_cache;
132 }
133
134 if (filp->f_pos == 2) {
135 if (jiffies - ctl.head.time >= SMB_MAX_AGE(server))
136 goto init_cache;
137
138 /*
139 * N.B. ncpfs checks mtime of dentry too here, we don't.
140 * 1. common smb servers do not update mtime on dir changes
141 * 2. it requires an extra smb request
142 * (revalidate has the same timeout as ctl.head.time)
143 *
144 * Instead smbfs invalidates its own cache on local changes
145 * and remote changes are not seen until timeout.
146 */
147 }
148
149 if (filp->f_pos > ctl.head.end)
150 goto finished;
151
152 ctl.fpos = filp->f_pos + (SMB_DIRCACHE_START - 2);
153 ctl.ofs = ctl.fpos / SMB_DIRCACHE_SIZE;
154 ctl.idx = ctl.fpos % SMB_DIRCACHE_SIZE;
155
156 for (;;) {
157 if (ctl.ofs != 0) {
158 ctl.page = find_lock_page(&dir->i_data, ctl.ofs);
159 if (!ctl.page)
160 goto invalid_cache;
161 ctl.cache = kmap(ctl.page);
162 if (!PageUptodate(ctl.page))
163 goto invalid_cache;
164 }
165 while (ctl.idx < SMB_DIRCACHE_SIZE) {
166 struct dentry *dent;
167 int res;
168
169 dent = smb_dget_fpos(ctl.cache->dentry[ctl.idx],
170 dentry, filp->f_pos);
171 if (!dent)
172 goto invalid_cache;
173
174 res = filldir(dirent, dent->d_name.name,
175 dent->d_name.len, filp->f_pos,
176 dent->d_inode->i_ino, DT_UNKNOWN);
177 dput(dent);
178 if (res)
179 goto finished;
180 filp->f_pos += 1;
181 ctl.idx += 1;
182 if (filp->f_pos > ctl.head.end)
183 goto finished;
184 }
185 if (ctl.page) {
186 kunmap(ctl.page);
187 SetPageUptodate(ctl.page);
188 unlock_page(ctl.page);
189 page_cache_release(ctl.page);
190 ctl.page = NULL;
191 }
192 ctl.idx = 0;
193 ctl.ofs += 1;
194 }
195invalid_cache:
196 if (ctl.page) {
197 kunmap(ctl.page);
198 unlock_page(ctl.page);
199 page_cache_release(ctl.page);
200 ctl.page = NULL;
201 }
202 ctl.cache = cache;
203init_cache:
204 smb_invalidate_dircache_entries(dentry);
205 ctl.head.time = jiffies;
206 ctl.head.eof = 0;
207 ctl.fpos = 2;
208 ctl.ofs = 0;
209 ctl.idx = SMB_DIRCACHE_START;
210 ctl.filled = 0;
211 ctl.valid = 1;
212read_really:
213 result = server->ops->readdir(filp, dirent, filldir, &ctl);
214 if (result == -ERESTARTSYS && page)
215 ClearPageUptodate(page);
216 if (ctl.idx == -1)
217 goto invalid_cache; /* retry */
218 ctl.head.end = ctl.fpos - 1;
219 ctl.head.eof = ctl.valid;
220finished:
221 if (page) {
222 cache->head = ctl.head;
223 kunmap(page);
224 if (result != -ERESTARTSYS)
225 SetPageUptodate(page);
226 unlock_page(page);
227 page_cache_release(page);
228 }
229 if (ctl.page) {
230 kunmap(ctl.page);
231 SetPageUptodate(ctl.page);
232 unlock_page(ctl.page);
233 page_cache_release(ctl.page);
234 }
235out:
236 unlock_kernel();
237 return result;
238}
239
240static int
241smb_dir_open(struct inode *dir, struct file *file)
242{
243 struct dentry *dentry = file->f_path.dentry;
244 struct smb_sb_info *server;
245 int error = 0;
246
247 VERBOSE("(%s/%s)\n", dentry->d_parent->d_name.name,
248 file->f_path.dentry->d_name.name);
249
250 /*
251 * Directory timestamps in the core protocol aren't updated
252 * when a file is added, so we give them a very short TTL.
253 */
254 lock_kernel();
255 server = server_from_dentry(dentry);
256 if (server->opt.protocol < SMB_PROTOCOL_LANMAN2) {
257 unsigned long age = jiffies - SMB_I(dir)->oldmtime;
258 if (age > 2*HZ)
259 smb_invalid_dir_cache(dir);
260 }
261
262 /*
263 * Note: in order to allow the smbmount process to open the
264 * mount point, we only revalidate if the connection is valid or
265 * if the process is trying to access something other than the root.
266 */
267 if (server->state == CONN_VALID || !IS_ROOT(dentry))
268 error = smb_revalidate_inode(dentry);
269 unlock_kernel();
270 return error;
271}
272
273/*
274 * Dentry operations routines
275 */
276static int smb_lookup_validate(struct dentry *, struct nameidata *);
277static int smb_hash_dentry(struct dentry *, struct qstr *);
278static int smb_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
279static int smb_delete_dentry(struct dentry *);
280
281static const struct dentry_operations smbfs_dentry_operations =
282{
283 .d_revalidate = smb_lookup_validate,
284 .d_hash = smb_hash_dentry,
285 .d_compare = smb_compare_dentry,
286 .d_delete = smb_delete_dentry,
287};
288
289static const struct dentry_operations smbfs_dentry_operations_case =
290{
291 .d_revalidate = smb_lookup_validate,
292 .d_delete = smb_delete_dentry,
293};
294
295
296/*
297 * This is the callback when the dcache has a lookup hit.
298 */
299static int
300smb_lookup_validate(struct dentry * dentry, struct nameidata *nd)
301{
302 struct smb_sb_info *server = server_from_dentry(dentry);
303 struct inode * inode = dentry->d_inode;
304 unsigned long age = jiffies - dentry->d_time;
305 int valid;
306
307 /*
308 * The default validation is based on dentry age:
309 * we believe in dentries for a few seconds. (But each
310 * successful server lookup renews the timestamp.)
311 */
312 valid = (age <= SMB_MAX_AGE(server));
313#ifdef SMBFS_DEBUG_VERBOSE
314 if (!valid)
315 VERBOSE("%s/%s not valid, age=%lu\n",
316 DENTRY_PATH(dentry), age);
317#endif
318
319 if (inode) {
320 lock_kernel();
321 if (is_bad_inode(inode)) {
322 PARANOIA("%s/%s has dud inode\n", DENTRY_PATH(dentry));
323 valid = 0;
324 } else if (!valid)
325 valid = (smb_revalidate_inode(dentry) == 0);
326 unlock_kernel();
327 } else {
328 /*
329 * What should we do for negative dentries?
330 */
331 }
332 return valid;
333}
334
335static int
336smb_hash_dentry(struct dentry *dir, struct qstr *this)
337{
338 unsigned long hash;
339 int i;
340
341 hash = init_name_hash();
342 for (i=0; i < this->len ; i++)
343 hash = partial_name_hash(tolower(this->name[i]), hash);
344 this->hash = end_name_hash(hash);
345
346 return 0;
347}
348
349static int
350smb_compare_dentry(struct dentry *dir, struct qstr *a, struct qstr *b)
351{
352 int i, result = 1;
353
354 if (a->len != b->len)
355 goto out;
356 for (i=0; i < a->len; i++) {
357 if (tolower(a->name[i]) != tolower(b->name[i]))
358 goto out;
359 }
360 result = 0;
361out:
362 return result;
363}
364
365/*
366 * This is the callback from dput() when d_count is going to 0.
367 * We use this to unhash dentries with bad inodes.
368 */
369static int
370smb_delete_dentry(struct dentry * dentry)
371{
372 if (dentry->d_inode) {
373 if (is_bad_inode(dentry->d_inode)) {
374 PARANOIA("bad inode, unhashing %s/%s\n",
375 DENTRY_PATH(dentry));
376 return 1;
377 }
378 } else {
379 /* N.B. Unhash negative dentries? */
380 }
381 return 0;
382}
383
384/*
385 * Initialize a new dentry
386 */
387void
388smb_new_dentry(struct dentry *dentry)
389{
390 struct smb_sb_info *server = server_from_dentry(dentry);
391
392 if (server->mnt->flags & SMB_MOUNT_CASE)
393 dentry->d_op = &smbfs_dentry_operations_case;
394 else
395 dentry->d_op = &smbfs_dentry_operations;
396 dentry->d_time = jiffies;
397}
398
399
400/*
401 * Whenever a lookup succeeds, we know the parent directories
402 * are all valid, so we want to update the dentry timestamps.
403 * N.B. Move this to dcache?
404 */
405void
406smb_renew_times(struct dentry * dentry)
407{
408 dget(dentry);
409 dentry->d_time = jiffies;
410
411 while (!IS_ROOT(dentry)) {
412 struct dentry *parent = dget_parent(dentry);
413 dput(dentry);
414 dentry = parent;
415
416 dentry->d_time = jiffies;
417 }
418 dput(dentry);
419}
420
421static struct dentry *
422smb_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
423{
424 struct smb_fattr finfo;
425 struct inode *inode;
426 int error;
427 struct smb_sb_info *server;
428
429 error = -ENAMETOOLONG;
430 if (dentry->d_name.len > SMB_MAXNAMELEN)
431 goto out;
432
433 /* Do not allow lookup of names with backslashes in */
434 error = -EINVAL;
435 if (memchr(dentry->d_name.name, '\\', dentry->d_name.len))
436 goto out;
437
438 lock_kernel();
439 error = smb_proc_getattr(dentry, &finfo);
440#ifdef SMBFS_PARANOIA
441 if (error && error != -ENOENT)
442 PARANOIA("find %s/%s failed, error=%d\n",
443 DENTRY_PATH(dentry), error);
444#endif
445
446 inode = NULL;
447 if (error == -ENOENT)
448 goto add_entry;
449 if (!error) {
450 error = -EACCES;
451 finfo.f_ino = iunique(dentry->d_sb, 2);
452 inode = smb_iget(dir->i_sb, &finfo);
453 if (inode) {
454 add_entry:
455 server = server_from_dentry(dentry);
456 if (server->mnt->flags & SMB_MOUNT_CASE)
457 dentry->d_op = &smbfs_dentry_operations_case;
458 else
459 dentry->d_op = &smbfs_dentry_operations;
460
461 d_add(dentry, inode);
462 smb_renew_times(dentry);
463 error = 0;
464 }
465 }
466 unlock_kernel();
467out:
468 return ERR_PTR(error);
469}
470
471/*
472 * This code is common to all routines creating a new inode.
473 */
474static int
475smb_instantiate(struct dentry *dentry, __u16 fileid, int have_id)
476{
477 struct smb_sb_info *server = server_from_dentry(dentry);
478 struct inode *inode;
479 int error;
480 struct smb_fattr fattr;
481
482 VERBOSE("file %s/%s, fileid=%u\n", DENTRY_PATH(dentry), fileid);
483
484 error = smb_proc_getattr(dentry, &fattr);
485 if (error)
486 goto out_close;
487
488 smb_renew_times(dentry);
489 fattr.f_ino = iunique(dentry->d_sb, 2);
490 inode = smb_iget(dentry->d_sb, &fattr);
491 if (!inode)
492 goto out_no_inode;
493
494 if (have_id) {
495 struct smb_inode_info *ei = SMB_I(inode);
496 ei->fileid = fileid;
497 ei->access = SMB_O_RDWR;
498 ei->open = server->generation;
499 }
500 d_instantiate(dentry, inode);
501out:
502 return error;
503
504out_no_inode:
505 error = -EACCES;
506out_close:
507 if (have_id) {
508 PARANOIA("%s/%s failed, error=%d, closing %u\n",
509 DENTRY_PATH(dentry), error, fileid);
510 smb_close_fileid(dentry, fileid);
511 }
512 goto out;
513}
514
515/* N.B. How should the mode argument be used? */
516static int
517smb_create(struct inode *dir, struct dentry *dentry, int mode,
518 struct nameidata *nd)
519{
520 struct smb_sb_info *server = server_from_dentry(dentry);
521 __u16 fileid;
522 int error;
523 struct iattr attr;
524
525 VERBOSE("creating %s/%s, mode=%d\n", DENTRY_PATH(dentry), mode);
526
527 lock_kernel();
528 smb_invalid_dir_cache(dir);
529 error = smb_proc_create(dentry, 0, get_seconds(), &fileid);
530 if (!error) {
531 if (server->opt.capabilities & SMB_CAP_UNIX) {
532 /* Set attributes for new file */
533 attr.ia_valid = ATTR_MODE;
534 attr.ia_mode = mode;
535 error = smb_proc_setattr_unix(dentry, &attr, 0, 0);
536 }
537 error = smb_instantiate(dentry, fileid, 1);
538 } else {
539 PARANOIA("%s/%s failed, error=%d\n",
540 DENTRY_PATH(dentry), error);
541 }
542 unlock_kernel();
543 return error;
544}
545
546/* N.B. How should the mode argument be used? */
547static int
548smb_mkdir(struct inode *dir, struct dentry *dentry, int mode)
549{
550 struct smb_sb_info *server = server_from_dentry(dentry);
551 int error;
552 struct iattr attr;
553
554 lock_kernel();
555 smb_invalid_dir_cache(dir);
556 error = smb_proc_mkdir(dentry);
557 if (!error) {
558 if (server->opt.capabilities & SMB_CAP_UNIX) {
559 /* Set attributes for new directory */
560 attr.ia_valid = ATTR_MODE;
561 attr.ia_mode = mode;
562 error = smb_proc_setattr_unix(dentry, &attr, 0, 0);
563 }
564 error = smb_instantiate(dentry, 0, 0);
565 }
566 unlock_kernel();
567 return error;
568}
569
570static int
571smb_rmdir(struct inode *dir, struct dentry *dentry)
572{
573 struct inode *inode = dentry->d_inode;
574 int error;
575
576 /*
577 * Close the directory if it's open.
578 */
579 lock_kernel();
580 smb_close(inode);
581
582 /*
583 * Check that nobody else is using the directory..
584 */
585 error = -EBUSY;
586 if (!d_unhashed(dentry))
587 goto out;
588
589 smb_invalid_dir_cache(dir);
590 error = smb_proc_rmdir(dentry);
591
592out:
593 unlock_kernel();
594 return error;
595}
596
597static int
598smb_unlink(struct inode *dir, struct dentry *dentry)
599{
600 int error;
601
602 /*
603 * Close the file if it's open.
604 */
605 lock_kernel();
606 smb_close(dentry->d_inode);
607
608 smb_invalid_dir_cache(dir);
609 error = smb_proc_unlink(dentry);
610 if (!error)
611 smb_renew_times(dentry);
612 unlock_kernel();
613 return error;
614}
615
616static int
617smb_rename(struct inode *old_dir, struct dentry *old_dentry,
618 struct inode *new_dir, struct dentry *new_dentry)
619{
620 int error;
621
622 /*
623 * Close any open files, and check whether to delete the
624 * target before attempting the rename.
625 */
626 lock_kernel();
627 if (old_dentry->d_inode)
628 smb_close(old_dentry->d_inode);
629 if (new_dentry->d_inode) {
630 smb_close(new_dentry->d_inode);
631 error = smb_proc_unlink(new_dentry);
632 if (error) {
633 VERBOSE("unlink %s/%s, error=%d\n",
634 DENTRY_PATH(new_dentry), error);
635 goto out;
636 }
637 /* FIXME */
638 d_delete(new_dentry);
639 }
640
641 smb_invalid_dir_cache(old_dir);
642 smb_invalid_dir_cache(new_dir);
643 error = smb_proc_mv(old_dentry, new_dentry);
644 if (!error) {
645 smb_renew_times(old_dentry);
646 smb_renew_times(new_dentry);
647 }
648out:
649 unlock_kernel();
650 return error;
651}
652
653/*
654 * FIXME: samba servers won't let you create device nodes unless uid/gid
655 * matches the connection credentials (and we don't know which those are ...)
656 */
657static int
658smb_make_node(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
659{
660 int error;
661 struct iattr attr;
662
663 attr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID;
664 attr.ia_mode = mode;
665 current_euid_egid(&attr.ia_uid, &attr.ia_gid);
666
667 if (!new_valid_dev(dev))
668 return -EINVAL;
669
670 smb_invalid_dir_cache(dir);
671 error = smb_proc_setattr_unix(dentry, &attr, MAJOR(dev), MINOR(dev));
672 if (!error) {
673 error = smb_instantiate(dentry, 0, 0);
674 }
675 return error;
676}
677
678/*
679 * dentry = existing file
680 * new_dentry = new file
681 */
682static int
683smb_link(struct dentry *dentry, struct inode *dir, struct dentry *new_dentry)
684{
685 int error;
686
687 DEBUG1("smb_link old=%s/%s new=%s/%s\n",
688 DENTRY_PATH(dentry), DENTRY_PATH(new_dentry));
689 smb_invalid_dir_cache(dir);
690 error = smb_proc_link(server_from_dentry(dentry), dentry, new_dentry);
691 if (!error) {
692 smb_renew_times(dentry);
693 error = smb_instantiate(new_dentry, 0, 0);
694 }
695 return error;
696}
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
deleted file mode 100644
index 8e187a0f94bb..000000000000
--- a/fs/smbfs/file.c
+++ /dev/null
@@ -1,454 +0,0 @@
1/*
2 * file.c
3 *
4 * Copyright (C) 1995, 1996, 1997 by Paal-Kr. Engstad and Volker Lendecke
5 * Copyright (C) 1997 by Volker Lendecke
6 *
7 * Please add a note about your changes to smbfs in the ChangeLog file.
8 */
9
10#include <linux/time.h>
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/fcntl.h>
14#include <linux/stat.h>
15#include <linux/mm.h>
16#include <linux/pagemap.h>
17#include <linux/smp_lock.h>
18#include <linux/net.h>
19#include <linux/aio.h>
20
21#include <asm/uaccess.h>
22#include <asm/system.h>
23
24#include <linux/smbno.h>
25#include <linux/smb_fs.h>
26
27#include "smb_debug.h"
28#include "proto.h"
29
30static int
31smb_fsync(struct file *file, int datasync)
32{
33 struct dentry *dentry = file->f_path.dentry;
34 struct smb_sb_info *server = server_from_dentry(dentry);
35 int result;
36
37 VERBOSE("sync file %s/%s\n", DENTRY_PATH(dentry));
38
39 /*
40 * The VFS will writepage() all dirty pages for us, but we
41 * should send a SMBflush to the server, letting it know that
42 * we want things synchronized with actual storage.
43 *
44 * Note: this function requires all pages to have been written already
45 * (should be ok with writepage_sync)
46 */
47 result = smb_proc_flush(server, SMB_I(dentry->d_inode)->fileid);
48 return result;
49}
50
51/*
52 * Read a page synchronously.
53 */
54static int
55smb_readpage_sync(struct dentry *dentry, struct page *page)
56{
57 char *buffer = kmap(page);
58 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
59 struct smb_sb_info *server = server_from_dentry(dentry);
60 unsigned int rsize = smb_get_rsize(server);
61 int count = PAGE_SIZE;
62 int result;
63
64 VERBOSE("file %s/%s, count=%d@%Ld, rsize=%d\n",
65 DENTRY_PATH(dentry), count, offset, rsize);
66
67 result = smb_open(dentry, SMB_O_RDONLY);
68 if (result < 0)
69 goto io_error;
70
71 do {
72 if (count < rsize)
73 rsize = count;
74
75 result = server->ops->read(dentry->d_inode,offset,rsize,buffer);
76 if (result < 0)
77 goto io_error;
78
79 count -= result;
80 offset += result;
81 buffer += result;
82 dentry->d_inode->i_atime =
83 current_fs_time(dentry->d_inode->i_sb);
84 if (result < rsize)
85 break;
86 } while (count);
87
88 memset(buffer, 0, count);
89 flush_dcache_page(page);
90 SetPageUptodate(page);
91 result = 0;
92
93io_error:
94 kunmap(page);
95 unlock_page(page);
96 return result;
97}
98
99/*
100 * We are called with the page locked and we unlock it when done.
101 */
102static int
103smb_readpage(struct file *file, struct page *page)
104{
105 int error;
106 struct dentry *dentry = file->f_path.dentry;
107
108 page_cache_get(page);
109 error = smb_readpage_sync(dentry, page);
110 page_cache_release(page);
111 return error;
112}
113
114/*
115 * Write a page synchronously.
116 * Offset is the data offset within the page.
117 */
118static int
119smb_writepage_sync(struct inode *inode, struct page *page,
120 unsigned long pageoffset, unsigned int count)
121{
122 loff_t offset;
123 char *buffer = kmap(page) + pageoffset;
124 struct smb_sb_info *server = server_from_inode(inode);
125 unsigned int wsize = smb_get_wsize(server);
126 int ret = 0;
127
128 offset = ((loff_t)page->index << PAGE_CACHE_SHIFT) + pageoffset;
129 VERBOSE("file ino=%ld, fileid=%d, count=%d@%Ld, wsize=%d\n",
130 inode->i_ino, SMB_I(inode)->fileid, count, offset, wsize);
131
132 do {
133 int write_ret;
134
135 if (count < wsize)
136 wsize = count;
137
138 write_ret = server->ops->write(inode, offset, wsize, buffer);
139 if (write_ret < 0) {
140 PARANOIA("failed write, wsize=%d, write_ret=%d\n",
141 wsize, write_ret);
142 ret = write_ret;
143 break;
144 }
145 /* N.B. what if result < wsize?? */
146#ifdef SMBFS_PARANOIA
147 if (write_ret < wsize)
148 PARANOIA("short write, wsize=%d, write_ret=%d\n",
149 wsize, write_ret);
150#endif
151 buffer += wsize;
152 offset += wsize;
153 count -= wsize;
154 /*
155 * Update the inode now rather than waiting for a refresh.
156 */
157 inode->i_mtime = inode->i_atime = current_fs_time(inode->i_sb);
158 SMB_I(inode)->flags |= SMB_F_LOCALWRITE;
159 if (offset > inode->i_size)
160 inode->i_size = offset;
161 } while (count);
162
163 kunmap(page);
164 return ret;
165}
166
167/*
168 * Write a page to the server. This will be used for NFS swapping only
169 * (for now), and we currently do this synchronously only.
170 *
171 * We are called with the page locked and we unlock it when done.
172 */
173static int
174smb_writepage(struct page *page, struct writeback_control *wbc)
175{
176 struct address_space *mapping = page->mapping;
177 struct inode *inode;
178 unsigned long end_index;
179 unsigned offset = PAGE_CACHE_SIZE;
180 int err;
181
182 BUG_ON(!mapping);
183 inode = mapping->host;
184 BUG_ON(!inode);
185
186 end_index = inode->i_size >> PAGE_CACHE_SHIFT;
187
188 /* easy case */
189 if (page->index < end_index)
190 goto do_it;
191 /* things got complicated... */
192 offset = inode->i_size & (PAGE_CACHE_SIZE-1);
193 /* OK, are we completely out? */
194 if (page->index >= end_index+1 || !offset)
195 return 0; /* truncated - don't care */
196do_it:
197 page_cache_get(page);
198 err = smb_writepage_sync(inode, page, 0, offset);
199 SetPageUptodate(page);
200 unlock_page(page);
201 page_cache_release(page);
202 return err;
203}
204
205static int
206smb_updatepage(struct file *file, struct page *page, unsigned long offset,
207 unsigned int count)
208{
209 struct dentry *dentry = file->f_path.dentry;
210
211 DEBUG1("(%s/%s %d@%lld)\n", DENTRY_PATH(dentry), count,
212 ((unsigned long long)page->index << PAGE_CACHE_SHIFT) + offset);
213
214 return smb_writepage_sync(dentry->d_inode, page, offset, count);
215}
216
217static ssize_t
218smb_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
219 unsigned long nr_segs, loff_t pos)
220{
221 struct file * file = iocb->ki_filp;
222 struct dentry * dentry = file->f_path.dentry;
223 ssize_t status;
224
225 VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry),
226 (unsigned long) iocb->ki_left, (unsigned long) pos);
227
228 status = smb_revalidate_inode(dentry);
229 if (status) {
230 PARANOIA("%s/%s validation failed, error=%Zd\n",
231 DENTRY_PATH(dentry), status);
232 goto out;
233 }
234
235 VERBOSE("before read, size=%ld, flags=%x, atime=%ld\n",
236 (long)dentry->d_inode->i_size,
237 dentry->d_inode->i_flags, dentry->d_inode->i_atime.tv_sec);
238
239 status = generic_file_aio_read(iocb, iov, nr_segs, pos);
240out:
241 return status;
242}
243
244static int
245smb_file_mmap(struct file * file, struct vm_area_struct * vma)
246{
247 struct dentry * dentry = file->f_path.dentry;
248 int status;
249
250 VERBOSE("file %s/%s, address %lu - %lu\n",
251 DENTRY_PATH(dentry), vma->vm_start, vma->vm_end);
252
253 status = smb_revalidate_inode(dentry);
254 if (status) {
255 PARANOIA("%s/%s validation failed, error=%d\n",
256 DENTRY_PATH(dentry), status);
257 goto out;
258 }
259 status = generic_file_mmap(file, vma);
260out:
261 return status;
262}
263
264static ssize_t
265smb_file_splice_read(struct file *file, loff_t *ppos,
266 struct pipe_inode_info *pipe, size_t count,
267 unsigned int flags)
268{
269 struct dentry *dentry = file->f_path.dentry;
270 ssize_t status;
271
272 VERBOSE("file %s/%s, pos=%Ld, count=%lu\n",
273 DENTRY_PATH(dentry), *ppos, count);
274
275 status = smb_revalidate_inode(dentry);
276 if (status) {
277 PARANOIA("%s/%s validation failed, error=%Zd\n",
278 DENTRY_PATH(dentry), status);
279 goto out;
280 }
281 status = generic_file_splice_read(file, ppos, pipe, count, flags);
282out:
283 return status;
284}
285
286/*
287 * This does the "real" work of the write. The generic routine has
288 * allocated the page, locked it, done all the page alignment stuff
289 * calculations etc. Now we should just copy the data from user
290 * space and write it back to the real medium..
291 *
292 * If the writer ends up delaying the write, the writer needs to
293 * increment the page use counts until he is done with the page.
294 */
295static int smb_write_begin(struct file *file, struct address_space *mapping,
296 loff_t pos, unsigned len, unsigned flags,
297 struct page **pagep, void **fsdata)
298{
299 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
300 *pagep = grab_cache_page_write_begin(mapping, index, flags);
301 if (!*pagep)
302 return -ENOMEM;
303 return 0;
304}
305
306static int smb_write_end(struct file *file, struct address_space *mapping,
307 loff_t pos, unsigned len, unsigned copied,
308 struct page *page, void *fsdata)
309{
310 int status;
311 unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
312
313 lock_kernel();
314 status = smb_updatepage(file, page, offset, copied);
315 unlock_kernel();
316
317 if (!status) {
318 if (!PageUptodate(page) && copied == PAGE_CACHE_SIZE)
319 SetPageUptodate(page);
320 status = copied;
321 }
322
323 unlock_page(page);
324 page_cache_release(page);
325
326 return status;
327}
328
329const struct address_space_operations smb_file_aops = {
330 .readpage = smb_readpage,
331 .writepage = smb_writepage,
332 .write_begin = smb_write_begin,
333 .write_end = smb_write_end,
334};
335
336/*
337 * Write to a file (through the page cache).
338 */
339static ssize_t
340smb_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
341 unsigned long nr_segs, loff_t pos)
342{
343 struct file * file = iocb->ki_filp;
344 struct dentry * dentry = file->f_path.dentry;
345 ssize_t result;
346
347 VERBOSE("file %s/%s, count=%lu@%lu\n",
348 DENTRY_PATH(dentry),
349 (unsigned long) iocb->ki_left, (unsigned long) pos);
350
351 result = smb_revalidate_inode(dentry);
352 if (result) {
353 PARANOIA("%s/%s validation failed, error=%Zd\n",
354 DENTRY_PATH(dentry), result);
355 goto out;
356 }
357
358 result = smb_open(dentry, SMB_O_WRONLY);
359 if (result)
360 goto out;
361
362 if (iocb->ki_left > 0) {
363 result = generic_file_aio_write(iocb, iov, nr_segs, pos);
364 VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n",
365 (long) file->f_pos, (long) dentry->d_inode->i_size,
366 dentry->d_inode->i_mtime.tv_sec,
367 dentry->d_inode->i_atime.tv_sec);
368 }
369out:
370 return result;
371}
372
373static int
374smb_file_open(struct inode *inode, struct file * file)
375{
376 int result;
377 struct dentry *dentry = file->f_path.dentry;
378 int smb_mode = (file->f_mode & O_ACCMODE) - 1;
379
380 lock_kernel();
381 result = smb_open(dentry, smb_mode);
382 if (result)
383 goto out;
384 SMB_I(inode)->openers++;
385out:
386 unlock_kernel();
387 return result;
388}
389
390static int
391smb_file_release(struct inode *inode, struct file * file)
392{
393 lock_kernel();
394 if (!--SMB_I(inode)->openers) {
395 /* We must flush any dirty pages now as we won't be able to
396 write anything after close. mmap can trigger this.
397 "openers" should perhaps include mmap'ers ... */
398 filemap_write_and_wait(inode->i_mapping);
399 smb_close(inode);
400 }
401 unlock_kernel();
402 return 0;
403}
404
405/*
406 * Check whether the required access is compatible with
407 * an inode's permission. SMB doesn't recognize superuser
408 * privileges, so we need our own check for this.
409 */
410static int
411smb_file_permission(struct inode *inode, int mask)
412{
413 int mode = inode->i_mode;
414 int error = 0;
415
416 VERBOSE("mode=%x, mask=%x\n", mode, mask);
417
418 /* Look at user permissions */
419 mode >>= 6;
420 if (mask & ~mode & (MAY_READ | MAY_WRITE | MAY_EXEC))
421 error = -EACCES;
422 return error;
423}
424
425static loff_t smb_remote_llseek(struct file *file, loff_t offset, int origin)
426{
427 loff_t ret;
428 lock_kernel();
429 ret = generic_file_llseek_unlocked(file, offset, origin);
430 unlock_kernel();
431 return ret;
432}
433
434const struct file_operations smb_file_operations =
435{
436 .llseek = smb_remote_llseek,
437 .read = do_sync_read,
438 .aio_read = smb_file_aio_read,
439 .write = do_sync_write,
440 .aio_write = smb_file_aio_write,
441 .unlocked_ioctl = smb_ioctl,
442 .mmap = smb_file_mmap,
443 .open = smb_file_open,
444 .release = smb_file_release,
445 .fsync = smb_fsync,
446 .splice_read = smb_file_splice_read,
447};
448
449const struct inode_operations smb_file_inode_operations =
450{
451 .permission = smb_file_permission,
452 .getattr = smb_getattr,
453 .setattr = smb_notify_change,
454};
diff --git a/fs/smbfs/getopt.c b/fs/smbfs/getopt.c
deleted file mode 100644
index 7ae0f5273ab1..000000000000
--- a/fs/smbfs/getopt.c
+++ /dev/null
@@ -1,64 +0,0 @@
1/*
2 * getopt.c
3 */
4
5#include <linux/kernel.h>
6#include <linux/string.h>
7#include <linux/net.h>
8
9#include "getopt.h"
10
11/**
12 * smb_getopt - option parser
13 * @caller: name of the caller, for error messages
14 * @options: the options string
15 * @opts: an array of &struct option entries controlling parser operations
16 * @optopt: output; will contain the current option
17 * @optarg: output; will contain the value (if one exists)
18 * @flag: output; may be NULL; should point to a long for or'ing flags
19 * @value: output; may be NULL; will be overwritten with the integer value
20 * of the current argument.
21 *
22 * Helper to parse options on the format used by mount ("a=b,c=d,e,f").
23 * Returns opts->val if a matching entry in the 'opts' array is found,
24 * 0 when no more tokens are found, -1 if an error is encountered.
25 */
26int smb_getopt(char *caller, char **options, struct option *opts,
27 char **optopt, char **optarg, unsigned long *flag,
28 unsigned long *value)
29{
30 char *token;
31 char *val;
32 int i;
33
34 do {
35 if ((token = strsep(options, ",")) == NULL)
36 return 0;
37 } while (*token == '\0');
38 *optopt = token;
39
40 *optarg = NULL;
41 if ((val = strchr (token, '=')) != NULL) {
42 *val++ = 0;
43 if (value)
44 *value = simple_strtoul(val, NULL, 0);
45 *optarg = val;
46 }
47
48 for (i = 0; opts[i].name != NULL; i++) {
49 if (!strcmp(opts[i].name, token)) {
50 if (!opts[i].flag && (!val || !*val)) {
51 printk("%s: the %s option requires an argument\n",
52 caller, token);
53 return -1;
54 }
55
56 if (flag && opts[i].flag)
57 *flag |= opts[i].flag;
58
59 return opts[i].val;
60 }
61 }
62 printk("%s: Unrecognized mount option %s\n", caller, token);
63 return -1;
64}
diff --git a/fs/smbfs/getopt.h b/fs/smbfs/getopt.h
deleted file mode 100644
index 146219ac7c46..000000000000
--- a/fs/smbfs/getopt.h
+++ /dev/null
@@ -1,14 +0,0 @@
1#ifndef _LINUX_GETOPT_H
2#define _LINUX_GETOPT_H
3
4struct option {
5 const char *name;
6 unsigned long flag;
7 int val;
8};
9
10extern int smb_getopt(char *caller, char **options, struct option *opts,
11 char **optopt, char **optarg, unsigned long *flag,
12 unsigned long *value);
13
14#endif /* _LINUX_GETOPT_H */
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
deleted file mode 100644
index f6e9ee59757e..000000000000
--- a/fs/smbfs/inode.c
+++ /dev/null
@@ -1,843 +0,0 @@
1/*
2 * inode.c
3 *
4 * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
5 * Copyright (C) 1997 by Volker Lendecke
6 *
7 * Please add a note about your changes to smbfs in the ChangeLog file.
8 */
9
10#include <linux/module.h>
11#include <linux/time.h>
12#include <linux/kernel.h>
13#include <linux/mm.h>
14#include <linux/string.h>
15#include <linux/stat.h>
16#include <linux/errno.h>
17#include <linux/slab.h>
18#include <linux/init.h>
19#include <linux/file.h>
20#include <linux/dcache.h>
21#include <linux/smp_lock.h>
22#include <linux/nls.h>
23#include <linux/seq_file.h>
24#include <linux/mount.h>
25#include <linux/net.h>
26#include <linux/vfs.h>
27#include <linux/highuid.h>
28#include <linux/sched.h>
29#include <linux/smb_fs.h>
30#include <linux/smbno.h>
31#include <linux/smb_mount.h>
32
33#include <asm/system.h>
34#include <asm/uaccess.h>
35
36#include "smb_debug.h"
37#include "getopt.h"
38#include "proto.h"
39
40/* Always pick a default string */
41#ifdef CONFIG_SMB_NLS_REMOTE
42#define SMB_NLS_REMOTE CONFIG_SMB_NLS_REMOTE
43#else
44#define SMB_NLS_REMOTE ""
45#endif
46
47#define SMB_TTL_DEFAULT 1000
48
49static void smb_evict_inode(struct inode *);
50static void smb_put_super(struct super_block *);
51static int smb_statfs(struct dentry *, struct kstatfs *);
52static int smb_show_options(struct seq_file *, struct vfsmount *);
53
54static struct kmem_cache *smb_inode_cachep;
55
56static struct inode *smb_alloc_inode(struct super_block *sb)
57{
58 struct smb_inode_info *ei;
59 ei = (struct smb_inode_info *)kmem_cache_alloc(smb_inode_cachep, GFP_KERNEL);
60 if (!ei)
61 return NULL;
62 return &ei->vfs_inode;
63}
64
65static void smb_destroy_inode(struct inode *inode)
66{
67 kmem_cache_free(smb_inode_cachep, SMB_I(inode));
68}
69
70static void init_once(void *foo)
71{
72 struct smb_inode_info *ei = (struct smb_inode_info *) foo;
73
74 inode_init_once(&ei->vfs_inode);
75}
76
77static int init_inodecache(void)
78{
79 smb_inode_cachep = kmem_cache_create("smb_inode_cache",
80 sizeof(struct smb_inode_info),
81 0, (SLAB_RECLAIM_ACCOUNT|
82 SLAB_MEM_SPREAD),
83 init_once);
84 if (smb_inode_cachep == NULL)
85 return -ENOMEM;
86 return 0;
87}
88
89static void destroy_inodecache(void)
90{
91 kmem_cache_destroy(smb_inode_cachep);
92}
93
94static int smb_remount(struct super_block *sb, int *flags, char *data)
95{
96 *flags |= MS_NODIRATIME;
97 return 0;
98}
99
100static const struct super_operations smb_sops =
101{
102 .alloc_inode = smb_alloc_inode,
103 .destroy_inode = smb_destroy_inode,
104 .drop_inode = generic_delete_inode,
105 .evict_inode = smb_evict_inode,
106 .put_super = smb_put_super,
107 .statfs = smb_statfs,
108 .show_options = smb_show_options,
109 .remount_fs = smb_remount,
110};
111
112
113/* We are always generating a new inode here */
114struct inode *
115smb_iget(struct super_block *sb, struct smb_fattr *fattr)
116{
117 struct smb_sb_info *server = SMB_SB(sb);
118 struct inode *result;
119
120 DEBUG1("smb_iget: %p\n", fattr);
121
122 result = new_inode(sb);
123 if (!result)
124 return result;
125 result->i_ino = fattr->f_ino;
126 SMB_I(result)->open = 0;
127 SMB_I(result)->fileid = 0;
128 SMB_I(result)->access = 0;
129 SMB_I(result)->flags = 0;
130 SMB_I(result)->closed = 0;
131 SMB_I(result)->openers = 0;
132 smb_set_inode_attr(result, fattr);
133 if (S_ISREG(result->i_mode)) {
134 result->i_op = &smb_file_inode_operations;
135 result->i_fop = &smb_file_operations;
136 result->i_data.a_ops = &smb_file_aops;
137 } else if (S_ISDIR(result->i_mode)) {
138 if (server->opt.capabilities & SMB_CAP_UNIX)
139 result->i_op = &smb_dir_inode_operations_unix;
140 else
141 result->i_op = &smb_dir_inode_operations;
142 result->i_fop = &smb_dir_operations;
143 } else if (S_ISLNK(result->i_mode)) {
144 result->i_op = &smb_link_inode_operations;
145 } else {
146 init_special_inode(result, result->i_mode, fattr->f_rdev);
147 }
148 insert_inode_hash(result);
149 return result;
150}
151
152/*
153 * Copy the inode data to a smb_fattr structure.
154 */
155void
156smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr)
157{
158 memset(fattr, 0, sizeof(struct smb_fattr));
159 fattr->f_mode = inode->i_mode;
160 fattr->f_nlink = inode->i_nlink;
161 fattr->f_ino = inode->i_ino;
162 fattr->f_uid = inode->i_uid;
163 fattr->f_gid = inode->i_gid;
164 fattr->f_size = inode->i_size;
165 fattr->f_mtime = inode->i_mtime;
166 fattr->f_ctime = inode->i_ctime;
167 fattr->f_atime = inode->i_atime;
168 fattr->f_blocks = inode->i_blocks;
169
170 fattr->attr = SMB_I(inode)->attr;
171 /*
172 * Keep the attributes in sync with the inode permissions.
173 */
174 if (fattr->f_mode & S_IWUSR)
175 fattr->attr &= ~aRONLY;
176 else
177 fattr->attr |= aRONLY;
178}
179
180/*
181 * Update the inode, possibly causing it to invalidate its pages if mtime/size
182 * is different from last time.
183 */
184void
185smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr)
186{
187 struct smb_inode_info *ei = SMB_I(inode);
188
189 /*
190 * A size change should have a different mtime, or same mtime
191 * but different size.
192 */
193 time_t last_time = inode->i_mtime.tv_sec;
194 loff_t last_sz = inode->i_size;
195
196 inode->i_mode = fattr->f_mode;
197 inode->i_nlink = fattr->f_nlink;
198 inode->i_uid = fattr->f_uid;
199 inode->i_gid = fattr->f_gid;
200 inode->i_ctime = fattr->f_ctime;
201 inode->i_blocks = fattr->f_blocks;
202 inode->i_size = fattr->f_size;
203 inode->i_mtime = fattr->f_mtime;
204 inode->i_atime = fattr->f_atime;
205 ei->attr = fattr->attr;
206
207 /*
208 * Update the "last time refreshed" field for revalidation.
209 */
210 ei->oldmtime = jiffies;
211
212 if (inode->i_mtime.tv_sec != last_time || inode->i_size != last_sz) {
213 VERBOSE("%ld changed, old=%ld, new=%ld, oz=%ld, nz=%ld\n",
214 inode->i_ino,
215 (long) last_time, (long) inode->i_mtime.tv_sec,
216 (long) last_sz, (long) inode->i_size);
217
218 if (!S_ISDIR(inode->i_mode))
219 invalidate_remote_inode(inode);
220 }
221}
222
223/*
224 * This is called if the connection has gone bad ...
225 * try to kill off all the current inodes.
226 */
227void
228smb_invalidate_inodes(struct smb_sb_info *server)
229{
230 VERBOSE("\n");
231 shrink_dcache_sb(SB_of(server));
232}
233
234/*
235 * This is called to update the inode attributes after
236 * we've made changes to a file or directory.
237 */
238static int
239smb_refresh_inode(struct dentry *dentry)
240{
241 struct inode *inode = dentry->d_inode;
242 int error;
243 struct smb_fattr fattr;
244
245 error = smb_proc_getattr(dentry, &fattr);
246 if (!error) {
247 smb_renew_times(dentry);
248 /*
249 * Check whether the type part of the mode changed,
250 * and don't update the attributes if it did.
251 *
252 * And don't dick with the root inode
253 */
254 if (inode->i_ino == 2)
255 return error;
256 if (S_ISLNK(inode->i_mode))
257 return error; /* VFS will deal with it */
258
259 if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT)) {
260 smb_set_inode_attr(inode, &fattr);
261 } else {
262 /*
263 * Big trouble! The inode has become a new object,
264 * so any operations attempted on it are invalid.
265 *
266 * To limit damage, mark the inode as bad so that
267 * subsequent lookup validations will fail.
268 */
269 PARANOIA("%s/%s changed mode, %07o to %07o\n",
270 DENTRY_PATH(dentry),
271 inode->i_mode, fattr.f_mode);
272
273 fattr.f_mode = inode->i_mode; /* save mode */
274 make_bad_inode(inode);
275 inode->i_mode = fattr.f_mode; /* restore mode */
276 /*
277 * No need to worry about unhashing the dentry: the
278 * lookup validation will see that the inode is bad.
279 * But we do want to invalidate the caches ...
280 */
281 if (!S_ISDIR(inode->i_mode))
282 invalidate_remote_inode(inode);
283 else
284 smb_invalid_dir_cache(inode);
285 error = -EIO;
286 }
287 }
288 return error;
289}
290
291/*
292 * This is called when we want to check whether the inode
293 * has changed on the server. If it has changed, we must
294 * invalidate our local caches.
295 */
296int
297smb_revalidate_inode(struct dentry *dentry)
298{
299 struct smb_sb_info *s = server_from_dentry(dentry);
300 struct inode *inode = dentry->d_inode;
301 int error = 0;
302
303 DEBUG1("smb_revalidate_inode\n");
304 lock_kernel();
305
306 /*
307 * Check whether we've recently refreshed the inode.
308 */
309 if (time_before(jiffies, SMB_I(inode)->oldmtime + SMB_MAX_AGE(s))) {
310 VERBOSE("up-to-date, ino=%ld, jiffies=%lu, oldtime=%lu\n",
311 inode->i_ino, jiffies, SMB_I(inode)->oldmtime);
312 goto out;
313 }
314
315 error = smb_refresh_inode(dentry);
316out:
317 unlock_kernel();
318 return error;
319}
320
321/*
322 * This routine is called when i_nlink == 0 and i_count goes to 0.
323 * All blocking cleanup operations need to go here to avoid races.
324 */
325static void
326smb_evict_inode(struct inode *ino)
327{
328 DEBUG1("ino=%ld\n", ino->i_ino);
329 truncate_inode_pages(&ino->i_data, 0);
330 end_writeback(ino);
331 lock_kernel();
332 if (smb_close(ino))
333 PARANOIA("could not close inode %ld\n", ino->i_ino);
334 unlock_kernel();
335}
336
337static struct option opts[] = {
338 { "version", 0, 'v' },
339 { "win95", SMB_MOUNT_WIN95, 1 },
340 { "oldattr", SMB_MOUNT_OLDATTR, 1 },
341 { "dirattr", SMB_MOUNT_DIRATTR, 1 },
342 { "case", SMB_MOUNT_CASE, 1 },
343 { "uid", 0, 'u' },
344 { "gid", 0, 'g' },
345 { "file_mode", 0, 'f' },
346 { "dir_mode", 0, 'd' },
347 { "iocharset", 0, 'i' },
348 { "codepage", 0, 'c' },
349 { "ttl", 0, 't' },
350 { NULL, 0, 0}
351};
352
353static int
354parse_options(struct smb_mount_data_kernel *mnt, char *options)
355{
356 int c;
357 unsigned long flags;
358 unsigned long value;
359 char *optarg;
360 char *optopt;
361
362 flags = 0;
363 while ( (c = smb_getopt("smbfs", &options, opts,
364 &optopt, &optarg, &flags, &value)) > 0) {
365
366 VERBOSE("'%s' -> '%s'\n", optopt, optarg ? optarg : "<none>");
367 switch (c) {
368 case 1:
369 /* got a "flag" option */
370 break;
371 case 'v':
372 if (value != SMB_MOUNT_VERSION) {
373 printk ("smbfs: Bad mount version %ld, expected %d\n",
374 value, SMB_MOUNT_VERSION);
375 return 0;
376 }
377 mnt->version = value;
378 break;
379 case 'u':
380 mnt->uid = value;
381 flags |= SMB_MOUNT_UID;
382 break;
383 case 'g':
384 mnt->gid = value;
385 flags |= SMB_MOUNT_GID;
386 break;
387 case 'f':
388 mnt->file_mode = (value & S_IRWXUGO) | S_IFREG;
389 flags |= SMB_MOUNT_FMODE;
390 break;
391 case 'd':
392 mnt->dir_mode = (value & S_IRWXUGO) | S_IFDIR;
393 flags |= SMB_MOUNT_DMODE;
394 break;
395 case 'i':
396 strlcpy(mnt->codepage.local_name, optarg,
397 SMB_NLS_MAXNAMELEN);
398 break;
399 case 'c':
400 strlcpy(mnt->codepage.remote_name, optarg,
401 SMB_NLS_MAXNAMELEN);
402 break;
403 case 't':
404 mnt->ttl = value;
405 break;
406 default:
407 printk ("smbfs: Unrecognized mount option %s\n",
408 optopt);
409 return -1;
410 }
411 }
412 mnt->flags = flags;
413 return c;
414}
415
416/*
417 * smb_show_options() is for displaying mount options in /proc/mounts.
418 * It tries to avoid showing settings that were not changed from their
419 * defaults.
420 */
421static int
422smb_show_options(struct seq_file *s, struct vfsmount *m)
423{
424 struct smb_mount_data_kernel *mnt = SMB_SB(m->mnt_sb)->mnt;
425 int i;
426
427 for (i = 0; opts[i].name != NULL; i++)
428 if (mnt->flags & opts[i].flag)
429 seq_printf(s, ",%s", opts[i].name);
430
431 if (mnt->flags & SMB_MOUNT_UID)
432 seq_printf(s, ",uid=%d", mnt->uid);
433 if (mnt->flags & SMB_MOUNT_GID)
434 seq_printf(s, ",gid=%d", mnt->gid);
435 if (mnt->mounted_uid != 0)
436 seq_printf(s, ",mounted_uid=%d", mnt->mounted_uid);
437
438 /*
439 * Defaults for file_mode and dir_mode are unknown to us; they
440 * depend on the current umask of the user doing the mount.
441 */
442 if (mnt->flags & SMB_MOUNT_FMODE)
443 seq_printf(s, ",file_mode=%04o", mnt->file_mode & S_IRWXUGO);
444 if (mnt->flags & SMB_MOUNT_DMODE)
445 seq_printf(s, ",dir_mode=%04o", mnt->dir_mode & S_IRWXUGO);
446
447 if (strcmp(mnt->codepage.local_name, CONFIG_NLS_DEFAULT))
448 seq_printf(s, ",iocharset=%s", mnt->codepage.local_name);
449 if (strcmp(mnt->codepage.remote_name, SMB_NLS_REMOTE))
450 seq_printf(s, ",codepage=%s", mnt->codepage.remote_name);
451
452 if (mnt->ttl != SMB_TTL_DEFAULT)
453 seq_printf(s, ",ttl=%d", mnt->ttl);
454
455 return 0;
456}
457
458static void
459smb_unload_nls(struct smb_sb_info *server)
460{
461 unload_nls(server->remote_nls);
462 unload_nls(server->local_nls);
463}
464
465static void
466smb_put_super(struct super_block *sb)
467{
468 struct smb_sb_info *server = SMB_SB(sb);
469
470 lock_kernel();
471
472 smb_lock_server(server);
473 server->state = CONN_INVALID;
474 smbiod_unregister_server(server);
475
476 smb_close_socket(server);
477
478 if (server->conn_pid)
479 kill_pid(server->conn_pid, SIGTERM, 1);
480
481 bdi_destroy(&server->bdi);
482 kfree(server->ops);
483 smb_unload_nls(server);
484 sb->s_fs_info = NULL;
485 smb_unlock_server(server);
486 put_pid(server->conn_pid);
487 kfree(server);
488
489 unlock_kernel();
490}
491
492static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
493{
494 struct smb_sb_info *server;
495 struct smb_mount_data_kernel *mnt;
496 struct smb_mount_data *oldmnt;
497 struct inode *root_inode;
498 struct smb_fattr root;
499 int ver;
500 void *mem;
501 static int warn_count;
502
503 lock_kernel();
504
505 if (warn_count < 5) {
506 warn_count++;
507 printk(KERN_EMERG "smbfs is deprecated and will be removed"
508 " from the 2.6.27 kernel. Please migrate to cifs\n");
509 }
510
511 if (!raw_data)
512 goto out_no_data;
513
514 oldmnt = (struct smb_mount_data *) raw_data;
515 ver = oldmnt->version;
516 if (ver != SMB_MOUNT_OLDVERSION && cpu_to_be32(ver) != SMB_MOUNT_ASCII)
517 goto out_wrong_data;
518
519 sb->s_flags |= MS_NODIRATIME;
520 sb->s_blocksize = 1024; /* Eh... Is this correct? */
521 sb->s_blocksize_bits = 10;
522 sb->s_magic = SMB_SUPER_MAGIC;
523 sb->s_op = &smb_sops;
524 sb->s_time_gran = 100;
525
526 server = kzalloc(sizeof(struct smb_sb_info), GFP_KERNEL);
527 if (!server)
528 goto out_no_server;
529 sb->s_fs_info = server;
530
531 if (bdi_setup_and_register(&server->bdi, "smbfs", BDI_CAP_MAP_COPY))
532 goto out_bdi;
533
534 sb->s_bdi = &server->bdi;
535
536 server->super_block = sb;
537 server->mnt = NULL;
538 server->sock_file = NULL;
539 init_waitqueue_head(&server->conn_wq);
540 init_MUTEX(&server->sem);
541 INIT_LIST_HEAD(&server->entry);
542 INIT_LIST_HEAD(&server->xmitq);
543 INIT_LIST_HEAD(&server->recvq);
544 server->conn_error = 0;
545 server->conn_pid = NULL;
546 server->state = CONN_INVALID; /* no connection yet */
547 server->generation = 0;
548
549 /* Allocate the global temp buffer and some superblock helper structs */
550 /* FIXME: move these to the smb_sb_info struct */
551 VERBOSE("alloc chunk = %lu\n", sizeof(struct smb_ops) +
552 sizeof(struct smb_mount_data_kernel));
553 mem = kmalloc(sizeof(struct smb_ops) +
554 sizeof(struct smb_mount_data_kernel), GFP_KERNEL);
555 if (!mem)
556 goto out_no_mem;
557
558 server->ops = mem;
559 smb_install_null_ops(server->ops);
560 server->mnt = mem + sizeof(struct smb_ops);
561
562 /* Setup NLS stuff */
563 server->remote_nls = NULL;
564 server->local_nls = NULL;
565
566 mnt = server->mnt;
567
568 memset(mnt, 0, sizeof(struct smb_mount_data_kernel));
569 strlcpy(mnt->codepage.local_name, CONFIG_NLS_DEFAULT,
570 SMB_NLS_MAXNAMELEN);
571 strlcpy(mnt->codepage.remote_name, SMB_NLS_REMOTE,
572 SMB_NLS_MAXNAMELEN);
573
574 mnt->ttl = SMB_TTL_DEFAULT;
575 if (ver == SMB_MOUNT_OLDVERSION) {
576 mnt->version = oldmnt->version;
577
578 SET_UID(mnt->uid, oldmnt->uid);
579 SET_GID(mnt->gid, oldmnt->gid);
580
581 mnt->file_mode = (oldmnt->file_mode & S_IRWXUGO) | S_IFREG;
582 mnt->dir_mode = (oldmnt->dir_mode & S_IRWXUGO) | S_IFDIR;
583
584 mnt->flags = (oldmnt->file_mode >> 9) | SMB_MOUNT_UID |
585 SMB_MOUNT_GID | SMB_MOUNT_FMODE | SMB_MOUNT_DMODE;
586 } else {
587 mnt->file_mode = S_IRWXU | S_IRGRP | S_IXGRP |
588 S_IROTH | S_IXOTH | S_IFREG;
589 mnt->dir_mode = S_IRWXU | S_IRGRP | S_IXGRP |
590 S_IROTH | S_IXOTH | S_IFDIR;
591 if (parse_options(mnt, raw_data))
592 goto out_bad_option;
593 }
594 mnt->mounted_uid = current_uid();
595 smb_setcodepage(server, &mnt->codepage);
596
597 /*
598 * Display the enabled options
599 * Note: smb_proc_getattr uses these in 2.4 (but was changed in 2.2)
600 */
601 if (mnt->flags & SMB_MOUNT_OLDATTR)
602 printk("SMBFS: Using core getattr (Win 95 speedup)\n");
603 else if (mnt->flags & SMB_MOUNT_DIRATTR)
604 printk("SMBFS: Using dir ff getattr\n");
605
606 if (smbiod_register_server(server) < 0) {
607 printk(KERN_ERR "smbfs: failed to start smbiod\n");
608 goto out_no_smbiod;
609 }
610
611 /*
612 * Keep the super block locked while we get the root inode.
613 */
614 smb_init_root_dirent(server, &root, sb);
615 root_inode = smb_iget(sb, &root);
616 if (!root_inode)
617 goto out_no_root;
618
619 sb->s_root = d_alloc_root(root_inode);
620 if (!sb->s_root)
621 goto out_no_root;
622
623 smb_new_dentry(sb->s_root);
624
625 unlock_kernel();
626 return 0;
627
628out_no_root:
629 iput(root_inode);
630out_no_smbiod:
631 smb_unload_nls(server);
632out_bad_option:
633 kfree(mem);
634out_no_mem:
635 bdi_destroy(&server->bdi);
636out_bdi:
637 if (!server->mnt)
638 printk(KERN_ERR "smb_fill_super: allocation failure\n");
639 sb->s_fs_info = NULL;
640 kfree(server);
641 goto out_fail;
642out_wrong_data:
643 printk(KERN_ERR "smbfs: mount_data version %d is not supported\n", ver);
644 goto out_fail;
645out_no_data:
646 printk(KERN_ERR "smb_fill_super: missing data argument\n");
647out_fail:
648 unlock_kernel();
649 return -EINVAL;
650out_no_server:
651 printk(KERN_ERR "smb_fill_super: cannot allocate struct smb_sb_info\n");
652 unlock_kernel();
653 return -ENOMEM;
654}
655
656static int
657smb_statfs(struct dentry *dentry, struct kstatfs *buf)
658{
659 int result;
660
661 lock_kernel();
662
663 result = smb_proc_dskattr(dentry, buf);
664
665 unlock_kernel();
666
667 buf->f_type = SMB_SUPER_MAGIC;
668 buf->f_namelen = SMB_MAXPATHLEN;
669 return result;
670}
671
672int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
673{
674 int err = smb_revalidate_inode(dentry);
675 if (!err)
676 generic_fillattr(dentry->d_inode, stat);
677 return err;
678}
679
680int
681smb_notify_change(struct dentry *dentry, struct iattr *attr)
682{
683 struct inode *inode = dentry->d_inode;
684 struct smb_sb_info *server = server_from_dentry(dentry);
685 unsigned int mask = (S_IFREG | S_IFDIR | S_IRWXUGO);
686 int error, changed, refresh = 0;
687 struct smb_fattr fattr;
688
689 lock_kernel();
690
691 error = smb_revalidate_inode(dentry);
692 if (error)
693 goto out;
694
695 if ((error = inode_change_ok(inode, attr)) < 0)
696 goto out;
697
698 error = -EPERM;
699 if ((attr->ia_valid & ATTR_UID) && (attr->ia_uid != server->mnt->uid))
700 goto out;
701
702 if ((attr->ia_valid & ATTR_GID) && (attr->ia_uid != server->mnt->gid))
703 goto out;
704
705 if ((attr->ia_valid & ATTR_MODE) && (attr->ia_mode & ~mask))
706 goto out;
707
708 if ((attr->ia_valid & ATTR_SIZE) != 0) {
709 VERBOSE("changing %s/%s, old size=%ld, new size=%ld\n",
710 DENTRY_PATH(dentry),
711 (long) inode->i_size, (long) attr->ia_size);
712
713 filemap_write_and_wait(inode->i_mapping);
714
715 error = smb_open(dentry, O_WRONLY);
716 if (error)
717 goto out;
718 error = server->ops->truncate(inode, attr->ia_size);
719 if (error)
720 goto out;
721 truncate_setsize(inode, attr->ia_size);
722 refresh = 1;
723 }
724
725 if (server->opt.capabilities & SMB_CAP_UNIX) {
726 /* For now we don't want to set the size with setattr_unix */
727 attr->ia_valid &= ~ATTR_SIZE;
728 /* FIXME: only call if we actually want to set something? */
729 error = smb_proc_setattr_unix(dentry, attr, 0, 0);
730 if (!error)
731 refresh = 1;
732
733 goto out;
734 }
735
736 /*
737 * Initialize the fattr and check for changed fields.
738 * Note: CTIME under SMB is creation time rather than
739 * change time, so we don't attempt to change it.
740 */
741 smb_get_inode_attr(inode, &fattr);
742
743 changed = 0;
744 if ((attr->ia_valid & ATTR_MTIME) != 0) {
745 fattr.f_mtime = attr->ia_mtime;
746 changed = 1;
747 }
748 if ((attr->ia_valid & ATTR_ATIME) != 0) {
749 fattr.f_atime = attr->ia_atime;
750 /* Earlier protocols don't have an access time */
751 if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
752 changed = 1;
753 }
754 if (changed) {
755 error = smb_proc_settime(dentry, &fattr);
756 if (error)
757 goto out;
758 refresh = 1;
759 }
760
761 /*
762 * Check for mode changes ... we're extremely limited in
763 * what can be set for SMB servers: just the read-only bit.
764 */
765 if ((attr->ia_valid & ATTR_MODE) != 0) {
766 VERBOSE("%s/%s mode change, old=%x, new=%x\n",
767 DENTRY_PATH(dentry), fattr.f_mode, attr->ia_mode);
768 changed = 0;
769 if (attr->ia_mode & S_IWUSR) {
770 if (fattr.attr & aRONLY) {
771 fattr.attr &= ~aRONLY;
772 changed = 1;
773 }
774 } else {
775 if (!(fattr.attr & aRONLY)) {
776 fattr.attr |= aRONLY;
777 changed = 1;
778 }
779 }
780 if (changed) {
781 error = smb_proc_setattr(dentry, &fattr);
782 if (error)
783 goto out;
784 refresh = 1;
785 }
786 }
787 error = 0;
788
789out:
790 if (refresh)
791 smb_refresh_inode(dentry);
792 unlock_kernel();
793 return error;
794}
795
796static int smb_get_sb(struct file_system_type *fs_type,
797 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
798{
799 return get_sb_nodev(fs_type, flags, data, smb_fill_super, mnt);
800}
801
802static struct file_system_type smb_fs_type = {
803 .owner = THIS_MODULE,
804 .name = "smbfs",
805 .get_sb = smb_get_sb,
806 .kill_sb = kill_anon_super,
807 .fs_flags = FS_BINARY_MOUNTDATA,
808};
809
810static int __init init_smb_fs(void)
811{
812 int err;
813 DEBUG1("registering ...\n");
814
815 err = init_inodecache();
816 if (err)
817 goto out_inode;
818 err = smb_init_request_cache();
819 if (err)
820 goto out_request;
821 err = register_filesystem(&smb_fs_type);
822 if (err)
823 goto out;
824 return 0;
825out:
826 smb_destroy_request_cache();
827out_request:
828 destroy_inodecache();
829out_inode:
830 return err;
831}
832
833static void __exit exit_smb_fs(void)
834{
835 DEBUG1("unregistering ...\n");
836 unregister_filesystem(&smb_fs_type);
837 smb_destroy_request_cache();
838 destroy_inodecache();
839}
840
841module_init(init_smb_fs)
842module_exit(exit_smb_fs)
843MODULE_LICENSE("GPL");
diff --git a/fs/smbfs/ioctl.c b/fs/smbfs/ioctl.c
deleted file mode 100644
index 07215312ad39..000000000000
--- a/fs/smbfs/ioctl.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * ioctl.c
3 *
4 * Copyright (C) 1995, 1996 by Volker Lendecke
5 * Copyright (C) 1997 by Volker Lendecke
6 *
7 * Please add a note about your changes to smbfs in the ChangeLog file.
8 */
9
10#include <linux/errno.h>
11#include <linux/fs.h>
12#include <linux/ioctl.h>
13#include <linux/time.h>
14#include <linux/mm.h>
15#include <linux/highuid.h>
16#include <linux/smp_lock.h>
17#include <linux/net.h>
18
19#include <linux/smb_fs.h>
20#include <linux/smb_mount.h>
21
22#include <asm/uaccess.h>
23
24#include "proto.h"
25
26long
27smb_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
28{
29 struct smb_sb_info *server = server_from_inode(filp->f_path.dentry->d_inode);
30 struct smb_conn_opt opt;
31 int result = -EINVAL;
32
33 lock_kernel();
34 switch (cmd) {
35 uid16_t uid16;
36 uid_t uid32;
37 case SMB_IOC_GETMOUNTUID:
38 SET_UID(uid16, server->mnt->mounted_uid);
39 result = put_user(uid16, (uid16_t __user *) arg);
40 break;
41 case SMB_IOC_GETMOUNTUID32:
42 SET_UID(uid32, server->mnt->mounted_uid);
43 result = put_user(uid32, (uid_t __user *) arg);
44 break;
45
46 case SMB_IOC_NEWCONN:
47 /* arg is smb_conn_opt, or NULL if no connection was made */
48 if (!arg) {
49 result = 0;
50 smb_lock_server(server);
51 server->state = CONN_RETRIED;
52 printk(KERN_ERR "Connection attempt failed! [%d]\n",
53 server->conn_error);
54 smbiod_flush(server);
55 smb_unlock_server(server);
56 break;
57 }
58
59 result = -EFAULT;
60 if (!copy_from_user(&opt, (void __user *)arg, sizeof(opt)))
61 result = smb_newconn(server, &opt);
62 break;
63 default:
64 break;
65 }
66 unlock_kernel();
67
68 return result;
69}
diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c
deleted file mode 100644
index 3dcf638d4d3a..000000000000
--- a/fs/smbfs/proc.c
+++ /dev/null
@@ -1,3503 +0,0 @@
1/*
2 * proc.c
3 *
4 * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
5 * Copyright (C) 1997 by Volker Lendecke
6 *
7 * Please add a note about your changes to smbfs in the ChangeLog file.
8 */
9
10#include <linux/types.h>
11#include <linux/capability.h>
12#include <linux/errno.h>
13#include <linux/slab.h>
14#include <linux/fs.h>
15#include <linux/file.h>
16#include <linux/stat.h>
17#include <linux/fcntl.h>
18#include <linux/dcache.h>
19#include <linux/nls.h>
20#include <linux/smp_lock.h>
21#include <linux/net.h>
22#include <linux/vfs.h>
23#include <linux/smb_fs.h>
24#include <linux/smbno.h>
25#include <linux/smb_mount.h>
26
27#include <net/sock.h>
28
29#include <asm/string.h>
30#include <asm/div64.h>
31
32#include "smb_debug.h"
33#include "proto.h"
34#include "request.h"
35
36
37/* Features. Undefine if they cause problems, this should perhaps be a
38 config option. */
39#define SMBFS_POSIX_UNLINK 1
40
41/* Allow smb_retry to be interrupted. */
42#define SMB_RETRY_INTR
43
44#define SMB_VWV(packet) ((packet) + SMB_HEADER_LEN)
45#define SMB_CMD(packet) (*(packet+8))
46#define SMB_WCT(packet) (*(packet+SMB_HEADER_LEN - 1))
47
48#define SMB_DIRINFO_SIZE 43
49#define SMB_STATUS_SIZE 21
50
51#define SMB_ST_BLKSIZE (PAGE_SIZE)
52#define SMB_ST_BLKSHIFT (PAGE_SHIFT)
53
54static struct smb_ops smb_ops_core;
55static struct smb_ops smb_ops_os2;
56static struct smb_ops smb_ops_win95;
57static struct smb_ops smb_ops_winNT;
58static struct smb_ops smb_ops_unix;
59static struct smb_ops smb_ops_null;
60
61static void
62smb_init_dirent(struct smb_sb_info *server, struct smb_fattr *fattr);
63static void
64smb_finish_dirent(struct smb_sb_info *server, struct smb_fattr *fattr);
65static int
66smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir,
67 struct smb_fattr *fattr);
68static int
69smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,
70 struct smb_fattr *fattr);
71static int
72smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
73 u16 attr);
74static int
75smb_proc_setattr_ext(struct smb_sb_info *server,
76 struct inode *inode, struct smb_fattr *fattr);
77static int
78smb_proc_query_cifsunix(struct smb_sb_info *server);
79static void
80install_ops(struct smb_ops *dst, struct smb_ops *src);
81
82
83static void
84str_upper(char *name, int len)
85{
86 while (len--)
87 {
88 if (*name >= 'a' && *name <= 'z')
89 *name -= ('a' - 'A');
90 name++;
91 }
92}
93
94#if 0
95static void
96str_lower(char *name, int len)
97{
98 while (len--)
99 {
100 if (*name >= 'A' && *name <= 'Z')
101 *name += ('a' - 'A');
102 name++;
103 }
104}
105#endif
106
107/* reverse a string inline. This is used by the dircache walking routines */
108static void reverse_string(char *buf, int len)
109{
110 char c;
111 char *end = buf+len-1;
112
113 while(buf < end) {
114 c = *buf;
115 *(buf++) = *end;
116 *(end--) = c;
117 }
118}
119
120/* no conversion, just a wrapper for memcpy. */
121static int convert_memcpy(unsigned char *output, int olen,
122 const unsigned char *input, int ilen,
123 struct nls_table *nls_from,
124 struct nls_table *nls_to)
125{
126 if (olen < ilen)
127 return -ENAMETOOLONG;
128 memcpy(output, input, ilen);
129 return ilen;
130}
131
132static inline int write_char(unsigned char ch, char *output, int olen)
133{
134 if (olen < 4)
135 return -ENAMETOOLONG;
136 sprintf(output, ":x%02x", ch);
137 return 4;
138}
139
140static inline int write_unichar(wchar_t ch, char *output, int olen)
141{
142 if (olen < 5)
143 return -ENAMETOOLONG;
144 sprintf(output, ":%04x", ch);
145 return 5;
146}
147
148/* convert from one "codepage" to another (possibly being utf8). */
149static int convert_cp(unsigned char *output, int olen,
150 const unsigned char *input, int ilen,
151 struct nls_table *nls_from,
152 struct nls_table *nls_to)
153{
154 int len = 0;
155 int n;
156 wchar_t ch;
157
158 while (ilen > 0) {
159 /* convert by changing to unicode and back to the new cp */
160 n = nls_from->char2uni(input, ilen, &ch);
161 if (n == -EINVAL) {
162 ilen--;
163 n = write_char(*input++, output, olen);
164 if (n < 0)
165 goto fail;
166 output += n;
167 olen -= n;
168 len += n;
169 continue;
170 } else if (n < 0)
171 goto fail;
172 input += n;
173 ilen -= n;
174
175 n = nls_to->uni2char(ch, output, olen);
176 if (n == -EINVAL)
177 n = write_unichar(ch, output, olen);
178 if (n < 0)
179 goto fail;
180 output += n;
181 olen -= n;
182
183 len += n;
184 }
185 return len;
186fail:
187 return n;
188}
189
190/* ----------------------------------------------------------- */
191
192/*
193 * nls_unicode
194 *
195 * This encodes/decodes little endian unicode format
196 */
197
198static int uni2char(wchar_t uni, unsigned char *out, int boundlen)
199{
200 if (boundlen < 2)
201 return -EINVAL;
202 *out++ = uni & 0xff;
203 *out++ = uni >> 8;
204 return 2;
205}
206
207static int char2uni(const unsigned char *rawstring, int boundlen, wchar_t *uni)
208{
209 if (boundlen < 2)
210 return -EINVAL;
211 *uni = (rawstring[1] << 8) | rawstring[0];
212 return 2;
213}
214
215static struct nls_table unicode_table = {
216 .charset = "unicode",
217 .uni2char = uni2char,
218 .char2uni = char2uni,
219};
220
221/* ----------------------------------------------------------- */
222
223static int setcodepage(struct nls_table **p, char *name)
224{
225 struct nls_table *nls;
226
227 if (!name || !*name) {
228 nls = NULL;
229 } else if ( (nls = load_nls(name)) == NULL) {
230 printk (KERN_ERR "smbfs: failed to load nls '%s'\n", name);
231 return -EINVAL;
232 }
233
234 /* if already set, unload the previous one. */
235 if (*p && *p != &unicode_table)
236 unload_nls(*p);
237 *p = nls;
238
239 return 0;
240}
241
242/* Handles all changes to codepage settings. */
243int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp)
244{
245 int n = 0;
246
247 smb_lock_server(server);
248
249 /* Don't load any nls_* at all, if no remote is requested */
250 if (!*cp->remote_name)
251 goto out;
252
253 /* local */
254 n = setcodepage(&server->local_nls, cp->local_name);
255 if (n != 0)
256 goto out;
257
258 /* remote */
259 if (!strcmp(cp->remote_name, "unicode")) {
260 server->remote_nls = &unicode_table;
261 } else {
262 n = setcodepage(&server->remote_nls, cp->remote_name);
263 if (n != 0)
264 setcodepage(&server->local_nls, NULL);
265 }
266
267out:
268 if (server->local_nls != NULL && server->remote_nls != NULL)
269 server->ops->convert = convert_cp;
270 else
271 server->ops->convert = convert_memcpy;
272
273 smb_unlock_server(server);
274 return n;
275}
276
277
278/*****************************************************************************/
279/* */
280/* Encoding/Decoding section */
281/* */
282/*****************************************************************************/
283
284static __u8 *
285smb_encode_smb_length(__u8 * p, __u32 len)
286{
287 *p = 0;
288 *(p+1) = 0;
289 *(p+2) = (len & 0xFF00) >> 8;
290 *(p+3) = (len & 0xFF);
291 if (len > 0xFFFF)
292 {
293 *(p+1) = 1;
294 }
295 return p + 4;
296}
297
298/*
299 * smb_build_path: build the path to entry and name storing it in buf.
300 * The path returned will have the trailing '\0'.
301 */
302static int smb_build_path(struct smb_sb_info *server, unsigned char *buf,
303 int maxlen,
304 struct dentry *entry, struct qstr *name)
305{
306 unsigned char *path = buf;
307 int len;
308 int unicode = (server->mnt->flags & SMB_MOUNT_UNICODE) != 0;
309
310 if (maxlen < (2<<unicode))
311 return -ENAMETOOLONG;
312
313 if (maxlen > SMB_MAXPATHLEN + 1)
314 maxlen = SMB_MAXPATHLEN + 1;
315
316 if (entry == NULL)
317 goto test_name_and_out;
318
319 /*
320 * If IS_ROOT, we have to do no walking at all.
321 */
322 if (IS_ROOT(entry) && !name) {
323 *path++ = '\\';
324 if (unicode) *path++ = '\0';
325 *path++ = '\0';
326 if (unicode) *path++ = '\0';
327 return path-buf;
328 }
329
330 /*
331 * Build the path string walking the tree backward from end to ROOT
332 * and store it in reversed order [see reverse_string()]
333 */
334 dget(entry);
335 while (!IS_ROOT(entry)) {
336 struct dentry *parent;
337
338 if (maxlen < (3<<unicode)) {
339 dput(entry);
340 return -ENAMETOOLONG;
341 }
342
343 spin_lock(&entry->d_lock);
344 len = server->ops->convert(path, maxlen-2,
345 entry->d_name.name, entry->d_name.len,
346 server->local_nls, server->remote_nls);
347 if (len < 0) {
348 spin_unlock(&entry->d_lock);
349 dput(entry);
350 return len;
351 }
352 reverse_string(path, len);
353 path += len;
354 if (unicode) {
355 /* Note: reverse order */
356 *path++ = '\0';
357 maxlen--;
358 }
359 *path++ = '\\';
360 maxlen -= len+1;
361 spin_unlock(&entry->d_lock);
362
363 parent = dget_parent(entry);
364 dput(entry);
365 entry = parent;
366 }
367 dput(entry);
368 reverse_string(buf, path-buf);
369
370 /* maxlen has space for at least one char */
371test_name_and_out:
372 if (name) {
373 if (maxlen < (3<<unicode))
374 return -ENAMETOOLONG;
375 *path++ = '\\';
376 if (unicode) {
377 *path++ = '\0';
378 maxlen--;
379 }
380 len = server->ops->convert(path, maxlen-2,
381 name->name, name->len,
382 server->local_nls, server->remote_nls);
383 if (len < 0)
384 return len;
385 path += len;
386 maxlen -= len+1;
387 }
388 /* maxlen has space for at least one char */
389 *path++ = '\0';
390 if (unicode) *path++ = '\0';
391 return path-buf;
392}
393
394static int smb_encode_path(struct smb_sb_info *server, char *buf, int maxlen,
395 struct dentry *dir, struct qstr *name)
396{
397 int result;
398
399 result = smb_build_path(server, buf, maxlen, dir, name);
400 if (result < 0)
401 goto out;
402 if (server->opt.protocol <= SMB_PROTOCOL_COREPLUS)
403 str_upper(buf, result);
404out:
405 return result;
406}
407
408/* encode_path for non-trans2 request SMBs */
409static int smb_simple_encode_path(struct smb_request *req, char **p,
410 struct dentry * entry, struct qstr * name)
411{
412 struct smb_sb_info *server = req->rq_server;
413 char *s = *p;
414 int res;
415 int maxlen = ((char *)req->rq_buffer + req->rq_bufsize) - s;
416 int unicode = (server->mnt->flags & SMB_MOUNT_UNICODE);
417
418 if (!maxlen)
419 return -ENAMETOOLONG;
420 *s++ = 4; /* ASCII data format */
421
422 /*
423 * SMB Unicode strings must be 16bit aligned relative the start of the
424 * packet. If they are not they must be padded with 0.
425 */
426 if (unicode) {
427 int align = s - (char *)req->rq_buffer;
428 if (!(align & 1)) {
429 *s++ = '\0';
430 maxlen--;
431 }
432 }
433
434 res = smb_encode_path(server, s, maxlen-1, entry, name);
435 if (res < 0)
436 return res;
437 *p = s + res;
438 return 0;
439}
440
441/* The following are taken directly from msdos-fs */
442
443/* Linear day numbers of the respective 1sts in non-leap years. */
444
445static int day_n[] =
446{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0};
447 /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
448
449
450static time_t
451utc2local(struct smb_sb_info *server, time_t time)
452{
453 return time - server->opt.serverzone*60;
454}
455
456static time_t
457local2utc(struct smb_sb_info *server, time_t time)
458{
459 return time + server->opt.serverzone*60;
460}
461
462/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
463
464static time_t
465date_dos2unix(struct smb_sb_info *server, __u16 date, __u16 time)
466{
467 int month, year;
468 time_t secs;
469
470 /* first subtract and mask after that... Otherwise, if
471 date == 0, bad things happen */
472 month = ((date >> 5) - 1) & 15;
473 year = date >> 9;
474 secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + 86400 *
475 ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - ((year & 3) == 0 &&
476 month < 2 ? 1 : 0) + 3653);
477 /* days since 1.1.70 plus 80's leap day */
478 return local2utc(server, secs);
479}
480
481
482/* Convert linear UNIX date to a MS-DOS time/date pair. */
483
484static void
485date_unix2dos(struct smb_sb_info *server,
486 int unix_date, __u16 *date, __u16 *time)
487{
488 int day, year, nl_day, month;
489
490 unix_date = utc2local(server, unix_date);
491 if (unix_date < 315532800)
492 unix_date = 315532800;
493
494 *time = (unix_date % 60) / 2 +
495 (((unix_date / 60) % 60) << 5) +
496 (((unix_date / 3600) % 24) << 11);
497
498 day = unix_date / 86400 - 3652;
499 year = day / 365;
500 if ((year + 3) / 4 + 365 * year > day)
501 year--;
502 day -= (year + 3) / 4 + 365 * year;
503 if (day == 59 && !(year & 3)) {
504 nl_day = day;
505 month = 2;
506 } else {
507 nl_day = (year & 3) || day <= 59 ? day : day - 1;
508 for (month = 1; month < 12; month++)
509 if (day_n[month] > nl_day)
510 break;
511 }
512 *date = nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9);
513}
514
515/* The following are taken from fs/ntfs/util.c */
516
517#define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000)
518
519/*
520 * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units)
521 * into Unix UTC (based 1970-01-01, in seconds).
522 */
523static struct timespec
524smb_ntutc2unixutc(u64 ntutc)
525{
526 struct timespec ts;
527 /* FIXME: what about the timezone difference? */
528 /* Subtract the NTFS time offset, then convert to 1s intervals. */
529 u64 t = ntutc - NTFS_TIME_OFFSET;
530 ts.tv_nsec = do_div(t, 10000000) * 100;
531 ts.tv_sec = t;
532 return ts;
533}
534
535/* Convert the Unix UTC into NT time */
536static u64
537smb_unixutc2ntutc(struct timespec ts)
538{
539 /* Note: timezone conversion is probably wrong. */
540 /* return ((u64)utc2local(server, t)) * 10000000 + NTFS_TIME_OFFSET; */
541 return ((u64)ts.tv_sec) * 10000000 + ts.tv_nsec/100 + NTFS_TIME_OFFSET;
542}
543
544#define MAX_FILE_MODE 6
545static mode_t file_mode[] = {
546 S_IFREG, S_IFDIR, S_IFLNK, S_IFCHR, S_IFBLK, S_IFIFO, S_IFSOCK
547};
548
549static int smb_filetype_to_mode(u32 filetype)
550{
551 if (filetype > MAX_FILE_MODE) {
552 PARANOIA("Filetype out of range: %d\n", filetype);
553 return S_IFREG;
554 }
555 return file_mode[filetype];
556}
557
558static u32 smb_filetype_from_mode(int mode)
559{
560 if (S_ISREG(mode))
561 return UNIX_TYPE_FILE;
562 if (S_ISDIR(mode))
563 return UNIX_TYPE_DIR;
564 if (S_ISLNK(mode))
565 return UNIX_TYPE_SYMLINK;
566 if (S_ISCHR(mode))
567 return UNIX_TYPE_CHARDEV;
568 if (S_ISBLK(mode))
569 return UNIX_TYPE_BLKDEV;
570 if (S_ISFIFO(mode))
571 return UNIX_TYPE_FIFO;
572 if (S_ISSOCK(mode))
573 return UNIX_TYPE_SOCKET;
574 return UNIX_TYPE_UNKNOWN;
575}
576
577
578/*****************************************************************************/
579/* */
580/* Support section. */
581/* */
582/*****************************************************************************/
583
584__u32
585smb_len(__u8 * p)
586{
587 return ((*(p+1) & 0x1) << 16L) | (*(p+2) << 8L) | *(p+3);
588}
589
590static __u16
591smb_bcc(__u8 * packet)
592{
593 int pos = SMB_HEADER_LEN + SMB_WCT(packet) * sizeof(__u16);
594 return WVAL(packet, pos);
595}
596
597/* smb_valid_packet: We check if packet fulfills the basic
598 requirements of a smb packet */
599
600static int
601smb_valid_packet(__u8 * packet)
602{
603 return (packet[4] == 0xff
604 && packet[5] == 'S'
605 && packet[6] == 'M'
606 && packet[7] == 'B'
607 && (smb_len(packet) + 4 == SMB_HEADER_LEN
608 + SMB_WCT(packet) * 2 + smb_bcc(packet)));
609}
610
611/* smb_verify: We check if we got the answer we expected, and if we
612 got enough data. If bcc == -1, we don't care. */
613
614static int
615smb_verify(__u8 * packet, int command, int wct, int bcc)
616{
617 if (SMB_CMD(packet) != command)
618 goto bad_command;
619 if (SMB_WCT(packet) < wct)
620 goto bad_wct;
621 if (bcc != -1 && smb_bcc(packet) < bcc)
622 goto bad_bcc;
623 return 0;
624
625bad_command:
626 printk(KERN_ERR "smb_verify: command=%x, SMB_CMD=%x??\n",
627 command, SMB_CMD(packet));
628 goto fail;
629bad_wct:
630 printk(KERN_ERR "smb_verify: command=%x, wct=%d, SMB_WCT=%d??\n",
631 command, wct, SMB_WCT(packet));
632 goto fail;
633bad_bcc:
634 printk(KERN_ERR "smb_verify: command=%x, bcc=%d, SMB_BCC=%d??\n",
635 command, bcc, smb_bcc(packet));
636fail:
637 return -EIO;
638}
639
640/*
641 * Returns the maximum read or write size for the "payload". Making all of the
642 * packet fit within the negotiated max_xmit size.
643 *
644 * N.B. Since this value is usually computed before locking the server,
645 * the server's packet size must never be decreased!
646 */
647static inline int
648smb_get_xmitsize(struct smb_sb_info *server, int overhead)
649{
650 return server->opt.max_xmit - overhead;
651}
652
653/*
654 * Calculate the maximum read size
655 */
656int
657smb_get_rsize(struct smb_sb_info *server)
658{
659 /* readX has 12 parameters, read has 5 */
660 int overhead = SMB_HEADER_LEN + 12 * sizeof(__u16) + 2 + 1 + 2;
661 int size = smb_get_xmitsize(server, overhead);
662
663 VERBOSE("xmit=%d, size=%d\n", server->opt.max_xmit, size);
664
665 return size;
666}
667
668/*
669 * Calculate the maximum write size
670 */
671int
672smb_get_wsize(struct smb_sb_info *server)
673{
674 /* writeX has 14 parameters, write has 5 */
675 int overhead = SMB_HEADER_LEN + 14 * sizeof(__u16) + 2 + 1 + 2;
676 int size = smb_get_xmitsize(server, overhead);
677
678 VERBOSE("xmit=%d, size=%d\n", server->opt.max_xmit, size);
679
680 return size;
681}
682
683/*
684 * Convert SMB error codes to -E... errno values.
685 */
686int
687smb_errno(struct smb_request *req)
688{
689 int errcls = req->rq_rcls;
690 int error = req->rq_err;
691 char *class = "Unknown";
692
693 VERBOSE("errcls %d code %d from command 0x%x\n",
694 errcls, error, SMB_CMD(req->rq_header));
695
696 if (errcls == ERRDOS) {
697 switch (error) {
698 case ERRbadfunc:
699 return -EINVAL;
700 case ERRbadfile:
701 case ERRbadpath:
702 return -ENOENT;
703 case ERRnofids:
704 return -EMFILE;
705 case ERRnoaccess:
706 return -EACCES;
707 case ERRbadfid:
708 return -EBADF;
709 case ERRbadmcb:
710 return -EREMOTEIO;
711 case ERRnomem:
712 return -ENOMEM;
713 case ERRbadmem:
714 return -EFAULT;
715 case ERRbadenv:
716 case ERRbadformat:
717 return -EREMOTEIO;
718 case ERRbadaccess:
719 return -EACCES;
720 case ERRbaddata:
721 return -E2BIG;
722 case ERRbaddrive:
723 return -ENXIO;
724 case ERRremcd:
725 return -EREMOTEIO;
726 case ERRdiffdevice:
727 return -EXDEV;
728 case ERRnofiles:
729 return -ENOENT;
730 case ERRbadshare:
731 return -ETXTBSY;
732 case ERRlock:
733 return -EDEADLK;
734 case ERRfilexists:
735 return -EEXIST;
736 case ERROR_INVALID_PARAMETER:
737 return -EINVAL;
738 case ERROR_DISK_FULL:
739 return -ENOSPC;
740 case ERROR_INVALID_NAME:
741 return -ENOENT;
742 case ERROR_DIR_NOT_EMPTY:
743 return -ENOTEMPTY;
744 case ERROR_NOT_LOCKED:
745 return -ENOLCK;
746 case ERROR_ALREADY_EXISTS:
747 return -EEXIST;
748 default:
749 class = "ERRDOS";
750 goto err_unknown;
751 }
752 } else if (errcls == ERRSRV) {
753 switch (error) {
754 /* N.B. This is wrong ... EIO ? */
755 case ERRerror:
756 return -ENFILE;
757 case ERRbadpw:
758 return -EINVAL;
759 case ERRbadtype:
760 case ERRtimeout:
761 return -EIO;
762 case ERRaccess:
763 return -EACCES;
764 /*
765 * This is a fatal error, as it means the "tree ID"
766 * for this connection is no longer valid. We map
767 * to a special error code and get a new connection.
768 */
769 case ERRinvnid:
770 return -EBADSLT;
771 default:
772 class = "ERRSRV";
773 goto err_unknown;
774 }
775 } else if (errcls == ERRHRD) {
776 switch (error) {
777 case ERRnowrite:
778 return -EROFS;
779 case ERRbadunit:
780 return -ENODEV;
781 case ERRnotready:
782 return -EUCLEAN;
783 case ERRbadcmd:
784 case ERRdata:
785 return -EIO;
786 case ERRbadreq:
787 return -ERANGE;
788 case ERRbadshare:
789 return -ETXTBSY;
790 case ERRlock:
791 return -EDEADLK;
792 case ERRdiskfull:
793 return -ENOSPC;
794 default:
795 class = "ERRHRD";
796 goto err_unknown;
797 }
798 } else if (errcls == ERRCMD) {
799 class = "ERRCMD";
800 } else if (errcls == SUCCESS) {
801 return 0; /* This is the only valid 0 return */
802 }
803
804err_unknown:
805 printk(KERN_ERR "smb_errno: class %s, code %d from command 0x%x\n",
806 class, error, SMB_CMD(req->rq_header));
807 return -EIO;
808}
809
810/* smb_request_ok: We expect the server to be locked. Then we do the
811 request and check the answer completely. When smb_request_ok
812 returns 0, you can be quite sure that everything went well. When
813 the answer is <=0, the returned number is a valid unix errno. */
814
815static int
816smb_request_ok(struct smb_request *req, int command, int wct, int bcc)
817{
818 int result;
819
820 req->rq_resp_wct = wct;
821 req->rq_resp_bcc = bcc;
822
823 result = smb_add_request(req);
824 if (result != 0) {
825 DEBUG1("smb_request failed\n");
826 goto out;
827 }
828
829 if (smb_valid_packet(req->rq_header) != 0) {
830 PARANOIA("invalid packet!\n");
831 goto out;
832 }
833
834 result = smb_verify(req->rq_header, command, wct, bcc);
835
836out:
837 return result;
838}
839
840/*
841 * This implements the NEWCONN ioctl. It installs the server pid,
842 * sets server->state to CONN_VALID, and wakes up the waiting process.
843 */
844int
845smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt)
846{
847 struct file *filp;
848 struct sock *sk;
849 int error;
850
851 VERBOSE("fd=%d, pid=%d\n", opt->fd, current->pid);
852
853 smb_lock_server(server);
854
855 /*
856 * Make sure we don't already have a valid connection ...
857 */
858 error = -EINVAL;
859 if (server->state == CONN_VALID)
860 goto out;
861
862 error = -EACCES;
863 if (current_uid() != server->mnt->mounted_uid &&
864 !capable(CAP_SYS_ADMIN))
865 goto out;
866
867 error = -EBADF;
868 filp = fget(opt->fd);
869 if (!filp)
870 goto out;
871 if (!smb_valid_socket(filp->f_path.dentry->d_inode))
872 goto out_putf;
873
874 server->sock_file = filp;
875 server->conn_pid = get_pid(task_pid(current));
876 server->opt = *opt;
877 server->generation += 1;
878 server->state = CONN_VALID;
879 error = 0;
880
881 if (server->conn_error) {
882 /*
883 * conn_error is the returncode we originally decided to
884 * drop the old connection on. This message should be positive
885 * and not make people ask questions on why smbfs is printing
886 * error messages ...
887 */
888 printk(KERN_INFO "SMB connection re-established (%d)\n",
889 server->conn_error);
890 server->conn_error = 0;
891 }
892
893 /*
894 * Store the server in sock user_data (Only used by sunrpc)
895 */
896 sk = SOCKET_I(filp->f_path.dentry->d_inode)->sk;
897 sk->sk_user_data = server;
898
899 /* chain into the data_ready callback */
900 server->data_ready = xchg(&sk->sk_data_ready, smb_data_ready);
901
902 /* check if we have an old smbmount that uses seconds for the
903 serverzone */
904 if (server->opt.serverzone > 12*60 || server->opt.serverzone < -12*60)
905 server->opt.serverzone /= 60;
906
907 /* now that we have an established connection we can detect the server
908 type and enable bug workarounds */
909 if (server->opt.protocol < SMB_PROTOCOL_LANMAN2)
910 install_ops(server->ops, &smb_ops_core);
911 else if (server->opt.protocol == SMB_PROTOCOL_LANMAN2)
912 install_ops(server->ops, &smb_ops_os2);
913 else if (server->opt.protocol == SMB_PROTOCOL_NT1 &&
914 (server->opt.max_xmit < 0x1000) &&
915 !(server->opt.capabilities & SMB_CAP_NT_SMBS)) {
916 /* FIXME: can we kill the WIN95 flag now? */
917 server->mnt->flags |= SMB_MOUNT_WIN95;
918 VERBOSE("detected WIN95 server\n");
919 install_ops(server->ops, &smb_ops_win95);
920 } else {
921 /*
922 * Samba has max_xmit 65535
923 * NT4spX has max_xmit 4536 (or something like that)
924 * win2k has ...
925 */
926 VERBOSE("detected NT1 (Samba, NT4/5) server\n");
927 install_ops(server->ops, &smb_ops_winNT);
928 }
929
930 /* FIXME: the win9x code wants to modify these ... (seek/trunc bug) */
931 if (server->mnt->flags & SMB_MOUNT_OLDATTR) {
932 server->ops->getattr = smb_proc_getattr_core;
933 } else if (server->mnt->flags & SMB_MOUNT_DIRATTR) {
934 server->ops->getattr = smb_proc_getattr_ff;
935 }
936
937 /* Decode server capabilities */
938 if (server->opt.capabilities & SMB_CAP_LARGE_FILES) {
939 /* Should be ok to set this now, as no one can access the
940 mount until the connection has been established. */
941 SB_of(server)->s_maxbytes = ~0ULL >> 1;
942 VERBOSE("LFS enabled\n");
943 }
944 if (server->opt.capabilities & SMB_CAP_UNICODE) {
945 server->mnt->flags |= SMB_MOUNT_UNICODE;
946 VERBOSE("Unicode enabled\n");
947 } else {
948 server->mnt->flags &= ~SMB_MOUNT_UNICODE;
949 }
950#if 0
951 /* flags we may test for other patches ... */
952 if (server->opt.capabilities & SMB_CAP_LARGE_READX) {
953 VERBOSE("Large reads enabled\n");
954 }
955 if (server->opt.capabilities & SMB_CAP_LARGE_WRITEX) {
956 VERBOSE("Large writes enabled\n");
957 }
958#endif
959 if (server->opt.capabilities & SMB_CAP_UNIX) {
960 struct inode *inode;
961 VERBOSE("Using UNIX CIFS extensions\n");
962 install_ops(server->ops, &smb_ops_unix);
963 inode = SB_of(server)->s_root->d_inode;
964 if (inode)
965 inode->i_op = &smb_dir_inode_operations_unix;
966 }
967
968 VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n",
969 server->opt.protocol, server->opt.max_xmit,
970 pid_nr(server->conn_pid), server->opt.capabilities);
971
972 /* FIXME: this really should be done by smbmount. */
973 if (server->opt.max_xmit > SMB_MAX_PACKET_SIZE) {
974 server->opt.max_xmit = SMB_MAX_PACKET_SIZE;
975 }
976
977 smb_unlock_server(server);
978 smbiod_wake_up();
979 if (server->opt.capabilities & SMB_CAP_UNIX)
980 smb_proc_query_cifsunix(server);
981
982 server->conn_complete++;
983 wake_up_interruptible_all(&server->conn_wq);
984 return error;
985
986out:
987 smb_unlock_server(server);
988 smbiod_wake_up();
989 return error;
990
991out_putf:
992 fput(filp);
993 goto out;
994}
995
996/* smb_setup_header: We completely set up the packet. You only have to
997 insert the command-specific fields */
998
999__u8 *
1000smb_setup_header(struct smb_request *req, __u8 command, __u16 wct, __u16 bcc)
1001{
1002 __u32 xmit_len = SMB_HEADER_LEN + wct * sizeof(__u16) + bcc + 2;
1003 __u8 *p = req->rq_header;
1004 struct smb_sb_info *server = req->rq_server;
1005
1006 p = smb_encode_smb_length(p, xmit_len - 4);
1007
1008 *p++ = 0xff;
1009 *p++ = 'S';
1010 *p++ = 'M';
1011 *p++ = 'B';
1012 *p++ = command;
1013
1014 memset(p, '\0', 19);
1015 p += 19;
1016 p += 8;
1017
1018 if (server->opt.protocol > SMB_PROTOCOL_CORE) {
1019 int flags = SMB_FLAGS_CASELESS_PATHNAMES;
1020 int flags2 = SMB_FLAGS2_LONG_PATH_COMPONENTS |
1021 SMB_FLAGS2_EXTENDED_ATTRIBUTES; /* EA? not really ... */
1022
1023 *(req->rq_header + smb_flg) = flags;
1024 if (server->mnt->flags & SMB_MOUNT_UNICODE)
1025 flags2 |= SMB_FLAGS2_UNICODE_STRINGS;
1026 WSET(req->rq_header, smb_flg2, flags2);
1027 }
1028 *p++ = wct; /* wct */
1029 p += 2 * wct;
1030 WSET(p, 0, bcc);
1031
1032 /* Include the header in the data to send */
1033 req->rq_iovlen = 1;
1034 req->rq_iov[0].iov_base = req->rq_header;
1035 req->rq_iov[0].iov_len = xmit_len - bcc;
1036
1037 return req->rq_buffer;
1038}
1039
1040static void
1041smb_setup_bcc(struct smb_request *req, __u8 *p)
1042{
1043 u16 bcc = p - req->rq_buffer;
1044 u8 *pbcc = req->rq_header + SMB_HEADER_LEN + 2*SMB_WCT(req->rq_header);
1045
1046 WSET(pbcc, 0, bcc);
1047
1048 smb_encode_smb_length(req->rq_header, SMB_HEADER_LEN +
1049 2*SMB_WCT(req->rq_header) - 2 + bcc);
1050
1051 /* Include the "bytes" in the data to send */
1052 req->rq_iovlen = 2;
1053 req->rq_iov[1].iov_base = req->rq_buffer;
1054 req->rq_iov[1].iov_len = bcc;
1055}
1056
1057static int
1058smb_proc_seek(struct smb_sb_info *server, __u16 fileid,
1059 __u16 mode, off_t offset)
1060{
1061 int result;
1062 struct smb_request *req;
1063
1064 result = -ENOMEM;
1065 if (! (req = smb_alloc_request(server, 0)))
1066 goto out;
1067
1068 smb_setup_header(req, SMBlseek, 4, 0);
1069 WSET(req->rq_header, smb_vwv0, fileid);
1070 WSET(req->rq_header, smb_vwv1, mode);
1071 DSET(req->rq_header, smb_vwv2, offset);
1072 req->rq_flags |= SMB_REQ_NORETRY;
1073
1074 result = smb_request_ok(req, SMBlseek, 2, 0);
1075 if (result < 0) {
1076 result = 0;
1077 goto out_free;
1078 }
1079
1080 result = DVAL(req->rq_header, smb_vwv0);
1081out_free:
1082 smb_rput(req);
1083out:
1084 return result;
1085}
1086
1087static int
1088smb_proc_open(struct smb_sb_info *server, struct dentry *dentry, int wish)
1089{
1090 struct inode *ino = dentry->d_inode;
1091 struct smb_inode_info *ei = SMB_I(ino);
1092 int mode, read_write = 0x42, read_only = 0x40;
1093 int res;
1094 char *p;
1095 struct smb_request *req;
1096
1097 /*
1098 * Attempt to open r/w, unless there are no write privileges.
1099 */
1100 mode = read_write;
1101 if (!(ino->i_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
1102 mode = read_only;
1103#if 0
1104 /* FIXME: why is this code not in? below we fix it so that a caller
1105 wanting RO doesn't get RW. smb_revalidate_inode does some
1106 optimization based on access mode. tail -f needs it to be correct.
1107
1108 We must open rw since we don't do the open if called a second time
1109 with different 'wish'. Is that not supported by smb servers? */
1110 if (!(wish & (O_WRONLY | O_RDWR)))
1111 mode = read_only;
1112#endif
1113
1114 res = -ENOMEM;
1115 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
1116 goto out;
1117
1118 retry:
1119 p = smb_setup_header(req, SMBopen, 2, 0);
1120 WSET(req->rq_header, smb_vwv0, mode);
1121 WSET(req->rq_header, smb_vwv1, aSYSTEM | aHIDDEN | aDIR);
1122 res = smb_simple_encode_path(req, &p, dentry, NULL);
1123 if (res < 0)
1124 goto out_free;
1125 smb_setup_bcc(req, p);
1126
1127 res = smb_request_ok(req, SMBopen, 7, 0);
1128 if (res != 0) {
1129 if (mode == read_write &&
1130 (res == -EACCES || res == -ETXTBSY || res == -EROFS))
1131 {
1132 VERBOSE("%s/%s R/W failed, error=%d, retrying R/O\n",
1133 DENTRY_PATH(dentry), res);
1134 mode = read_only;
1135 req->rq_flags = 0;
1136 goto retry;
1137 }
1138 goto out_free;
1139 }
1140 /* We should now have data in vwv[0..6]. */
1141
1142 ei->fileid = WVAL(req->rq_header, smb_vwv0);
1143 ei->attr = WVAL(req->rq_header, smb_vwv1);
1144 /* smb_vwv2 has mtime */
1145 /* smb_vwv4 has size */
1146 ei->access = (WVAL(req->rq_header, smb_vwv6) & SMB_ACCMASK);
1147 ei->open = server->generation;
1148
1149out_free:
1150 smb_rput(req);
1151out:
1152 return res;
1153}
1154
1155/*
1156 * Make sure the file is open, and check that the access
1157 * is compatible with the desired access.
1158 */
1159int
1160smb_open(struct dentry *dentry, int wish)
1161{
1162 struct inode *inode = dentry->d_inode;
1163 int result;
1164 __u16 access;
1165
1166 result = -ENOENT;
1167 if (!inode) {
1168 printk(KERN_ERR "smb_open: no inode for dentry %s/%s\n",
1169 DENTRY_PATH(dentry));
1170 goto out;
1171 }
1172
1173 if (!smb_is_open(inode)) {
1174 struct smb_sb_info *server = server_from_inode(inode);
1175 result = 0;
1176 if (!smb_is_open(inode))
1177 result = smb_proc_open(server, dentry, wish);
1178 if (result)
1179 goto out;
1180 /*
1181 * A successful open means the path is still valid ...
1182 */
1183 smb_renew_times(dentry);
1184 }
1185
1186 /*
1187 * Check whether the access is compatible with the desired mode.
1188 */
1189 result = 0;
1190 access = SMB_I(inode)->access;
1191 if (access != wish && access != SMB_O_RDWR) {
1192 PARANOIA("%s/%s access denied, access=%x, wish=%x\n",
1193 DENTRY_PATH(dentry), access, wish);
1194 result = -EACCES;
1195 }
1196out:
1197 return result;
1198}
1199
1200static int
1201smb_proc_close(struct smb_sb_info *server, __u16 fileid, __u32 mtime)
1202{
1203 struct smb_request *req;
1204 int result = -ENOMEM;
1205
1206 if (! (req = smb_alloc_request(server, 0)))
1207 goto out;
1208
1209 smb_setup_header(req, SMBclose, 3, 0);
1210 WSET(req->rq_header, smb_vwv0, fileid);
1211 DSET(req->rq_header, smb_vwv1, utc2local(server, mtime));
1212 req->rq_flags |= SMB_REQ_NORETRY;
1213 result = smb_request_ok(req, SMBclose, 0, 0);
1214
1215 smb_rput(req);
1216out:
1217 return result;
1218}
1219
1220/*
1221 * Win NT 4.0 has an apparent bug in that it fails to update the
1222 * modify time when writing to a file. As a workaround, we update
1223 * both modify and access time locally, and post the times to the
1224 * server when closing the file.
1225 */
1226static int
1227smb_proc_close_inode(struct smb_sb_info *server, struct inode * ino)
1228{
1229 struct smb_inode_info *ei = SMB_I(ino);
1230 int result = 0;
1231 if (smb_is_open(ino))
1232 {
1233 /*
1234 * We clear the open flag in advance, in case another
1235 * process observes the value while we block below.
1236 */
1237 ei->open = 0;
1238
1239 /*
1240 * Kludge alert: SMB timestamps are accurate only to
1241 * two seconds ... round the times to avoid needless
1242 * cache invalidations!
1243 */
1244 if (ino->i_mtime.tv_sec & 1) {
1245 ino->i_mtime.tv_sec--;
1246 ino->i_mtime.tv_nsec = 0;
1247 }
1248 if (ino->i_atime.tv_sec & 1) {
1249 ino->i_atime.tv_sec--;
1250 ino->i_atime.tv_nsec = 0;
1251 }
1252 /*
1253 * If the file is open with write permissions,
1254 * update the time stamps to sync mtime and atime.
1255 */
1256 if ((server->opt.capabilities & SMB_CAP_UNIX) == 0 &&
1257 (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) &&
1258 !(ei->access == SMB_O_RDONLY))
1259 {
1260 struct smb_fattr fattr;
1261 smb_get_inode_attr(ino, &fattr);
1262 smb_proc_setattr_ext(server, ino, &fattr);
1263 }
1264
1265 result = smb_proc_close(server, ei->fileid, ino->i_mtime.tv_sec);
1266 /*
1267 * Force a revalidation after closing ... some servers
1268 * don't post the size until the file has been closed.
1269 */
1270 if (server->opt.protocol < SMB_PROTOCOL_NT1)
1271 ei->oldmtime = 0;
1272 ei->closed = jiffies;
1273 }
1274 return result;
1275}
1276
1277int
1278smb_close(struct inode *ino)
1279{
1280 int result = 0;
1281
1282 if (smb_is_open(ino)) {
1283 struct smb_sb_info *server = server_from_inode(ino);
1284 result = smb_proc_close_inode(server, ino);
1285 }
1286 return result;
1287}
1288
1289/*
1290 * This is used to close a file following a failed instantiate.
1291 * Since we don't have an inode, we can't use any of the above.
1292 */
1293int
1294smb_close_fileid(struct dentry *dentry, __u16 fileid)
1295{
1296 struct smb_sb_info *server = server_from_dentry(dentry);
1297 int result;
1298
1299 result = smb_proc_close(server, fileid, get_seconds());
1300 return result;
1301}
1302
1303/* In smb_proc_read and smb_proc_write we do not retry, because the
1304 file-id would not be valid after a reconnection. */
1305
1306static void
1307smb_proc_read_data(struct smb_request *req)
1308{
1309 req->rq_iov[0].iov_base = req->rq_buffer;
1310 req->rq_iov[0].iov_len = 3;
1311
1312 req->rq_iov[1].iov_base = req->rq_page;
1313 req->rq_iov[1].iov_len = req->rq_rsize;
1314 req->rq_iovlen = 2;
1315
1316 req->rq_rlen = smb_len(req->rq_header) + 4 - req->rq_bytes_recvd;
1317}
1318
1319static int
1320smb_proc_read(struct inode *inode, loff_t offset, int count, char *data)
1321{
1322 struct smb_sb_info *server = server_from_inode(inode);
1323 __u16 returned_count, data_len;
1324 unsigned char *buf;
1325 int result;
1326 struct smb_request *req;
1327 u8 rbuf[4];
1328
1329 result = -ENOMEM;
1330 if (! (req = smb_alloc_request(server, 0)))
1331 goto out;
1332
1333 smb_setup_header(req, SMBread, 5, 0);
1334 buf = req->rq_header;
1335 WSET(buf, smb_vwv0, SMB_I(inode)->fileid);
1336 WSET(buf, smb_vwv1, count);
1337 DSET(buf, smb_vwv2, offset);
1338 WSET(buf, smb_vwv4, 0);
1339
1340 req->rq_page = data;
1341 req->rq_rsize = count;
1342 req->rq_callback = smb_proc_read_data;
1343 req->rq_buffer = rbuf;
1344 req->rq_flags |= SMB_REQ_NORETRY | SMB_REQ_STATIC;
1345
1346 result = smb_request_ok(req, SMBread, 5, -1);
1347 if (result < 0)
1348 goto out_free;
1349 returned_count = WVAL(req->rq_header, smb_vwv0);
1350
1351 data_len = WVAL(rbuf, 1);
1352
1353 if (returned_count != data_len) {
1354 printk(KERN_NOTICE "smb_proc_read: returned != data_len\n");
1355 printk(KERN_NOTICE "smb_proc_read: ret_c=%d, data_len=%d\n",
1356 returned_count, data_len);
1357 }
1358 result = data_len;
1359
1360out_free:
1361 smb_rput(req);
1362out:
1363 VERBOSE("ino=%ld, fileid=%d, count=%d, result=%d\n",
1364 inode->i_ino, SMB_I(inode)->fileid, count, result);
1365 return result;
1366}
1367
1368static int
1369smb_proc_write(struct inode *inode, loff_t offset, int count, const char *data)
1370{
1371 struct smb_sb_info *server = server_from_inode(inode);
1372 int result;
1373 u16 fileid = SMB_I(inode)->fileid;
1374 u8 buf[4];
1375 struct smb_request *req;
1376
1377 result = -ENOMEM;
1378 if (! (req = smb_alloc_request(server, 0)))
1379 goto out;
1380
1381 VERBOSE("ino=%ld, fileid=%d, count=%d@%Ld\n",
1382 inode->i_ino, fileid, count, offset);
1383
1384 smb_setup_header(req, SMBwrite, 5, count + 3);
1385 WSET(req->rq_header, smb_vwv0, fileid);
1386 WSET(req->rq_header, smb_vwv1, count);
1387 DSET(req->rq_header, smb_vwv2, offset);
1388 WSET(req->rq_header, smb_vwv4, 0);
1389
1390 buf[0] = 1;
1391 WSET(buf, 1, count); /* yes, again ... */
1392 req->rq_iov[1].iov_base = buf;
1393 req->rq_iov[1].iov_len = 3;
1394 req->rq_iov[2].iov_base = (char *) data;
1395 req->rq_iov[2].iov_len = count;
1396 req->rq_iovlen = 3;
1397 req->rq_flags |= SMB_REQ_NORETRY;
1398
1399 result = smb_request_ok(req, SMBwrite, 1, 0);
1400 if (result >= 0)
1401 result = WVAL(req->rq_header, smb_vwv0);
1402
1403 smb_rput(req);
1404out:
1405 return result;
1406}
1407
1408/*
1409 * In smb_proc_readX and smb_proc_writeX we do not retry, because the
1410 * file-id would not be valid after a reconnection.
1411 */
1412
1413#define SMB_READX_MAX_PAD 64
1414static void
1415smb_proc_readX_data(struct smb_request *req)
1416{
1417 /* header length, excluding the netbios length (-4) */
1418 int hdrlen = SMB_HEADER_LEN + req->rq_resp_wct*2 - 2;
1419 int data_off = WVAL(req->rq_header, smb_vwv6);
1420
1421 /*
1422 * Some genius made the padding to the data bytes arbitrary.
1423 * So we must first calculate the amount of padding used by the server.
1424 */
1425 data_off -= hdrlen;
1426 if (data_off > SMB_READX_MAX_PAD || data_off < 0) {
1427 PARANOIA("offset is larger than SMB_READX_MAX_PAD or negative!\n");
1428 PARANOIA("%d > %d || %d < 0\n", data_off, SMB_READX_MAX_PAD, data_off);
1429 req->rq_rlen = req->rq_bufsize + 1;
1430 return;
1431 }
1432 req->rq_iov[0].iov_base = req->rq_buffer;
1433 req->rq_iov[0].iov_len = data_off;
1434
1435 req->rq_iov[1].iov_base = req->rq_page;
1436 req->rq_iov[1].iov_len = req->rq_rsize;
1437 req->rq_iovlen = 2;
1438
1439 req->rq_rlen = smb_len(req->rq_header) + 4 - req->rq_bytes_recvd;
1440}
1441
1442static int
1443smb_proc_readX(struct inode *inode, loff_t offset, int count, char *data)
1444{
1445 struct smb_sb_info *server = server_from_inode(inode);
1446 unsigned char *buf;
1447 int result;
1448 struct smb_request *req;
1449 static char pad[SMB_READX_MAX_PAD];
1450
1451 result = -ENOMEM;
1452 if (! (req = smb_alloc_request(server, 0)))
1453 goto out;
1454
1455 smb_setup_header(req, SMBreadX, 12, 0);
1456 buf = req->rq_header;
1457 WSET(buf, smb_vwv0, 0x00ff);
1458 WSET(buf, smb_vwv1, 0);
1459 WSET(buf, smb_vwv2, SMB_I(inode)->fileid);
1460 DSET(buf, smb_vwv3, (u32)offset); /* low 32 bits */
1461 WSET(buf, smb_vwv5, count);
1462 WSET(buf, smb_vwv6, 0);
1463 DSET(buf, smb_vwv7, 0);
1464 WSET(buf, smb_vwv9, 0);
1465 DSET(buf, smb_vwv10, (u32)(offset >> 32)); /* high 32 bits */
1466 WSET(buf, smb_vwv11, 0);
1467
1468 req->rq_page = data;
1469 req->rq_rsize = count;
1470 req->rq_callback = smb_proc_readX_data;
1471 req->rq_buffer = pad;
1472 req->rq_bufsize = SMB_READX_MAX_PAD;
1473 req->rq_flags |= SMB_REQ_STATIC | SMB_REQ_NORETRY;
1474
1475 result = smb_request_ok(req, SMBreadX, 12, -1);
1476 if (result < 0)
1477 goto out_free;
1478 result = WVAL(req->rq_header, smb_vwv5);
1479
1480out_free:
1481 smb_rput(req);
1482out:
1483 VERBOSE("ino=%ld, fileid=%d, count=%d, result=%d\n",
1484 inode->i_ino, SMB_I(inode)->fileid, count, result);
1485 return result;
1486}
1487
1488static int
1489smb_proc_writeX(struct inode *inode, loff_t offset, int count, const char *data)
1490{
1491 struct smb_sb_info *server = server_from_inode(inode);
1492 int result;
1493 u8 *p;
1494 static u8 pad[4];
1495 struct smb_request *req;
1496
1497 result = -ENOMEM;
1498 if (! (req = smb_alloc_request(server, 0)))
1499 goto out;
1500
1501 VERBOSE("ino=%ld, fileid=%d, count=%d@%Ld\n",
1502 inode->i_ino, SMB_I(inode)->fileid, count, offset);
1503
1504 p = smb_setup_header(req, SMBwriteX, 14, count + 1);
1505 WSET(req->rq_header, smb_vwv0, 0x00ff);
1506 WSET(req->rq_header, smb_vwv1, 0);
1507 WSET(req->rq_header, smb_vwv2, SMB_I(inode)->fileid);
1508 DSET(req->rq_header, smb_vwv3, (u32)offset); /* low 32 bits */
1509 DSET(req->rq_header, smb_vwv5, 0);
1510 WSET(req->rq_header, smb_vwv7, 0); /* write mode */
1511 WSET(req->rq_header, smb_vwv8, 0);
1512 WSET(req->rq_header, smb_vwv9, 0);
1513 WSET(req->rq_header, smb_vwv10, count); /* data length */
1514 WSET(req->rq_header, smb_vwv11, smb_vwv12 + 2 + 1);
1515 DSET(req->rq_header, smb_vwv12, (u32)(offset >> 32));
1516
1517 req->rq_iov[1].iov_base = pad;
1518 req->rq_iov[1].iov_len = 1;
1519 req->rq_iov[2].iov_base = (char *) data;
1520 req->rq_iov[2].iov_len = count;
1521 req->rq_iovlen = 3;
1522 req->rq_flags |= SMB_REQ_NORETRY;
1523
1524 result = smb_request_ok(req, SMBwriteX, 6, 0);
1525 if (result >= 0)
1526 result = WVAL(req->rq_header, smb_vwv2);
1527
1528 smb_rput(req);
1529out:
1530 return result;
1531}
1532
1533int
1534smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid)
1535{
1536 struct smb_sb_info *server = server_from_dentry(dentry);
1537 char *p;
1538 int result;
1539 struct smb_request *req;
1540
1541 result = -ENOMEM;
1542 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
1543 goto out;
1544
1545 p = smb_setup_header(req, SMBcreate, 3, 0);
1546 WSET(req->rq_header, smb_vwv0, attr);
1547 DSET(req->rq_header, smb_vwv1, utc2local(server, ctime));
1548 result = smb_simple_encode_path(req, &p, dentry, NULL);
1549 if (result < 0)
1550 goto out_free;
1551 smb_setup_bcc(req, p);
1552
1553 result = smb_request_ok(req, SMBcreate, 1, 0);
1554 if (result < 0)
1555 goto out_free;
1556
1557 *fileid = WVAL(req->rq_header, smb_vwv0);
1558 result = 0;
1559
1560out_free:
1561 smb_rput(req);
1562out:
1563 return result;
1564}
1565
1566int
1567smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry)
1568{
1569 struct smb_sb_info *server = server_from_dentry(old_dentry);
1570 char *p;
1571 int result;
1572 struct smb_request *req;
1573
1574 result = -ENOMEM;
1575 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
1576 goto out;
1577
1578 p = smb_setup_header(req, SMBmv, 1, 0);
1579 WSET(req->rq_header, smb_vwv0, aSYSTEM | aHIDDEN | aDIR);
1580 result = smb_simple_encode_path(req, &p, old_dentry, NULL);
1581 if (result < 0)
1582 goto out_free;
1583 result = smb_simple_encode_path(req, &p, new_dentry, NULL);
1584 if (result < 0)
1585 goto out_free;
1586 smb_setup_bcc(req, p);
1587
1588 if ((result = smb_request_ok(req, SMBmv, 0, 0)) < 0)
1589 goto out_free;
1590 result = 0;
1591
1592out_free:
1593 smb_rput(req);
1594out:
1595 return result;
1596}
1597
1598/*
1599 * Code common to mkdir and rmdir.
1600 */
1601static int
1602smb_proc_generic_command(struct dentry *dentry, __u8 command)
1603{
1604 struct smb_sb_info *server = server_from_dentry(dentry);
1605 char *p;
1606 int result;
1607 struct smb_request *req;
1608
1609 result = -ENOMEM;
1610 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
1611 goto out;
1612
1613 p = smb_setup_header(req, command, 0, 0);
1614 result = smb_simple_encode_path(req, &p, dentry, NULL);
1615 if (result < 0)
1616 goto out_free;
1617 smb_setup_bcc(req, p);
1618
1619 result = smb_request_ok(req, command, 0, 0);
1620 if (result < 0)
1621 goto out_free;
1622 result = 0;
1623
1624out_free:
1625 smb_rput(req);
1626out:
1627 return result;
1628}
1629
1630int
1631smb_proc_mkdir(struct dentry *dentry)
1632{
1633 return smb_proc_generic_command(dentry, SMBmkdir);
1634}
1635
1636int
1637smb_proc_rmdir(struct dentry *dentry)
1638{
1639 return smb_proc_generic_command(dentry, SMBrmdir);
1640}
1641
1642#if SMBFS_POSIX_UNLINK
1643/*
1644 * Removes readonly attribute from a file. Used by unlink to give posix
1645 * semantics.
1646 */
1647static int
1648smb_set_rw(struct dentry *dentry,struct smb_sb_info *server)
1649{
1650 int result;
1651 struct smb_fattr fattr;
1652
1653 /* FIXME: cifsUE should allow removing a readonly file. */
1654
1655 /* first get current attribute */
1656 smb_init_dirent(server, &fattr);
1657 result = server->ops->getattr(server, dentry, &fattr);
1658 smb_finish_dirent(server, &fattr);
1659 if (result < 0)
1660 return result;
1661
1662 /* if RONLY attribute is set, remove it */
1663 if (fattr.attr & aRONLY) { /* read only attribute is set */
1664 fattr.attr &= ~aRONLY;
1665 result = smb_proc_setattr_core(server, dentry, fattr.attr);
1666 }
1667 return result;
1668}
1669#endif
1670
1671int
1672smb_proc_unlink(struct dentry *dentry)
1673{
1674 struct smb_sb_info *server = server_from_dentry(dentry);
1675 int flag = 0;
1676 char *p;
1677 int result;
1678 struct smb_request *req;
1679
1680 result = -ENOMEM;
1681 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
1682 goto out;
1683
1684 retry:
1685 p = smb_setup_header(req, SMBunlink, 1, 0);
1686 WSET(req->rq_header, smb_vwv0, aSYSTEM | aHIDDEN);
1687 result = smb_simple_encode_path(req, &p, dentry, NULL);
1688 if (result < 0)
1689 goto out_free;
1690 smb_setup_bcc(req, p);
1691
1692 if ((result = smb_request_ok(req, SMBunlink, 0, 0)) < 0) {
1693#if SMBFS_POSIX_UNLINK
1694 if (result == -EACCES && !flag) {
1695 /* Posix semantics is for the read-only state
1696 of a file to be ignored in unlink(). In the
1697 SMB world a unlink() is refused on a
1698 read-only file. To make things easier for
1699 unix users we try to override the files
1700 permission if the unlink fails with the
1701 right error.
1702 This introduces a race condition that could
1703 lead to a file being written by someone who
1704 shouldn't have access, but as far as I can
1705 tell that is unavoidable */
1706
1707 /* remove RONLY attribute and try again */
1708 result = smb_set_rw(dentry,server);
1709 if (result == 0) {
1710 flag = 1;
1711 req->rq_flags = 0;
1712 goto retry;
1713 }
1714 }
1715#endif
1716 goto out_free;
1717 }
1718 result = 0;
1719
1720out_free:
1721 smb_rput(req);
1722out:
1723 return result;
1724}
1725
1726int
1727smb_proc_flush(struct smb_sb_info *server, __u16 fileid)
1728{
1729 int result;
1730 struct smb_request *req;
1731
1732 result = -ENOMEM;
1733 if (! (req = smb_alloc_request(server, 0)))
1734 goto out;
1735
1736 smb_setup_header(req, SMBflush, 1, 0);
1737 WSET(req->rq_header, smb_vwv0, fileid);
1738 req->rq_flags |= SMB_REQ_NORETRY;
1739 result = smb_request_ok(req, SMBflush, 0, 0);
1740
1741 smb_rput(req);
1742out:
1743 return result;
1744}
1745
1746static int
1747smb_proc_trunc32(struct inode *inode, loff_t length)
1748{
1749 /*
1750 * Writing 0bytes is old-SMB magic for truncating files.
1751 * MAX_NON_LFS should prevent this from being called with a too
1752 * large offset.
1753 */
1754 return smb_proc_write(inode, length, 0, NULL);
1755}
1756
1757static int
1758smb_proc_trunc64(struct inode *inode, loff_t length)
1759{
1760 struct smb_sb_info *server = server_from_inode(inode);
1761 int result;
1762 char *param;
1763 char *data;
1764 struct smb_request *req;
1765
1766 result = -ENOMEM;
1767 if (! (req = smb_alloc_request(server, 14)))
1768 goto out;
1769
1770 param = req->rq_buffer;
1771 data = req->rq_buffer + 6;
1772
1773 /* FIXME: must we also set allocation size? winNT seems to do that */
1774 WSET(param, 0, SMB_I(inode)->fileid);
1775 WSET(param, 2, SMB_SET_FILE_END_OF_FILE_INFO);
1776 WSET(param, 4, 0);
1777 LSET(data, 0, length);
1778
1779 req->rq_trans2_command = TRANSACT2_SETFILEINFO;
1780 req->rq_ldata = 8;
1781 req->rq_data = data;
1782 req->rq_lparm = 6;
1783 req->rq_parm = param;
1784 req->rq_flags |= SMB_REQ_NORETRY;
1785 result = smb_add_request(req);
1786 if (result < 0)
1787 goto out_free;
1788
1789 result = 0;
1790 if (req->rq_rcls != 0)
1791 result = smb_errno(req);
1792
1793out_free:
1794 smb_rput(req);
1795out:
1796 return result;
1797}
1798
1799static int
1800smb_proc_trunc95(struct inode *inode, loff_t length)
1801{
1802 struct smb_sb_info *server = server_from_inode(inode);
1803 int result = smb_proc_trunc32(inode, length);
1804
1805 /*
1806 * win9x doesn't appear to update the size immediately.
1807 * It will return the old file size after the truncate,
1808 * confusing smbfs. So we force an update.
1809 *
1810 * FIXME: is this still necessary?
1811 */
1812 smb_proc_flush(server, SMB_I(inode)->fileid);
1813 return result;
1814}
1815
1816static void
1817smb_init_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
1818{
1819 memset(fattr, 0, sizeof(*fattr));
1820
1821 fattr->f_nlink = 1;
1822 fattr->f_uid = server->mnt->uid;
1823 fattr->f_gid = server->mnt->gid;
1824 fattr->f_unix = 0;
1825}
1826
1827static void
1828smb_finish_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
1829{
1830 if (fattr->f_unix)
1831 return;
1832
1833 fattr->f_mode = server->mnt->file_mode;
1834 if (fattr->attr & aDIR) {
1835 fattr->f_mode = server->mnt->dir_mode;
1836 fattr->f_size = SMB_ST_BLKSIZE;
1837 }
1838 /* Check the read-only flag */
1839 if (fattr->attr & aRONLY)
1840 fattr->f_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
1841
1842 /* How many 512 byte blocks do we need for this file? */
1843 fattr->f_blocks = 0;
1844 if (fattr->f_size != 0)
1845 fattr->f_blocks = 1 + ((fattr->f_size-1) >> 9);
1846 return;
1847}
1848
1849void
1850smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr,
1851 struct super_block *sb)
1852{
1853 smb_init_dirent(server, fattr);
1854 fattr->attr = aDIR;
1855 fattr->f_ino = 2; /* traditional root inode number */
1856 fattr->f_mtime = current_fs_time(sb);
1857 smb_finish_dirent(server, fattr);
1858}
1859
1860/*
1861 * Decode a dirent for old protocols
1862 *
1863 * qname is filled with the decoded, and possibly translated, name.
1864 * fattr receives decoded attributes
1865 *
1866 * Bugs Noted:
1867 * (1) Pathworks servers may pad the name with extra spaces.
1868 */
1869static char *
1870smb_decode_short_dirent(struct smb_sb_info *server, char *p,
1871 struct qstr *qname, struct smb_fattr *fattr,
1872 unsigned char *name_buf)
1873{
1874 int len;
1875
1876 /*
1877 * SMB doesn't have a concept of inode numbers ...
1878 */
1879 smb_init_dirent(server, fattr);
1880 fattr->f_ino = 0; /* FIXME: do we need this? */
1881
1882 p += SMB_STATUS_SIZE; /* reserved (search_status) */
1883 fattr->attr = *p;
1884 fattr->f_mtime.tv_sec = date_dos2unix(server, WVAL(p, 3), WVAL(p, 1));
1885 fattr->f_mtime.tv_nsec = 0;
1886 fattr->f_size = DVAL(p, 5);
1887 fattr->f_ctime = fattr->f_mtime;
1888 fattr->f_atime = fattr->f_mtime;
1889 qname->name = p + 9;
1890 len = strnlen(qname->name, 12);
1891
1892 /*
1893 * Trim trailing blanks for Pathworks servers
1894 */
1895 while (len > 2 && qname->name[len-1] == ' ')
1896 len--;
1897
1898 smb_finish_dirent(server, fattr);
1899
1900#if 0
1901 /* FIXME: These only work for ascii chars, and recent smbmount doesn't
1902 allow the flag to be set anyway. It kills const. Remove? */
1903 switch (server->opt.case_handling) {
1904 case SMB_CASE_UPPER:
1905 str_upper(entry->name, len);
1906 break;
1907 case SMB_CASE_LOWER:
1908 str_lower(entry->name, len);
1909 break;
1910 default:
1911 break;
1912 }
1913#endif
1914
1915 qname->len = 0;
1916 len = server->ops->convert(name_buf, SMB_MAXNAMELEN,
1917 qname->name, len,
1918 server->remote_nls, server->local_nls);
1919 if (len > 0) {
1920 qname->len = len;
1921 qname->name = name_buf;
1922 DEBUG1("len=%d, name=%.*s\n",qname->len,qname->len,qname->name);
1923 }
1924
1925 return p + 22;
1926}
1927
1928/*
1929 * This routine is used to read in directory entries from the network.
1930 * Note that it is for short directory name seeks, i.e.: protocol <
1931 * SMB_PROTOCOL_LANMAN2
1932 */
1933static int
1934smb_proc_readdir_short(struct file *filp, void *dirent, filldir_t filldir,
1935 struct smb_cache_control *ctl)
1936{
1937 struct dentry *dir = filp->f_path.dentry;
1938 struct smb_sb_info *server = server_from_dentry(dir);
1939 struct qstr qname;
1940 struct smb_fattr fattr;
1941 char *p;
1942 int result;
1943 int i, first, entries_seen, entries;
1944 int entries_asked = (server->opt.max_xmit - 100) / SMB_DIRINFO_SIZE;
1945 __u16 bcc;
1946 __u16 count;
1947 char status[SMB_STATUS_SIZE];
1948 static struct qstr mask = {
1949 .name = "*.*",
1950 .len = 3,
1951 };
1952 unsigned char *last_status;
1953 struct smb_request *req;
1954 unsigned char *name_buf;
1955
1956 VERBOSE("%s/%s\n", DENTRY_PATH(dir));
1957
1958 lock_kernel();
1959
1960 result = -ENOMEM;
1961 if (! (name_buf = kmalloc(SMB_MAXNAMELEN, GFP_KERNEL)))
1962 goto out;
1963
1964 first = 1;
1965 entries = 0;
1966 entries_seen = 2; /* implicit . and .. */
1967
1968 result = -ENOMEM;
1969 if (! (req = smb_alloc_request(server, server->opt.max_xmit)))
1970 goto out_name;
1971
1972 while (1) {
1973 p = smb_setup_header(req, SMBsearch, 2, 0);
1974 WSET(req->rq_header, smb_vwv0, entries_asked);
1975 WSET(req->rq_header, smb_vwv1, aDIR);
1976 if (first == 1) {
1977 result = smb_simple_encode_path(req, &p, dir, &mask);
1978 if (result < 0)
1979 goto out_free;
1980 if (p + 3 > (char *)req->rq_buffer + req->rq_bufsize) {
1981 result = -ENAMETOOLONG;
1982 goto out_free;
1983 }
1984 *p++ = 5;
1985 WSET(p, 0, 0);
1986 p += 2;
1987 first = 0;
1988 } else {
1989 if (p + 5 + SMB_STATUS_SIZE >
1990 (char *)req->rq_buffer + req->rq_bufsize) {
1991 result = -ENAMETOOLONG;
1992 goto out_free;
1993 }
1994
1995 *p++ = 4;
1996 *p++ = 0;
1997 *p++ = 5;
1998 WSET(p, 0, SMB_STATUS_SIZE);
1999 p += 2;
2000 memcpy(p, status, SMB_STATUS_SIZE);
2001 p += SMB_STATUS_SIZE;
2002 }
2003
2004 smb_setup_bcc(req, p);
2005
2006 result = smb_request_ok(req, SMBsearch, 1, -1);
2007 if (result < 0) {
2008 if ((req->rq_rcls == ERRDOS) &&
2009 (req->rq_err == ERRnofiles))
2010 break;
2011 goto out_free;
2012 }
2013 count = WVAL(req->rq_header, smb_vwv0);
2014 if (count <= 0)
2015 break;
2016
2017 result = -EIO;
2018 bcc = smb_bcc(req->rq_header);
2019 if (bcc != count * SMB_DIRINFO_SIZE + 3)
2020 goto out_free;
2021 p = req->rq_buffer + 3;
2022
2023
2024 /* Make sure the response fits in the buffer. Fixed sized
2025 entries means we don't have to check in the decode loop. */
2026
2027 last_status = req->rq_buffer + 3 + (count-1) * SMB_DIRINFO_SIZE;
2028
2029 if (last_status + SMB_DIRINFO_SIZE >=
2030 req->rq_buffer + req->rq_bufsize) {
2031 printk(KERN_ERR "smb_proc_readdir_short: "
2032 "last dir entry outside buffer! "
2033 "%d@%p %d@%p\n", SMB_DIRINFO_SIZE, last_status,
2034 req->rq_bufsize, req->rq_buffer);
2035 goto out_free;
2036 }
2037
2038 /* Read the last entry into the status field. */
2039 memcpy(status, last_status, SMB_STATUS_SIZE);
2040
2041
2042 /* Now we are ready to parse smb directory entries. */
2043
2044 for (i = 0; i < count; i++) {
2045 p = smb_decode_short_dirent(server, p,
2046 &qname, &fattr, name_buf);
2047 if (qname.len == 0)
2048 continue;
2049
2050 if (entries_seen == 2 && qname.name[0] == '.') {
2051 if (qname.len == 1)
2052 continue;
2053 if (qname.name[1] == '.' && qname.len == 2)
2054 continue;
2055 }
2056 if (!smb_fill_cache(filp, dirent, filldir, ctl,
2057 &qname, &fattr))
2058 ; /* stop reading? */
2059 entries_seen++;
2060 }
2061 }
2062 result = entries;
2063
2064out_free:
2065 smb_rput(req);
2066out_name:
2067 kfree(name_buf);
2068out:
2069 unlock_kernel();
2070 return result;
2071}
2072
2073static void smb_decode_unix_basic(struct smb_fattr *fattr, struct smb_sb_info *server, char *p)
2074{
2075 u64 size, disk_bytes;
2076
2077 /* FIXME: verify nls support. all is sent as utf8? */
2078
2079 fattr->f_unix = 1;
2080 fattr->f_mode = 0;
2081
2082 /* FIXME: use the uniqueID from the remote instead? */
2083 /* 0 L file size in bytes */
2084 /* 8 L file size on disk in bytes (block count) */
2085 /* 40 L uid */
2086 /* 48 L gid */
2087 /* 56 W file type */
2088 /* 60 L devmajor */
2089 /* 68 L devminor */
2090 /* 76 L unique ID (inode) */
2091 /* 84 L permissions */
2092 /* 92 L link count */
2093
2094 size = LVAL(p, 0);
2095 disk_bytes = LVAL(p, 8);
2096
2097 /*
2098 * Some samba versions round up on-disk byte usage
2099 * to 1MB boundaries, making it useless. When seeing
2100 * that, use the size instead.
2101 */
2102 if (!(disk_bytes & 0xfffff))
2103 disk_bytes = size+511;
2104
2105 fattr->f_size = size;
2106 fattr->f_blocks = disk_bytes >> 9;
2107 fattr->f_ctime = smb_ntutc2unixutc(LVAL(p, 16));
2108 fattr->f_atime = smb_ntutc2unixutc(LVAL(p, 24));
2109 fattr->f_mtime = smb_ntutc2unixutc(LVAL(p, 32));
2110
2111 if (server->mnt->flags & SMB_MOUNT_UID)
2112 fattr->f_uid = server->mnt->uid;
2113 else
2114 fattr->f_uid = LVAL(p, 40);
2115
2116 if (server->mnt->flags & SMB_MOUNT_GID)
2117 fattr->f_gid = server->mnt->gid;
2118 else
2119 fattr->f_gid = LVAL(p, 48);
2120
2121 fattr->f_mode |= smb_filetype_to_mode(WVAL(p, 56));
2122
2123 if (S_ISBLK(fattr->f_mode) || S_ISCHR(fattr->f_mode)) {
2124 __u64 major = LVAL(p, 60);
2125 __u64 minor = LVAL(p, 68);
2126
2127 fattr->f_rdev = MKDEV(major & 0xffffffff, minor & 0xffffffff);
2128 if (MAJOR(fattr->f_rdev) != (major & 0xffffffff) ||
2129 MINOR(fattr->f_rdev) != (minor & 0xffffffff))
2130 fattr->f_rdev = 0;
2131 }
2132
2133 fattr->f_mode |= LVAL(p, 84);
2134
2135 if ( (server->mnt->flags & SMB_MOUNT_DMODE) &&
2136 (S_ISDIR(fattr->f_mode)) )
2137 fattr->f_mode = (server->mnt->dir_mode & S_IRWXUGO) | S_IFDIR;
2138 else if ( (server->mnt->flags & SMB_MOUNT_FMODE) &&
2139 !(S_ISDIR(fattr->f_mode)) )
2140 fattr->f_mode = (server->mnt->file_mode & S_IRWXUGO) |
2141 (fattr->f_mode & S_IFMT);
2142
2143}
2144
2145/*
2146 * Interpret a long filename structure using the specified info level:
2147 * level 1 for anything below NT1 protocol
2148 * level 260 for NT1 protocol
2149 *
2150 * qname is filled with the decoded, and possibly translated, name
2151 * fattr receives decoded attributes.
2152 *
2153 * Bugs Noted:
2154 * (1) Win NT 4.0 appends a null byte to names and counts it in the length!
2155 */
2156static char *
2157smb_decode_long_dirent(struct smb_sb_info *server, char *p, int level,
2158 struct qstr *qname, struct smb_fattr *fattr,
2159 unsigned char *name_buf)
2160{
2161 char *result;
2162 unsigned int len = 0;
2163 int n;
2164 __u16 date, time;
2165 int unicode = (server->mnt->flags & SMB_MOUNT_UNICODE);
2166
2167 /*
2168 * SMB doesn't have a concept of inode numbers ...
2169 */
2170 smb_init_dirent(server, fattr);
2171 fattr->f_ino = 0; /* FIXME: do we need this? */
2172
2173 switch (level) {
2174 case 1:
2175 len = *((unsigned char *) p + 22);
2176 qname->name = p + 23;
2177 result = p + 24 + len;
2178
2179 date = WVAL(p, 0);
2180 time = WVAL(p, 2);
2181 fattr->f_ctime.tv_sec = date_dos2unix(server, date, time);
2182 fattr->f_ctime.tv_nsec = 0;
2183
2184 date = WVAL(p, 4);
2185 time = WVAL(p, 6);
2186 fattr->f_atime.tv_sec = date_dos2unix(server, date, time);
2187 fattr->f_atime.tv_nsec = 0;
2188
2189 date = WVAL(p, 8);
2190 time = WVAL(p, 10);
2191 fattr->f_mtime.tv_sec = date_dos2unix(server, date, time);
2192 fattr->f_mtime.tv_nsec = 0;
2193 fattr->f_size = DVAL(p, 12);
2194 /* ULONG allocation size */
2195 fattr->attr = WVAL(p, 20);
2196
2197 VERBOSE("info 1 at %p, len=%d, name=%.*s\n",
2198 p, len, len, qname->name);
2199 break;
2200 case 260:
2201 result = p + WVAL(p, 0);
2202 len = DVAL(p, 60);
2203 if (len > 255) len = 255;
2204 /* NT4 null terminates, unless we are using unicode ... */
2205 qname->name = p + 94;
2206 if (!unicode && len && qname->name[len-1] == '\0')
2207 len--;
2208
2209 fattr->f_ctime = smb_ntutc2unixutc(LVAL(p, 8));
2210 fattr->f_atime = smb_ntutc2unixutc(LVAL(p, 16));
2211 fattr->f_mtime = smb_ntutc2unixutc(LVAL(p, 24));
2212 /* change time (32) */
2213 fattr->f_size = LVAL(p, 40);
2214 /* alloc size (48) */
2215 fattr->attr = DVAL(p, 56);
2216
2217 VERBOSE("info 260 at %p, len=%d, name=%.*s\n",
2218 p, len, len, qname->name);
2219 break;
2220 case SMB_FIND_FILE_UNIX:
2221 result = p + WVAL(p, 0);
2222 qname->name = p + 108;
2223
2224 len = strlen(qname->name);
2225 /* FIXME: should we check the length?? */
2226
2227 p += 8;
2228 smb_decode_unix_basic(fattr, server, p);
2229 VERBOSE("info SMB_FIND_FILE_UNIX at %p, len=%d, name=%.*s\n",
2230 p, len, len, qname->name);
2231 break;
2232 default:
2233 PARANOIA("Unknown info level %d\n", level);
2234 result = p + WVAL(p, 0);
2235 goto out;
2236 }
2237
2238 smb_finish_dirent(server, fattr);
2239
2240#if 0
2241 /* FIXME: These only work for ascii chars, and recent smbmount doesn't
2242 allow the flag to be set anyway. Remove? */
2243 switch (server->opt.case_handling) {
2244 case SMB_CASE_UPPER:
2245 str_upper(qname->name, len);
2246 break;
2247 case SMB_CASE_LOWER:
2248 str_lower(qname->name, len);
2249 break;
2250 default:
2251 break;
2252 }
2253#endif
2254
2255 qname->len = 0;
2256 n = server->ops->convert(name_buf, SMB_MAXNAMELEN,
2257 qname->name, len,
2258 server->remote_nls, server->local_nls);
2259 if (n > 0) {
2260 qname->len = n;
2261 qname->name = name_buf;
2262 }
2263
2264out:
2265 return result;
2266}
2267
2268/* findfirst/findnext flags */
2269#define SMB_CLOSE_AFTER_FIRST (1<<0)
2270#define SMB_CLOSE_IF_END (1<<1)
2271#define SMB_REQUIRE_RESUME_KEY (1<<2)
2272#define SMB_CONTINUE_BIT (1<<3)
2273
2274/*
2275 * Note: samba-2.0.7 (at least) has a very similar routine, cli_list, in
2276 * source/libsmb/clilist.c. When looking for smb bugs in the readdir code,
2277 * go there for advise.
2278 *
2279 * Bugs Noted:
2280 * (1) When using Info Level 1 Win NT 4.0 truncates directory listings
2281 * for certain patterns of names and/or lengths. The breakage pattern
2282 * is completely reproducible and can be toggled by the creation of a
2283 * single file. (E.g. echo hi >foo breaks, rm -f foo works.)
2284 */
2285static int
2286smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,
2287 struct smb_cache_control *ctl)
2288{
2289 struct dentry *dir = filp->f_path.dentry;
2290 struct smb_sb_info *server = server_from_dentry(dir);
2291 struct qstr qname;
2292 struct smb_fattr fattr;
2293
2294 unsigned char *p, *lastname;
2295 char *mask, *param;
2296 __u16 command;
2297 int first, entries_seen;
2298
2299 /* Both NT and OS/2 accept info level 1 (but see note below). */
2300 int info_level = 260;
2301 const int max_matches = 512;
2302
2303 unsigned int ff_searchcount = 0;
2304 unsigned int ff_eos = 0;
2305 unsigned int ff_lastname = 0;
2306 unsigned int ff_dir_handle = 0;
2307 unsigned int loop_count = 0;
2308 unsigned int mask_len, i;
2309 int result;
2310 struct smb_request *req;
2311 unsigned char *name_buf;
2312 static struct qstr star = {
2313 .name = "*",
2314 .len = 1,
2315 };
2316
2317 lock_kernel();
2318
2319 /*
2320 * We always prefer unix style. Use info level 1 for older
2321 * servers that don't do 260.
2322 */
2323 if (server->opt.capabilities & SMB_CAP_UNIX)
2324 info_level = SMB_FIND_FILE_UNIX;
2325 else if (server->opt.protocol < SMB_PROTOCOL_NT1)
2326 info_level = 1;
2327
2328 result = -ENOMEM;
2329 if (! (name_buf = kmalloc(SMB_MAXNAMELEN+2, GFP_KERNEL)))
2330 goto out;
2331 if (! (req = smb_alloc_request(server, server->opt.max_xmit)))
2332 goto out_name;
2333 param = req->rq_buffer;
2334
2335 /*
2336 * Encode the initial path
2337 */
2338 mask = param + 12;
2339
2340 result = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dir, &star);
2341 if (result <= 0)
2342 goto out_free;
2343 mask_len = result - 1; /* mask_len is strlen, not #bytes */
2344 result = 0;
2345 first = 1;
2346 VERBOSE("starting mask_len=%d, mask=%s\n", mask_len, mask);
2347
2348 entries_seen = 2;
2349 ff_eos = 0;
2350
2351 while (ff_eos == 0) {
2352 loop_count += 1;
2353 if (loop_count > 10) {
2354 printk(KERN_WARNING "smb_proc_readdir_long: "
2355 "Looping in FIND_NEXT??\n");
2356 result = -EIO;
2357 break;
2358 }
2359
2360 if (first != 0) {
2361 command = TRANSACT2_FINDFIRST;
2362 WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
2363 WSET(param, 2, max_matches); /* max count */
2364 WSET(param, 4, SMB_CLOSE_IF_END);
2365 WSET(param, 6, info_level);
2366 DSET(param, 8, 0);
2367 } else {
2368 command = TRANSACT2_FINDNEXT;
2369
2370 VERBOSE("handle=0x%X, lastname=%d, mask=%.*s\n",
2371 ff_dir_handle, ff_lastname, mask_len, mask);
2372
2373 WSET(param, 0, ff_dir_handle); /* search handle */
2374 WSET(param, 2, max_matches); /* max count */
2375 WSET(param, 4, info_level);
2376 DSET(param, 6, 0);
2377 WSET(param, 10, SMB_CONTINUE_BIT|SMB_CLOSE_IF_END);
2378 }
2379
2380 req->rq_trans2_command = command;
2381 req->rq_ldata = 0;
2382 req->rq_data = NULL;
2383 req->rq_lparm = 12 + mask_len + 1;
2384 req->rq_parm = param;
2385 req->rq_flags = 0;
2386 result = smb_add_request(req);
2387 if (result < 0) {
2388 PARANOIA("error=%d, breaking\n", result);
2389 break;
2390 }
2391
2392 if (req->rq_rcls == ERRSRV && req->rq_err == ERRerror) {
2393 /* a damn Win95 bug - sometimes it clags if you
2394 ask it too fast */
2395 schedule_timeout_interruptible(msecs_to_jiffies(200));
2396 continue;
2397 }
2398
2399 if (req->rq_rcls != 0) {
2400 result = smb_errno(req);
2401 PARANOIA("name=%s, result=%d, rcls=%d, err=%d\n",
2402 mask, result, req->rq_rcls, req->rq_err);
2403 break;
2404 }
2405
2406 /* parse out some important return info */
2407 if (first != 0) {
2408 ff_dir_handle = WVAL(req->rq_parm, 0);
2409 ff_searchcount = WVAL(req->rq_parm, 2);
2410 ff_eos = WVAL(req->rq_parm, 4);
2411 ff_lastname = WVAL(req->rq_parm, 8);
2412 } else {
2413 ff_searchcount = WVAL(req->rq_parm, 0);
2414 ff_eos = WVAL(req->rq_parm, 2);
2415 ff_lastname = WVAL(req->rq_parm, 6);
2416 }
2417
2418 if (ff_searchcount == 0)
2419 break;
2420
2421 /* Now we are ready to parse smb directory entries. */
2422
2423 /* point to the data bytes */
2424 p = req->rq_data;
2425 for (i = 0; i < ff_searchcount; i++) {
2426 /* make sure we stay within the buffer */
2427 if (p >= req->rq_data + req->rq_ldata) {
2428 printk(KERN_ERR "smb_proc_readdir_long: "
2429 "dirent pointer outside buffer! "
2430 "%p %d@%p\n",
2431 p, req->rq_ldata, req->rq_data);
2432 result = -EIO; /* always a comm. error? */
2433 goto out_free;
2434 }
2435
2436 p = smb_decode_long_dirent(server, p, info_level,
2437 &qname, &fattr, name_buf);
2438
2439 /* ignore . and .. from the server */
2440 if (entries_seen == 2 && qname.name[0] == '.') {
2441 if (qname.len == 1)
2442 continue;
2443 if (qname.name[1] == '.' && qname.len == 2)
2444 continue;
2445 }
2446
2447 if (!smb_fill_cache(filp, dirent, filldir, ctl,
2448 &qname, &fattr))
2449 ; /* stop reading? */
2450 entries_seen++;
2451 }
2452
2453 VERBOSE("received %d entries, eos=%d\n", ff_searchcount,ff_eos);
2454
2455 /*
2456 * We might need the lastname for continuations.
2457 *
2458 * Note that some servers (win95?) point to the filename and
2459 * others (NT4, Samba using NT1) to the dir entry. We assume
2460 * here that those who do not point to a filename do not need
2461 * this info to continue the listing.
2462 *
2463 * OS/2 needs this and talks infolevel 1.
2464 * NetApps want lastname with infolevel 260.
2465 * win2k want lastname with infolevel 260, and points to
2466 * the record not to the name.
2467 * Samba+CifsUnixExt doesn't need lastname.
2468 *
2469 * Both are happy if we return the data they point to. So we do.
2470 * (FIXME: above is not true with win2k)
2471 */
2472 mask_len = 0;
2473 if (info_level != SMB_FIND_FILE_UNIX &&
2474 ff_lastname > 0 && ff_lastname < req->rq_ldata) {
2475 lastname = req->rq_data + ff_lastname;
2476
2477 switch (info_level) {
2478 case 260:
2479 mask_len = req->rq_ldata - ff_lastname;
2480 break;
2481 case 1:
2482 /* lastname points to a length byte */
2483 mask_len = *lastname++;
2484 if (ff_lastname + 1 + mask_len > req->rq_ldata)
2485 mask_len = req->rq_ldata - ff_lastname - 1;
2486 break;
2487 }
2488
2489 /*
2490 * Update the mask string for the next message.
2491 */
2492 if (mask_len > 255)
2493 mask_len = 255;
2494 if (mask_len)
2495 strncpy(mask, lastname, mask_len);
2496 }
2497 mask_len = strnlen(mask, mask_len);
2498 VERBOSE("new mask, len=%d@%d of %d, mask=%.*s\n",
2499 mask_len, ff_lastname, req->rq_ldata, mask_len, mask);
2500
2501 first = 0;
2502 loop_count = 0;
2503 }
2504
2505out_free:
2506 smb_rput(req);
2507out_name:
2508 kfree(name_buf);
2509out:
2510 unlock_kernel();
2511 return result;
2512}
2513
2514/*
2515 * This version uses the trans2 TRANSACT2_FINDFIRST message
2516 * to get the attribute data.
2517 *
2518 * Bugs Noted:
2519 */
2520static int
2521smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,
2522 struct smb_fattr *fattr)
2523{
2524 char *param, *mask;
2525 __u16 date, time;
2526 int mask_len, result;
2527 struct smb_request *req;
2528
2529 result = -ENOMEM;
2530 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
2531 goto out;
2532 param = req->rq_buffer;
2533 mask = param + 12;
2534
2535 mask_len = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dentry,NULL);
2536 if (mask_len < 0) {
2537 result = mask_len;
2538 goto out_free;
2539 }
2540 VERBOSE("name=%s, len=%d\n", mask, mask_len);
2541 WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
2542 WSET(param, 2, 1); /* max count */
2543 WSET(param, 4, 1); /* close after this call */
2544 WSET(param, 6, 1); /* info_level */
2545 DSET(param, 8, 0);
2546
2547 req->rq_trans2_command = TRANSACT2_FINDFIRST;
2548 req->rq_ldata = 0;
2549 req->rq_data = NULL;
2550 req->rq_lparm = 12 + mask_len;
2551 req->rq_parm = param;
2552 req->rq_flags = 0;
2553 result = smb_add_request(req);
2554 if (result < 0)
2555 goto out_free;
2556 if (req->rq_rcls != 0) {
2557 result = smb_errno(req);
2558#ifdef SMBFS_PARANOIA
2559 if (result != -ENOENT)
2560 PARANOIA("error for %s, rcls=%d, err=%d\n",
2561 mask, req->rq_rcls, req->rq_err);
2562#endif
2563 goto out_free;
2564 }
2565 /* Make sure we got enough data ... */
2566 result = -EINVAL;
2567 if (req->rq_ldata < 22 || WVAL(req->rq_parm, 2) != 1) {
2568 PARANOIA("bad result for %s, len=%d, count=%d\n",
2569 mask, req->rq_ldata, WVAL(req->rq_parm, 2));
2570 goto out_free;
2571 }
2572
2573 /*
2574 * Decode the response into the fattr ...
2575 */
2576 date = WVAL(req->rq_data, 0);
2577 time = WVAL(req->rq_data, 2);
2578 fattr->f_ctime.tv_sec = date_dos2unix(server, date, time);
2579 fattr->f_ctime.tv_nsec = 0;
2580
2581 date = WVAL(req->rq_data, 4);
2582 time = WVAL(req->rq_data, 6);
2583 fattr->f_atime.tv_sec = date_dos2unix(server, date, time);
2584 fattr->f_atime.tv_nsec = 0;
2585
2586 date = WVAL(req->rq_data, 8);
2587 time = WVAL(req->rq_data, 10);
2588 fattr->f_mtime.tv_sec = date_dos2unix(server, date, time);
2589 fattr->f_mtime.tv_nsec = 0;
2590 VERBOSE("name=%s, date=%x, time=%x, mtime=%ld\n",
2591 mask, date, time, fattr->f_mtime.tv_sec);
2592 fattr->f_size = DVAL(req->rq_data, 12);
2593 /* ULONG allocation size */
2594 fattr->attr = WVAL(req->rq_data, 20);
2595 result = 0;
2596
2597out_free:
2598 smb_rput(req);
2599out:
2600 return result;
2601}
2602
2603static int
2604smb_proc_getattr_core(struct smb_sb_info *server, struct dentry *dir,
2605 struct smb_fattr *fattr)
2606{
2607 int result;
2608 char *p;
2609 struct smb_request *req;
2610
2611 result = -ENOMEM;
2612 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
2613 goto out;
2614
2615 p = smb_setup_header(req, SMBgetatr, 0, 0);
2616 result = smb_simple_encode_path(req, &p, dir, NULL);
2617 if (result < 0)
2618 goto out_free;
2619 smb_setup_bcc(req, p);
2620
2621 if ((result = smb_request_ok(req, SMBgetatr, 10, 0)) < 0)
2622 goto out_free;
2623 fattr->attr = WVAL(req->rq_header, smb_vwv0);
2624 fattr->f_mtime.tv_sec = local2utc(server, DVAL(req->rq_header, smb_vwv1));
2625 fattr->f_mtime.tv_nsec = 0;
2626 fattr->f_size = DVAL(req->rq_header, smb_vwv3);
2627 fattr->f_ctime = fattr->f_mtime;
2628 fattr->f_atime = fattr->f_mtime;
2629#ifdef SMBFS_DEBUG_TIMESTAMP
2630 printk("getattr_core: %s/%s, mtime=%ld\n",
2631 DENTRY_PATH(dir), fattr->f_mtime);
2632#endif
2633 result = 0;
2634
2635out_free:
2636 smb_rput(req);
2637out:
2638 return result;
2639}
2640
2641/*
2642 * Bugs Noted:
2643 * (1) Win 95 swaps the date and time fields in the standard info level.
2644 */
2645static int
2646smb_proc_getattr_trans2(struct smb_sb_info *server, struct dentry *dir,
2647 struct smb_request *req, int infolevel)
2648{
2649 char *p, *param;
2650 int result;
2651
2652 param = req->rq_buffer;
2653 WSET(param, 0, infolevel);
2654 DSET(param, 2, 0);
2655 result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL);
2656 if (result < 0)
2657 goto out;
2658 p = param + 6 + result;
2659
2660 req->rq_trans2_command = TRANSACT2_QPATHINFO;
2661 req->rq_ldata = 0;
2662 req->rq_data = NULL;
2663 req->rq_lparm = p - param;
2664 req->rq_parm = param;
2665 req->rq_flags = 0;
2666 result = smb_add_request(req);
2667 if (result < 0)
2668 goto out;
2669 if (req->rq_rcls != 0) {
2670 VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
2671 &param[6], result, req->rq_rcls, req->rq_err);
2672 result = smb_errno(req);
2673 goto out;
2674 }
2675 result = -ENOENT;
2676 if (req->rq_ldata < 22) {
2677 PARANOIA("not enough data for %s, len=%d\n",
2678 &param[6], req->rq_ldata);
2679 goto out;
2680 }
2681
2682 result = 0;
2683out:
2684 return result;
2685}
2686
2687static int
2688smb_proc_getattr_trans2_std(struct smb_sb_info *server, struct dentry *dir,
2689 struct smb_fattr *attr)
2690{
2691 u16 date, time;
2692 int off_date = 0, off_time = 2;
2693 int result;
2694 struct smb_request *req;
2695
2696 result = -ENOMEM;
2697 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
2698 goto out;
2699
2700 result = smb_proc_getattr_trans2(server, dir, req, SMB_INFO_STANDARD);
2701 if (result < 0)
2702 goto out_free;
2703
2704 /*
2705 * Kludge alert: Win 95 swaps the date and time field,
2706 * contrary to the CIFS docs and Win NT practice.
2707 */
2708 if (server->mnt->flags & SMB_MOUNT_WIN95) {
2709 off_date = 2;
2710 off_time = 0;
2711 }
2712 date = WVAL(req->rq_data, off_date);
2713 time = WVAL(req->rq_data, off_time);
2714 attr->f_ctime.tv_sec = date_dos2unix(server, date, time);
2715 attr->f_ctime.tv_nsec = 0;
2716
2717 date = WVAL(req->rq_data, 4 + off_date);
2718 time = WVAL(req->rq_data, 4 + off_time);
2719 attr->f_atime.tv_sec = date_dos2unix(server, date, time);
2720 attr->f_atime.tv_nsec = 0;
2721
2722 date = WVAL(req->rq_data, 8 + off_date);
2723 time = WVAL(req->rq_data, 8 + off_time);
2724 attr->f_mtime.tv_sec = date_dos2unix(server, date, time);
2725 attr->f_mtime.tv_nsec = 0;
2726#ifdef SMBFS_DEBUG_TIMESTAMP
2727 printk(KERN_DEBUG "getattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n",
2728 DENTRY_PATH(dir), date, time, attr->f_mtime);
2729#endif
2730 attr->f_size = DVAL(req->rq_data, 12);
2731 attr->attr = WVAL(req->rq_data, 20);
2732
2733out_free:
2734 smb_rput(req);
2735out:
2736 return result;
2737}
2738
2739static int
2740smb_proc_getattr_trans2_all(struct smb_sb_info *server, struct dentry *dir,
2741 struct smb_fattr *attr)
2742{
2743 struct smb_request *req;
2744 int result;
2745
2746 result = -ENOMEM;
2747 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
2748 goto out;
2749
2750 result = smb_proc_getattr_trans2(server, dir, req,
2751 SMB_QUERY_FILE_ALL_INFO);
2752 if (result < 0)
2753 goto out_free;
2754
2755 attr->f_ctime = smb_ntutc2unixutc(LVAL(req->rq_data, 0));
2756 attr->f_atime = smb_ntutc2unixutc(LVAL(req->rq_data, 8));
2757 attr->f_mtime = smb_ntutc2unixutc(LVAL(req->rq_data, 16));
2758 /* change (24) */
2759 attr->attr = WVAL(req->rq_data, 32);
2760 /* pad? (34) */
2761 /* allocated size (40) */
2762 attr->f_size = LVAL(req->rq_data, 48);
2763
2764out_free:
2765 smb_rput(req);
2766out:
2767 return result;
2768}
2769
2770static int
2771smb_proc_getattr_unix(struct smb_sb_info *server, struct dentry *dir,
2772 struct smb_fattr *attr)
2773{
2774 struct smb_request *req;
2775 int result;
2776
2777 result = -ENOMEM;
2778 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
2779 goto out;
2780
2781 result = smb_proc_getattr_trans2(server, dir, req,
2782 SMB_QUERY_FILE_UNIX_BASIC);
2783 if (result < 0)
2784 goto out_free;
2785
2786 smb_decode_unix_basic(attr, server, req->rq_data);
2787
2788out_free:
2789 smb_rput(req);
2790out:
2791 return result;
2792}
2793
2794static int
2795smb_proc_getattr_95(struct smb_sb_info *server, struct dentry *dir,
2796 struct smb_fattr *attr)
2797{
2798 struct inode *inode = dir->d_inode;
2799 int result;
2800
2801 /* FIXME: why not use the "all" version? */
2802 result = smb_proc_getattr_trans2_std(server, dir, attr);
2803 if (result < 0)
2804 goto out;
2805
2806 /*
2807 * None of the getattr versions here can make win9x return the right
2808 * filesize if there are changes made to an open file.
2809 * A seek-to-end does return the right size, but we only need to do
2810 * that on files we have written.
2811 */
2812 if (inode && SMB_I(inode)->flags & SMB_F_LOCALWRITE &&
2813 smb_is_open(inode))
2814 {
2815 __u16 fileid = SMB_I(inode)->fileid;
2816 attr->f_size = smb_proc_seek(server, fileid, 2, 0);
2817 }
2818
2819out:
2820 return result;
2821}
2822
2823static int
2824smb_proc_ops_wait(struct smb_sb_info *server)
2825{
2826 int result;
2827
2828 result = wait_event_interruptible_timeout(server->conn_wq,
2829 server->conn_complete, 30*HZ);
2830
2831 if (!result || signal_pending(current))
2832 return -EIO;
2833
2834 return 0;
2835}
2836
2837static int
2838smb_proc_getattr_null(struct smb_sb_info *server, struct dentry *dir,
2839 struct smb_fattr *fattr)
2840{
2841 int result;
2842
2843 if (smb_proc_ops_wait(server) < 0)
2844 return -EIO;
2845
2846 smb_init_dirent(server, fattr);
2847 result = server->ops->getattr(server, dir, fattr);
2848 smb_finish_dirent(server, fattr);
2849
2850 return result;
2851}
2852
2853static int
2854smb_proc_readdir_null(struct file *filp, void *dirent, filldir_t filldir,
2855 struct smb_cache_control *ctl)
2856{
2857 struct smb_sb_info *server = server_from_dentry(filp->f_path.dentry);
2858
2859 if (smb_proc_ops_wait(server) < 0)
2860 return -EIO;
2861
2862 return server->ops->readdir(filp, dirent, filldir, ctl);
2863}
2864
2865int
2866smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr)
2867{
2868 struct smb_sb_info *server = server_from_dentry(dir);
2869 int result;
2870
2871 smb_init_dirent(server, fattr);
2872 result = server->ops->getattr(server, dir, fattr);
2873 smb_finish_dirent(server, fattr);
2874
2875 return result;
2876}
2877
2878
2879/*
2880 * Because of bugs in the core protocol, we use this only to set
2881 * attributes. See smb_proc_settime() below for timestamp handling.
2882 *
2883 * Bugs Noted:
2884 * (1) If mtime is non-zero, both Win 3.1 and Win 95 fail
2885 * with an undocumented error (ERRDOS code 50). Setting
2886 * mtime to 0 allows the attributes to be set.
2887 * (2) The extra parameters following the name string aren't
2888 * in the CIFS docs, but seem to be necessary for operation.
2889 */
2890static int
2891smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
2892 __u16 attr)
2893{
2894 char *p;
2895 int result;
2896 struct smb_request *req;
2897
2898 result = -ENOMEM;
2899 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
2900 goto out;
2901
2902 p = smb_setup_header(req, SMBsetatr, 8, 0);
2903 WSET(req->rq_header, smb_vwv0, attr);
2904 DSET(req->rq_header, smb_vwv1, 0); /* mtime */
2905 WSET(req->rq_header, smb_vwv3, 0); /* reserved values */
2906 WSET(req->rq_header, smb_vwv4, 0);
2907 WSET(req->rq_header, smb_vwv5, 0);
2908 WSET(req->rq_header, smb_vwv6, 0);
2909 WSET(req->rq_header, smb_vwv7, 0);
2910 result = smb_simple_encode_path(req, &p, dentry, NULL);
2911 if (result < 0)
2912 goto out_free;
2913 if (p + 2 > (char *)req->rq_buffer + req->rq_bufsize) {
2914 result = -ENAMETOOLONG;
2915 goto out_free;
2916 }
2917 *p++ = 4;
2918 *p++ = 0;
2919 smb_setup_bcc(req, p);
2920
2921 result = smb_request_ok(req, SMBsetatr, 0, 0);
2922 if (result < 0)
2923 goto out_free;
2924 result = 0;
2925
2926out_free:
2927 smb_rput(req);
2928out:
2929 return result;
2930}
2931
2932/*
2933 * Because of bugs in the trans2 setattr messages, we must set
2934 * attributes and timestamps separately. The core SMBsetatr
2935 * message seems to be the only reliable way to set attributes.
2936 */
2937int
2938smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr)
2939{
2940 struct smb_sb_info *server = server_from_dentry(dir);
2941 int result;
2942
2943 VERBOSE("setting %s/%s, open=%d\n",
2944 DENTRY_PATH(dir), smb_is_open(dir->d_inode));
2945 result = smb_proc_setattr_core(server, dir, fattr->attr);
2946 return result;
2947}
2948
2949/*
2950 * Sets the timestamps for an file open with write permissions.
2951 */
2952static int
2953smb_proc_setattr_ext(struct smb_sb_info *server,
2954 struct inode *inode, struct smb_fattr *fattr)
2955{
2956 __u16 date, time;
2957 int result;
2958 struct smb_request *req;
2959
2960 result = -ENOMEM;
2961 if (! (req = smb_alloc_request(server, 0)))
2962 goto out;
2963
2964 smb_setup_header(req, SMBsetattrE, 7, 0);
2965 WSET(req->rq_header, smb_vwv0, SMB_I(inode)->fileid);
2966 /* We don't change the creation time */
2967 WSET(req->rq_header, smb_vwv1, 0);
2968 WSET(req->rq_header, smb_vwv2, 0);
2969 date_unix2dos(server, fattr->f_atime.tv_sec, &date, &time);
2970 WSET(req->rq_header, smb_vwv3, date);
2971 WSET(req->rq_header, smb_vwv4, time);
2972 date_unix2dos(server, fattr->f_mtime.tv_sec, &date, &time);
2973 WSET(req->rq_header, smb_vwv5, date);
2974 WSET(req->rq_header, smb_vwv6, time);
2975#ifdef SMBFS_DEBUG_TIMESTAMP
2976 printk(KERN_DEBUG "smb_proc_setattr_ext: date=%d, time=%d, mtime=%ld\n",
2977 date, time, fattr->f_mtime);
2978#endif
2979
2980 req->rq_flags |= SMB_REQ_NORETRY;
2981 result = smb_request_ok(req, SMBsetattrE, 0, 0);
2982 if (result < 0)
2983 goto out_free;
2984 result = 0;
2985out_free:
2986 smb_rput(req);
2987out:
2988 return result;
2989}
2990
2991/*
2992 * Bugs Noted:
2993 * (1) The TRANSACT2_SETPATHINFO message under Win NT 4.0 doesn't
2994 * set the file's attribute flags.
2995 */
2996static int
2997smb_proc_setattr_trans2(struct smb_sb_info *server,
2998 struct dentry *dir, struct smb_fattr *fattr)
2999{
3000 __u16 date, time;
3001 char *p, *param;
3002 int result;
3003 char data[26];
3004 struct smb_request *req;
3005
3006 result = -ENOMEM;
3007 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
3008 goto out;
3009 param = req->rq_buffer;
3010
3011 WSET(param, 0, 1); /* Info level SMB_INFO_STANDARD */
3012 DSET(param, 2, 0);
3013 result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL);
3014 if (result < 0)
3015 goto out_free;
3016 p = param + 6 + result;
3017
3018 WSET(data, 0, 0); /* creation time */
3019 WSET(data, 2, 0);
3020 date_unix2dos(server, fattr->f_atime.tv_sec, &date, &time);
3021 WSET(data, 4, date);
3022 WSET(data, 6, time);
3023 date_unix2dos(server, fattr->f_mtime.tv_sec, &date, &time);
3024 WSET(data, 8, date);
3025 WSET(data, 10, time);
3026#ifdef SMBFS_DEBUG_TIMESTAMP
3027 printk(KERN_DEBUG "setattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n",
3028 DENTRY_PATH(dir), date, time, fattr->f_mtime);
3029#endif
3030 DSET(data, 12, 0); /* size */
3031 DSET(data, 16, 0); /* blksize */
3032 WSET(data, 20, 0); /* attr */
3033 DSET(data, 22, 0); /* ULONG EA size */
3034
3035 req->rq_trans2_command = TRANSACT2_SETPATHINFO;
3036 req->rq_ldata = 26;
3037 req->rq_data = data;
3038 req->rq_lparm = p - param;
3039 req->rq_parm = param;
3040 req->rq_flags = 0;
3041 result = smb_add_request(req);
3042 if (result < 0)
3043 goto out_free;
3044 result = 0;
3045 if (req->rq_rcls != 0)
3046 result = smb_errno(req);
3047
3048out_free:
3049 smb_rput(req);
3050out:
3051 return result;
3052}
3053
3054/*
3055 * ATTR_MODE 0x001
3056 * ATTR_UID 0x002
3057 * ATTR_GID 0x004
3058 * ATTR_SIZE 0x008
3059 * ATTR_ATIME 0x010
3060 * ATTR_MTIME 0x020
3061 * ATTR_CTIME 0x040
3062 * ATTR_ATIME_SET 0x080
3063 * ATTR_MTIME_SET 0x100
3064 * ATTR_FORCE 0x200
3065 * ATTR_ATTR_FLAG 0x400
3066 *
3067 * major/minor should only be set by mknod.
3068 */
3069int
3070smb_proc_setattr_unix(struct dentry *d, struct iattr *attr,
3071 unsigned int major, unsigned int minor)
3072{
3073 struct smb_sb_info *server = server_from_dentry(d);
3074 u64 nttime;
3075 char *p, *param;
3076 int result;
3077 char data[100];
3078 struct smb_request *req;
3079
3080 result = -ENOMEM;
3081 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
3082 goto out;
3083 param = req->rq_buffer;
3084
3085 DEBUG1("valid flags = 0x%04x\n", attr->ia_valid);
3086
3087 WSET(param, 0, SMB_SET_FILE_UNIX_BASIC);
3088 DSET(param, 2, 0);
3089 result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, d, NULL);
3090 if (result < 0)
3091 goto out_free;
3092 p = param + 6 + result;
3093
3094 /* 0 L file size in bytes */
3095 /* 8 L file size on disk in bytes (block count) */
3096 /* 40 L uid */
3097 /* 48 L gid */
3098 /* 56 W file type enum */
3099 /* 60 L devmajor */
3100 /* 68 L devminor */
3101 /* 76 L unique ID (inode) */
3102 /* 84 L permissions */
3103 /* 92 L link count */
3104 LSET(data, 0, SMB_SIZE_NO_CHANGE);
3105 LSET(data, 8, SMB_SIZE_NO_CHANGE);
3106 LSET(data, 16, SMB_TIME_NO_CHANGE);
3107 LSET(data, 24, SMB_TIME_NO_CHANGE);
3108 LSET(data, 32, SMB_TIME_NO_CHANGE);
3109 LSET(data, 40, SMB_UID_NO_CHANGE);
3110 LSET(data, 48, SMB_GID_NO_CHANGE);
3111 DSET(data, 56, smb_filetype_from_mode(attr->ia_mode));
3112 LSET(data, 60, major);
3113 LSET(data, 68, minor);
3114 LSET(data, 76, 0);
3115 LSET(data, 84, SMB_MODE_NO_CHANGE);
3116 LSET(data, 92, 0);
3117
3118 if (attr->ia_valid & ATTR_SIZE) {
3119 LSET(data, 0, attr->ia_size);
3120 LSET(data, 8, 0); /* can't set anyway */
3121 }
3122
3123 /*
3124 * FIXME: check the conversion function it the correct one
3125 *
3126 * we can't set ctime but we might as well pass this to the server
3127 * and let it ignore it.
3128 */
3129 if (attr->ia_valid & ATTR_CTIME) {
3130 nttime = smb_unixutc2ntutc(attr->ia_ctime);
3131 LSET(data, 16, nttime);
3132 }
3133 if (attr->ia_valid & ATTR_ATIME) {
3134 nttime = smb_unixutc2ntutc(attr->ia_atime);
3135 LSET(data, 24, nttime);
3136 }
3137 if (attr->ia_valid & ATTR_MTIME) {
3138 nttime = smb_unixutc2ntutc(attr->ia_mtime);
3139 LSET(data, 32, nttime);
3140 }
3141
3142 if (attr->ia_valid & ATTR_UID) {
3143 LSET(data, 40, attr->ia_uid);
3144 }
3145 if (attr->ia_valid & ATTR_GID) {
3146 LSET(data, 48, attr->ia_gid);
3147 }
3148
3149 if (attr->ia_valid & ATTR_MODE) {
3150 LSET(data, 84, attr->ia_mode);
3151 }
3152
3153 req->rq_trans2_command = TRANSACT2_SETPATHINFO;
3154 req->rq_ldata = 100;
3155 req->rq_data = data;
3156 req->rq_lparm = p - param;
3157 req->rq_parm = param;
3158 req->rq_flags = 0;
3159 result = smb_add_request(req);
3160
3161out_free:
3162 smb_rput(req);
3163out:
3164 return result;
3165}
3166
3167
3168/*
3169 * Set the modify and access timestamps for a file.
3170 *
3171 * Incredibly enough, in all of SMB there is no message to allow
3172 * setting both attributes and timestamps at once.
3173 *
3174 * Bugs Noted:
3175 * (1) Win 95 doesn't support the TRANSACT2_SETFILEINFO message
3176 * with info level 1 (INFO_STANDARD).
3177 * (2) Win 95 seems not to support setting directory timestamps.
3178 * (3) Under the core protocol apparently the only way to set the
3179 * timestamp is to open and close the file.
3180 */
3181int
3182smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr)
3183{
3184 struct smb_sb_info *server = server_from_dentry(dentry);
3185 struct inode *inode = dentry->d_inode;
3186 int result;
3187
3188 VERBOSE("setting %s/%s, open=%d\n",
3189 DENTRY_PATH(dentry), smb_is_open(inode));
3190
3191 /* setting the time on a Win95 server fails (tridge) */
3192 if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 &&
3193 !(server->mnt->flags & SMB_MOUNT_WIN95)) {
3194 if (smb_is_open(inode) && SMB_I(inode)->access != SMB_O_RDONLY)
3195 result = smb_proc_setattr_ext(server, inode, fattr);
3196 else
3197 result = smb_proc_setattr_trans2(server, dentry, fattr);
3198 } else {
3199 /*
3200 * Fail silently on directories ... timestamp can't be set?
3201 */
3202 result = 0;
3203 if (S_ISREG(inode->i_mode)) {
3204 /*
3205 * Set the mtime by opening and closing the file.
3206 * Note that the file is opened read-only, but this
3207 * still allows us to set the date (tridge)
3208 */
3209 result = -EACCES;
3210 if (!smb_is_open(inode))
3211 smb_proc_open(server, dentry, SMB_O_RDONLY);
3212 if (smb_is_open(inode)) {
3213 inode->i_mtime = fattr->f_mtime;
3214 result = smb_proc_close_inode(server, inode);
3215 }
3216 }
3217 }
3218
3219 return result;
3220}
3221
3222int
3223smb_proc_dskattr(struct dentry *dentry, struct kstatfs *attr)
3224{
3225 struct smb_sb_info *server = SMB_SB(dentry->d_sb);
3226 int result;
3227 char *p;
3228 long unit;
3229 struct smb_request *req;
3230
3231 result = -ENOMEM;
3232 if (! (req = smb_alloc_request(server, 0)))
3233 goto out;
3234
3235 smb_setup_header(req, SMBdskattr, 0, 0);
3236 if ((result = smb_request_ok(req, SMBdskattr, 5, 0)) < 0)
3237 goto out_free;
3238 p = SMB_VWV(req->rq_header);
3239 unit = (WVAL(p, 2) * WVAL(p, 4)) >> SMB_ST_BLKSHIFT;
3240 attr->f_blocks = WVAL(p, 0) * unit;
3241 attr->f_bsize = SMB_ST_BLKSIZE;
3242 attr->f_bavail = attr->f_bfree = WVAL(p, 6) * unit;
3243 result = 0;
3244
3245out_free:
3246 smb_rput(req);
3247out:
3248 return result;
3249}
3250
3251int
3252smb_proc_read_link(struct smb_sb_info *server, struct dentry *d,
3253 char *buffer, int len)
3254{
3255 char *p, *param;
3256 int result;
3257 struct smb_request *req;
3258
3259 DEBUG1("readlink of %s/%s\n", DENTRY_PATH(d));
3260
3261 result = -ENOMEM;
3262 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
3263 goto out;
3264 param = req->rq_buffer;
3265
3266 WSET(param, 0, SMB_QUERY_FILE_UNIX_LINK);
3267 DSET(param, 2, 0);
3268 result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, d, NULL);
3269 if (result < 0)
3270 goto out_free;
3271 p = param + 6 + result;
3272
3273 req->rq_trans2_command = TRANSACT2_QPATHINFO;
3274 req->rq_ldata = 0;
3275 req->rq_data = NULL;
3276 req->rq_lparm = p - param;
3277 req->rq_parm = param;
3278 req->rq_flags = 0;
3279 result = smb_add_request(req);
3280 if (result < 0)
3281 goto out_free;
3282 DEBUG1("for %s: result=%d, rcls=%d, err=%d\n",
3283 &param[6], result, req->rq_rcls, req->rq_err);
3284
3285 /* copy data up to the \0 or buffer length */
3286 result = len;
3287 if (req->rq_ldata < len)
3288 result = req->rq_ldata;
3289 strncpy(buffer, req->rq_data, result);
3290
3291out_free:
3292 smb_rput(req);
3293out:
3294 return result;
3295}
3296
3297
3298/*
3299 * Create a symlink object called dentry which points to oldpath.
3300 * Samba does not permit dangling links but returns a suitable error message.
3301 */
3302int
3303smb_proc_symlink(struct smb_sb_info *server, struct dentry *d,
3304 const char *oldpath)
3305{
3306 char *p, *param;
3307 int result;
3308 struct smb_request *req;
3309
3310 result = -ENOMEM;
3311 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
3312 goto out;
3313 param = req->rq_buffer;
3314
3315 WSET(param, 0, SMB_SET_FILE_UNIX_LINK);
3316 DSET(param, 2, 0);
3317 result = smb_encode_path(server, param + 6, SMB_MAXPATHLEN+1, d, NULL);
3318 if (result < 0)
3319 goto out_free;
3320 p = param + 6 + result;
3321
3322 req->rq_trans2_command = TRANSACT2_SETPATHINFO;
3323 req->rq_ldata = strlen(oldpath) + 1;
3324 req->rq_data = (char *) oldpath;
3325 req->rq_lparm = p - param;
3326 req->rq_parm = param;
3327 req->rq_flags = 0;
3328 result = smb_add_request(req);
3329 if (result < 0)
3330 goto out_free;
3331
3332 DEBUG1("for %s: result=%d, rcls=%d, err=%d\n",
3333 &param[6], result, req->rq_rcls, req->rq_err);
3334 result = 0;
3335
3336out_free:
3337 smb_rput(req);
3338out:
3339 return result;
3340}
3341
3342/*
3343 * Create a hard link object called new_dentry which points to dentry.
3344 */
3345int
3346smb_proc_link(struct smb_sb_info *server, struct dentry *dentry,
3347 struct dentry *new_dentry)
3348{
3349 char *p, *param;
3350 int result;
3351 struct smb_request *req;
3352
3353 result = -ENOMEM;
3354 if (! (req = smb_alloc_request(server, PAGE_SIZE)))
3355 goto out;
3356 param = req->rq_buffer;
3357
3358 WSET(param, 0, SMB_SET_FILE_UNIX_HLINK);
3359 DSET(param, 2, 0);
3360 result = smb_encode_path(server, param + 6, SMB_MAXPATHLEN+1,
3361 new_dentry, NULL);
3362 if (result < 0)
3363 goto out_free;
3364 p = param + 6 + result;
3365
3366 /* Grr, pointless separation of parameters and data ... */
3367 req->rq_data = p;
3368 req->rq_ldata = smb_encode_path(server, p, SMB_MAXPATHLEN+1,
3369 dentry, NULL);
3370
3371 req->rq_trans2_command = TRANSACT2_SETPATHINFO;
3372 req->rq_lparm = p - param;
3373 req->rq_parm = param;
3374 req->rq_flags = 0;
3375 result = smb_add_request(req);
3376 if (result < 0)
3377 goto out_free;
3378
3379 DEBUG1("for %s: result=%d, rcls=%d, err=%d\n",
3380 &param[6], result, req->rq_rcls, req->rq_err);
3381 result = 0;
3382
3383out_free:
3384 smb_rput(req);
3385out:
3386 return result;
3387}
3388
3389static int
3390smb_proc_query_cifsunix(struct smb_sb_info *server)
3391{
3392 int result;
3393 int major, minor;
3394 u64 caps;
3395 char param[2];
3396 struct smb_request *req;
3397
3398 result = -ENOMEM;
3399 if (! (req = smb_alloc_request(server, 100)))
3400 goto out;
3401
3402 WSET(param, 0, SMB_QUERY_CIFS_UNIX_INFO);
3403
3404 req->rq_trans2_command = TRANSACT2_QFSINFO;
3405 req->rq_ldata = 0;
3406 req->rq_data = NULL;
3407 req->rq_lparm = 2;
3408 req->rq_parm = param;
3409 req->rq_flags = 0;
3410 result = smb_add_request(req);
3411 if (result < 0)
3412 goto out_free;
3413
3414 if (req->rq_ldata < 12) {
3415 PARANOIA("Not enough data\n");
3416 goto out_free;
3417 }
3418 major = WVAL(req->rq_data, 0);
3419 minor = WVAL(req->rq_data, 2);
3420
3421 DEBUG1("Server implements CIFS Extensions for UNIX systems v%d.%d\n",
3422 major, minor);
3423 /* FIXME: verify that we are ok with this major/minor? */
3424
3425 caps = LVAL(req->rq_data, 4);
3426 DEBUG1("Server capabilities 0x%016llx\n", caps);
3427
3428out_free:
3429 smb_rput(req);
3430out:
3431 return result;
3432}
3433
3434
3435static void
3436install_ops(struct smb_ops *dst, struct smb_ops *src)
3437{
3438 memcpy(dst, src, sizeof(void *) * SMB_OPS_NUM_STATIC);
3439}
3440
3441/* < LANMAN2 */
3442static struct smb_ops smb_ops_core =
3443{
3444 .read = smb_proc_read,
3445 .write = smb_proc_write,
3446 .readdir = smb_proc_readdir_short,
3447 .getattr = smb_proc_getattr_core,
3448 .truncate = smb_proc_trunc32,
3449};
3450
3451/* LANMAN2, OS/2, others? */
3452static struct smb_ops smb_ops_os2 =
3453{
3454 .read = smb_proc_read,
3455 .write = smb_proc_write,
3456 .readdir = smb_proc_readdir_long,
3457 .getattr = smb_proc_getattr_trans2_std,
3458 .truncate = smb_proc_trunc32,
3459};
3460
3461/* Win95, and possibly some NetApp versions too */
3462static struct smb_ops smb_ops_win95 =
3463{
3464 .read = smb_proc_read, /* does not support 12word readX */
3465 .write = smb_proc_write,
3466 .readdir = smb_proc_readdir_long,
3467 .getattr = smb_proc_getattr_95,
3468 .truncate = smb_proc_trunc95,
3469};
3470
3471/* Samba, NT4 and NT5 */
3472static struct smb_ops smb_ops_winNT =
3473{
3474 .read = smb_proc_readX,
3475 .write = smb_proc_writeX,
3476 .readdir = smb_proc_readdir_long,
3477 .getattr = smb_proc_getattr_trans2_all,
3478 .truncate = smb_proc_trunc64,
3479};
3480
3481/* Samba w/ unix extensions. Others? */
3482static struct smb_ops smb_ops_unix =
3483{
3484 .read = smb_proc_readX,
3485 .write = smb_proc_writeX,
3486 .readdir = smb_proc_readdir_long,
3487 .getattr = smb_proc_getattr_unix,
3488 /* FIXME: core/ext/time setattr needs to be cleaned up! */
3489 /* .setattr = smb_proc_setattr_unix, */
3490 .truncate = smb_proc_trunc64,
3491};
3492
3493/* Place holder until real ops are in place */
3494static struct smb_ops smb_ops_null =
3495{
3496 .readdir = smb_proc_readdir_null,
3497 .getattr = smb_proc_getattr_null,
3498};
3499
3500void smb_install_null_ops(struct smb_ops *ops)
3501{
3502 install_ops(ops, &smb_ops_null);
3503}
diff --git a/fs/smbfs/proto.h b/fs/smbfs/proto.h
deleted file mode 100644
index 05939a6f43e6..000000000000
--- a/fs/smbfs/proto.h
+++ /dev/null
@@ -1,87 +0,0 @@
1/*
2 * Autogenerated with cproto on: Sat Sep 13 17:18:51 CEST 2003
3 */
4
5struct smb_request;
6struct sock;
7struct statfs;
8
9/* proc.c */
10extern int smb_setcodepage(struct smb_sb_info *server, struct smb_nls_codepage *cp);
11extern __u32 smb_len(__u8 *p);
12extern int smb_get_rsize(struct smb_sb_info *server);
13extern int smb_get_wsize(struct smb_sb_info *server);
14extern int smb_errno(struct smb_request *req);
15extern int smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt);
16extern __u8 *smb_setup_header(struct smb_request *req, __u8 command, __u16 wct, __u16 bcc);
17extern int smb_open(struct dentry *dentry, int wish);
18extern int smb_close(struct inode *ino);
19extern int smb_close_fileid(struct dentry *dentry, __u16 fileid);
20extern int smb_proc_create(struct dentry *dentry, __u16 attr, time_t ctime, __u16 *fileid);
21extern int smb_proc_mv(struct dentry *old_dentry, struct dentry *new_dentry);
22extern int smb_proc_mkdir(struct dentry *dentry);
23extern int smb_proc_rmdir(struct dentry *dentry);
24extern int smb_proc_unlink(struct dentry *dentry);
25extern int smb_proc_flush(struct smb_sb_info *server, __u16 fileid);
26extern void smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr,
27 struct super_block *sb);
28extern int smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr);
29extern int smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr);
30extern int smb_proc_setattr_unix(struct dentry *d, struct iattr *attr, unsigned int major, unsigned int minor);
31extern int smb_proc_settime(struct dentry *dentry, struct smb_fattr *fattr);
32extern int smb_proc_dskattr(struct dentry *dentry, struct kstatfs *attr);
33extern int smb_proc_read_link(struct smb_sb_info *server, struct dentry *d, char *buffer, int len);
34extern int smb_proc_symlink(struct smb_sb_info *server, struct dentry *d, const char *oldpath);
35extern int smb_proc_link(struct smb_sb_info *server, struct dentry *dentry, struct dentry *new_dentry);
36extern void smb_install_null_ops(struct smb_ops *ops);
37/* dir.c */
38extern const struct file_operations smb_dir_operations;
39extern const struct inode_operations smb_dir_inode_operations;
40extern const struct inode_operations smb_dir_inode_operations_unix;
41extern void smb_new_dentry(struct dentry *dentry);
42extern void smb_renew_times(struct dentry *dentry);
43/* cache.c */
44extern void smb_invalid_dir_cache(struct inode *dir);
45extern void smb_invalidate_dircache_entries(struct dentry *parent);
46extern struct dentry *smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos);
47extern int smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir, struct smb_cache_control *ctrl, struct qstr *qname, struct smb_fattr *entry);
48/* sock.c */
49extern void smb_data_ready(struct sock *sk, int len);
50extern int smb_valid_socket(struct inode *inode);
51extern void smb_close_socket(struct smb_sb_info *server);
52extern int smb_recv_available(struct smb_sb_info *server);
53extern int smb_receive_header(struct smb_sb_info *server);
54extern int smb_receive_drop(struct smb_sb_info *server);
55extern int smb_receive(struct smb_sb_info *server, struct smb_request *req);
56extern int smb_send_request(struct smb_request *req);
57/* inode.c */
58extern struct inode *smb_iget(struct super_block *sb, struct smb_fattr *fattr);
59extern void smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr);
60extern void smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr);
61extern void smb_invalidate_inodes(struct smb_sb_info *server);
62extern int smb_revalidate_inode(struct dentry *dentry);
63extern int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
64extern int smb_notify_change(struct dentry *dentry, struct iattr *attr);
65/* file.c */
66extern const struct address_space_operations smb_file_aops;
67extern const struct file_operations smb_file_operations;
68extern const struct inode_operations smb_file_inode_operations;
69/* ioctl.c */
70extern long smb_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
71/* smbiod.c */
72extern void smbiod_wake_up(void);
73extern int smbiod_register_server(struct smb_sb_info *server);
74extern void smbiod_unregister_server(struct smb_sb_info *server);
75extern void smbiod_flush(struct smb_sb_info *server);
76extern int smbiod_retry(struct smb_sb_info *server);
77/* request.c */
78extern int smb_init_request_cache(void);
79extern void smb_destroy_request_cache(void);
80extern struct smb_request *smb_alloc_request(struct smb_sb_info *server, int bufsize);
81extern void smb_rput(struct smb_request *req);
82extern int smb_add_request(struct smb_request *req);
83extern int smb_request_send_server(struct smb_sb_info *server);
84extern int smb_request_recv(struct smb_sb_info *server);
85/* symlink.c */
86extern int smb_symlink(struct inode *inode, struct dentry *dentry, const char *oldname);
87extern const struct inode_operations smb_link_inode_operations;
diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c
deleted file mode 100644
index 45f45933e862..000000000000
--- a/fs/smbfs/request.c
+++ /dev/null
@@ -1,818 +0,0 @@
1/*
2 * request.c
3 *
4 * Copyright (C) 2001 by Urban Widmark
5 *
6 * Please add a note about your changes to smbfs in the ChangeLog file.
7 */
8
9#include <linux/kernel.h>
10#include <linux/types.h>
11#include <linux/fs.h>
12#include <linux/slab.h>
13#include <linux/net.h>
14#include <linux/sched.h>
15
16#include <linux/smb_fs.h>
17#include <linux/smbno.h>
18#include <linux/smb_mount.h>
19
20#include "smb_debug.h"
21#include "request.h"
22#include "proto.h"
23
24/* #define SMB_SLAB_DEBUG (SLAB_RED_ZONE | SLAB_POISON) */
25#define SMB_SLAB_DEBUG 0
26
27/* cache for request structures */
28static struct kmem_cache *req_cachep;
29
30static int smb_request_send_req(struct smb_request *req);
31
32/*
33 /proc/slabinfo:
34 name, active, num, objsize, active_slabs, num_slaps, #pages
35*/
36
37
38int smb_init_request_cache(void)
39{
40 req_cachep = kmem_cache_create("smb_request",
41 sizeof(struct smb_request), 0,
42 SMB_SLAB_DEBUG | SLAB_HWCACHE_ALIGN,
43 NULL);
44 if (req_cachep == NULL)
45 return -ENOMEM;
46
47 return 0;
48}
49
50void smb_destroy_request_cache(void)
51{
52 kmem_cache_destroy(req_cachep);
53}
54
55/*
56 * Allocate and initialise a request structure
57 */
58static struct smb_request *smb_do_alloc_request(struct smb_sb_info *server,
59 int bufsize)
60{
61 struct smb_request *req;
62 unsigned char *buf = NULL;
63
64 req = kmem_cache_zalloc(req_cachep, GFP_KERNEL);
65 VERBOSE("allocating request: %p\n", req);
66 if (!req)
67 goto out;
68
69 if (bufsize > 0) {
70 buf = kmalloc(bufsize, GFP_NOFS);
71 if (!buf) {
72 kmem_cache_free(req_cachep, req);
73 return NULL;
74 }
75 }
76
77 req->rq_buffer = buf;
78 req->rq_bufsize = bufsize;
79 req->rq_server = server;
80 init_waitqueue_head(&req->rq_wait);
81 INIT_LIST_HEAD(&req->rq_queue);
82 atomic_set(&req->rq_count, 1);
83
84out:
85 return req;
86}
87
88struct smb_request *smb_alloc_request(struct smb_sb_info *server, int bufsize)
89{
90 struct smb_request *req = NULL;
91
92 for (;;) {
93 atomic_inc(&server->nr_requests);
94 if (atomic_read(&server->nr_requests) <= MAX_REQUEST_HARD) {
95 req = smb_do_alloc_request(server, bufsize);
96 if (req != NULL)
97 break;
98 }
99
100#if 0
101 /*
102 * Try to free up at least one request in order to stay
103 * below the hard limit
104 */
105 if (nfs_try_to_free_pages(server))
106 continue;
107
108 if (fatal_signal_pending(current))
109 return ERR_PTR(-ERESTARTSYS);
110 current->policy = SCHED_YIELD;
111 schedule();
112#else
113 /* FIXME: we want something like nfs does above, but that
114 requires changes to all callers and can wait. */
115 break;
116#endif
117 }
118 return req;
119}
120
121static void smb_free_request(struct smb_request *req)
122{
123 atomic_dec(&req->rq_server->nr_requests);
124 if (req->rq_buffer && !(req->rq_flags & SMB_REQ_STATIC))
125 kfree(req->rq_buffer);
126 kfree(req->rq_trans2buffer);
127 kmem_cache_free(req_cachep, req);
128}
129
130/*
131 * What prevents a rget to race with a rput? The count must never drop to zero
132 * while it is in use. Only rput if it is ok that it is free'd.
133 */
134static void smb_rget(struct smb_request *req)
135{
136 atomic_inc(&req->rq_count);
137}
138void smb_rput(struct smb_request *req)
139{
140 if (atomic_dec_and_test(&req->rq_count)) {
141 list_del_init(&req->rq_queue);
142 smb_free_request(req);
143 }
144}
145
146/* setup to receive the data part of the SMB */
147static int smb_setup_bcc(struct smb_request *req)
148{
149 int result = 0;
150 req->rq_rlen = smb_len(req->rq_header) + 4 - req->rq_bytes_recvd;
151
152 if (req->rq_rlen > req->rq_bufsize) {
153 PARANOIA("Packet too large %d > %d\n",
154 req->rq_rlen, req->rq_bufsize);
155 return -ENOBUFS;
156 }
157
158 req->rq_iov[0].iov_base = req->rq_buffer;
159 req->rq_iov[0].iov_len = req->rq_rlen;
160 req->rq_iovlen = 1;
161
162 return result;
163}
164
165/*
166 * Prepare a "normal" request structure.
167 */
168static int smb_setup_request(struct smb_request *req)
169{
170 int len = smb_len(req->rq_header) + 4;
171 req->rq_slen = len;
172
173 /* if we expect a data part in the reply we set the iov's to read it */
174 if (req->rq_resp_bcc)
175 req->rq_setup_read = smb_setup_bcc;
176
177 /* This tries to support re-using the same request */
178 req->rq_bytes_sent = 0;
179 req->rq_rcls = 0;
180 req->rq_err = 0;
181 req->rq_errno = 0;
182 req->rq_fragment = 0;
183 kfree(req->rq_trans2buffer);
184 req->rq_trans2buffer = NULL;
185
186 return 0;
187}
188
189/*
190 * Prepare a transaction2 request structure
191 */
192static int smb_setup_trans2request(struct smb_request *req)
193{
194 struct smb_sb_info *server = req->rq_server;
195 int mparam, mdata;
196 static unsigned char padding[4];
197
198 /* I know the following is very ugly, but I want to build the
199 smb packet as efficiently as possible. */
200
201 const int smb_parameters = 15;
202 const int header = SMB_HEADER_LEN + 2 * smb_parameters + 2;
203 const int oparam = ALIGN(header + 3, sizeof(u32));
204 const int odata = ALIGN(oparam + req->rq_lparm, sizeof(u32));
205 const int bcc = (req->rq_data ? odata + req->rq_ldata :
206 oparam + req->rq_lparm) - header;
207
208 if ((bcc + oparam) > server->opt.max_xmit)
209 return -ENOMEM;
210 smb_setup_header(req, SMBtrans2, smb_parameters, bcc);
211
212 /*
213 * max parameters + max data + max setup == bufsize to make NT4 happy
214 * and not abort the transfer or split into multiple responses. It also
215 * makes smbfs happy as handling packets larger than the buffer size
216 * is extra work.
217 *
218 * OS/2 is probably going to hate me for this ...
219 */
220 mparam = SMB_TRANS2_MAX_PARAM;
221 mdata = req->rq_bufsize - mparam;
222
223 mdata = server->opt.max_xmit - mparam - 100;
224 if (mdata < 1024) {
225 mdata = 1024;
226 mparam = 20;
227 }
228
229#if 0
230 /* NT/win2k has ~4k max_xmit, so with this we request more than it wants
231 to return as one SMB. Useful for testing the fragmented trans2
232 handling. */
233 mdata = 8192;
234#endif
235
236 WSET(req->rq_header, smb_tpscnt, req->rq_lparm);
237 WSET(req->rq_header, smb_tdscnt, req->rq_ldata);
238 WSET(req->rq_header, smb_mprcnt, mparam);
239 WSET(req->rq_header, smb_mdrcnt, mdata);
240 WSET(req->rq_header, smb_msrcnt, 0); /* max setup always 0 ? */
241 WSET(req->rq_header, smb_flags, 0);
242 DSET(req->rq_header, smb_timeout, 0);
243 WSET(req->rq_header, smb_pscnt, req->rq_lparm);
244 WSET(req->rq_header, smb_psoff, oparam - 4);
245 WSET(req->rq_header, smb_dscnt, req->rq_ldata);
246 WSET(req->rq_header, smb_dsoff, req->rq_data ? odata - 4 : 0);
247 *(req->rq_header + smb_suwcnt) = 0x01; /* setup count */
248 *(req->rq_header + smb_suwcnt + 1) = 0x00; /* reserved */
249 WSET(req->rq_header, smb_setup0, req->rq_trans2_command);
250
251 req->rq_iovlen = 2;
252 req->rq_iov[0].iov_base = (void *) req->rq_header;
253 req->rq_iov[0].iov_len = oparam;
254 req->rq_iov[1].iov_base = (req->rq_parm==NULL) ? padding : req->rq_parm;
255 req->rq_iov[1].iov_len = req->rq_lparm;
256 req->rq_slen = oparam + req->rq_lparm;
257
258 if (req->rq_data) {
259 req->rq_iovlen += 2;
260 req->rq_iov[2].iov_base = padding;
261 req->rq_iov[2].iov_len = odata - oparam - req->rq_lparm;
262 req->rq_iov[3].iov_base = req->rq_data;
263 req->rq_iov[3].iov_len = req->rq_ldata;
264 req->rq_slen = odata + req->rq_ldata;
265 }
266
267 /* always a data part for trans2 replies */
268 req->rq_setup_read = smb_setup_bcc;
269
270 return 0;
271}
272
273/*
274 * Add a request and tell smbiod to process it
275 */
276int smb_add_request(struct smb_request *req)
277{
278 long timeleft;
279 struct smb_sb_info *server = req->rq_server;
280 int result = 0;
281
282 smb_setup_request(req);
283 if (req->rq_trans2_command) {
284 if (req->rq_buffer == NULL) {
285 PARANOIA("trans2 attempted without response buffer!\n");
286 return -EIO;
287 }
288 result = smb_setup_trans2request(req);
289 }
290 if (result < 0)
291 return result;
292
293#ifdef SMB_DEBUG_PACKET_SIZE
294 add_xmit_stats(req);
295#endif
296
297 /* add 'req' to the queue of requests */
298 if (smb_lock_server_interruptible(server))
299 return -EINTR;
300
301 /*
302 * Try to send the request as the process. If that fails we queue the
303 * request and let smbiod send it later.
304 */
305
306 /* FIXME: each server has a number on the maximum number of parallel
307 requests. 10, 50 or so. We should not allow more requests to be
308 active. */
309 if (server->mid > 0xf000)
310 server->mid = 0;
311 req->rq_mid = server->mid++;
312 WSET(req->rq_header, smb_mid, req->rq_mid);
313
314 result = 0;
315 if (server->state == CONN_VALID) {
316 if (list_empty(&server->xmitq))
317 result = smb_request_send_req(req);
318 if (result < 0) {
319 /* Connection lost? */
320 server->conn_error = result;
321 server->state = CONN_INVALID;
322 }
323 }
324 if (result != 1)
325 list_add_tail(&req->rq_queue, &server->xmitq);
326 smb_rget(req);
327
328 if (server->state != CONN_VALID)
329 smbiod_retry(server);
330
331 smb_unlock_server(server);
332
333 smbiod_wake_up();
334
335 timeleft = wait_event_interruptible_timeout(req->rq_wait,
336 req->rq_flags & SMB_REQ_RECEIVED, 30*HZ);
337 if (!timeleft || signal_pending(current)) {
338 /*
339 * On timeout or on interrupt we want to try and remove the
340 * request from the recvq/xmitq.
341 * First check if the request is still part of a queue. (May
342 * have been removed by some error condition)
343 */
344 smb_lock_server(server);
345 if (!list_empty(&req->rq_queue)) {
346 list_del_init(&req->rq_queue);
347 smb_rput(req);
348 }
349 smb_unlock_server(server);
350 }
351
352 if (!timeleft) {
353 PARANOIA("request [%p, mid=%d] timed out!\n",
354 req, req->rq_mid);
355 VERBOSE("smb_com: %02x\n", *(req->rq_header + smb_com));
356 VERBOSE("smb_rcls: %02x\n", *(req->rq_header + smb_rcls));
357 VERBOSE("smb_flg: %02x\n", *(req->rq_header + smb_flg));
358 VERBOSE("smb_tid: %04x\n", WVAL(req->rq_header, smb_tid));
359 VERBOSE("smb_pid: %04x\n", WVAL(req->rq_header, smb_pid));
360 VERBOSE("smb_uid: %04x\n", WVAL(req->rq_header, smb_uid));
361 VERBOSE("smb_mid: %04x\n", WVAL(req->rq_header, smb_mid));
362 VERBOSE("smb_wct: %02x\n", *(req->rq_header + smb_wct));
363
364 req->rq_rcls = ERRSRV;
365 req->rq_err = ERRtimeout;
366
367 /* Just in case it was "stuck" */
368 smbiod_wake_up();
369 }
370 VERBOSE("woke up, rcls=%d\n", req->rq_rcls);
371
372 if (req->rq_rcls != 0)
373 req->rq_errno = smb_errno(req);
374 if (signal_pending(current))
375 req->rq_errno = -ERESTARTSYS;
376 return req->rq_errno;
377}
378
379/*
380 * Send a request and place it on the recvq if successfully sent.
381 * Must be called with the server lock held.
382 */
383static int smb_request_send_req(struct smb_request *req)
384{
385 struct smb_sb_info *server = req->rq_server;
386 int result;
387
388 if (req->rq_bytes_sent == 0) {
389 WSET(req->rq_header, smb_tid, server->opt.tid);
390 WSET(req->rq_header, smb_pid, 1);
391 WSET(req->rq_header, smb_uid, server->opt.server_uid);
392 }
393
394 result = smb_send_request(req);
395 if (result < 0 && result != -EAGAIN)
396 goto out;
397
398 result = 0;
399 if (!(req->rq_flags & SMB_REQ_TRANSMITTED))
400 goto out;
401
402 list_move_tail(&req->rq_queue, &server->recvq);
403 result = 1;
404out:
405 return result;
406}
407
408/*
409 * Sends one request for this server. (smbiod)
410 * Must be called with the server lock held.
411 * Returns: <0 on error
412 * 0 if no request could be completely sent
413 * 1 if all data for one request was sent
414 */
415int smb_request_send_server(struct smb_sb_info *server)
416{
417 struct list_head *head;
418 struct smb_request *req;
419 int result;
420
421 if (server->state != CONN_VALID)
422 return 0;
423
424 /* dequeue first request, if any */
425 req = NULL;
426 head = server->xmitq.next;
427 if (head != &server->xmitq) {
428 req = list_entry(head, struct smb_request, rq_queue);
429 }
430 if (!req)
431 return 0;
432
433 result = smb_request_send_req(req);
434 if (result < 0) {
435 server->conn_error = result;
436 list_move(&req->rq_queue, &server->xmitq);
437 result = -EIO;
438 goto out;
439 }
440
441out:
442 return result;
443}
444
445/*
446 * Try to find a request matching this "mid". Typically the first entry will
447 * be the matching one.
448 */
449static struct smb_request *find_request(struct smb_sb_info *server, int mid)
450{
451 struct list_head *tmp;
452 struct smb_request *req = NULL;
453
454 list_for_each(tmp, &server->recvq) {
455 req = list_entry(tmp, struct smb_request, rq_queue);
456 if (req->rq_mid == mid) {
457 break;
458 }
459 req = NULL;
460 }
461
462 if (!req) {
463 VERBOSE("received reply with mid %d but no request!\n",
464 WVAL(server->header, smb_mid));
465 server->rstate = SMB_RECV_DROP;
466 }
467
468 return req;
469}
470
471/*
472 * Called when we have read the smb header and believe this is a response.
473 */
474static int smb_init_request(struct smb_sb_info *server, struct smb_request *req)
475{
476 int hdrlen, wct;
477
478 memcpy(req->rq_header, server->header, SMB_HEADER_LEN);
479
480 wct = *(req->rq_header + smb_wct);
481 if (wct > 20) {
482 PARANOIA("wct too large, %d > 20\n", wct);
483 server->rstate = SMB_RECV_DROP;
484 return 0;
485 }
486
487 req->rq_resp_wct = wct;
488 hdrlen = SMB_HEADER_LEN + wct*2 + 2;
489 VERBOSE("header length: %d smb_wct: %2d\n", hdrlen, wct);
490
491 req->rq_bytes_recvd = SMB_HEADER_LEN;
492 req->rq_rlen = hdrlen;
493 req->rq_iov[0].iov_base = req->rq_header;
494 req->rq_iov[0].iov_len = hdrlen;
495 req->rq_iovlen = 1;
496 server->rstate = SMB_RECV_PARAM;
497
498#ifdef SMB_DEBUG_PACKET_SIZE
499 add_recv_stats(smb_len(server->header));
500#endif
501 return 0;
502}
503
504/*
505 * Reads the SMB parameters
506 */
507static int smb_recv_param(struct smb_sb_info *server, struct smb_request *req)
508{
509 int result;
510
511 result = smb_receive(server, req);
512 if (result < 0)
513 return result;
514 if (req->rq_bytes_recvd < req->rq_rlen)
515 return 0;
516
517 VERBOSE("result: %d smb_bcc: %04x\n", result,
518 WVAL(req->rq_header, SMB_HEADER_LEN +
519 (*(req->rq_header + smb_wct) * 2)));
520
521 result = 0;
522 req->rq_iov[0].iov_base = NULL;
523 req->rq_rlen = 0;
524 if (req->rq_callback)
525 req->rq_callback(req);
526 else if (req->rq_setup_read)
527 result = req->rq_setup_read(req);
528 if (result < 0) {
529 server->rstate = SMB_RECV_DROP;
530 return result;
531 }
532
533 server->rstate = req->rq_rlen > 0 ? SMB_RECV_DATA : SMB_RECV_END;
534
535 req->rq_bytes_recvd = 0; // recvd out of the iov
536
537 VERBOSE("rlen: %d\n", req->rq_rlen);
538 if (req->rq_rlen < 0) {
539 PARANOIA("Parameters read beyond end of packet!\n");
540 server->rstate = SMB_RECV_END;
541 return -EIO;
542 }
543 return 0;
544}
545
546/*
547 * Reads the SMB data
548 */
549static int smb_recv_data(struct smb_sb_info *server, struct smb_request *req)
550{
551 int result;
552
553 result = smb_receive(server, req);
554 if (result < 0)
555 goto out;
556 if (req->rq_bytes_recvd < req->rq_rlen)
557 goto out;
558 server->rstate = SMB_RECV_END;
559out:
560 VERBOSE("result: %d\n", result);
561 return result;
562}
563
564/*
565 * Receive a transaction2 response
566 * Return: 0 if the response has been fully read
567 * 1 if there are further "fragments" to read
568 * <0 if there is an error
569 */
570static int smb_recv_trans2(struct smb_sb_info *server, struct smb_request *req)
571{
572 unsigned char *inbuf;
573 unsigned int parm_disp, parm_offset, parm_count, parm_tot;
574 unsigned int data_disp, data_offset, data_count, data_tot;
575 int hdrlen = SMB_HEADER_LEN + req->rq_resp_wct*2 - 2;
576
577 VERBOSE("handling trans2\n");
578
579 inbuf = req->rq_header;
580 data_tot = WVAL(inbuf, smb_tdrcnt);
581 parm_tot = WVAL(inbuf, smb_tprcnt);
582 parm_disp = WVAL(inbuf, smb_prdisp);
583 parm_offset = WVAL(inbuf, smb_proff);
584 parm_count = WVAL(inbuf, smb_prcnt);
585 data_disp = WVAL(inbuf, smb_drdisp);
586 data_offset = WVAL(inbuf, smb_droff);
587 data_count = WVAL(inbuf, smb_drcnt);
588
589 /* Modify offset for the split header/buffer we use */
590 if (data_count || data_offset) {
591 if (unlikely(data_offset < hdrlen))
592 goto out_bad_data;
593 else
594 data_offset -= hdrlen;
595 }
596 if (parm_count || parm_offset) {
597 if (unlikely(parm_offset < hdrlen))
598 goto out_bad_parm;
599 else
600 parm_offset -= hdrlen;
601 }
602
603 if (parm_count == parm_tot && data_count == data_tot) {
604 /*
605 * This packet has all the trans2 data.
606 *
607 * We setup the request so that this will be the common
608 * case. It may be a server error to not return a
609 * response that fits.
610 */
611 VERBOSE("single trans2 response "
612 "dcnt=%u, pcnt=%u, doff=%u, poff=%u\n",
613 data_count, parm_count,
614 data_offset, parm_offset);
615 req->rq_ldata = data_count;
616 req->rq_lparm = parm_count;
617 req->rq_data = req->rq_buffer + data_offset;
618 req->rq_parm = req->rq_buffer + parm_offset;
619 if (unlikely(parm_offset + parm_count > req->rq_rlen))
620 goto out_bad_parm;
621 if (unlikely(data_offset + data_count > req->rq_rlen))
622 goto out_bad_data;
623 return 0;
624 }
625
626 VERBOSE("multi trans2 response "
627 "frag=%d, dcnt=%u, pcnt=%u, doff=%u, poff=%u\n",
628 req->rq_fragment,
629 data_count, parm_count,
630 data_offset, parm_offset);
631
632 if (!req->rq_fragment) {
633 int buf_len;
634
635 /* We got the first trans2 fragment */
636 req->rq_fragment = 1;
637 req->rq_total_data = data_tot;
638 req->rq_total_parm = parm_tot;
639 req->rq_ldata = 0;
640 req->rq_lparm = 0;
641
642 buf_len = data_tot + parm_tot;
643 if (buf_len > SMB_MAX_PACKET_SIZE)
644 goto out_too_long;
645
646 req->rq_trans2bufsize = buf_len;
647 req->rq_trans2buffer = kzalloc(buf_len, GFP_NOFS);
648 if (!req->rq_trans2buffer)
649 goto out_no_mem;
650
651 req->rq_parm = req->rq_trans2buffer;
652 req->rq_data = req->rq_trans2buffer + parm_tot;
653 } else if (unlikely(req->rq_total_data < data_tot ||
654 req->rq_total_parm < parm_tot))
655 goto out_data_grew;
656
657 if (unlikely(parm_disp + parm_count > req->rq_total_parm ||
658 parm_offset + parm_count > req->rq_rlen))
659 goto out_bad_parm;
660 if (unlikely(data_disp + data_count > req->rq_total_data ||
661 data_offset + data_count > req->rq_rlen))
662 goto out_bad_data;
663
664 inbuf = req->rq_buffer;
665 memcpy(req->rq_parm + parm_disp, inbuf + parm_offset, parm_count);
666 memcpy(req->rq_data + data_disp, inbuf + data_offset, data_count);
667
668 req->rq_ldata += data_count;
669 req->rq_lparm += parm_count;
670
671 /*
672 * Check whether we've received all of the data. Note that
673 * we use the packet totals -- total lengths might shrink!
674 */
675 if (req->rq_ldata >= data_tot && req->rq_lparm >= parm_tot) {
676 req->rq_ldata = data_tot;
677 req->rq_lparm = parm_tot;
678 return 0;
679 }
680 return 1;
681
682out_too_long:
683 printk(KERN_ERR "smb_trans2: data/param too long, data=%u, parm=%u\n",
684 data_tot, parm_tot);
685 goto out_EIO;
686out_no_mem:
687 printk(KERN_ERR "smb_trans2: couldn't allocate data area of %d bytes\n",
688 req->rq_trans2bufsize);
689 req->rq_errno = -ENOMEM;
690 goto out;
691out_data_grew:
692 printk(KERN_ERR "smb_trans2: data/params grew!\n");
693 goto out_EIO;
694out_bad_parm:
695 printk(KERN_ERR "smb_trans2: invalid parms, disp=%u, cnt=%u, tot=%u, ofs=%u\n",
696 parm_disp, parm_count, parm_tot, parm_offset);
697 goto out_EIO;
698out_bad_data:
699 printk(KERN_ERR "smb_trans2: invalid data, disp=%u, cnt=%u, tot=%u, ofs=%u\n",
700 data_disp, data_count, data_tot, data_offset);
701out_EIO:
702 req->rq_errno = -EIO;
703out:
704 return req->rq_errno;
705}
706
707/*
708 * State machine for receiving responses. We handle the fact that we can't
709 * read the full response in one try by having states telling us how much we
710 * have read.
711 *
712 * Must be called with the server lock held (only called from smbiod).
713 *
714 * Return: <0 on error
715 */
716int smb_request_recv(struct smb_sb_info *server)
717{
718 struct smb_request *req = NULL;
719 int result = 0;
720
721 if (smb_recv_available(server) <= 0)
722 return 0;
723
724 VERBOSE("state: %d\n", server->rstate);
725 switch (server->rstate) {
726 case SMB_RECV_DROP:
727 result = smb_receive_drop(server);
728 if (result < 0)
729 break;
730 if (server->rstate == SMB_RECV_DROP)
731 break;
732 server->rstate = SMB_RECV_START;
733 /* fallthrough */
734 case SMB_RECV_START:
735 server->smb_read = 0;
736 server->rstate = SMB_RECV_HEADER;
737 /* fallthrough */
738 case SMB_RECV_HEADER:
739 result = smb_receive_header(server);
740 if (result < 0)
741 break;
742 if (server->rstate == SMB_RECV_HEADER)
743 break;
744 if (! (*(server->header + smb_flg) & SMB_FLAGS_REPLY) ) {
745 server->rstate = SMB_RECV_REQUEST;
746 break;
747 }
748 if (server->rstate != SMB_RECV_HCOMPLETE)
749 break;
750 /* fallthrough */
751 case SMB_RECV_HCOMPLETE:
752 req = find_request(server, WVAL(server->header, smb_mid));
753 if (!req)
754 break;
755 smb_init_request(server, req);
756 req->rq_rcls = *(req->rq_header + smb_rcls);
757 req->rq_err = WVAL(req->rq_header, smb_err);
758 if (server->rstate != SMB_RECV_PARAM)
759 break;
760 /* fallthrough */
761 case SMB_RECV_PARAM:
762 if (!req)
763 req = find_request(server,WVAL(server->header,smb_mid));
764 if (!req)
765 break;
766 result = smb_recv_param(server, req);
767 if (result < 0)
768 break;
769 if (server->rstate != SMB_RECV_DATA)
770 break;
771 /* fallthrough */
772 case SMB_RECV_DATA:
773 if (!req)
774 req = find_request(server,WVAL(server->header,smb_mid));
775 if (!req)
776 break;
777 result = smb_recv_data(server, req);
778 if (result < 0)
779 break;
780 break;
781
782 /* We should never be called with any of these states */
783 case SMB_RECV_END:
784 case SMB_RECV_REQUEST:
785 BUG();
786 }
787
788 if (result < 0) {
789 /* We saw an error */
790 return result;
791 }
792
793 if (server->rstate != SMB_RECV_END)
794 return 0;
795
796 result = 0;
797 if (req->rq_trans2_command && req->rq_rcls == SUCCESS)
798 result = smb_recv_trans2(server, req);
799
800 /*
801 * Response completely read. Drop any extra bytes sent by the server.
802 * (Yes, servers sometimes add extra bytes to responses)
803 */
804 VERBOSE("smb_len: %d smb_read: %d\n",
805 server->smb_len, server->smb_read);
806 if (server->smb_read < server->smb_len)
807 smb_receive_drop(server);
808
809 server->rstate = SMB_RECV_START;
810
811 if (!result) {
812 list_del_init(&req->rq_queue);
813 req->rq_flags |= SMB_REQ_RECEIVED;
814 smb_rput(req);
815 wake_up_interruptible(&req->rq_wait);
816 }
817 return 0;
818}
diff --git a/fs/smbfs/request.h b/fs/smbfs/request.h
deleted file mode 100644
index efb21451e7c9..000000000000
--- a/fs/smbfs/request.h
+++ /dev/null
@@ -1,70 +0,0 @@
1#include <linux/list.h>
2#include <linux/types.h>
3#include <linux/uio.h>
4#include <linux/wait.h>
5
6struct smb_request {
7 struct list_head rq_queue; /* recvq or xmitq for the server */
8
9 atomic_t rq_count;
10
11 wait_queue_head_t rq_wait;
12 int rq_flags;
13 int rq_mid; /* multiplex ID, set by request.c */
14
15 struct smb_sb_info *rq_server;
16
17 /* header + word count + parameter words + byte count */
18 unsigned char rq_header[SMB_HEADER_LEN + 20*2 + 2];
19
20 int rq_bufsize;
21 unsigned char *rq_buffer;
22
23 /* FIXME: this is not good enough for merging IO requests. */
24 unsigned char *rq_page;
25 int rq_rsize;
26
27 int rq_resp_wct;
28 int rq_resp_bcc;
29
30 int rq_rlen;
31 int rq_bytes_recvd;
32
33 int rq_slen;
34 int rq_bytes_sent;
35
36 int rq_iovlen;
37 struct kvec rq_iov[4];
38
39 int (*rq_setup_read) (struct smb_request *);
40 void (*rq_callback) (struct smb_request *);
41
42 /* ------ trans2 stuff ------ */
43
44 u16 rq_trans2_command; /* 0 if not a trans2 request */
45 unsigned int rq_ldata;
46 unsigned char *rq_data;
47 unsigned int rq_lparm;
48 unsigned char *rq_parm;
49
50 int rq_fragment;
51 u32 rq_total_data;
52 u32 rq_total_parm;
53 int rq_trans2bufsize;
54 unsigned char *rq_trans2buffer;
55
56 /* ------ response ------ */
57
58 unsigned short rq_rcls;
59 unsigned short rq_err;
60 int rq_errno;
61};
62
63#define SMB_REQ_STATIC 0x0001 /* rq_buffer is static */
64#define SMB_REQ_NORETRY 0x0002 /* request is invalid after retry */
65
66#define SMB_REQ_TRANSMITTED 0x4000 /* all data has been sent */
67#define SMB_REQ_RECEIVED 0x8000 /* reply received, smbiod is done */
68
69#define xSMB_REQ_NOREPLY 0x0004 /* we don't want the reply (if any) */
70#define xSMB_REQ_NORECEIVER 0x0008 /* caller doesn't wait for response */
diff --git a/fs/smbfs/smb_debug.h b/fs/smbfs/smb_debug.h
deleted file mode 100644
index fc4b1a5dd755..000000000000
--- a/fs/smbfs/smb_debug.h
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2 * Defines some debug macros for smbfs.
3 */
4
5/* This makes a dentry parent/child name pair. Useful for debugging printk's */
6#define DENTRY_PATH(dentry) \
7 (dentry)->d_parent->d_name.name,(dentry)->d_name.name
8
9/*
10 * safety checks that should never happen ???
11 * these are normally enabled.
12 */
13#ifdef SMBFS_PARANOIA
14# define PARANOIA(f, a...) printk(KERN_NOTICE "%s: " f, __func__ , ## a)
15#else
16# define PARANOIA(f, a...) do { ; } while(0)
17#endif
18
19/* lots of debug messages */
20#ifdef SMBFS_DEBUG_VERBOSE
21# define VERBOSE(f, a...) printk(KERN_DEBUG "%s: " f, __func__ , ## a)
22#else
23# define VERBOSE(f, a...) do { ; } while(0)
24#endif
25
26/*
27 * "normal" debug messages, but not with a normal DEBUG define ... way
28 * too common name.
29 */
30#ifdef SMBFS_DEBUG
31#define DEBUG1(f, a...) printk(KERN_DEBUG "%s: " f, __func__ , ## a)
32#else
33#define DEBUG1(f, a...) do { ; } while(0)
34#endif
diff --git a/fs/smbfs/smbiod.c b/fs/smbfs/smbiod.c
deleted file mode 100644
index 0e39a924f10a..000000000000
--- a/fs/smbfs/smbiod.c
+++ /dev/null
@@ -1,344 +0,0 @@
1/*
2 * smbiod.c
3 *
4 * Copyright (C) 2000, Charles Loep / Corel Corp.
5 * Copyright (C) 2001, Urban Widmark
6 */
7
8
9#include <linux/sched.h>
10#include <linux/kernel.h>
11#include <linux/mm.h>
12#include <linux/string.h>
13#include <linux/stat.h>
14#include <linux/errno.h>
15#include <linux/init.h>
16#include <linux/file.h>
17#include <linux/dcache.h>
18#include <linux/module.h>
19#include <linux/net.h>
20#include <linux/kthread.h>
21#include <net/ip.h>
22
23#include <linux/smb_fs.h>
24#include <linux/smbno.h>
25#include <linux/smb_mount.h>
26
27#include <asm/system.h>
28#include <asm/uaccess.h>
29
30#include "smb_debug.h"
31#include "request.h"
32#include "proto.h"
33
34enum smbiod_state {
35 SMBIOD_DEAD,
36 SMBIOD_STARTING,
37 SMBIOD_RUNNING,
38};
39
40static enum smbiod_state smbiod_state = SMBIOD_DEAD;
41static struct task_struct *smbiod_thread;
42static DECLARE_WAIT_QUEUE_HEAD(smbiod_wait);
43static LIST_HEAD(smb_servers);
44static DEFINE_SPINLOCK(servers_lock);
45
46#define SMBIOD_DATA_READY (1<<0)
47static unsigned long smbiod_flags;
48
49static int smbiod(void *);
50static int smbiod_start(void);
51
52/*
53 * called when there's work for us to do
54 */
55void smbiod_wake_up(void)
56{
57 if (smbiod_state == SMBIOD_DEAD)
58 return;
59 set_bit(SMBIOD_DATA_READY, &smbiod_flags);
60 wake_up_interruptible(&smbiod_wait);
61}
62
63/*
64 * start smbiod if none is running
65 */
66static int smbiod_start(void)
67{
68 struct task_struct *tsk;
69 int err = 0;
70
71 if (smbiod_state != SMBIOD_DEAD)
72 return 0;
73 smbiod_state = SMBIOD_STARTING;
74 __module_get(THIS_MODULE);
75 spin_unlock(&servers_lock);
76 tsk = kthread_run(smbiod, NULL, "smbiod");
77 if (IS_ERR(tsk)) {
78 err = PTR_ERR(tsk);
79 module_put(THIS_MODULE);
80 }
81
82 spin_lock(&servers_lock);
83 if (err < 0) {
84 smbiod_state = SMBIOD_DEAD;
85 smbiod_thread = NULL;
86 } else {
87 smbiod_state = SMBIOD_RUNNING;
88 smbiod_thread = tsk;
89 }
90 return err;
91}
92
93/*
94 * register a server & start smbiod if necessary
95 */
96int smbiod_register_server(struct smb_sb_info *server)
97{
98 int ret;
99 spin_lock(&servers_lock);
100 list_add(&server->entry, &smb_servers);
101 VERBOSE("%p\n", server);
102 ret = smbiod_start();
103 spin_unlock(&servers_lock);
104 return ret;
105}
106
107/*
108 * Unregister a server
109 * Must be called with the server lock held.
110 */
111void smbiod_unregister_server(struct smb_sb_info *server)
112{
113 spin_lock(&servers_lock);
114 list_del_init(&server->entry);
115 VERBOSE("%p\n", server);
116 spin_unlock(&servers_lock);
117
118 smbiod_wake_up();
119 smbiod_flush(server);
120}
121
122void smbiod_flush(struct smb_sb_info *server)
123{
124 struct list_head *tmp, *n;
125 struct smb_request *req;
126
127 list_for_each_safe(tmp, n, &server->xmitq) {
128 req = list_entry(tmp, struct smb_request, rq_queue);
129 req->rq_errno = -EIO;
130 list_del_init(&req->rq_queue);
131 smb_rput(req);
132 wake_up_interruptible(&req->rq_wait);
133 }
134 list_for_each_safe(tmp, n, &server->recvq) {
135 req = list_entry(tmp, struct smb_request, rq_queue);
136 req->rq_errno = -EIO;
137 list_del_init(&req->rq_queue);
138 smb_rput(req);
139 wake_up_interruptible(&req->rq_wait);
140 }
141}
142
143/*
144 * Wake up smbmount and make it reconnect to the server.
145 * This must be called with the server locked.
146 *
147 * FIXME: add smbconnect version to this
148 */
149int smbiod_retry(struct smb_sb_info *server)
150{
151 struct list_head *head;
152 struct smb_request *req;
153 struct pid *pid = get_pid(server->conn_pid);
154 int result = 0;
155
156 VERBOSE("state: %d\n", server->state);
157 if (server->state == CONN_VALID || server->state == CONN_RETRYING)
158 goto out;
159
160 smb_invalidate_inodes(server);
161
162 /*
163 * Some requests are meaningless after a retry, so we abort them.
164 * One example are all requests using 'fileid' since the files are
165 * closed on retry.
166 */
167 head = server->xmitq.next;
168 while (head != &server->xmitq) {
169 req = list_entry(head, struct smb_request, rq_queue);
170 head = head->next;
171
172 req->rq_bytes_sent = 0;
173 if (req->rq_flags & SMB_REQ_NORETRY) {
174 VERBOSE("aborting request %p on xmitq\n", req);
175 req->rq_errno = -EIO;
176 list_del_init(&req->rq_queue);
177 smb_rput(req);
178 wake_up_interruptible(&req->rq_wait);
179 }
180 }
181
182 /*
183 * FIXME: test the code for retrying request we already sent
184 */
185 head = server->recvq.next;
186 while (head != &server->recvq) {
187 req = list_entry(head, struct smb_request, rq_queue);
188 head = head->next;
189#if 0
190 if (req->rq_flags & SMB_REQ_RETRY) {
191 /* must move the request to the xmitq */
192 VERBOSE("retrying request %p on recvq\n", req);
193 list_move(&req->rq_queue, &server->xmitq);
194 continue;
195 }
196#endif
197
198 VERBOSE("aborting request %p on recvq\n", req);
199 /* req->rq_rcls = ???; */ /* FIXME: set smb error code too? */
200 req->rq_errno = -EIO;
201 list_del_init(&req->rq_queue);
202 smb_rput(req);
203 wake_up_interruptible(&req->rq_wait);
204 }
205
206 smb_close_socket(server);
207
208 if (!pid) {
209 /* FIXME: this is fatal, umount? */
210 printk(KERN_ERR "smb_retry: no connection process\n");
211 server->state = CONN_RETRIED;
212 goto out;
213 }
214
215 /*
216 * Change state so that only one retry per server will be started.
217 */
218 server->state = CONN_RETRYING;
219
220 /*
221 * Note: use the "priv" flag, as a user process may need to reconnect.
222 */
223 result = kill_pid(pid, SIGUSR1, 1);
224 if (result) {
225 /* FIXME: this is most likely fatal, umount? */
226 printk(KERN_ERR "smb_retry: signal failed [%d]\n", result);
227 goto out;
228 }
229 VERBOSE("signalled pid %d\n", pid_nr(pid));
230
231 /* FIXME: The retried requests should perhaps get a "time boost". */
232
233out:
234 put_pid(pid);
235 return result;
236}
237
238/*
239 * Currently handles lockingX packets.
240 */
241static void smbiod_handle_request(struct smb_sb_info *server)
242{
243 PARANOIA("smbiod got a request ... and we don't implement oplocks!\n");
244 server->rstate = SMB_RECV_DROP;
245}
246
247/*
248 * Do some IO for one server.
249 */
250static void smbiod_doio(struct smb_sb_info *server)
251{
252 int result;
253 int maxwork = 7;
254
255 if (server->state != CONN_VALID)
256 goto out;
257
258 do {
259 result = smb_request_recv(server);
260 if (result < 0) {
261 server->state = CONN_INVALID;
262 smbiod_retry(server);
263 goto out; /* reconnecting is slow */
264 } else if (server->rstate == SMB_RECV_REQUEST)
265 smbiod_handle_request(server);
266 } while (result > 0 && maxwork-- > 0);
267
268 /*
269 * If there is more to read then we want to be sure to wake up again.
270 */
271 if (server->state != CONN_VALID)
272 goto out;
273 if (smb_recv_available(server) > 0)
274 set_bit(SMBIOD_DATA_READY, &smbiod_flags);
275
276 do {
277 result = smb_request_send_server(server);
278 if (result < 0) {
279 server->state = CONN_INVALID;
280 smbiod_retry(server);
281 goto out; /* reconnecting is slow */
282 }
283 } while (result > 0);
284
285 /*
286 * If the last request was not sent out we want to wake up again.
287 */
288 if (!list_empty(&server->xmitq))
289 set_bit(SMBIOD_DATA_READY, &smbiod_flags);
290
291out:
292 return;
293}
294
295/*
296 * smbiod kernel thread
297 */
298static int smbiod(void *unused)
299{
300 VERBOSE("SMB Kernel thread starting (%d) ...\n", current->pid);
301
302 for (;;) {
303 struct smb_sb_info *server;
304 struct list_head *pos, *n;
305
306 /* FIXME: Use poll? */
307 wait_event_interruptible(smbiod_wait,
308 test_bit(SMBIOD_DATA_READY, &smbiod_flags));
309 if (signal_pending(current)) {
310 spin_lock(&servers_lock);
311 smbiod_state = SMBIOD_DEAD;
312 spin_unlock(&servers_lock);
313 break;
314 }
315
316 clear_bit(SMBIOD_DATA_READY, &smbiod_flags);
317
318 spin_lock(&servers_lock);
319 if (list_empty(&smb_servers)) {
320 smbiod_state = SMBIOD_DEAD;
321 spin_unlock(&servers_lock);
322 break;
323 }
324
325 list_for_each_safe(pos, n, &smb_servers) {
326 server = list_entry(pos, struct smb_sb_info, entry);
327 VERBOSE("checking server %p\n", server);
328
329 if (server->state == CONN_VALID) {
330 spin_unlock(&servers_lock);
331
332 smb_lock_server(server);
333 smbiod_doio(server);
334 smb_unlock_server(server);
335
336 spin_lock(&servers_lock);
337 }
338 }
339 spin_unlock(&servers_lock);
340 }
341
342 VERBOSE("SMB Kernel thread exiting (%d) ...\n", current->pid);
343 module_put_and_exit(0);
344}
diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c
deleted file mode 100644
index e37fe4deebd0..000000000000
--- a/fs/smbfs/sock.c
+++ /dev/null
@@ -1,386 +0,0 @@
1/*
2 * sock.c
3 *
4 * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
5 * Copyright (C) 1997 by Volker Lendecke
6 *
7 * Please add a note about your changes to smbfs in the ChangeLog file.
8 */
9
10#include <linux/fs.h>
11#include <linux/time.h>
12#include <linux/errno.h>
13#include <linux/socket.h>
14#include <linux/fcntl.h>
15#include <linux/file.h>
16#include <linux/in.h>
17#include <linux/net.h>
18#include <linux/mm.h>
19#include <linux/netdevice.h>
20#include <linux/workqueue.h>
21#include <net/scm.h>
22#include <net/tcp_states.h>
23#include <net/ip.h>
24
25#include <linux/smb_fs.h>
26#include <linux/smb.h>
27#include <linux/smbno.h>
28
29#include <asm/uaccess.h>
30#include <asm/ioctls.h>
31
32#include "smb_debug.h"
33#include "proto.h"
34#include "request.h"
35
36
37static int
38_recvfrom(struct socket *socket, unsigned char *ubuf, int size, unsigned flags)
39{
40 struct kvec iov = {ubuf, size};
41 struct msghdr msg = {.msg_flags = flags};
42 msg.msg_flags |= MSG_DONTWAIT | MSG_NOSIGNAL;
43 return kernel_recvmsg(socket, &msg, &iov, 1, size, msg.msg_flags);
44}
45
46/*
47 * Return the server this socket belongs to
48 */
49static struct smb_sb_info *
50server_from_socket(struct socket *socket)
51{
52 return socket->sk->sk_user_data;
53}
54
55/*
56 * Called when there is data on the socket.
57 */
58void
59smb_data_ready(struct sock *sk, int len)
60{
61 struct smb_sb_info *server = server_from_socket(sk->sk_socket);
62 void (*data_ready)(struct sock *, int) = server->data_ready;
63
64 data_ready(sk, len);
65 VERBOSE("(%p, %d)\n", sk, len);
66 smbiod_wake_up();
67}
68
69int
70smb_valid_socket(struct inode * inode)
71{
72 return (inode && S_ISSOCK(inode->i_mode) &&
73 SOCKET_I(inode)->type == SOCK_STREAM);
74}
75
76static struct socket *
77server_sock(struct smb_sb_info *server)
78{
79 struct file *file;
80
81 if (server && (file = server->sock_file))
82 {
83#ifdef SMBFS_PARANOIA
84 if (!smb_valid_socket(file->f_path.dentry->d_inode))
85 PARANOIA("bad socket!\n");
86#endif
87 return SOCKET_I(file->f_path.dentry->d_inode);
88 }
89 return NULL;
90}
91
92void
93smb_close_socket(struct smb_sb_info *server)
94{
95 struct file * file = server->sock_file;
96
97 if (file) {
98 struct socket *sock = server_sock(server);
99
100 VERBOSE("closing socket %p\n", sock);
101 sock->sk->sk_data_ready = server->data_ready;
102 server->sock_file = NULL;
103 fput(file);
104 }
105}
106
107static int
108smb_get_length(struct socket *socket, unsigned char *header)
109{
110 int result;
111
112 result = _recvfrom(socket, header, 4, MSG_PEEK);
113 if (result == -EAGAIN)
114 return -ENODATA;
115 if (result < 0) {
116 PARANOIA("recv error = %d\n", -result);
117 return result;
118 }
119 if (result < 4)
120 return -ENODATA;
121
122 switch (header[0]) {
123 case 0x00:
124 case 0x82:
125 break;
126
127 case 0x85:
128 DEBUG1("Got SESSION KEEP ALIVE\n");
129 _recvfrom(socket, header, 4, 0); /* read away */
130 return -ENODATA;
131
132 default:
133 PARANOIA("Invalid NBT packet, code=%x\n", header[0]);
134 return -EIO;
135 }
136
137 /* The length in the RFC NB header is the raw data length */
138 return smb_len(header);
139}
140
141int
142smb_recv_available(struct smb_sb_info *server)
143{
144 mm_segment_t oldfs;
145 int avail, err;
146 struct socket *sock = server_sock(server);
147
148 oldfs = get_fs();
149 set_fs(get_ds());
150 err = sock->ops->ioctl(sock, SIOCINQ, (unsigned long) &avail);
151 set_fs(oldfs);
152 return (err >= 0) ? avail : err;
153}
154
155/*
156 * Adjust the kvec to move on 'n' bytes (from nfs/sunrpc)
157 */
158static int
159smb_move_iov(struct kvec **data, size_t *num, struct kvec *vec, unsigned amount)
160{
161 struct kvec *iv = *data;
162 int i;
163 int len;
164
165 /*
166 * Eat any sent kvecs
167 */
168 while (iv->iov_len <= amount) {
169 amount -= iv->iov_len;
170 iv++;
171 (*num)--;
172 }
173
174 /*
175 * And chew down the partial one
176 */
177 vec[0].iov_len = iv->iov_len-amount;
178 vec[0].iov_base =((unsigned char *)iv->iov_base)+amount;
179 iv++;
180
181 len = vec[0].iov_len;
182
183 /*
184 * And copy any others
185 */
186 for (i = 1; i < *num; i++) {
187 vec[i] = *iv++;
188 len += vec[i].iov_len;
189 }
190
191 *data = vec;
192 return len;
193}
194
195/*
196 * smb_receive_header
197 * Only called by the smbiod thread.
198 */
199int
200smb_receive_header(struct smb_sb_info *server)
201{
202 struct socket *sock;
203 int result = 0;
204 unsigned char peek_buf[4];
205
206 result = -EIO;
207 sock = server_sock(server);
208 if (!sock)
209 goto out;
210 if (sock->sk->sk_state != TCP_ESTABLISHED)
211 goto out;
212
213 if (!server->smb_read) {
214 result = smb_get_length(sock, peek_buf);
215 if (result < 0) {
216 if (result == -ENODATA)
217 result = 0;
218 goto out;
219 }
220 server->smb_len = result + 4;
221
222 if (server->smb_len < SMB_HEADER_LEN) {
223 PARANOIA("short packet: %d\n", result);
224 server->rstate = SMB_RECV_DROP;
225 result = -EIO;
226 goto out;
227 }
228 if (server->smb_len > SMB_MAX_PACKET_SIZE) {
229 PARANOIA("long packet: %d\n", result);
230 server->rstate = SMB_RECV_DROP;
231 result = -EIO;
232 goto out;
233 }
234 }
235
236 result = _recvfrom(sock, server->header + server->smb_read,
237 SMB_HEADER_LEN - server->smb_read, 0);
238 VERBOSE("_recvfrom: %d\n", result);
239 if (result < 0) {
240 VERBOSE("receive error: %d\n", result);
241 goto out;
242 }
243 server->smb_read += result;
244
245 if (server->smb_read == SMB_HEADER_LEN)
246 server->rstate = SMB_RECV_HCOMPLETE;
247out:
248 return result;
249}
250
251static char drop_buffer[PAGE_SIZE];
252
253/*
254 * smb_receive_drop - read and throw away the data
255 * Only called by the smbiod thread.
256 *
257 * FIXME: we are in the kernel, could we just tell the socket that we want
258 * to drop stuff from the buffer?
259 */
260int
261smb_receive_drop(struct smb_sb_info *server)
262{
263 struct socket *sock;
264 unsigned int flags;
265 struct kvec iov;
266 struct msghdr msg;
267 int rlen = smb_len(server->header) - server->smb_read + 4;
268 int result = -EIO;
269
270 if (rlen > PAGE_SIZE)
271 rlen = PAGE_SIZE;
272
273 sock = server_sock(server);
274 if (!sock)
275 goto out;
276 if (sock->sk->sk_state != TCP_ESTABLISHED)
277 goto out;
278
279 flags = MSG_DONTWAIT | MSG_NOSIGNAL;
280 iov.iov_base = drop_buffer;
281 iov.iov_len = PAGE_SIZE;
282 msg.msg_flags = flags;
283 msg.msg_name = NULL;
284 msg.msg_namelen = 0;
285 msg.msg_control = NULL;
286
287 result = kernel_recvmsg(sock, &msg, &iov, 1, rlen, flags);
288
289 VERBOSE("read: %d\n", result);
290 if (result < 0) {
291 VERBOSE("receive error: %d\n", result);
292 goto out;
293 }
294 server->smb_read += result;
295
296 if (server->smb_read >= server->smb_len)
297 server->rstate = SMB_RECV_END;
298
299out:
300 return result;
301}
302
303/*
304 * smb_receive
305 * Only called by the smbiod thread.
306 */
307int
308smb_receive(struct smb_sb_info *server, struct smb_request *req)
309{
310 struct socket *sock;
311 unsigned int flags;
312 struct kvec iov[4];
313 struct kvec *p = req->rq_iov;
314 size_t num = req->rq_iovlen;
315 struct msghdr msg;
316 int rlen;
317 int result = -EIO;
318
319 sock = server_sock(server);
320 if (!sock)
321 goto out;
322 if (sock->sk->sk_state != TCP_ESTABLISHED)
323 goto out;
324
325 flags = MSG_DONTWAIT | MSG_NOSIGNAL;
326 msg.msg_flags = flags;
327 msg.msg_name = NULL;
328 msg.msg_namelen = 0;
329 msg.msg_control = NULL;
330
331 /* Dont repeat bytes and count available bufferspace */
332 rlen = min_t(int, smb_move_iov(&p, &num, iov, req->rq_bytes_recvd),
333 (req->rq_rlen - req->rq_bytes_recvd));
334
335 result = kernel_recvmsg(sock, &msg, p, num, rlen, flags);
336
337 VERBOSE("read: %d\n", result);
338 if (result < 0) {
339 VERBOSE("receive error: %d\n", result);
340 goto out;
341 }
342 req->rq_bytes_recvd += result;
343 server->smb_read += result;
344
345out:
346 return result;
347}
348
349/*
350 * Try to send a SMB request. This may return after sending only parts of the
351 * request. SMB_REQ_TRANSMITTED will be set if a request was fully sent.
352 *
353 * Parts of this was taken from xprt_sendmsg from net/sunrpc/xprt.c
354 */
355int
356smb_send_request(struct smb_request *req)
357{
358 struct smb_sb_info *server = req->rq_server;
359 struct socket *sock;
360 struct msghdr msg = {.msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT};
361 int slen = req->rq_slen - req->rq_bytes_sent;
362 int result = -EIO;
363 struct kvec iov[4];
364 struct kvec *p = req->rq_iov;
365 size_t num = req->rq_iovlen;
366
367 sock = server_sock(server);
368 if (!sock)
369 goto out;
370 if (sock->sk->sk_state != TCP_ESTABLISHED)
371 goto out;
372
373 /* Dont repeat bytes */
374 if (req->rq_bytes_sent)
375 smb_move_iov(&p, &num, iov, req->rq_bytes_sent);
376
377 result = kernel_sendmsg(sock, &msg, p, num, slen);
378
379 if (result >= 0) {
380 req->rq_bytes_sent += result;
381 if (req->rq_bytes_sent >= req->rq_slen)
382 req->rq_flags |= SMB_REQ_TRANSMITTED;
383 }
384out:
385 return result;
386}
diff --git a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c
deleted file mode 100644
index 00b2909bd469..000000000000
--- a/fs/smbfs/symlink.c
+++ /dev/null
@@ -1,68 +0,0 @@
1/*
2 * symlink.c
3 *
4 * Copyright (C) 2002 by John Newbigin
5 *
6 * Please add a note about your changes to smbfs in the ChangeLog file.
7 */
8
9#include <linux/kernel.h>
10#include <linux/errno.h>
11#include <linux/fcntl.h>
12#include <linux/stat.h>
13#include <linux/mm.h>
14#include <linux/slab.h>
15#include <linux/pagemap.h>
16#include <linux/net.h>
17#include <linux/namei.h>
18
19#include <asm/uaccess.h>
20#include <asm/system.h>
21
22#include <linux/smbno.h>
23#include <linux/smb_fs.h>
24
25#include "smb_debug.h"
26#include "proto.h"
27
28int smb_symlink(struct inode *inode, struct dentry *dentry, const char *oldname)
29{
30 DEBUG1("create symlink %s -> %s/%s\n", oldname, DENTRY_PATH(dentry));
31
32 return smb_proc_symlink(server_from_dentry(dentry), dentry, oldname);
33}
34
35static void *smb_follow_link(struct dentry *dentry, struct nameidata *nd)
36{
37 char *link = __getname();
38 DEBUG1("followlink of %s/%s\n", DENTRY_PATH(dentry));
39
40 if (!link) {
41 link = ERR_PTR(-ENOMEM);
42 } else {
43 int len = smb_proc_read_link(server_from_dentry(dentry),
44 dentry, link, PATH_MAX - 1);
45 if (len < 0) {
46 __putname(link);
47 link = ERR_PTR(len);
48 } else {
49 link[len] = 0;
50 }
51 }
52 nd_set_link(nd, link);
53 return NULL;
54}
55
56static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
57{
58 char *s = nd_get_link(nd);
59 if (!IS_ERR(s))
60 __putname(s);
61}
62
63const struct inode_operations smb_link_inode_operations =
64{
65 .readlink = generic_readlink,
66 .follow_link = smb_follow_link,
67 .put_link = smb_put_link,
68};