Commit d063389ecf20e5c20be91a0007656deb9fc38a1c

Authored by Pekka Enberg
Committed by Linus Torvalds
1 parent 44db77f33c

[PATCH] smbfs: remove kmalloc wrapper

Remove the remaining kmalloc() wrapper bits from fs/smbfs/.

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 4 changed files with 12 additions and 81 deletions Inline Diff

1 # 1 #
2 # Makefile for the linux smb-filesystem routines. 2 # Makefile for the linux smb-filesystem routines.
3 # 3 #
4 4
5 obj-$(CONFIG_SMB_FS) += smbfs.o 5 obj-$(CONFIG_SMB_FS) += smbfs.o
6 6
7 smbfs-objs := proc.o dir.o cache.o sock.o inode.o file.o ioctl.o getopt.o \ 7 smbfs-objs := proc.o dir.o cache.o sock.o inode.o file.o ioctl.o getopt.o \
8 symlink.o smbiod.o request.o 8 symlink.o smbiod.o request.o
9 9
10 # If you want debugging output, you may add these flags to the EXTRA_CFLAGS 10 # If you want debugging output, you may add these flags to the EXTRA_CFLAGS
11 # SMBFS_PARANOIA should normally be enabled. 11 # SMBFS_PARANOIA should normally be enabled.
12 12
13 EXTRA_CFLAGS += -DSMBFS_PARANOIA 13 EXTRA_CFLAGS += -DSMBFS_PARANOIA
14 #EXTRA_CFLAGS += -DSMBFS_DEBUG 14 #EXTRA_CFLAGS += -DSMBFS_DEBUG
15 #EXTRA_CFLAGS += -DSMBFS_DEBUG_VERBOSE 15 #EXTRA_CFLAGS += -DSMBFS_DEBUG_VERBOSE
16 #EXTRA_CFLAGS += -DDEBUG_SMB_MALLOC
17 #EXTRA_CFLAGS += -DDEBUG_SMB_TIMESTAMP 16 #EXTRA_CFLAGS += -DDEBUG_SMB_TIMESTAMP
18 #EXTRA_CFLAGS += -Werror 17 #EXTRA_CFLAGS += -Werror
19 18
20 # 19 #
21 # Maintainer rules 20 # Maintainer rules
22 # 21 #
23 22
24 # getopt.c not included. It is intentionally separate 23 # getopt.c not included. It is intentionally separate
25 SRC = proc.c dir.c cache.c sock.c inode.c file.c ioctl.c smbiod.c request.c \ 24 SRC = proc.c dir.c cache.c sock.c inode.c file.c ioctl.c smbiod.c request.c \
26 symlink.c 25 symlink.c
27 26
28 proto: 27 proto:
29 -rm -f proto.h 28 -rm -f proto.h
30 @echo > proto2.h "/*" 29 @echo > proto2.h "/*"
31 @echo >> proto2.h " * Autogenerated with cproto on: " `date` 30 @echo >> proto2.h " * Autogenerated with cproto on: " `date`
32 @echo >> proto2.h " */" 31 @echo >> proto2.h " */"
33 @echo >> proto2.h "" 32 @echo >> proto2.h ""
34 @echo >> proto2.h "struct smb_request;" 33 @echo >> proto2.h "struct smb_request;"
35 @echo >> proto2.h "struct sock;" 34 @echo >> proto2.h "struct sock;"
36 @echo >> proto2.h "struct statfs;" 35 @echo >> proto2.h "struct statfs;"
37 @echo >> proto2.h "" 36 @echo >> proto2.h ""
38 cproto -E "gcc -E" -e -v -I $(TOPDIR)/include -DMAKING_PROTO -D__KERNEL__ $(SRC) >> proto2.h 37 cproto -E "gcc -E" -e -v -I $(TOPDIR)/include -DMAKING_PROTO -D__KERNEL__ $(SRC) >> proto2.h
39 mv proto2.h proto.h 38 mv proto2.h proto.h
40 39
1 /* 1 /*
2 * inode.c 2 * inode.c
3 * 3 *
4 * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke 4 * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
5 * Copyright (C) 1997 by Volker Lendecke 5 * Copyright (C) 1997 by Volker Lendecke
6 * 6 *
7 * Please add a note about your changes to smbfs in the ChangeLog file. 7 * Please add a note about your changes to smbfs in the ChangeLog file.
8 */ 8 */
9 9
10 #include <linux/config.h> 10 #include <linux/config.h>
11 #include <linux/module.h> 11 #include <linux/module.h>
12 #include <linux/time.h> 12 #include <linux/time.h>
13 #include <linux/kernel.h> 13 #include <linux/kernel.h>
14 #include <linux/mm.h> 14 #include <linux/mm.h>
15 #include <linux/string.h> 15 #include <linux/string.h>
16 #include <linux/stat.h> 16 #include <linux/stat.h>
17 #include <linux/errno.h> 17 #include <linux/errno.h>
18 #include <linux/slab.h> 18 #include <linux/slab.h>
19 #include <linux/init.h> 19 #include <linux/init.h>
20 #include <linux/file.h> 20 #include <linux/file.h>
21 #include <linux/dcache.h> 21 #include <linux/dcache.h>
22 #include <linux/smp_lock.h> 22 #include <linux/smp_lock.h>
23 #include <linux/nls.h> 23 #include <linux/nls.h>
24 #include <linux/seq_file.h> 24 #include <linux/seq_file.h>
25 #include <linux/mount.h> 25 #include <linux/mount.h>
26 #include <linux/net.h> 26 #include <linux/net.h>
27 #include <linux/vfs.h> 27 #include <linux/vfs.h>
28 #include <linux/highuid.h> 28 #include <linux/highuid.h>
29 #include <linux/smb_fs.h> 29 #include <linux/smb_fs.h>
30 #include <linux/smbno.h> 30 #include <linux/smbno.h>
31 #include <linux/smb_mount.h> 31 #include <linux/smb_mount.h>
32 32
33 #include <asm/system.h> 33 #include <asm/system.h>
34 #include <asm/uaccess.h> 34 #include <asm/uaccess.h>
35 35
36 #include "smb_debug.h" 36 #include "smb_debug.h"
37 #include "getopt.h" 37 #include "getopt.h"
38 #include "proto.h" 38 #include "proto.h"
39 39
40 /* Always pick a default string */ 40 /* Always pick a default string */
41 #ifdef CONFIG_SMB_NLS_REMOTE 41 #ifdef CONFIG_SMB_NLS_REMOTE
42 #define SMB_NLS_REMOTE CONFIG_SMB_NLS_REMOTE 42 #define SMB_NLS_REMOTE CONFIG_SMB_NLS_REMOTE
43 #else 43 #else
44 #define SMB_NLS_REMOTE "" 44 #define SMB_NLS_REMOTE ""
45 #endif 45 #endif
46 46
47 #define SMB_TTL_DEFAULT 1000 47 #define SMB_TTL_DEFAULT 1000
48 48
49 static void smb_delete_inode(struct inode *); 49 static void smb_delete_inode(struct inode *);
50 static void smb_put_super(struct super_block *); 50 static void smb_put_super(struct super_block *);
51 static int smb_statfs(struct super_block *, struct kstatfs *); 51 static int smb_statfs(struct super_block *, struct kstatfs *);
52 static int smb_show_options(struct seq_file *, struct vfsmount *); 52 static int smb_show_options(struct seq_file *, struct vfsmount *);
53 53
54 static kmem_cache_t *smb_inode_cachep; 54 static kmem_cache_t *smb_inode_cachep;
55 55
56 static struct inode *smb_alloc_inode(struct super_block *sb) 56 static struct inode *smb_alloc_inode(struct super_block *sb)
57 { 57 {
58 struct smb_inode_info *ei; 58 struct smb_inode_info *ei;
59 ei = (struct smb_inode_info *)kmem_cache_alloc(smb_inode_cachep, SLAB_KERNEL); 59 ei = (struct smb_inode_info *)kmem_cache_alloc(smb_inode_cachep, SLAB_KERNEL);
60 if (!ei) 60 if (!ei)
61 return NULL; 61 return NULL;
62 return &ei->vfs_inode; 62 return &ei->vfs_inode;
63 } 63 }
64 64
65 static void smb_destroy_inode(struct inode *inode) 65 static void smb_destroy_inode(struct inode *inode)
66 { 66 {
67 kmem_cache_free(smb_inode_cachep, SMB_I(inode)); 67 kmem_cache_free(smb_inode_cachep, SMB_I(inode));
68 } 68 }
69 69
70 static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) 70 static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
71 { 71 {
72 struct smb_inode_info *ei = (struct smb_inode_info *) foo; 72 struct smb_inode_info *ei = (struct smb_inode_info *) foo;
73 unsigned long flagmask = SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR; 73 unsigned long flagmask = SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR;
74 74
75 if ((flags & flagmask) == SLAB_CTOR_CONSTRUCTOR) 75 if ((flags & flagmask) == SLAB_CTOR_CONSTRUCTOR)
76 inode_init_once(&ei->vfs_inode); 76 inode_init_once(&ei->vfs_inode);
77 } 77 }
78 78
79 static int init_inodecache(void) 79 static int init_inodecache(void)
80 { 80 {
81 smb_inode_cachep = kmem_cache_create("smb_inode_cache", 81 smb_inode_cachep = kmem_cache_create("smb_inode_cache",
82 sizeof(struct smb_inode_info), 82 sizeof(struct smb_inode_info),
83 0, SLAB_RECLAIM_ACCOUNT, 83 0, SLAB_RECLAIM_ACCOUNT,
84 init_once, NULL); 84 init_once, NULL);
85 if (smb_inode_cachep == NULL) 85 if (smb_inode_cachep == NULL)
86 return -ENOMEM; 86 return -ENOMEM;
87 return 0; 87 return 0;
88 } 88 }
89 89
90 static void destroy_inodecache(void) 90 static void destroy_inodecache(void)
91 { 91 {
92 if (kmem_cache_destroy(smb_inode_cachep)) 92 if (kmem_cache_destroy(smb_inode_cachep))
93 printk(KERN_INFO "smb_inode_cache: not all structures were freed\n"); 93 printk(KERN_INFO "smb_inode_cache: not all structures were freed\n");
94 } 94 }
95 95
96 static int smb_remount(struct super_block *sb, int *flags, char *data) 96 static int smb_remount(struct super_block *sb, int *flags, char *data)
97 { 97 {
98 *flags |= MS_NODIRATIME; 98 *flags |= MS_NODIRATIME;
99 return 0; 99 return 0;
100 } 100 }
101 101
102 static struct super_operations smb_sops = 102 static struct super_operations smb_sops =
103 { 103 {
104 .alloc_inode = smb_alloc_inode, 104 .alloc_inode = smb_alloc_inode,
105 .destroy_inode = smb_destroy_inode, 105 .destroy_inode = smb_destroy_inode,
106 .drop_inode = generic_delete_inode, 106 .drop_inode = generic_delete_inode,
107 .delete_inode = smb_delete_inode, 107 .delete_inode = smb_delete_inode,
108 .put_super = smb_put_super, 108 .put_super = smb_put_super,
109 .statfs = smb_statfs, 109 .statfs = smb_statfs,
110 .show_options = smb_show_options, 110 .show_options = smb_show_options,
111 .remount_fs = smb_remount, 111 .remount_fs = smb_remount,
112 }; 112 };
113 113
114 114
115 /* We are always generating a new inode here */ 115 /* We are always generating a new inode here */
116 struct inode * 116 struct inode *
117 smb_iget(struct super_block *sb, struct smb_fattr *fattr) 117 smb_iget(struct super_block *sb, struct smb_fattr *fattr)
118 { 118 {
119 struct smb_sb_info *server = SMB_SB(sb); 119 struct smb_sb_info *server = SMB_SB(sb);
120 struct inode *result; 120 struct inode *result;
121 121
122 DEBUG1("smb_iget: %p\n", fattr); 122 DEBUG1("smb_iget: %p\n", fattr);
123 123
124 result = new_inode(sb); 124 result = new_inode(sb);
125 if (!result) 125 if (!result)
126 return result; 126 return result;
127 result->i_ino = fattr->f_ino; 127 result->i_ino = fattr->f_ino;
128 SMB_I(result)->open = 0; 128 SMB_I(result)->open = 0;
129 SMB_I(result)->fileid = 0; 129 SMB_I(result)->fileid = 0;
130 SMB_I(result)->access = 0; 130 SMB_I(result)->access = 0;
131 SMB_I(result)->flags = 0; 131 SMB_I(result)->flags = 0;
132 SMB_I(result)->closed = 0; 132 SMB_I(result)->closed = 0;
133 SMB_I(result)->openers = 0; 133 SMB_I(result)->openers = 0;
134 smb_set_inode_attr(result, fattr); 134 smb_set_inode_attr(result, fattr);
135 if (S_ISREG(result->i_mode)) { 135 if (S_ISREG(result->i_mode)) {
136 result->i_op = &smb_file_inode_operations; 136 result->i_op = &smb_file_inode_operations;
137 result->i_fop = &smb_file_operations; 137 result->i_fop = &smb_file_operations;
138 result->i_data.a_ops = &smb_file_aops; 138 result->i_data.a_ops = &smb_file_aops;
139 } else if (S_ISDIR(result->i_mode)) { 139 } else if (S_ISDIR(result->i_mode)) {
140 if (server->opt.capabilities & SMB_CAP_UNIX) 140 if (server->opt.capabilities & SMB_CAP_UNIX)
141 result->i_op = &smb_dir_inode_operations_unix; 141 result->i_op = &smb_dir_inode_operations_unix;
142 else 142 else
143 result->i_op = &smb_dir_inode_operations; 143 result->i_op = &smb_dir_inode_operations;
144 result->i_fop = &smb_dir_operations; 144 result->i_fop = &smb_dir_operations;
145 } else if (S_ISLNK(result->i_mode)) { 145 } else if (S_ISLNK(result->i_mode)) {
146 result->i_op = &smb_link_inode_operations; 146 result->i_op = &smb_link_inode_operations;
147 } else { 147 } else {
148 init_special_inode(result, result->i_mode, fattr->f_rdev); 148 init_special_inode(result, result->i_mode, fattr->f_rdev);
149 } 149 }
150 insert_inode_hash(result); 150 insert_inode_hash(result);
151 return result; 151 return result;
152 } 152 }
153 153
154 /* 154 /*
155 * Copy the inode data to a smb_fattr structure. 155 * Copy the inode data to a smb_fattr structure.
156 */ 156 */
157 void 157 void
158 smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr) 158 smb_get_inode_attr(struct inode *inode, struct smb_fattr *fattr)
159 { 159 {
160 memset(fattr, 0, sizeof(struct smb_fattr)); 160 memset(fattr, 0, sizeof(struct smb_fattr));
161 fattr->f_mode = inode->i_mode; 161 fattr->f_mode = inode->i_mode;
162 fattr->f_nlink = inode->i_nlink; 162 fattr->f_nlink = inode->i_nlink;
163 fattr->f_ino = inode->i_ino; 163 fattr->f_ino = inode->i_ino;
164 fattr->f_uid = inode->i_uid; 164 fattr->f_uid = inode->i_uid;
165 fattr->f_gid = inode->i_gid; 165 fattr->f_gid = inode->i_gid;
166 fattr->f_size = inode->i_size; 166 fattr->f_size = inode->i_size;
167 fattr->f_mtime = inode->i_mtime; 167 fattr->f_mtime = inode->i_mtime;
168 fattr->f_ctime = inode->i_ctime; 168 fattr->f_ctime = inode->i_ctime;
169 fattr->f_atime = inode->i_atime; 169 fattr->f_atime = inode->i_atime;
170 fattr->f_blksize= inode->i_blksize; 170 fattr->f_blksize= inode->i_blksize;
171 fattr->f_blocks = inode->i_blocks; 171 fattr->f_blocks = inode->i_blocks;
172 172
173 fattr->attr = SMB_I(inode)->attr; 173 fattr->attr = SMB_I(inode)->attr;
174 /* 174 /*
175 * Keep the attributes in sync with the inode permissions. 175 * Keep the attributes in sync with the inode permissions.
176 */ 176 */
177 if (fattr->f_mode & S_IWUSR) 177 if (fattr->f_mode & S_IWUSR)
178 fattr->attr &= ~aRONLY; 178 fattr->attr &= ~aRONLY;
179 else 179 else
180 fattr->attr |= aRONLY; 180 fattr->attr |= aRONLY;
181 } 181 }
182 182
183 /* 183 /*
184 * Update the inode, possibly causing it to invalidate its pages if mtime/size 184 * Update the inode, possibly causing it to invalidate its pages if mtime/size
185 * is different from last time. 185 * is different from last time.
186 */ 186 */
187 void 187 void
188 smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr) 188 smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr)
189 { 189 {
190 struct smb_inode_info *ei = SMB_I(inode); 190 struct smb_inode_info *ei = SMB_I(inode);
191 191
192 /* 192 /*
193 * A size change should have a different mtime, or same mtime 193 * A size change should have a different mtime, or same mtime
194 * but different size. 194 * but different size.
195 */ 195 */
196 time_t last_time = inode->i_mtime.tv_sec; 196 time_t last_time = inode->i_mtime.tv_sec;
197 loff_t last_sz = inode->i_size; 197 loff_t last_sz = inode->i_size;
198 198
199 inode->i_mode = fattr->f_mode; 199 inode->i_mode = fattr->f_mode;
200 inode->i_nlink = fattr->f_nlink; 200 inode->i_nlink = fattr->f_nlink;
201 inode->i_uid = fattr->f_uid; 201 inode->i_uid = fattr->f_uid;
202 inode->i_gid = fattr->f_gid; 202 inode->i_gid = fattr->f_gid;
203 inode->i_ctime = fattr->f_ctime; 203 inode->i_ctime = fattr->f_ctime;
204 inode->i_blksize= fattr->f_blksize; 204 inode->i_blksize= fattr->f_blksize;
205 inode->i_blocks = fattr->f_blocks; 205 inode->i_blocks = fattr->f_blocks;
206 inode->i_size = fattr->f_size; 206 inode->i_size = fattr->f_size;
207 inode->i_mtime = fattr->f_mtime; 207 inode->i_mtime = fattr->f_mtime;
208 inode->i_atime = fattr->f_atime; 208 inode->i_atime = fattr->f_atime;
209 ei->attr = fattr->attr; 209 ei->attr = fattr->attr;
210 210
211 /* 211 /*
212 * Update the "last time refreshed" field for revalidation. 212 * Update the "last time refreshed" field for revalidation.
213 */ 213 */
214 ei->oldmtime = jiffies; 214 ei->oldmtime = jiffies;
215 215
216 if (inode->i_mtime.tv_sec != last_time || inode->i_size != last_sz) { 216 if (inode->i_mtime.tv_sec != last_time || inode->i_size != last_sz) {
217 VERBOSE("%ld changed, old=%ld, new=%ld, oz=%ld, nz=%ld\n", 217 VERBOSE("%ld changed, old=%ld, new=%ld, oz=%ld, nz=%ld\n",
218 inode->i_ino, 218 inode->i_ino,
219 (long) last_time, (long) inode->i_mtime, 219 (long) last_time, (long) inode->i_mtime,
220 (long) last_sz, (long) inode->i_size); 220 (long) last_sz, (long) inode->i_size);
221 221
222 if (!S_ISDIR(inode->i_mode)) 222 if (!S_ISDIR(inode->i_mode))
223 invalidate_remote_inode(inode); 223 invalidate_remote_inode(inode);
224 } 224 }
225 } 225 }
226 226
227 /* 227 /*
228 * This is called if the connection has gone bad ... 228 * This is called if the connection has gone bad ...
229 * try to kill off all the current inodes. 229 * try to kill off all the current inodes.
230 */ 230 */
231 void 231 void
232 smb_invalidate_inodes(struct smb_sb_info *server) 232 smb_invalidate_inodes(struct smb_sb_info *server)
233 { 233 {
234 VERBOSE("\n"); 234 VERBOSE("\n");
235 shrink_dcache_sb(SB_of(server)); 235 shrink_dcache_sb(SB_of(server));
236 invalidate_inodes(SB_of(server)); 236 invalidate_inodes(SB_of(server));
237 } 237 }
238 238
239 /* 239 /*
240 * This is called to update the inode attributes after 240 * This is called to update the inode attributes after
241 * we've made changes to a file or directory. 241 * we've made changes to a file or directory.
242 */ 242 */
243 static int 243 static int
244 smb_refresh_inode(struct dentry *dentry) 244 smb_refresh_inode(struct dentry *dentry)
245 { 245 {
246 struct inode *inode = dentry->d_inode; 246 struct inode *inode = dentry->d_inode;
247 int error; 247 int error;
248 struct smb_fattr fattr; 248 struct smb_fattr fattr;
249 249
250 error = smb_proc_getattr(dentry, &fattr); 250 error = smb_proc_getattr(dentry, &fattr);
251 if (!error) { 251 if (!error) {
252 smb_renew_times(dentry); 252 smb_renew_times(dentry);
253 /* 253 /*
254 * Check whether the type part of the mode changed, 254 * Check whether the type part of the mode changed,
255 * and don't update the attributes if it did. 255 * and don't update the attributes if it did.
256 * 256 *
257 * And don't dick with the root inode 257 * And don't dick with the root inode
258 */ 258 */
259 if (inode->i_ino == 2) 259 if (inode->i_ino == 2)
260 return error; 260 return error;
261 if (S_ISLNK(inode->i_mode)) 261 if (S_ISLNK(inode->i_mode))
262 return error; /* VFS will deal with it */ 262 return error; /* VFS will deal with it */
263 263
264 if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT)) { 264 if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT)) {
265 smb_set_inode_attr(inode, &fattr); 265 smb_set_inode_attr(inode, &fattr);
266 } else { 266 } else {
267 /* 267 /*
268 * Big trouble! The inode has become a new object, 268 * Big trouble! The inode has become a new object,
269 * so any operations attempted on it are invalid. 269 * so any operations attempted on it are invalid.
270 * 270 *
271 * To limit damage, mark the inode as bad so that 271 * To limit damage, mark the inode as bad so that
272 * subsequent lookup validations will fail. 272 * subsequent lookup validations will fail.
273 */ 273 */
274 PARANOIA("%s/%s changed mode, %07o to %07o\n", 274 PARANOIA("%s/%s changed mode, %07o to %07o\n",
275 DENTRY_PATH(dentry), 275 DENTRY_PATH(dentry),
276 inode->i_mode, fattr.f_mode); 276 inode->i_mode, fattr.f_mode);
277 277
278 fattr.f_mode = inode->i_mode; /* save mode */ 278 fattr.f_mode = inode->i_mode; /* save mode */
279 make_bad_inode(inode); 279 make_bad_inode(inode);
280 inode->i_mode = fattr.f_mode; /* restore mode */ 280 inode->i_mode = fattr.f_mode; /* restore mode */
281 /* 281 /*
282 * No need to worry about unhashing the dentry: the 282 * No need to worry about unhashing the dentry: the
283 * lookup validation will see that the inode is bad. 283 * lookup validation will see that the inode is bad.
284 * But we do want to invalidate the caches ... 284 * But we do want to invalidate the caches ...
285 */ 285 */
286 if (!S_ISDIR(inode->i_mode)) 286 if (!S_ISDIR(inode->i_mode))
287 invalidate_remote_inode(inode); 287 invalidate_remote_inode(inode);
288 else 288 else
289 smb_invalid_dir_cache(inode); 289 smb_invalid_dir_cache(inode);
290 error = -EIO; 290 error = -EIO;
291 } 291 }
292 } 292 }
293 return error; 293 return error;
294 } 294 }
295 295
296 /* 296 /*
297 * This is called when we want to check whether the inode 297 * This is called when we want to check whether the inode
298 * has changed on the server. If it has changed, we must 298 * has changed on the server. If it has changed, we must
299 * invalidate our local caches. 299 * invalidate our local caches.
300 */ 300 */
301 int 301 int
302 smb_revalidate_inode(struct dentry *dentry) 302 smb_revalidate_inode(struct dentry *dentry)
303 { 303 {
304 struct smb_sb_info *s = server_from_dentry(dentry); 304 struct smb_sb_info *s = server_from_dentry(dentry);
305 struct inode *inode = dentry->d_inode; 305 struct inode *inode = dentry->d_inode;
306 int error = 0; 306 int error = 0;
307 307
308 DEBUG1("smb_revalidate_inode\n"); 308 DEBUG1("smb_revalidate_inode\n");
309 lock_kernel(); 309 lock_kernel();
310 310
311 /* 311 /*
312 * Check whether we've recently refreshed the inode. 312 * Check whether we've recently refreshed the inode.
313 */ 313 */
314 if (time_before(jiffies, SMB_I(inode)->oldmtime + SMB_MAX_AGE(s))) { 314 if (time_before(jiffies, SMB_I(inode)->oldmtime + SMB_MAX_AGE(s))) {
315 VERBOSE("up-to-date, ino=%ld, jiffies=%lu, oldtime=%lu\n", 315 VERBOSE("up-to-date, ino=%ld, jiffies=%lu, oldtime=%lu\n",
316 inode->i_ino, jiffies, SMB_I(inode)->oldmtime); 316 inode->i_ino, jiffies, SMB_I(inode)->oldmtime);
317 goto out; 317 goto out;
318 } 318 }
319 319
320 error = smb_refresh_inode(dentry); 320 error = smb_refresh_inode(dentry);
321 out: 321 out:
322 unlock_kernel(); 322 unlock_kernel();
323 return error; 323 return error;
324 } 324 }
325 325
326 /* 326 /*
327 * This routine is called when i_nlink == 0 and i_count goes to 0. 327 * This routine is called when i_nlink == 0 and i_count goes to 0.
328 * All blocking cleanup operations need to go here to avoid races. 328 * All blocking cleanup operations need to go here to avoid races.
329 */ 329 */
330 static void 330 static void
331 smb_delete_inode(struct inode *ino) 331 smb_delete_inode(struct inode *ino)
332 { 332 {
333 DEBUG1("ino=%ld\n", ino->i_ino); 333 DEBUG1("ino=%ld\n", ino->i_ino);
334 truncate_inode_pages(&ino->i_data, 0); 334 truncate_inode_pages(&ino->i_data, 0);
335 lock_kernel(); 335 lock_kernel();
336 if (smb_close(ino)) 336 if (smb_close(ino))
337 PARANOIA("could not close inode %ld\n", ino->i_ino); 337 PARANOIA("could not close inode %ld\n", ino->i_ino);
338 unlock_kernel(); 338 unlock_kernel();
339 clear_inode(ino); 339 clear_inode(ino);
340 } 340 }
341 341
342 static struct option opts[] = { 342 static struct option opts[] = {
343 { "version", 0, 'v' }, 343 { "version", 0, 'v' },
344 { "win95", SMB_MOUNT_WIN95, 1 }, 344 { "win95", SMB_MOUNT_WIN95, 1 },
345 { "oldattr", SMB_MOUNT_OLDATTR, 1 }, 345 { "oldattr", SMB_MOUNT_OLDATTR, 1 },
346 { "dirattr", SMB_MOUNT_DIRATTR, 1 }, 346 { "dirattr", SMB_MOUNT_DIRATTR, 1 },
347 { "case", SMB_MOUNT_CASE, 1 }, 347 { "case", SMB_MOUNT_CASE, 1 },
348 { "uid", 0, 'u' }, 348 { "uid", 0, 'u' },
349 { "gid", 0, 'g' }, 349 { "gid", 0, 'g' },
350 { "file_mode", 0, 'f' }, 350 { "file_mode", 0, 'f' },
351 { "dir_mode", 0, 'd' }, 351 { "dir_mode", 0, 'd' },
352 { "iocharset", 0, 'i' }, 352 { "iocharset", 0, 'i' },
353 { "codepage", 0, 'c' }, 353 { "codepage", 0, 'c' },
354 { "ttl", 0, 't' }, 354 { "ttl", 0, 't' },
355 { NULL, 0, 0} 355 { NULL, 0, 0}
356 }; 356 };
357 357
358 static int 358 static int
359 parse_options(struct smb_mount_data_kernel *mnt, char *options) 359 parse_options(struct smb_mount_data_kernel *mnt, char *options)
360 { 360 {
361 int c; 361 int c;
362 unsigned long flags; 362 unsigned long flags;
363 unsigned long value; 363 unsigned long value;
364 char *optarg; 364 char *optarg;
365 char *optopt; 365 char *optopt;
366 366
367 flags = 0; 367 flags = 0;
368 while ( (c = smb_getopt("smbfs", &options, opts, 368 while ( (c = smb_getopt("smbfs", &options, opts,
369 &optopt, &optarg, &flags, &value)) > 0) { 369 &optopt, &optarg, &flags, &value)) > 0) {
370 370
371 VERBOSE("'%s' -> '%s'\n", optopt, optarg ? optarg : "<none>"); 371 VERBOSE("'%s' -> '%s'\n", optopt, optarg ? optarg : "<none>");
372 switch (c) { 372 switch (c) {
373 case 1: 373 case 1:
374 /* got a "flag" option */ 374 /* got a "flag" option */
375 break; 375 break;
376 case 'v': 376 case 'v':
377 if (value != SMB_MOUNT_VERSION) { 377 if (value != SMB_MOUNT_VERSION) {
378 printk ("smbfs: Bad mount version %ld, expected %d\n", 378 printk ("smbfs: Bad mount version %ld, expected %d\n",
379 value, SMB_MOUNT_VERSION); 379 value, SMB_MOUNT_VERSION);
380 return 0; 380 return 0;
381 } 381 }
382 mnt->version = value; 382 mnt->version = value;
383 break; 383 break;
384 case 'u': 384 case 'u':
385 mnt->uid = value; 385 mnt->uid = value;
386 flags |= SMB_MOUNT_UID; 386 flags |= SMB_MOUNT_UID;
387 break; 387 break;
388 case 'g': 388 case 'g':
389 mnt->gid = value; 389 mnt->gid = value;
390 flags |= SMB_MOUNT_GID; 390 flags |= SMB_MOUNT_GID;
391 break; 391 break;
392 case 'f': 392 case 'f':
393 mnt->file_mode = (value & S_IRWXUGO) | S_IFREG; 393 mnt->file_mode = (value & S_IRWXUGO) | S_IFREG;
394 flags |= SMB_MOUNT_FMODE; 394 flags |= SMB_MOUNT_FMODE;
395 break; 395 break;
396 case 'd': 396 case 'd':
397 mnt->dir_mode = (value & S_IRWXUGO) | S_IFDIR; 397 mnt->dir_mode = (value & S_IRWXUGO) | S_IFDIR;
398 flags |= SMB_MOUNT_DMODE; 398 flags |= SMB_MOUNT_DMODE;
399 break; 399 break;
400 case 'i': 400 case 'i':
401 strlcpy(mnt->codepage.local_name, optarg, 401 strlcpy(mnt->codepage.local_name, optarg,
402 SMB_NLS_MAXNAMELEN); 402 SMB_NLS_MAXNAMELEN);
403 break; 403 break;
404 case 'c': 404 case 'c':
405 strlcpy(mnt->codepage.remote_name, optarg, 405 strlcpy(mnt->codepage.remote_name, optarg,
406 SMB_NLS_MAXNAMELEN); 406 SMB_NLS_MAXNAMELEN);
407 break; 407 break;
408 case 't': 408 case 't':
409 mnt->ttl = value; 409 mnt->ttl = value;
410 break; 410 break;
411 default: 411 default:
412 printk ("smbfs: Unrecognized mount option %s\n", 412 printk ("smbfs: Unrecognized mount option %s\n",
413 optopt); 413 optopt);
414 return -1; 414 return -1;
415 } 415 }
416 } 416 }
417 mnt->flags = flags; 417 mnt->flags = flags;
418 return c; 418 return c;
419 } 419 }
420 420
421 /* 421 /*
422 * smb_show_options() is for displaying mount options in /proc/mounts. 422 * smb_show_options() is for displaying mount options in /proc/mounts.
423 * It tries to avoid showing settings that were not changed from their 423 * It tries to avoid showing settings that were not changed from their
424 * defaults. 424 * defaults.
425 */ 425 */
426 static int 426 static int
427 smb_show_options(struct seq_file *s, struct vfsmount *m) 427 smb_show_options(struct seq_file *s, struct vfsmount *m)
428 { 428 {
429 struct smb_mount_data_kernel *mnt = SMB_SB(m->mnt_sb)->mnt; 429 struct smb_mount_data_kernel *mnt = SMB_SB(m->mnt_sb)->mnt;
430 int i; 430 int i;
431 431
432 for (i = 0; opts[i].name != NULL; i++) 432 for (i = 0; opts[i].name != NULL; i++)
433 if (mnt->flags & opts[i].flag) 433 if (mnt->flags & opts[i].flag)
434 seq_printf(s, ",%s", opts[i].name); 434 seq_printf(s, ",%s", opts[i].name);
435 435
436 if (mnt->flags & SMB_MOUNT_UID) 436 if (mnt->flags & SMB_MOUNT_UID)
437 seq_printf(s, ",uid=%d", mnt->uid); 437 seq_printf(s, ",uid=%d", mnt->uid);
438 if (mnt->flags & SMB_MOUNT_GID) 438 if (mnt->flags & SMB_MOUNT_GID)
439 seq_printf(s, ",gid=%d", mnt->gid); 439 seq_printf(s, ",gid=%d", mnt->gid);
440 if (mnt->mounted_uid != 0) 440 if (mnt->mounted_uid != 0)
441 seq_printf(s, ",mounted_uid=%d", mnt->mounted_uid); 441 seq_printf(s, ",mounted_uid=%d", mnt->mounted_uid);
442 442
443 /* 443 /*
444 * Defaults for file_mode and dir_mode are unknown to us; they 444 * Defaults for file_mode and dir_mode are unknown to us; they
445 * depend on the current umask of the user doing the mount. 445 * depend on the current umask of the user doing the mount.
446 */ 446 */
447 if (mnt->flags & SMB_MOUNT_FMODE) 447 if (mnt->flags & SMB_MOUNT_FMODE)
448 seq_printf(s, ",file_mode=%04o", mnt->file_mode & S_IRWXUGO); 448 seq_printf(s, ",file_mode=%04o", mnt->file_mode & S_IRWXUGO);
449 if (mnt->flags & SMB_MOUNT_DMODE) 449 if (mnt->flags & SMB_MOUNT_DMODE)
450 seq_printf(s, ",dir_mode=%04o", mnt->dir_mode & S_IRWXUGO); 450 seq_printf(s, ",dir_mode=%04o", mnt->dir_mode & S_IRWXUGO);
451 451
452 if (strcmp(mnt->codepage.local_name, CONFIG_NLS_DEFAULT)) 452 if (strcmp(mnt->codepage.local_name, CONFIG_NLS_DEFAULT))
453 seq_printf(s, ",iocharset=%s", mnt->codepage.local_name); 453 seq_printf(s, ",iocharset=%s", mnt->codepage.local_name);
454 if (strcmp(mnt->codepage.remote_name, SMB_NLS_REMOTE)) 454 if (strcmp(mnt->codepage.remote_name, SMB_NLS_REMOTE))
455 seq_printf(s, ",codepage=%s", mnt->codepage.remote_name); 455 seq_printf(s, ",codepage=%s", mnt->codepage.remote_name);
456 456
457 if (mnt->ttl != SMB_TTL_DEFAULT) 457 if (mnt->ttl != SMB_TTL_DEFAULT)
458 seq_printf(s, ",ttl=%d", mnt->ttl); 458 seq_printf(s, ",ttl=%d", mnt->ttl);
459 459
460 return 0; 460 return 0;
461 } 461 }
462 462
463 static void 463 static void
464 smb_unload_nls(struct smb_sb_info *server) 464 smb_unload_nls(struct smb_sb_info *server)
465 { 465 {
466 if (server->remote_nls) { 466 if (server->remote_nls) {
467 unload_nls(server->remote_nls); 467 unload_nls(server->remote_nls);
468 server->remote_nls = NULL; 468 server->remote_nls = NULL;
469 } 469 }
470 if (server->local_nls) { 470 if (server->local_nls) {
471 unload_nls(server->local_nls); 471 unload_nls(server->local_nls);
472 server->local_nls = NULL; 472 server->local_nls = NULL;
473 } 473 }
474 } 474 }
475 475
476 static void 476 static void
477 smb_put_super(struct super_block *sb) 477 smb_put_super(struct super_block *sb)
478 { 478 {
479 struct smb_sb_info *server = SMB_SB(sb); 479 struct smb_sb_info *server = SMB_SB(sb);
480 480
481 smb_lock_server(server); 481 smb_lock_server(server);
482 server->state = CONN_INVALID; 482 server->state = CONN_INVALID;
483 smbiod_unregister_server(server); 483 smbiod_unregister_server(server);
484 484
485 smb_close_socket(server); 485 smb_close_socket(server);
486 486
487 if (server->conn_pid) 487 if (server->conn_pid)
488 kill_proc(server->conn_pid, SIGTERM, 1); 488 kill_proc(server->conn_pid, SIGTERM, 1);
489 489
490 smb_kfree(server->ops); 490 kfree(server->ops);
491 smb_unload_nls(server); 491 smb_unload_nls(server);
492 sb->s_fs_info = NULL; 492 sb->s_fs_info = NULL;
493 smb_unlock_server(server); 493 smb_unlock_server(server);
494 smb_kfree(server); 494 kfree(server);
495 } 495 }
496 496
497 static int smb_fill_super(struct super_block *sb, void *raw_data, int silent) 497 static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
498 { 498 {
499 struct smb_sb_info *server; 499 struct smb_sb_info *server;
500 struct smb_mount_data_kernel *mnt; 500 struct smb_mount_data_kernel *mnt;
501 struct smb_mount_data *oldmnt; 501 struct smb_mount_data *oldmnt;
502 struct inode *root_inode; 502 struct inode *root_inode;
503 struct smb_fattr root; 503 struct smb_fattr root;
504 int ver; 504 int ver;
505 void *mem; 505 void *mem;
506 506
507 if (!raw_data) 507 if (!raw_data)
508 goto out_no_data; 508 goto out_no_data;
509 509
510 oldmnt = (struct smb_mount_data *) raw_data; 510 oldmnt = (struct smb_mount_data *) raw_data;
511 ver = oldmnt->version; 511 ver = oldmnt->version;
512 if (ver != SMB_MOUNT_OLDVERSION && cpu_to_be32(ver) != SMB_MOUNT_ASCII) 512 if (ver != SMB_MOUNT_OLDVERSION && cpu_to_be32(ver) != SMB_MOUNT_ASCII)
513 goto out_wrong_data; 513 goto out_wrong_data;
514 514
515 sb->s_flags |= MS_NODIRATIME; 515 sb->s_flags |= MS_NODIRATIME;
516 sb->s_blocksize = 1024; /* Eh... Is this correct? */ 516 sb->s_blocksize = 1024; /* Eh... Is this correct? */
517 sb->s_blocksize_bits = 10; 517 sb->s_blocksize_bits = 10;
518 sb->s_magic = SMB_SUPER_MAGIC; 518 sb->s_magic = SMB_SUPER_MAGIC;
519 sb->s_op = &smb_sops; 519 sb->s_op = &smb_sops;
520 sb->s_time_gran = 100; 520 sb->s_time_gran = 100;
521 521
522 server = smb_kmalloc(sizeof(struct smb_sb_info), GFP_KERNEL); 522 server = kzalloc(sizeof(struct smb_sb_info), GFP_KERNEL);
523 if (!server) 523 if (!server)
524 goto out_no_server; 524 goto out_no_server;
525 sb->s_fs_info = server; 525 sb->s_fs_info = server;
526 memset(server, 0, sizeof(struct smb_sb_info));
527 526
528 server->super_block = sb; 527 server->super_block = sb;
529 server->mnt = NULL; 528 server->mnt = NULL;
530 server->sock_file = NULL; 529 server->sock_file = NULL;
531 init_waitqueue_head(&server->conn_wq); 530 init_waitqueue_head(&server->conn_wq);
532 init_MUTEX(&server->sem); 531 init_MUTEX(&server->sem);
533 INIT_LIST_HEAD(&server->entry); 532 INIT_LIST_HEAD(&server->entry);
534 INIT_LIST_HEAD(&server->xmitq); 533 INIT_LIST_HEAD(&server->xmitq);
535 INIT_LIST_HEAD(&server->recvq); 534 INIT_LIST_HEAD(&server->recvq);
536 server->conn_error = 0; 535 server->conn_error = 0;
537 server->conn_pid = 0; 536 server->conn_pid = 0;
538 server->state = CONN_INVALID; /* no connection yet */ 537 server->state = CONN_INVALID; /* no connection yet */
539 server->generation = 0; 538 server->generation = 0;
540 539
541 /* Allocate the global temp buffer and some superblock helper structs */ 540 /* Allocate the global temp buffer and some superblock helper structs */
542 /* FIXME: move these to the smb_sb_info struct */ 541 /* FIXME: move these to the smb_sb_info struct */
543 VERBOSE("alloc chunk = %d\n", sizeof(struct smb_ops) + 542 VERBOSE("alloc chunk = %d\n", sizeof(struct smb_ops) +
544 sizeof(struct smb_mount_data_kernel)); 543 sizeof(struct smb_mount_data_kernel));
545 mem = smb_kmalloc(sizeof(struct smb_ops) + 544 mem = kmalloc(sizeof(struct smb_ops) +
546 sizeof(struct smb_mount_data_kernel), GFP_KERNEL); 545 sizeof(struct smb_mount_data_kernel), GFP_KERNEL);
547 if (!mem) 546 if (!mem)
548 goto out_no_mem; 547 goto out_no_mem;
549 548
550 server->ops = mem; 549 server->ops = mem;
551 smb_install_null_ops(server->ops); 550 smb_install_null_ops(server->ops);
552 server->mnt = mem + sizeof(struct smb_ops); 551 server->mnt = mem + sizeof(struct smb_ops);
553 552
554 /* Setup NLS stuff */ 553 /* Setup NLS stuff */
555 server->remote_nls = NULL; 554 server->remote_nls = NULL;
556 server->local_nls = NULL; 555 server->local_nls = NULL;
557 556
558 mnt = server->mnt; 557 mnt = server->mnt;
559 558
560 memset(mnt, 0, sizeof(struct smb_mount_data_kernel)); 559 memset(mnt, 0, sizeof(struct smb_mount_data_kernel));
561 strlcpy(mnt->codepage.local_name, CONFIG_NLS_DEFAULT, 560 strlcpy(mnt->codepage.local_name, CONFIG_NLS_DEFAULT,
562 SMB_NLS_MAXNAMELEN); 561 SMB_NLS_MAXNAMELEN);
563 strlcpy(mnt->codepage.remote_name, SMB_NLS_REMOTE, 562 strlcpy(mnt->codepage.remote_name, SMB_NLS_REMOTE,
564 SMB_NLS_MAXNAMELEN); 563 SMB_NLS_MAXNAMELEN);
565 564
566 mnt->ttl = SMB_TTL_DEFAULT; 565 mnt->ttl = SMB_TTL_DEFAULT;
567 if (ver == SMB_MOUNT_OLDVERSION) { 566 if (ver == SMB_MOUNT_OLDVERSION) {
568 mnt->version = oldmnt->version; 567 mnt->version = oldmnt->version;
569 568
570 SET_UID(mnt->uid, oldmnt->uid); 569 SET_UID(mnt->uid, oldmnt->uid);
571 SET_GID(mnt->gid, oldmnt->gid); 570 SET_GID(mnt->gid, oldmnt->gid);
572 571
573 mnt->file_mode = (oldmnt->file_mode & S_IRWXUGO) | S_IFREG; 572 mnt->file_mode = (oldmnt->file_mode & S_IRWXUGO) | S_IFREG;
574 mnt->dir_mode = (oldmnt->dir_mode & S_IRWXUGO) | S_IFDIR; 573 mnt->dir_mode = (oldmnt->dir_mode & S_IRWXUGO) | S_IFDIR;
575 574
576 mnt->flags = (oldmnt->file_mode >> 9) | SMB_MOUNT_UID | 575 mnt->flags = (oldmnt->file_mode >> 9) | SMB_MOUNT_UID |
577 SMB_MOUNT_GID | SMB_MOUNT_FMODE | SMB_MOUNT_DMODE; 576 SMB_MOUNT_GID | SMB_MOUNT_FMODE | SMB_MOUNT_DMODE;
578 } else { 577 } else {
579 mnt->file_mode = S_IRWXU | S_IRGRP | S_IXGRP | 578 mnt->file_mode = S_IRWXU | S_IRGRP | S_IXGRP |
580 S_IROTH | S_IXOTH | S_IFREG; 579 S_IROTH | S_IXOTH | S_IFREG;
581 mnt->dir_mode = S_IRWXU | S_IRGRP | S_IXGRP | 580 mnt->dir_mode = S_IRWXU | S_IRGRP | S_IXGRP |
582 S_IROTH | S_IXOTH | S_IFDIR; 581 S_IROTH | S_IXOTH | S_IFDIR;
583 if (parse_options(mnt, raw_data)) 582 if (parse_options(mnt, raw_data))
584 goto out_bad_option; 583 goto out_bad_option;
585 } 584 }
586 mnt->mounted_uid = current->uid; 585 mnt->mounted_uid = current->uid;
587 smb_setcodepage(server, &mnt->codepage); 586 smb_setcodepage(server, &mnt->codepage);
588 587
589 /* 588 /*
590 * Display the enabled options 589 * Display the enabled options
591 * Note: smb_proc_getattr uses these in 2.4 (but was changed in 2.2) 590 * Note: smb_proc_getattr uses these in 2.4 (but was changed in 2.2)
592 */ 591 */
593 if (mnt->flags & SMB_MOUNT_OLDATTR) 592 if (mnt->flags & SMB_MOUNT_OLDATTR)
594 printk("SMBFS: Using core getattr (Win 95 speedup)\n"); 593 printk("SMBFS: Using core getattr (Win 95 speedup)\n");
595 else if (mnt->flags & SMB_MOUNT_DIRATTR) 594 else if (mnt->flags & SMB_MOUNT_DIRATTR)
596 printk("SMBFS: Using dir ff getattr\n"); 595 printk("SMBFS: Using dir ff getattr\n");
597 596
598 if (smbiod_register_server(server) < 0) { 597 if (smbiod_register_server(server) < 0) {
599 printk(KERN_ERR "smbfs: failed to start smbiod\n"); 598 printk(KERN_ERR "smbfs: failed to start smbiod\n");
600 goto out_no_smbiod; 599 goto out_no_smbiod;
601 } 600 }
602 601
603 /* 602 /*
604 * Keep the super block locked while we get the root inode. 603 * Keep the super block locked while we get the root inode.
605 */ 604 */
606 smb_init_root_dirent(server, &root, sb); 605 smb_init_root_dirent(server, &root, sb);
607 root_inode = smb_iget(sb, &root); 606 root_inode = smb_iget(sb, &root);
608 if (!root_inode) 607 if (!root_inode)
609 goto out_no_root; 608 goto out_no_root;
610 609
611 sb->s_root = d_alloc_root(root_inode); 610 sb->s_root = d_alloc_root(root_inode);
612 if (!sb->s_root) 611 if (!sb->s_root)
613 goto out_no_root; 612 goto out_no_root;
614 613
615 smb_new_dentry(sb->s_root); 614 smb_new_dentry(sb->s_root);
616 615
617 return 0; 616 return 0;
618 617
619 out_no_root: 618 out_no_root:
620 iput(root_inode); 619 iput(root_inode);
621 out_no_smbiod: 620 out_no_smbiod:
622 smb_unload_nls(server); 621 smb_unload_nls(server);
623 out_bad_option: 622 out_bad_option:
624 smb_kfree(mem); 623 kfree(mem);
625 out_no_mem: 624 out_no_mem:
626 if (!server->mnt) 625 if (!server->mnt)
627 printk(KERN_ERR "smb_fill_super: allocation failure\n"); 626 printk(KERN_ERR "smb_fill_super: allocation failure\n");
628 sb->s_fs_info = NULL; 627 sb->s_fs_info = NULL;
629 smb_kfree(server); 628 kfree(server);
630 goto out_fail; 629 goto out_fail;
631 out_wrong_data: 630 out_wrong_data:
632 printk(KERN_ERR "smbfs: mount_data version %d is not supported\n", ver); 631 printk(KERN_ERR "smbfs: mount_data version %d is not supported\n", ver);
633 goto out_fail; 632 goto out_fail;
634 out_no_data: 633 out_no_data:
635 printk(KERN_ERR "smb_fill_super: missing data argument\n"); 634 printk(KERN_ERR "smb_fill_super: missing data argument\n");
636 out_fail: 635 out_fail:
637 return -EINVAL; 636 return -EINVAL;
638 out_no_server: 637 out_no_server:
639 printk(KERN_ERR "smb_fill_super: cannot allocate struct smb_sb_info\n"); 638 printk(KERN_ERR "smb_fill_super: cannot allocate struct smb_sb_info\n");
640 return -ENOMEM; 639 return -ENOMEM;
641 } 640 }
642 641
643 static int 642 static int
644 smb_statfs(struct super_block *sb, struct kstatfs *buf) 643 smb_statfs(struct super_block *sb, struct kstatfs *buf)
645 { 644 {
646 int result; 645 int result;
647 646
648 lock_kernel(); 647 lock_kernel();
649 648
650 result = smb_proc_dskattr(sb, buf); 649 result = smb_proc_dskattr(sb, buf);
651 650
652 unlock_kernel(); 651 unlock_kernel();
653 652
654 buf->f_type = SMB_SUPER_MAGIC; 653 buf->f_type = SMB_SUPER_MAGIC;
655 buf->f_namelen = SMB_MAXPATHLEN; 654 buf->f_namelen = SMB_MAXPATHLEN;
656 return result; 655 return result;
657 } 656 }
658 657
659 int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) 658 int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
660 { 659 {
661 int err = smb_revalidate_inode(dentry); 660 int err = smb_revalidate_inode(dentry);
662 if (!err) 661 if (!err)
663 generic_fillattr(dentry->d_inode, stat); 662 generic_fillattr(dentry->d_inode, stat);
664 return err; 663 return err;
665 } 664 }
666 665
667 int 666 int
668 smb_notify_change(struct dentry *dentry, struct iattr *attr) 667 smb_notify_change(struct dentry *dentry, struct iattr *attr)
669 { 668 {
670 struct inode *inode = dentry->d_inode; 669 struct inode *inode = dentry->d_inode;
671 struct smb_sb_info *server = server_from_dentry(dentry); 670 struct smb_sb_info *server = server_from_dentry(dentry);
672 unsigned int mask = (S_IFREG | S_IFDIR | S_IRWXUGO); 671 unsigned int mask = (S_IFREG | S_IFDIR | S_IRWXUGO);
673 int error, changed, refresh = 0; 672 int error, changed, refresh = 0;
674 struct smb_fattr fattr; 673 struct smb_fattr fattr;
675 674
676 lock_kernel(); 675 lock_kernel();
677 676
678 error = smb_revalidate_inode(dentry); 677 error = smb_revalidate_inode(dentry);
679 if (error) 678 if (error)
680 goto out; 679 goto out;
681 680
682 if ((error = inode_change_ok(inode, attr)) < 0) 681 if ((error = inode_change_ok(inode, attr)) < 0)
683 goto out; 682 goto out;
684 683
685 error = -EPERM; 684 error = -EPERM;
686 if ((attr->ia_valid & ATTR_UID) && (attr->ia_uid != server->mnt->uid)) 685 if ((attr->ia_valid & ATTR_UID) && (attr->ia_uid != server->mnt->uid))
687 goto out; 686 goto out;
688 687
689 if ((attr->ia_valid & ATTR_GID) && (attr->ia_uid != server->mnt->gid)) 688 if ((attr->ia_valid & ATTR_GID) && (attr->ia_uid != server->mnt->gid))
690 goto out; 689 goto out;
691 690
692 if ((attr->ia_valid & ATTR_MODE) && (attr->ia_mode & ~mask)) 691 if ((attr->ia_valid & ATTR_MODE) && (attr->ia_mode & ~mask))
693 goto out; 692 goto out;
694 693
695 if ((attr->ia_valid & ATTR_SIZE) != 0) { 694 if ((attr->ia_valid & ATTR_SIZE) != 0) {
696 VERBOSE("changing %s/%s, old size=%ld, new size=%ld\n", 695 VERBOSE("changing %s/%s, old size=%ld, new size=%ld\n",
697 DENTRY_PATH(dentry), 696 DENTRY_PATH(dentry),
698 (long) inode->i_size, (long) attr->ia_size); 697 (long) inode->i_size, (long) attr->ia_size);
699 698
700 filemap_write_and_wait(inode->i_mapping); 699 filemap_write_and_wait(inode->i_mapping);
701 700
702 error = smb_open(dentry, O_WRONLY); 701 error = smb_open(dentry, O_WRONLY);
703 if (error) 702 if (error)
704 goto out; 703 goto out;
705 error = server->ops->truncate(inode, attr->ia_size); 704 error = server->ops->truncate(inode, attr->ia_size);
706 if (error) 705 if (error)
707 goto out; 706 goto out;
708 error = vmtruncate(inode, attr->ia_size); 707 error = vmtruncate(inode, attr->ia_size);
709 if (error) 708 if (error)
710 goto out; 709 goto out;
711 refresh = 1; 710 refresh = 1;
712 } 711 }
713 712
714 if (server->opt.capabilities & SMB_CAP_UNIX) { 713 if (server->opt.capabilities & SMB_CAP_UNIX) {
715 /* For now we don't want to set the size with setattr_unix */ 714 /* For now we don't want to set the size with setattr_unix */
716 attr->ia_valid &= ~ATTR_SIZE; 715 attr->ia_valid &= ~ATTR_SIZE;
717 /* FIXME: only call if we actually want to set something? */ 716 /* FIXME: only call if we actually want to set something? */
718 error = smb_proc_setattr_unix(dentry, attr, 0, 0); 717 error = smb_proc_setattr_unix(dentry, attr, 0, 0);
719 if (!error) 718 if (!error)
720 refresh = 1; 719 refresh = 1;
721 720
722 goto out; 721 goto out;
723 } 722 }
724 723
725 /* 724 /*
726 * Initialize the fattr and check for changed fields. 725 * Initialize the fattr and check for changed fields.
727 * Note: CTIME under SMB is creation time rather than 726 * Note: CTIME under SMB is creation time rather than
728 * change time, so we don't attempt to change it. 727 * change time, so we don't attempt to change it.
729 */ 728 */
730 smb_get_inode_attr(inode, &fattr); 729 smb_get_inode_attr(inode, &fattr);
731 730
732 changed = 0; 731 changed = 0;
733 if ((attr->ia_valid & ATTR_MTIME) != 0) { 732 if ((attr->ia_valid & ATTR_MTIME) != 0) {
734 fattr.f_mtime = attr->ia_mtime; 733 fattr.f_mtime = attr->ia_mtime;
735 changed = 1; 734 changed = 1;
736 } 735 }
737 if ((attr->ia_valid & ATTR_ATIME) != 0) { 736 if ((attr->ia_valid & ATTR_ATIME) != 0) {
738 fattr.f_atime = attr->ia_atime; 737 fattr.f_atime = attr->ia_atime;
739 /* Earlier protocols don't have an access time */ 738 /* Earlier protocols don't have an access time */
740 if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) 739 if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2)
741 changed = 1; 740 changed = 1;
742 } 741 }
743 if (changed) { 742 if (changed) {
744 error = smb_proc_settime(dentry, &fattr); 743 error = smb_proc_settime(dentry, &fattr);
745 if (error) 744 if (error)
746 goto out; 745 goto out;
747 refresh = 1; 746 refresh = 1;
748 } 747 }
749 748
750 /* 749 /*
751 * Check for mode changes ... we're extremely limited in 750 * Check for mode changes ... we're extremely limited in
752 * what can be set for SMB servers: just the read-only bit. 751 * what can be set for SMB servers: just the read-only bit.
753 */ 752 */
754 if ((attr->ia_valid & ATTR_MODE) != 0) { 753 if ((attr->ia_valid & ATTR_MODE) != 0) {
755 VERBOSE("%s/%s mode change, old=%x, new=%x\n", 754 VERBOSE("%s/%s mode change, old=%x, new=%x\n",
756 DENTRY_PATH(dentry), fattr.f_mode, attr->ia_mode); 755 DENTRY_PATH(dentry), fattr.f_mode, attr->ia_mode);
757 changed = 0; 756 changed = 0;
758 if (attr->ia_mode & S_IWUSR) { 757 if (attr->ia_mode & S_IWUSR) {
759 if (fattr.attr & aRONLY) { 758 if (fattr.attr & aRONLY) {
760 fattr.attr &= ~aRONLY; 759 fattr.attr &= ~aRONLY;
761 changed = 1; 760 changed = 1;
762 } 761 }
763 } else { 762 } else {
764 if (!(fattr.attr & aRONLY)) { 763 if (!(fattr.attr & aRONLY)) {
765 fattr.attr |= aRONLY; 764 fattr.attr |= aRONLY;
766 changed = 1; 765 changed = 1;
767 } 766 }
768 } 767 }
769 if (changed) { 768 if (changed) {
770 error = smb_proc_setattr(dentry, &fattr); 769 error = smb_proc_setattr(dentry, &fattr);
771 if (error) 770 if (error)
772 goto out; 771 goto out;
773 refresh = 1; 772 refresh = 1;
774 } 773 }
775 } 774 }
776 error = 0; 775 error = 0;
777 776
778 out: 777 out:
779 if (refresh) 778 if (refresh)
780 smb_refresh_inode(dentry); 779 smb_refresh_inode(dentry);
781 unlock_kernel(); 780 unlock_kernel();
782 return error; 781 return error;
783 } 782 }
784 783
785 #ifdef DEBUG_SMB_MALLOC
786 int smb_malloced;
787 int smb_current_kmalloced;
788 int smb_current_vmalloced;
789 #endif
790
791 static struct super_block *smb_get_sb(struct file_system_type *fs_type, 784 static struct super_block *smb_get_sb(struct file_system_type *fs_type,
792 int flags, const char *dev_name, void *data) 785 int flags, const char *dev_name, void *data)
793 { 786 {
794 return get_sb_nodev(fs_type, flags, data, smb_fill_super); 787 return get_sb_nodev(fs_type, flags, data, smb_fill_super);
795 } 788 }
796 789
797 static struct file_system_type smb_fs_type = { 790 static struct file_system_type smb_fs_type = {
798 .owner = THIS_MODULE, 791 .owner = THIS_MODULE,
799 .name = "smbfs", 792 .name = "smbfs",
800 .get_sb = smb_get_sb, 793 .get_sb = smb_get_sb,
801 .kill_sb = kill_anon_super, 794 .kill_sb = kill_anon_super,
802 .fs_flags = FS_BINARY_MOUNTDATA, 795 .fs_flags = FS_BINARY_MOUNTDATA,
803 }; 796 };
804 797
805 static int __init init_smb_fs(void) 798 static int __init init_smb_fs(void)
806 { 799 {
807 int err; 800 int err;
808 DEBUG1("registering ...\n"); 801 DEBUG1("registering ...\n");
809 802
810 #ifdef DEBUG_SMB_MALLOC
811 smb_malloced = 0;
812 smb_current_kmalloced = 0;
813 smb_current_vmalloced = 0;
814 #endif
815
816 err = init_inodecache(); 803 err = init_inodecache();
817 if (err) 804 if (err)
818 goto out_inode; 805 goto out_inode;
819 err = smb_init_request_cache(); 806 err = smb_init_request_cache();
820 if (err) 807 if (err)
821 goto out_request; 808 goto out_request;
822 err = register_filesystem(&smb_fs_type); 809 err = register_filesystem(&smb_fs_type);
823 if (err) 810 if (err)
824 goto out; 811 goto out;
825 return 0; 812 return 0;
826 out: 813 out:
827 smb_destroy_request_cache(); 814 smb_destroy_request_cache();
828 out_request: 815 out_request:
829 destroy_inodecache(); 816 destroy_inodecache();
830 out_inode: 817 out_inode:
831 return err; 818 return err;
832 } 819 }
833 820
834 static void __exit exit_smb_fs(void) 821 static void __exit exit_smb_fs(void)
835 { 822 {
836 DEBUG1("unregistering ...\n"); 823 DEBUG1("unregistering ...\n");
837 unregister_filesystem(&smb_fs_type); 824 unregister_filesystem(&smb_fs_type);
838 smb_destroy_request_cache(); 825 smb_destroy_request_cache();
839 destroy_inodecache(); 826 destroy_inodecache();
840 #ifdef DEBUG_SMB_MALLOC
841 printk(KERN_DEBUG "smb_malloced: %d\n", smb_malloced);
842 printk(KERN_DEBUG "smb_current_kmalloced: %d\n",smb_current_kmalloced);
843 printk(KERN_DEBUG "smb_current_vmalloced: %d\n",smb_current_vmalloced);
844 #endif
845 } 827 }
846 828
847 module_init(init_smb_fs) 829 module_init(init_smb_fs)
848 module_exit(exit_smb_fs) 830 module_exit(exit_smb_fs)
849 MODULE_LICENSE("GPL"); 831 MODULE_LICENSE("GPL");
850 832
1 /* 1 /*
2 * request.c 2 * request.c
3 * 3 *
4 * Copyright (C) 2001 by Urban Widmark 4 * Copyright (C) 2001 by Urban Widmark
5 * 5 *
6 * Please add a note about your changes to smbfs in the ChangeLog file. 6 * Please add a note about your changes to smbfs in the ChangeLog file.
7 */ 7 */
8 8
9 #include <linux/types.h> 9 #include <linux/types.h>
10 #include <linux/fs.h> 10 #include <linux/fs.h>
11 #include <linux/slab.h> 11 #include <linux/slab.h>
12 #include <linux/net.h> 12 #include <linux/net.h>
13 13
14 #include <linux/smb_fs.h> 14 #include <linux/smb_fs.h>
15 #include <linux/smbno.h> 15 #include <linux/smbno.h>
16 #include <linux/smb_mount.h> 16 #include <linux/smb_mount.h>
17 17
18 #include "smb_debug.h" 18 #include "smb_debug.h"
19 #include "request.h" 19 #include "request.h"
20 #include "proto.h" 20 #include "proto.h"
21 21
22 /* #define SMB_SLAB_DEBUG (SLAB_RED_ZONE | SLAB_POISON) */ 22 /* #define SMB_SLAB_DEBUG (SLAB_RED_ZONE | SLAB_POISON) */
23 #define SMB_SLAB_DEBUG 0 23 #define SMB_SLAB_DEBUG 0
24 24
25 #define ROUND_UP(x) (((x)+3) & ~3) 25 #define ROUND_UP(x) (((x)+3) & ~3)
26 26
27 /* cache for request structures */ 27 /* cache for request structures */
28 static kmem_cache_t *req_cachep; 28 static kmem_cache_t *req_cachep;
29 29
30 static int smb_request_send_req(struct smb_request *req); 30 static int smb_request_send_req(struct smb_request *req);
31 31
32 /* 32 /*
33 /proc/slabinfo: 33 /proc/slabinfo:
34 name, active, num, objsize, active_slabs, num_slaps, #pages 34 name, active, num, objsize, active_slabs, num_slaps, #pages
35 */ 35 */
36 36
37 37
38 int smb_init_request_cache(void) 38 int smb_init_request_cache(void)
39 { 39 {
40 req_cachep = kmem_cache_create("smb_request", 40 req_cachep = kmem_cache_create("smb_request",
41 sizeof(struct smb_request), 0, 41 sizeof(struct smb_request), 0,
42 SMB_SLAB_DEBUG | SLAB_HWCACHE_ALIGN, 42 SMB_SLAB_DEBUG | SLAB_HWCACHE_ALIGN,
43 NULL, NULL); 43 NULL, NULL);
44 if (req_cachep == NULL) 44 if (req_cachep == NULL)
45 return -ENOMEM; 45 return -ENOMEM;
46 46
47 return 0; 47 return 0;
48 } 48 }
49 49
50 void smb_destroy_request_cache(void) 50 void smb_destroy_request_cache(void)
51 { 51 {
52 if (kmem_cache_destroy(req_cachep)) 52 if (kmem_cache_destroy(req_cachep))
53 printk(KERN_INFO "smb_destroy_request_cache: not all structures were freed\n"); 53 printk(KERN_INFO "smb_destroy_request_cache: not all structures were freed\n");
54 } 54 }
55 55
56 /* 56 /*
57 * Allocate and initialise a request structure 57 * Allocate and initialise a request structure
58 */ 58 */
59 static struct smb_request *smb_do_alloc_request(struct smb_sb_info *server, 59 static struct smb_request *smb_do_alloc_request(struct smb_sb_info *server,
60 int bufsize) 60 int bufsize)
61 { 61 {
62 struct smb_request *req; 62 struct smb_request *req;
63 unsigned char *buf = NULL; 63 unsigned char *buf = NULL;
64 64
65 req = kmem_cache_alloc(req_cachep, SLAB_KERNEL); 65 req = kmem_cache_alloc(req_cachep, SLAB_KERNEL);
66 VERBOSE("allocating request: %p\n", req); 66 VERBOSE("allocating request: %p\n", req);
67 if (!req) 67 if (!req)
68 goto out; 68 goto out;
69 69
70 if (bufsize > 0) { 70 if (bufsize > 0) {
71 buf = smb_kmalloc(bufsize, GFP_NOFS); 71 buf = kmalloc(bufsize, GFP_NOFS);
72 if (!buf) { 72 if (!buf) {
73 kmem_cache_free(req_cachep, req); 73 kmem_cache_free(req_cachep, req);
74 return NULL; 74 return NULL;
75 } 75 }
76 } 76 }
77 77
78 memset(req, 0, sizeof(struct smb_request)); 78 memset(req, 0, sizeof(struct smb_request));
79 req->rq_buffer = buf; 79 req->rq_buffer = buf;
80 req->rq_bufsize = bufsize; 80 req->rq_bufsize = bufsize;
81 req->rq_server = server; 81 req->rq_server = server;
82 init_waitqueue_head(&req->rq_wait); 82 init_waitqueue_head(&req->rq_wait);
83 INIT_LIST_HEAD(&req->rq_queue); 83 INIT_LIST_HEAD(&req->rq_queue);
84 atomic_set(&req->rq_count, 1); 84 atomic_set(&req->rq_count, 1);
85 85
86 out: 86 out:
87 return req; 87 return req;
88 } 88 }
89 89
90 struct smb_request *smb_alloc_request(struct smb_sb_info *server, int bufsize) 90 struct smb_request *smb_alloc_request(struct smb_sb_info *server, int bufsize)
91 { 91 {
92 struct smb_request *req = NULL; 92 struct smb_request *req = NULL;
93 93
94 for (;;) { 94 for (;;) {
95 atomic_inc(&server->nr_requests); 95 atomic_inc(&server->nr_requests);
96 if (atomic_read(&server->nr_requests) <= MAX_REQUEST_HARD) { 96 if (atomic_read(&server->nr_requests) <= MAX_REQUEST_HARD) {
97 req = smb_do_alloc_request(server, bufsize); 97 req = smb_do_alloc_request(server, bufsize);
98 if (req != NULL) 98 if (req != NULL)
99 break; 99 break;
100 } 100 }
101 101
102 #if 0 102 #if 0
103 /* 103 /*
104 * Try to free up at least one request in order to stay 104 * Try to free up at least one request in order to stay
105 * below the hard limit 105 * below the hard limit
106 */ 106 */
107 if (nfs_try_to_free_pages(server)) 107 if (nfs_try_to_free_pages(server))
108 continue; 108 continue;
109 109
110 if (signalled() && (server->flags & NFS_MOUNT_INTR)) 110 if (signalled() && (server->flags & NFS_MOUNT_INTR))
111 return ERR_PTR(-ERESTARTSYS); 111 return ERR_PTR(-ERESTARTSYS);
112 current->policy = SCHED_YIELD; 112 current->policy = SCHED_YIELD;
113 schedule(); 113 schedule();
114 #else 114 #else
115 /* FIXME: we want something like nfs does above, but that 115 /* FIXME: we want something like nfs does above, but that
116 requires changes to all callers and can wait. */ 116 requires changes to all callers and can wait. */
117 break; 117 break;
118 #endif 118 #endif
119 } 119 }
120 return req; 120 return req;
121 } 121 }
122 122
123 static void smb_free_request(struct smb_request *req) 123 static void smb_free_request(struct smb_request *req)
124 { 124 {
125 atomic_dec(&req->rq_server->nr_requests); 125 atomic_dec(&req->rq_server->nr_requests);
126 if (req->rq_buffer && !(req->rq_flags & SMB_REQ_STATIC)) 126 if (req->rq_buffer && !(req->rq_flags & SMB_REQ_STATIC))
127 smb_kfree(req->rq_buffer); 127 kfree(req->rq_buffer);
128 if (req->rq_trans2buffer) 128 kfree(req->rq_trans2buffer);
129 smb_kfree(req->rq_trans2buffer);
130 kmem_cache_free(req_cachep, req); 129 kmem_cache_free(req_cachep, req);
131 } 130 }
132 131
133 /* 132 /*
134 * What prevents a rget to race with a rput? The count must never drop to zero 133 * What prevents a rget to race with a rput? The count must never drop to zero
135 * while it is in use. Only rput if it is ok that it is free'd. 134 * while it is in use. Only rput if it is ok that it is free'd.
136 */ 135 */
137 static void smb_rget(struct smb_request *req) 136 static void smb_rget(struct smb_request *req)
138 { 137 {
139 atomic_inc(&req->rq_count); 138 atomic_inc(&req->rq_count);
140 } 139 }
141 void smb_rput(struct smb_request *req) 140 void smb_rput(struct smb_request *req)
142 { 141 {
143 if (atomic_dec_and_test(&req->rq_count)) { 142 if (atomic_dec_and_test(&req->rq_count)) {
144 list_del_init(&req->rq_queue); 143 list_del_init(&req->rq_queue);
145 smb_free_request(req); 144 smb_free_request(req);
146 } 145 }
147 } 146 }
148 147
149 /* setup to receive the data part of the SMB */ 148 /* setup to receive the data part of the SMB */
150 static int smb_setup_bcc(struct smb_request *req) 149 static int smb_setup_bcc(struct smb_request *req)
151 { 150 {
152 int result = 0; 151 int result = 0;
153 req->rq_rlen = smb_len(req->rq_header) + 4 - req->rq_bytes_recvd; 152 req->rq_rlen = smb_len(req->rq_header) + 4 - req->rq_bytes_recvd;
154 153
155 if (req->rq_rlen > req->rq_bufsize) { 154 if (req->rq_rlen > req->rq_bufsize) {
156 PARANOIA("Packet too large %d > %d\n", 155 PARANOIA("Packet too large %d > %d\n",
157 req->rq_rlen, req->rq_bufsize); 156 req->rq_rlen, req->rq_bufsize);
158 return -ENOBUFS; 157 return -ENOBUFS;
159 } 158 }
160 159
161 req->rq_iov[0].iov_base = req->rq_buffer; 160 req->rq_iov[0].iov_base = req->rq_buffer;
162 req->rq_iov[0].iov_len = req->rq_rlen; 161 req->rq_iov[0].iov_len = req->rq_rlen;
163 req->rq_iovlen = 1; 162 req->rq_iovlen = 1;
164 163
165 return result; 164 return result;
166 } 165 }
167 166
168 /* 167 /*
169 * Prepare a "normal" request structure. 168 * Prepare a "normal" request structure.
170 */ 169 */
171 static int smb_setup_request(struct smb_request *req) 170 static int smb_setup_request(struct smb_request *req)
172 { 171 {
173 int len = smb_len(req->rq_header) + 4; 172 int len = smb_len(req->rq_header) + 4;
174 req->rq_slen = len; 173 req->rq_slen = len;
175 174
176 /* if we expect a data part in the reply we set the iov's to read it */ 175 /* if we expect a data part in the reply we set the iov's to read it */
177 if (req->rq_resp_bcc) 176 if (req->rq_resp_bcc)
178 req->rq_setup_read = smb_setup_bcc; 177 req->rq_setup_read = smb_setup_bcc;
179 178
180 /* This tries to support re-using the same request */ 179 /* This tries to support re-using the same request */
181 req->rq_bytes_sent = 0; 180 req->rq_bytes_sent = 0;
182 req->rq_rcls = 0; 181 req->rq_rcls = 0;
183 req->rq_err = 0; 182 req->rq_err = 0;
184 req->rq_errno = 0; 183 req->rq_errno = 0;
185 req->rq_fragment = 0; 184 req->rq_fragment = 0;
186 if (req->rq_trans2buffer) 185 kfree(req->rq_trans2buffer);
187 smb_kfree(req->rq_trans2buffer);
188 186
189 return 0; 187 return 0;
190 } 188 }
191 189
192 /* 190 /*
193 * Prepare a transaction2 request structure 191 * Prepare a transaction2 request structure
194 */ 192 */
195 static int smb_setup_trans2request(struct smb_request *req) 193 static int smb_setup_trans2request(struct smb_request *req)
196 { 194 {
197 struct smb_sb_info *server = req->rq_server; 195 struct smb_sb_info *server = req->rq_server;
198 int mparam, mdata; 196 int mparam, mdata;
199 static unsigned char padding[4]; 197 static unsigned char padding[4];
200 198
201 /* I know the following is very ugly, but I want to build the 199 /* I know the following is very ugly, but I want to build the
202 smb packet as efficiently as possible. */ 200 smb packet as efficiently as possible. */
203 201
204 const int smb_parameters = 15; 202 const int smb_parameters = 15;
205 const int header = SMB_HEADER_LEN + 2 * smb_parameters + 2; 203 const int header = SMB_HEADER_LEN + 2 * smb_parameters + 2;
206 const int oparam = ROUND_UP(header + 3); 204 const int oparam = ROUND_UP(header + 3);
207 const int odata = ROUND_UP(oparam + req->rq_lparm); 205 const int odata = ROUND_UP(oparam + req->rq_lparm);
208 const int bcc = (req->rq_data ? odata + req->rq_ldata : 206 const int bcc = (req->rq_data ? odata + req->rq_ldata :
209 oparam + req->rq_lparm) - header; 207 oparam + req->rq_lparm) - header;
210 208
211 if ((bcc + oparam) > server->opt.max_xmit) 209 if ((bcc + oparam) > server->opt.max_xmit)
212 return -ENOMEM; 210 return -ENOMEM;
213 smb_setup_header(req, SMBtrans2, smb_parameters, bcc); 211 smb_setup_header(req, SMBtrans2, smb_parameters, bcc);
214 212
215 /* 213 /*
216 * max parameters + max data + max setup == bufsize to make NT4 happy 214 * max parameters + max data + max setup == bufsize to make NT4 happy
217 * and not abort the transfer or split into multiple responses. It also 215 * and not abort the transfer or split into multiple responses. It also
218 * makes smbfs happy as handling packets larger than the buffer size 216 * makes smbfs happy as handling packets larger than the buffer size
219 * is extra work. 217 * is extra work.
220 * 218 *
221 * OS/2 is probably going to hate me for this ... 219 * OS/2 is probably going to hate me for this ...
222 */ 220 */
223 mparam = SMB_TRANS2_MAX_PARAM; 221 mparam = SMB_TRANS2_MAX_PARAM;
224 mdata = req->rq_bufsize - mparam; 222 mdata = req->rq_bufsize - mparam;
225 223
226 mdata = server->opt.max_xmit - mparam - 100; 224 mdata = server->opt.max_xmit - mparam - 100;
227 if (mdata < 1024) { 225 if (mdata < 1024) {
228 mdata = 1024; 226 mdata = 1024;
229 mparam = 20; 227 mparam = 20;
230 } 228 }
231 229
232 #if 0 230 #if 0
233 /* NT/win2k has ~4k max_xmit, so with this we request more than it wants 231 /* NT/win2k has ~4k max_xmit, so with this we request more than it wants
234 to return as one SMB. Useful for testing the fragmented trans2 232 to return as one SMB. Useful for testing the fragmented trans2
235 handling. */ 233 handling. */
236 mdata = 8192; 234 mdata = 8192;
237 #endif 235 #endif
238 236
239 WSET(req->rq_header, smb_tpscnt, req->rq_lparm); 237 WSET(req->rq_header, smb_tpscnt, req->rq_lparm);
240 WSET(req->rq_header, smb_tdscnt, req->rq_ldata); 238 WSET(req->rq_header, smb_tdscnt, req->rq_ldata);
241 WSET(req->rq_header, smb_mprcnt, mparam); 239 WSET(req->rq_header, smb_mprcnt, mparam);
242 WSET(req->rq_header, smb_mdrcnt, mdata); 240 WSET(req->rq_header, smb_mdrcnt, mdata);
243 WSET(req->rq_header, smb_msrcnt, 0); /* max setup always 0 ? */ 241 WSET(req->rq_header, smb_msrcnt, 0); /* max setup always 0 ? */
244 WSET(req->rq_header, smb_flags, 0); 242 WSET(req->rq_header, smb_flags, 0);
245 DSET(req->rq_header, smb_timeout, 0); 243 DSET(req->rq_header, smb_timeout, 0);
246 WSET(req->rq_header, smb_pscnt, req->rq_lparm); 244 WSET(req->rq_header, smb_pscnt, req->rq_lparm);
247 WSET(req->rq_header, smb_psoff, oparam - 4); 245 WSET(req->rq_header, smb_psoff, oparam - 4);
248 WSET(req->rq_header, smb_dscnt, req->rq_ldata); 246 WSET(req->rq_header, smb_dscnt, req->rq_ldata);
249 WSET(req->rq_header, smb_dsoff, req->rq_data ? odata - 4 : 0); 247 WSET(req->rq_header, smb_dsoff, req->rq_data ? odata - 4 : 0);
250 *(req->rq_header + smb_suwcnt) = 0x01; /* setup count */ 248 *(req->rq_header + smb_suwcnt) = 0x01; /* setup count */
251 *(req->rq_header + smb_suwcnt + 1) = 0x00; /* reserved */ 249 *(req->rq_header + smb_suwcnt + 1) = 0x00; /* reserved */
252 WSET(req->rq_header, smb_setup0, req->rq_trans2_command); 250 WSET(req->rq_header, smb_setup0, req->rq_trans2_command);
253 251
254 req->rq_iovlen = 2; 252 req->rq_iovlen = 2;
255 req->rq_iov[0].iov_base = (void *) req->rq_header; 253 req->rq_iov[0].iov_base = (void *) req->rq_header;
256 req->rq_iov[0].iov_len = oparam; 254 req->rq_iov[0].iov_len = oparam;
257 req->rq_iov[1].iov_base = (req->rq_parm==NULL) ? padding : req->rq_parm; 255 req->rq_iov[1].iov_base = (req->rq_parm==NULL) ? padding : req->rq_parm;
258 req->rq_iov[1].iov_len = req->rq_lparm; 256 req->rq_iov[1].iov_len = req->rq_lparm;
259 req->rq_slen = oparam + req->rq_lparm; 257 req->rq_slen = oparam + req->rq_lparm;
260 258
261 if (req->rq_data) { 259 if (req->rq_data) {
262 req->rq_iovlen += 2; 260 req->rq_iovlen += 2;
263 req->rq_iov[2].iov_base = padding; 261 req->rq_iov[2].iov_base = padding;
264 req->rq_iov[2].iov_len = odata - oparam - req->rq_lparm; 262 req->rq_iov[2].iov_len = odata - oparam - req->rq_lparm;
265 req->rq_iov[3].iov_base = req->rq_data; 263 req->rq_iov[3].iov_base = req->rq_data;
266 req->rq_iov[3].iov_len = req->rq_ldata; 264 req->rq_iov[3].iov_len = req->rq_ldata;
267 req->rq_slen = odata + req->rq_ldata; 265 req->rq_slen = odata + req->rq_ldata;
268 } 266 }
269 267
270 /* always a data part for trans2 replies */ 268 /* always a data part for trans2 replies */
271 req->rq_setup_read = smb_setup_bcc; 269 req->rq_setup_read = smb_setup_bcc;
272 270
273 return 0; 271 return 0;
274 } 272 }
275 273
276 /* 274 /*
277 * Add a request and tell smbiod to process it 275 * Add a request and tell smbiod to process it
278 */ 276 */
279 int smb_add_request(struct smb_request *req) 277 int smb_add_request(struct smb_request *req)
280 { 278 {
281 long timeleft; 279 long timeleft;
282 struct smb_sb_info *server = req->rq_server; 280 struct smb_sb_info *server = req->rq_server;
283 int result = 0; 281 int result = 0;
284 282
285 smb_setup_request(req); 283 smb_setup_request(req);
286 if (req->rq_trans2_command) { 284 if (req->rq_trans2_command) {
287 if (req->rq_buffer == NULL) { 285 if (req->rq_buffer == NULL) {
288 PARANOIA("trans2 attempted without response buffer!\n"); 286 PARANOIA("trans2 attempted without response buffer!\n");
289 return -EIO; 287 return -EIO;
290 } 288 }
291 result = smb_setup_trans2request(req); 289 result = smb_setup_trans2request(req);
292 } 290 }
293 if (result < 0) 291 if (result < 0)
294 return result; 292 return result;
295 293
296 #ifdef SMB_DEBUG_PACKET_SIZE 294 #ifdef SMB_DEBUG_PACKET_SIZE
297 add_xmit_stats(req); 295 add_xmit_stats(req);
298 #endif 296 #endif
299 297
300 /* add 'req' to the queue of requests */ 298 /* add 'req' to the queue of requests */
301 if (smb_lock_server_interruptible(server)) 299 if (smb_lock_server_interruptible(server))
302 return -EINTR; 300 return -EINTR;
303 301
304 /* 302 /*
305 * Try to send the request as the process. If that fails we queue the 303 * Try to send the request as the process. If that fails we queue the
306 * request and let smbiod send it later. 304 * request and let smbiod send it later.
307 */ 305 */
308 306
309 /* FIXME: each server has a number on the maximum number of parallel 307 /* FIXME: each server has a number on the maximum number of parallel
310 requests. 10, 50 or so. We should not allow more requests to be 308 requests. 10, 50 or so. We should not allow more requests to be
311 active. */ 309 active. */
312 if (server->mid > 0xf000) 310 if (server->mid > 0xf000)
313 server->mid = 0; 311 server->mid = 0;
314 req->rq_mid = server->mid++; 312 req->rq_mid = server->mid++;
315 WSET(req->rq_header, smb_mid, req->rq_mid); 313 WSET(req->rq_header, smb_mid, req->rq_mid);
316 314
317 result = 0; 315 result = 0;
318 if (server->state == CONN_VALID) { 316 if (server->state == CONN_VALID) {
319 if (list_empty(&server->xmitq)) 317 if (list_empty(&server->xmitq))
320 result = smb_request_send_req(req); 318 result = smb_request_send_req(req);
321 if (result < 0) { 319 if (result < 0) {
322 /* Connection lost? */ 320 /* Connection lost? */
323 server->conn_error = result; 321 server->conn_error = result;
324 server->state = CONN_INVALID; 322 server->state = CONN_INVALID;
325 } 323 }
326 } 324 }
327 if (result != 1) 325 if (result != 1)
328 list_add_tail(&req->rq_queue, &server->xmitq); 326 list_add_tail(&req->rq_queue, &server->xmitq);
329 smb_rget(req); 327 smb_rget(req);
330 328
331 if (server->state != CONN_VALID) 329 if (server->state != CONN_VALID)
332 smbiod_retry(server); 330 smbiod_retry(server);
333 331
334 smb_unlock_server(server); 332 smb_unlock_server(server);
335 333
336 smbiod_wake_up(); 334 smbiod_wake_up();
337 335
338 timeleft = wait_event_interruptible_timeout(req->rq_wait, 336 timeleft = wait_event_interruptible_timeout(req->rq_wait,
339 req->rq_flags & SMB_REQ_RECEIVED, 30*HZ); 337 req->rq_flags & SMB_REQ_RECEIVED, 30*HZ);
340 if (!timeleft || signal_pending(current)) { 338 if (!timeleft || signal_pending(current)) {
341 /* 339 /*
342 * On timeout or on interrupt we want to try and remove the 340 * On timeout or on interrupt we want to try and remove the
343 * request from the recvq/xmitq. 341 * request from the recvq/xmitq.
344 */ 342 */
345 smb_lock_server(server); 343 smb_lock_server(server);
346 if (!(req->rq_flags & SMB_REQ_RECEIVED)) { 344 if (!(req->rq_flags & SMB_REQ_RECEIVED)) {
347 list_del_init(&req->rq_queue); 345 list_del_init(&req->rq_queue);
348 smb_rput(req); 346 smb_rput(req);
349 } 347 }
350 smb_unlock_server(server); 348 smb_unlock_server(server);
351 } 349 }
352 350
353 if (!timeleft) { 351 if (!timeleft) {
354 PARANOIA("request [%p, mid=%d] timed out!\n", 352 PARANOIA("request [%p, mid=%d] timed out!\n",
355 req, req->rq_mid); 353 req, req->rq_mid);
356 VERBOSE("smb_com: %02x\n", *(req->rq_header + smb_com)); 354 VERBOSE("smb_com: %02x\n", *(req->rq_header + smb_com));
357 VERBOSE("smb_rcls: %02x\n", *(req->rq_header + smb_rcls)); 355 VERBOSE("smb_rcls: %02x\n", *(req->rq_header + smb_rcls));
358 VERBOSE("smb_flg: %02x\n", *(req->rq_header + smb_flg)); 356 VERBOSE("smb_flg: %02x\n", *(req->rq_header + smb_flg));
359 VERBOSE("smb_tid: %04x\n", WVAL(req->rq_header, smb_tid)); 357 VERBOSE("smb_tid: %04x\n", WVAL(req->rq_header, smb_tid));
360 VERBOSE("smb_pid: %04x\n", WVAL(req->rq_header, smb_pid)); 358 VERBOSE("smb_pid: %04x\n", WVAL(req->rq_header, smb_pid));
361 VERBOSE("smb_uid: %04x\n", WVAL(req->rq_header, smb_uid)); 359 VERBOSE("smb_uid: %04x\n", WVAL(req->rq_header, smb_uid));
362 VERBOSE("smb_mid: %04x\n", WVAL(req->rq_header, smb_mid)); 360 VERBOSE("smb_mid: %04x\n", WVAL(req->rq_header, smb_mid));
363 VERBOSE("smb_wct: %02x\n", *(req->rq_header + smb_wct)); 361 VERBOSE("smb_wct: %02x\n", *(req->rq_header + smb_wct));
364 362
365 req->rq_rcls = ERRSRV; 363 req->rq_rcls = ERRSRV;
366 req->rq_err = ERRtimeout; 364 req->rq_err = ERRtimeout;
367 365
368 /* Just in case it was "stuck" */ 366 /* Just in case it was "stuck" */
369 smbiod_wake_up(); 367 smbiod_wake_up();
370 } 368 }
371 VERBOSE("woke up, rcls=%d\n", req->rq_rcls); 369 VERBOSE("woke up, rcls=%d\n", req->rq_rcls);
372 370
373 if (req->rq_rcls != 0) 371 if (req->rq_rcls != 0)
374 req->rq_errno = smb_errno(req); 372 req->rq_errno = smb_errno(req);
375 if (signal_pending(current)) 373 if (signal_pending(current))
376 req->rq_errno = -ERESTARTSYS; 374 req->rq_errno = -ERESTARTSYS;
377 return req->rq_errno; 375 return req->rq_errno;
378 } 376 }
379 377
380 /* 378 /*
381 * Send a request and place it on the recvq if successfully sent. 379 * Send a request and place it on the recvq if successfully sent.
382 * Must be called with the server lock held. 380 * Must be called with the server lock held.
383 */ 381 */
384 static int smb_request_send_req(struct smb_request *req) 382 static int smb_request_send_req(struct smb_request *req)
385 { 383 {
386 struct smb_sb_info *server = req->rq_server; 384 struct smb_sb_info *server = req->rq_server;
387 int result; 385 int result;
388 386
389 if (req->rq_bytes_sent == 0) { 387 if (req->rq_bytes_sent == 0) {
390 WSET(req->rq_header, smb_tid, server->opt.tid); 388 WSET(req->rq_header, smb_tid, server->opt.tid);
391 WSET(req->rq_header, smb_pid, 1); 389 WSET(req->rq_header, smb_pid, 1);
392 WSET(req->rq_header, smb_uid, server->opt.server_uid); 390 WSET(req->rq_header, smb_uid, server->opt.server_uid);
393 } 391 }
394 392
395 result = smb_send_request(req); 393 result = smb_send_request(req);
396 if (result < 0 && result != -EAGAIN) 394 if (result < 0 && result != -EAGAIN)
397 goto out; 395 goto out;
398 396
399 result = 0; 397 result = 0;
400 if (!(req->rq_flags & SMB_REQ_TRANSMITTED)) 398 if (!(req->rq_flags & SMB_REQ_TRANSMITTED))
401 goto out; 399 goto out;
402 400
403 list_del_init(&req->rq_queue); 401 list_del_init(&req->rq_queue);
404 list_add_tail(&req->rq_queue, &server->recvq); 402 list_add_tail(&req->rq_queue, &server->recvq);
405 result = 1; 403 result = 1;
406 out: 404 out:
407 return result; 405 return result;
408 } 406 }
409 407
410 /* 408 /*
411 * Sends one request for this server. (smbiod) 409 * Sends one request for this server. (smbiod)
412 * Must be called with the server lock held. 410 * Must be called with the server lock held.
413 * Returns: <0 on error 411 * Returns: <0 on error
414 * 0 if no request could be completely sent 412 * 0 if no request could be completely sent
415 * 1 if all data for one request was sent 413 * 1 if all data for one request was sent
416 */ 414 */
417 int smb_request_send_server(struct smb_sb_info *server) 415 int smb_request_send_server(struct smb_sb_info *server)
418 { 416 {
419 struct list_head *head; 417 struct list_head *head;
420 struct smb_request *req; 418 struct smb_request *req;
421 int result; 419 int result;
422 420
423 if (server->state != CONN_VALID) 421 if (server->state != CONN_VALID)
424 return 0; 422 return 0;
425 423
426 /* dequeue first request, if any */ 424 /* dequeue first request, if any */
427 req = NULL; 425 req = NULL;
428 head = server->xmitq.next; 426 head = server->xmitq.next;
429 if (head != &server->xmitq) { 427 if (head != &server->xmitq) {
430 req = list_entry(head, struct smb_request, rq_queue); 428 req = list_entry(head, struct smb_request, rq_queue);
431 } 429 }
432 if (!req) 430 if (!req)
433 return 0; 431 return 0;
434 432
435 result = smb_request_send_req(req); 433 result = smb_request_send_req(req);
436 if (result < 0) { 434 if (result < 0) {
437 server->conn_error = result; 435 server->conn_error = result;
438 list_del_init(&req->rq_queue); 436 list_del_init(&req->rq_queue);
439 list_add(&req->rq_queue, &server->xmitq); 437 list_add(&req->rq_queue, &server->xmitq);
440 result = -EIO; 438 result = -EIO;
441 goto out; 439 goto out;
442 } 440 }
443 441
444 out: 442 out:
445 return result; 443 return result;
446 } 444 }
447 445
448 /* 446 /*
449 * Try to find a request matching this "mid". Typically the first entry will 447 * Try to find a request matching this "mid". Typically the first entry will
450 * be the matching one. 448 * be the matching one.
451 */ 449 */
452 static struct smb_request *find_request(struct smb_sb_info *server, int mid) 450 static struct smb_request *find_request(struct smb_sb_info *server, int mid)
453 { 451 {
454 struct list_head *tmp; 452 struct list_head *tmp;
455 struct smb_request *req = NULL; 453 struct smb_request *req = NULL;
456 454
457 list_for_each(tmp, &server->recvq) { 455 list_for_each(tmp, &server->recvq) {
458 req = list_entry(tmp, struct smb_request, rq_queue); 456 req = list_entry(tmp, struct smb_request, rq_queue);
459 if (req->rq_mid == mid) { 457 if (req->rq_mid == mid) {
460 break; 458 break;
461 } 459 }
462 req = NULL; 460 req = NULL;
463 } 461 }
464 462
465 if (!req) { 463 if (!req) {
466 VERBOSE("received reply with mid %d but no request!\n", 464 VERBOSE("received reply with mid %d but no request!\n",
467 WVAL(server->header, smb_mid)); 465 WVAL(server->header, smb_mid));
468 server->rstate = SMB_RECV_DROP; 466 server->rstate = SMB_RECV_DROP;
469 } 467 }
470 468
471 return req; 469 return req;
472 } 470 }
473 471
474 /* 472 /*
475 * Called when we have read the smb header and believe this is a response. 473 * Called when we have read the smb header and believe this is a response.
476 */ 474 */
477 static int smb_init_request(struct smb_sb_info *server, struct smb_request *req) 475 static int smb_init_request(struct smb_sb_info *server, struct smb_request *req)
478 { 476 {
479 int hdrlen, wct; 477 int hdrlen, wct;
480 478
481 memcpy(req->rq_header, server->header, SMB_HEADER_LEN); 479 memcpy(req->rq_header, server->header, SMB_HEADER_LEN);
482 480
483 wct = *(req->rq_header + smb_wct); 481 wct = *(req->rq_header + smb_wct);
484 if (wct > 20) { 482 if (wct > 20) {
485 PARANOIA("wct too large, %d > 20\n", wct); 483 PARANOIA("wct too large, %d > 20\n", wct);
486 server->rstate = SMB_RECV_DROP; 484 server->rstate = SMB_RECV_DROP;
487 return 0; 485 return 0;
488 } 486 }
489 487
490 req->rq_resp_wct = wct; 488 req->rq_resp_wct = wct;
491 hdrlen = SMB_HEADER_LEN + wct*2 + 2; 489 hdrlen = SMB_HEADER_LEN + wct*2 + 2;
492 VERBOSE("header length: %d smb_wct: %2d\n", hdrlen, wct); 490 VERBOSE("header length: %d smb_wct: %2d\n", hdrlen, wct);
493 491
494 req->rq_bytes_recvd = SMB_HEADER_LEN; 492 req->rq_bytes_recvd = SMB_HEADER_LEN;
495 req->rq_rlen = hdrlen; 493 req->rq_rlen = hdrlen;
496 req->rq_iov[0].iov_base = req->rq_header; 494 req->rq_iov[0].iov_base = req->rq_header;
497 req->rq_iov[0].iov_len = hdrlen; 495 req->rq_iov[0].iov_len = hdrlen;
498 req->rq_iovlen = 1; 496 req->rq_iovlen = 1;
499 server->rstate = SMB_RECV_PARAM; 497 server->rstate = SMB_RECV_PARAM;
500 498
501 #ifdef SMB_DEBUG_PACKET_SIZE 499 #ifdef SMB_DEBUG_PACKET_SIZE
502 add_recv_stats(smb_len(server->header)); 500 add_recv_stats(smb_len(server->header));
503 #endif 501 #endif
504 return 0; 502 return 0;
505 } 503 }
506 504
507 /* 505 /*
508 * Reads the SMB parameters 506 * Reads the SMB parameters
509 */ 507 */
510 static int smb_recv_param(struct smb_sb_info *server, struct smb_request *req) 508 static int smb_recv_param(struct smb_sb_info *server, struct smb_request *req)
511 { 509 {
512 int result; 510 int result;
513 511
514 result = smb_receive(server, req); 512 result = smb_receive(server, req);
515 if (result < 0) 513 if (result < 0)
516 return result; 514 return result;
517 if (req->rq_bytes_recvd < req->rq_rlen) 515 if (req->rq_bytes_recvd < req->rq_rlen)
518 return 0; 516 return 0;
519 517
520 VERBOSE("result: %d smb_bcc: %04x\n", result, 518 VERBOSE("result: %d smb_bcc: %04x\n", result,
521 WVAL(req->rq_header, SMB_HEADER_LEN + 519 WVAL(req->rq_header, SMB_HEADER_LEN +
522 (*(req->rq_header + smb_wct) * 2))); 520 (*(req->rq_header + smb_wct) * 2)));
523 521
524 result = 0; 522 result = 0;
525 req->rq_iov[0].iov_base = NULL; 523 req->rq_iov[0].iov_base = NULL;
526 req->rq_rlen = 0; 524 req->rq_rlen = 0;
527 if (req->rq_callback) 525 if (req->rq_callback)
528 req->rq_callback(req); 526 req->rq_callback(req);
529 else if (req->rq_setup_read) 527 else if (req->rq_setup_read)
530 result = req->rq_setup_read(req); 528 result = req->rq_setup_read(req);
531 if (result < 0) { 529 if (result < 0) {
532 server->rstate = SMB_RECV_DROP; 530 server->rstate = SMB_RECV_DROP;
533 return result; 531 return result;
534 } 532 }
535 533
536 server->rstate = req->rq_rlen > 0 ? SMB_RECV_DATA : SMB_RECV_END; 534 server->rstate = req->rq_rlen > 0 ? SMB_RECV_DATA : SMB_RECV_END;
537 535
538 req->rq_bytes_recvd = 0; // recvd out of the iov 536 req->rq_bytes_recvd = 0; // recvd out of the iov
539 537
540 VERBOSE("rlen: %d\n", req->rq_rlen); 538 VERBOSE("rlen: %d\n", req->rq_rlen);
541 if (req->rq_rlen < 0) { 539 if (req->rq_rlen < 0) {
542 PARANOIA("Parameters read beyond end of packet!\n"); 540 PARANOIA("Parameters read beyond end of packet!\n");
543 server->rstate = SMB_RECV_END; 541 server->rstate = SMB_RECV_END;
544 return -EIO; 542 return -EIO;
545 } 543 }
546 return 0; 544 return 0;
547 } 545 }
548 546
549 /* 547 /*
550 * Reads the SMB data 548 * Reads the SMB data
551 */ 549 */
552 static int smb_recv_data(struct smb_sb_info *server, struct smb_request *req) 550 static int smb_recv_data(struct smb_sb_info *server, struct smb_request *req)
553 { 551 {
554 int result; 552 int result;
555 553
556 result = smb_receive(server, req); 554 result = smb_receive(server, req);
557 if (result < 0) 555 if (result < 0)
558 goto out; 556 goto out;
559 if (req->rq_bytes_recvd < req->rq_rlen) 557 if (req->rq_bytes_recvd < req->rq_rlen)
560 goto out; 558 goto out;
561 server->rstate = SMB_RECV_END; 559 server->rstate = SMB_RECV_END;
562 out: 560 out:
563 VERBOSE("result: %d\n", result); 561 VERBOSE("result: %d\n", result);
564 return result; 562 return result;
565 } 563 }
566 564
567 /* 565 /*
568 * Receive a transaction2 response 566 * Receive a transaction2 response
569 * Return: 0 if the response has been fully read 567 * Return: 0 if the response has been fully read
570 * 1 if there are further "fragments" to read 568 * 1 if there are further "fragments" to read
571 * <0 if there is an error 569 * <0 if there is an error
572 */ 570 */
573 static int smb_recv_trans2(struct smb_sb_info *server, struct smb_request *req) 571 static int smb_recv_trans2(struct smb_sb_info *server, struct smb_request *req)
574 { 572 {
575 unsigned char *inbuf; 573 unsigned char *inbuf;
576 unsigned int parm_disp, parm_offset, parm_count, parm_tot; 574 unsigned int parm_disp, parm_offset, parm_count, parm_tot;
577 unsigned int data_disp, data_offset, data_count, data_tot; 575 unsigned int data_disp, data_offset, data_count, data_tot;
578 int hdrlen = SMB_HEADER_LEN + req->rq_resp_wct*2 - 2; 576 int hdrlen = SMB_HEADER_LEN + req->rq_resp_wct*2 - 2;
579 577
580 VERBOSE("handling trans2\n"); 578 VERBOSE("handling trans2\n");
581 579
582 inbuf = req->rq_header; 580 inbuf = req->rq_header;
583 data_tot = WVAL(inbuf, smb_tdrcnt); 581 data_tot = WVAL(inbuf, smb_tdrcnt);
584 parm_tot = WVAL(inbuf, smb_tprcnt); 582 parm_tot = WVAL(inbuf, smb_tprcnt);
585 parm_disp = WVAL(inbuf, smb_prdisp); 583 parm_disp = WVAL(inbuf, smb_prdisp);
586 parm_offset = WVAL(inbuf, smb_proff); 584 parm_offset = WVAL(inbuf, smb_proff);
587 parm_count = WVAL(inbuf, smb_prcnt); 585 parm_count = WVAL(inbuf, smb_prcnt);
588 data_disp = WVAL(inbuf, smb_drdisp); 586 data_disp = WVAL(inbuf, smb_drdisp);
589 data_offset = WVAL(inbuf, smb_droff); 587 data_offset = WVAL(inbuf, smb_droff);
590 data_count = WVAL(inbuf, smb_drcnt); 588 data_count = WVAL(inbuf, smb_drcnt);
591 589
592 /* Modify offset for the split header/buffer we use */ 590 /* Modify offset for the split header/buffer we use */
593 if (data_count || data_offset) { 591 if (data_count || data_offset) {
594 if (unlikely(data_offset < hdrlen)) 592 if (unlikely(data_offset < hdrlen))
595 goto out_bad_data; 593 goto out_bad_data;
596 else 594 else
597 data_offset -= hdrlen; 595 data_offset -= hdrlen;
598 } 596 }
599 if (parm_count || parm_offset) { 597 if (parm_count || parm_offset) {
600 if (unlikely(parm_offset < hdrlen)) 598 if (unlikely(parm_offset < hdrlen))
601 goto out_bad_parm; 599 goto out_bad_parm;
602 else 600 else
603 parm_offset -= hdrlen; 601 parm_offset -= hdrlen;
604 } 602 }
605 603
606 if (parm_count == parm_tot && data_count == data_tot) { 604 if (parm_count == parm_tot && data_count == data_tot) {
607 /* 605 /*
608 * This packet has all the trans2 data. 606 * This packet has all the trans2 data.
609 * 607 *
610 * We setup the request so that this will be the common 608 * We setup the request so that this will be the common
611 * case. It may be a server error to not return a 609 * case. It may be a server error to not return a
612 * response that fits. 610 * response that fits.
613 */ 611 */
614 VERBOSE("single trans2 response " 612 VERBOSE("single trans2 response "
615 "dcnt=%u, pcnt=%u, doff=%u, poff=%u\n", 613 "dcnt=%u, pcnt=%u, doff=%u, poff=%u\n",
616 data_count, parm_count, 614 data_count, parm_count,
617 data_offset, parm_offset); 615 data_offset, parm_offset);
618 req->rq_ldata = data_count; 616 req->rq_ldata = data_count;
619 req->rq_lparm = parm_count; 617 req->rq_lparm = parm_count;
620 req->rq_data = req->rq_buffer + data_offset; 618 req->rq_data = req->rq_buffer + data_offset;
621 req->rq_parm = req->rq_buffer + parm_offset; 619 req->rq_parm = req->rq_buffer + parm_offset;
622 if (unlikely(parm_offset + parm_count > req->rq_rlen)) 620 if (unlikely(parm_offset + parm_count > req->rq_rlen))
623 goto out_bad_parm; 621 goto out_bad_parm;
624 if (unlikely(data_offset + data_count > req->rq_rlen)) 622 if (unlikely(data_offset + data_count > req->rq_rlen))
625 goto out_bad_data; 623 goto out_bad_data;
626 return 0; 624 return 0;
627 } 625 }
628 626
629 VERBOSE("multi trans2 response " 627 VERBOSE("multi trans2 response "
630 "frag=%d, dcnt=%u, pcnt=%u, doff=%u, poff=%u\n", 628 "frag=%d, dcnt=%u, pcnt=%u, doff=%u, poff=%u\n",
631 req->rq_fragment, 629 req->rq_fragment,
632 data_count, parm_count, 630 data_count, parm_count,
633 data_offset, parm_offset); 631 data_offset, parm_offset);
634 632
635 if (!req->rq_fragment) { 633 if (!req->rq_fragment) {
636 int buf_len; 634 int buf_len;
637 635
638 /* We got the first trans2 fragment */ 636 /* We got the first trans2 fragment */
639 req->rq_fragment = 1; 637 req->rq_fragment = 1;
640 req->rq_total_data = data_tot; 638 req->rq_total_data = data_tot;
641 req->rq_total_parm = parm_tot; 639 req->rq_total_parm = parm_tot;
642 req->rq_ldata = 0; 640 req->rq_ldata = 0;
643 req->rq_lparm = 0; 641 req->rq_lparm = 0;
644 642
645 buf_len = data_tot + parm_tot; 643 buf_len = data_tot + parm_tot;
646 if (buf_len > SMB_MAX_PACKET_SIZE) 644 if (buf_len > SMB_MAX_PACKET_SIZE)
647 goto out_too_long; 645 goto out_too_long;
648 646
649 req->rq_trans2bufsize = buf_len; 647 req->rq_trans2bufsize = buf_len;
650 req->rq_trans2buffer = smb_kmalloc(buf_len, GFP_NOFS); 648 req->rq_trans2buffer = kzalloc(buf_len, GFP_NOFS);
651 if (!req->rq_trans2buffer) 649 if (!req->rq_trans2buffer)
652 goto out_no_mem; 650 goto out_no_mem;
653 memset(req->rq_trans2buffer, 0, buf_len);
654 651
655 req->rq_parm = req->rq_trans2buffer; 652 req->rq_parm = req->rq_trans2buffer;
656 req->rq_data = req->rq_trans2buffer + parm_tot; 653 req->rq_data = req->rq_trans2buffer + parm_tot;
657 } else if (unlikely(req->rq_total_data < data_tot || 654 } else if (unlikely(req->rq_total_data < data_tot ||
658 req->rq_total_parm < parm_tot)) 655 req->rq_total_parm < parm_tot))
659 goto out_data_grew; 656 goto out_data_grew;
660 657
661 if (unlikely(parm_disp + parm_count > req->rq_total_parm || 658 if (unlikely(parm_disp + parm_count > req->rq_total_parm ||
662 parm_offset + parm_count > req->rq_rlen)) 659 parm_offset + parm_count > req->rq_rlen))
663 goto out_bad_parm; 660 goto out_bad_parm;
664 if (unlikely(data_disp + data_count > req->rq_total_data || 661 if (unlikely(data_disp + data_count > req->rq_total_data ||
665 data_offset + data_count > req->rq_rlen)) 662 data_offset + data_count > req->rq_rlen))
666 goto out_bad_data; 663 goto out_bad_data;
667 664
668 inbuf = req->rq_buffer; 665 inbuf = req->rq_buffer;
669 memcpy(req->rq_parm + parm_disp, inbuf + parm_offset, parm_count); 666 memcpy(req->rq_parm + parm_disp, inbuf + parm_offset, parm_count);
670 memcpy(req->rq_data + data_disp, inbuf + data_offset, data_count); 667 memcpy(req->rq_data + data_disp, inbuf + data_offset, data_count);
671 668
672 req->rq_ldata += data_count; 669 req->rq_ldata += data_count;
673 req->rq_lparm += parm_count; 670 req->rq_lparm += parm_count;
674 671
675 /* 672 /*
676 * Check whether we've received all of the data. Note that 673 * Check whether we've received all of the data. Note that
677 * we use the packet totals -- total lengths might shrink! 674 * we use the packet totals -- total lengths might shrink!
678 */ 675 */
679 if (req->rq_ldata >= data_tot && req->rq_lparm >= parm_tot) { 676 if (req->rq_ldata >= data_tot && req->rq_lparm >= parm_tot) {
680 req->rq_ldata = data_tot; 677 req->rq_ldata = data_tot;
681 req->rq_lparm = parm_tot; 678 req->rq_lparm = parm_tot;
682 return 0; 679 return 0;
683 } 680 }
684 return 1; 681 return 1;
685 682
686 out_too_long: 683 out_too_long:
687 printk(KERN_ERR "smb_trans2: data/param too long, data=%u, parm=%u\n", 684 printk(KERN_ERR "smb_trans2: data/param too long, data=%u, parm=%u\n",
688 data_tot, parm_tot); 685 data_tot, parm_tot);
689 goto out_EIO; 686 goto out_EIO;
690 out_no_mem: 687 out_no_mem:
691 printk(KERN_ERR "smb_trans2: couldn't allocate data area of %d bytes\n", 688 printk(KERN_ERR "smb_trans2: couldn't allocate data area of %d bytes\n",
692 req->rq_trans2bufsize); 689 req->rq_trans2bufsize);
693 req->rq_errno = -ENOMEM; 690 req->rq_errno = -ENOMEM;
694 goto out; 691 goto out;
695 out_data_grew: 692 out_data_grew:
696 printk(KERN_ERR "smb_trans2: data/params grew!\n"); 693 printk(KERN_ERR "smb_trans2: data/params grew!\n");
697 goto out_EIO; 694 goto out_EIO;
698 out_bad_parm: 695 out_bad_parm:
699 printk(KERN_ERR "smb_trans2: invalid parms, disp=%u, cnt=%u, tot=%u, ofs=%u\n", 696 printk(KERN_ERR "smb_trans2: invalid parms, disp=%u, cnt=%u, tot=%u, ofs=%u\n",
700 parm_disp, parm_count, parm_tot, parm_offset); 697 parm_disp, parm_count, parm_tot, parm_offset);
701 goto out_EIO; 698 goto out_EIO;
702 out_bad_data: 699 out_bad_data:
703 printk(KERN_ERR "smb_trans2: invalid data, disp=%u, cnt=%u, tot=%u, ofs=%u\n", 700 printk(KERN_ERR "smb_trans2: invalid data, disp=%u, cnt=%u, tot=%u, ofs=%u\n",
704 data_disp, data_count, data_tot, data_offset); 701 data_disp, data_count, data_tot, data_offset);
705 out_EIO: 702 out_EIO:
706 req->rq_errno = -EIO; 703 req->rq_errno = -EIO;
707 out: 704 out:
708 return req->rq_errno; 705 return req->rq_errno;
709 } 706 }
710 707
711 /* 708 /*
712 * State machine for receiving responses. We handle the fact that we can't 709 * State machine for receiving responses. We handle the fact that we can't
713 * read the full response in one try by having states telling us how much we 710 * read the full response in one try by having states telling us how much we
714 * have read. 711 * have read.
715 * 712 *
716 * Must be called with the server lock held (only called from smbiod). 713 * Must be called with the server lock held (only called from smbiod).
717 * 714 *
718 * Return: <0 on error 715 * Return: <0 on error
719 */ 716 */
720 int smb_request_recv(struct smb_sb_info *server) 717 int smb_request_recv(struct smb_sb_info *server)
721 { 718 {
722 struct smb_request *req = NULL; 719 struct smb_request *req = NULL;
723 int result = 0; 720 int result = 0;
724 721
725 if (smb_recv_available(server) <= 0) 722 if (smb_recv_available(server) <= 0)
726 return 0; 723 return 0;
727 724
728 VERBOSE("state: %d\n", server->rstate); 725 VERBOSE("state: %d\n", server->rstate);
729 switch (server->rstate) { 726 switch (server->rstate) {
730 case SMB_RECV_DROP: 727 case SMB_RECV_DROP:
731 result = smb_receive_drop(server); 728 result = smb_receive_drop(server);
732 if (result < 0) 729 if (result < 0)
733 break; 730 break;
734 if (server->rstate == SMB_RECV_DROP) 731 if (server->rstate == SMB_RECV_DROP)
735 break; 732 break;
736 server->rstate = SMB_RECV_START; 733 server->rstate = SMB_RECV_START;
737 /* fallthrough */ 734 /* fallthrough */
738 case SMB_RECV_START: 735 case SMB_RECV_START:
739 server->smb_read = 0; 736 server->smb_read = 0;
740 server->rstate = SMB_RECV_HEADER; 737 server->rstate = SMB_RECV_HEADER;
741 /* fallthrough */ 738 /* fallthrough */
742 case SMB_RECV_HEADER: 739 case SMB_RECV_HEADER:
743 result = smb_receive_header(server); 740 result = smb_receive_header(server);
744 if (result < 0) 741 if (result < 0)
745 break; 742 break;
746 if (server->rstate == SMB_RECV_HEADER) 743 if (server->rstate == SMB_RECV_HEADER)
747 break; 744 break;
748 if (! (*(server->header + smb_flg) & SMB_FLAGS_REPLY) ) { 745 if (! (*(server->header + smb_flg) & SMB_FLAGS_REPLY) ) {
749 server->rstate = SMB_RECV_REQUEST; 746 server->rstate = SMB_RECV_REQUEST;
750 break; 747 break;
751 } 748 }
752 if (server->rstate != SMB_RECV_HCOMPLETE) 749 if (server->rstate != SMB_RECV_HCOMPLETE)
753 break; 750 break;
754 /* fallthrough */ 751 /* fallthrough */
755 case SMB_RECV_HCOMPLETE: 752 case SMB_RECV_HCOMPLETE:
756 req = find_request(server, WVAL(server->header, smb_mid)); 753 req = find_request(server, WVAL(server->header, smb_mid));
757 if (!req) 754 if (!req)
758 break; 755 break;
759 smb_init_request(server, req); 756 smb_init_request(server, req);
760 req->rq_rcls = *(req->rq_header + smb_rcls); 757 req->rq_rcls = *(req->rq_header + smb_rcls);
761 req->rq_err = WVAL(req->rq_header, smb_err); 758 req->rq_err = WVAL(req->rq_header, smb_err);
762 if (server->rstate != SMB_RECV_PARAM) 759 if (server->rstate != SMB_RECV_PARAM)
763 break; 760 break;
764 /* fallthrough */ 761 /* fallthrough */
765 case SMB_RECV_PARAM: 762 case SMB_RECV_PARAM:
766 if (!req) 763 if (!req)
767 req = find_request(server,WVAL(server->header,smb_mid)); 764 req = find_request(server,WVAL(server->header,smb_mid));
768 if (!req) 765 if (!req)
769 break; 766 break;
770 result = smb_recv_param(server, req); 767 result = smb_recv_param(server, req);
771 if (result < 0) 768 if (result < 0)
772 break; 769 break;
773 if (server->rstate != SMB_RECV_DATA) 770 if (server->rstate != SMB_RECV_DATA)
774 break; 771 break;
775 /* fallthrough */ 772 /* fallthrough */
776 case SMB_RECV_DATA: 773 case SMB_RECV_DATA:
777 if (!req) 774 if (!req)
778 req = find_request(server,WVAL(server->header,smb_mid)); 775 req = find_request(server,WVAL(server->header,smb_mid));
779 if (!req) 776 if (!req)
780 break; 777 break;
781 result = smb_recv_data(server, req); 778 result = smb_recv_data(server, req);
782 if (result < 0) 779 if (result < 0)
783 break; 780 break;
784 break; 781 break;
785 782
786 /* We should never be called with any of these states */ 783 /* We should never be called with any of these states */
787 case SMB_RECV_END: 784 case SMB_RECV_END:
788 case SMB_RECV_REQUEST: 785 case SMB_RECV_REQUEST:
789 BUG(); 786 BUG();
790 } 787 }
791 788
792 if (result < 0) { 789 if (result < 0) {
793 /* We saw an error */ 790 /* We saw an error */
794 return result; 791 return result;
795 } 792 }
796 793
797 if (server->rstate != SMB_RECV_END) 794 if (server->rstate != SMB_RECV_END)
798 return 0; 795 return 0;
799 796
800 result = 0; 797 result = 0;
801 if (req->rq_trans2_command && req->rq_rcls == SUCCESS) 798 if (req->rq_trans2_command && req->rq_rcls == SUCCESS)
802 result = smb_recv_trans2(server, req); 799 result = smb_recv_trans2(server, req);
803 800
804 /* 801 /*
805 * Response completely read. Drop any extra bytes sent by the server. 802 * Response completely read. Drop any extra bytes sent by the server.
806 * (Yes, servers sometimes add extra bytes to responses) 803 * (Yes, servers sometimes add extra bytes to responses)
807 */ 804 */
808 VERBOSE("smb_len: %d smb_read: %d\n", 805 VERBOSE("smb_len: %d smb_read: %d\n",
809 server->smb_len, server->smb_read); 806 server->smb_len, server->smb_read);
810 if (server->smb_read < server->smb_len) 807 if (server->smb_read < server->smb_len)
811 smb_receive_drop(server); 808 smb_receive_drop(server);
812 809
813 server->rstate = SMB_RECV_START; 810 server->rstate = SMB_RECV_START;
814 811
815 if (!result) { 812 if (!result) {
816 list_del_init(&req->rq_queue); 813 list_del_init(&req->rq_queue);
817 req->rq_flags |= SMB_REQ_RECEIVED; 814 req->rq_flags |= SMB_REQ_RECEIVED;
818 smb_rput(req); 815 smb_rput(req);
819 wake_up_interruptible(&req->rq_wait); 816 wake_up_interruptible(&req->rq_wait);
820 } 817 }
821 return 0; 818 return 0;
822 } 819 }
823 820
include/linux/smb_fs.h
1 /* 1 /*
2 * smb_fs.h 2 * smb_fs.h
3 * 3 *
4 * Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke 4 * Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke
5 * Copyright (C) 1997 by Volker Lendecke 5 * Copyright (C) 1997 by Volker Lendecke
6 * 6 *
7 */ 7 */
8 8
9 #ifndef _LINUX_SMB_FS_H 9 #ifndef _LINUX_SMB_FS_H
10 #define _LINUX_SMB_FS_H 10 #define _LINUX_SMB_FS_H
11 11
12 #include <linux/smb.h> 12 #include <linux/smb.h>
13 #include <linux/smb_fs_i.h> 13 #include <linux/smb_fs_i.h>
14 #include <linux/smb_fs_sb.h> 14 #include <linux/smb_fs_sb.h>
15 15
16 /* 16 /*
17 * ioctl commands 17 * ioctl commands
18 */ 18 */
19 #define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_old_uid_t) 19 #define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_old_uid_t)
20 #define SMB_IOC_NEWCONN _IOW('u', 2, struct smb_conn_opt) 20 #define SMB_IOC_NEWCONN _IOW('u', 2, struct smb_conn_opt)
21 21
22 /* __kernel_uid_t can never change, so we have to use __kernel_uid32_t */ 22 /* __kernel_uid_t can never change, so we have to use __kernel_uid32_t */
23 #define SMB_IOC_GETMOUNTUID32 _IOR('u', 3, __kernel_uid32_t) 23 #define SMB_IOC_GETMOUNTUID32 _IOR('u', 3, __kernel_uid32_t)
24 24
25 25
26 #ifdef __KERNEL__ 26 #ifdef __KERNEL__
27 27
28 #include <linux/fs.h> 28 #include <linux/fs.h>
29 #include <linux/pagemap.h> 29 #include <linux/pagemap.h>
30 #include <linux/vmalloc.h> 30 #include <linux/vmalloc.h>
31 #include <linux/smb_mount.h> 31 #include <linux/smb_mount.h>
32 #include <asm/unaligned.h> 32 #include <asm/unaligned.h>
33 33
34 static inline struct smb_sb_info *SMB_SB(struct super_block *sb) 34 static inline struct smb_sb_info *SMB_SB(struct super_block *sb)
35 { 35 {
36 return sb->s_fs_info; 36 return sb->s_fs_info;
37 } 37 }
38 38
39 static inline struct smb_inode_info *SMB_I(struct inode *inode) 39 static inline struct smb_inode_info *SMB_I(struct inode *inode)
40 { 40 {
41 return container_of(inode, struct smb_inode_info, vfs_inode); 41 return container_of(inode, struct smb_inode_info, vfs_inode);
42 } 42 }
43 43
44 /* macro names are short for word, double-word, long value (?) */ 44 /* macro names are short for word, double-word, long value (?) */
45 #define WVAL(buf,pos) \ 45 #define WVAL(buf,pos) \
46 (le16_to_cpu(get_unaligned((u16 *)((u8 *)(buf) + (pos))))) 46 (le16_to_cpu(get_unaligned((u16 *)((u8 *)(buf) + (pos)))))
47 #define DVAL(buf,pos) \ 47 #define DVAL(buf,pos) \
48 (le32_to_cpu(get_unaligned((u32 *)((u8 *)(buf) + (pos))))) 48 (le32_to_cpu(get_unaligned((u32 *)((u8 *)(buf) + (pos)))))
49 #define LVAL(buf,pos) \ 49 #define LVAL(buf,pos) \
50 (le64_to_cpu(get_unaligned((u64 *)((u8 *)(buf) + (pos))))) 50 (le64_to_cpu(get_unaligned((u64 *)((u8 *)(buf) + (pos)))))
51 #define WSET(buf,pos,val) \ 51 #define WSET(buf,pos,val) \
52 put_unaligned(cpu_to_le16((u16)(val)), (u16 *)((u8 *)(buf) + (pos))) 52 put_unaligned(cpu_to_le16((u16)(val)), (u16 *)((u8 *)(buf) + (pos)))
53 #define DSET(buf,pos,val) \ 53 #define DSET(buf,pos,val) \
54 put_unaligned(cpu_to_le32((u32)(val)), (u32 *)((u8 *)(buf) + (pos))) 54 put_unaligned(cpu_to_le32((u32)(val)), (u32 *)((u8 *)(buf) + (pos)))
55 #define LSET(buf,pos,val) \ 55 #define LSET(buf,pos,val) \
56 put_unaligned(cpu_to_le64((u64)(val)), (u64 *)((u8 *)(buf) + (pos))) 56 put_unaligned(cpu_to_le64((u64)(val)), (u64 *)((u8 *)(buf) + (pos)))
57 57
58 /* where to find the base of the SMB packet proper */ 58 /* where to find the base of the SMB packet proper */
59 #define smb_base(buf) ((u8 *)(((u8 *)(buf))+4)) 59 #define smb_base(buf) ((u8 *)(((u8 *)(buf))+4))
60 60
61 #ifdef DEBUG_SMB_MALLOC
62
63 #include <linux/slab.h>
64
65 extern int smb_malloced;
66 extern int smb_current_vmalloced;
67 extern int smb_current_kmalloced;
68
69 static inline void *
70 smb_vmalloc(unsigned int size)
71 {
72 smb_malloced += 1;
73 smb_current_vmalloced += 1;
74 return vmalloc(size);
75 }
76
77 static inline void
78 smb_vfree(void *obj)
79 {
80 smb_current_vmalloced -= 1;
81 vfree(obj);
82 }
83
84 static inline void *
85 smb_kmalloc(size_t size, int flags)
86 {
87 smb_malloced += 1;
88 smb_current_kmalloced += 1;
89 return kmalloc(size, flags);
90 }
91
92 static inline void
93 smb_kfree(void *obj)
94 {
95 smb_current_kmalloced -= 1;
96 kfree(obj);
97 }
98
99 #else /* DEBUG_SMB_MALLOC */
100
101 #define smb_kmalloc(s,p) kmalloc(s,p)
102 #define smb_kfree(o) kfree(o)
103 #define smb_vmalloc(s) vmalloc(s)
104 #define smb_vfree(o) vfree(o)
105
106 #endif /* DEBUG_SMB_MALLOC */
107
108 /* 61 /*
109 * Flags for the in-memory inode 62 * Flags for the in-memory inode
110 */ 63 */
111 #define SMB_F_LOCALWRITE 0x02 /* file modified locally */ 64 #define SMB_F_LOCALWRITE 0x02 /* file modified locally */
112 65
113 66
114 /* NT1 protocol capability bits */ 67 /* NT1 protocol capability bits */
115 #define SMB_CAP_RAW_MODE 0x00000001 68 #define SMB_CAP_RAW_MODE 0x00000001
116 #define SMB_CAP_MPX_MODE 0x00000002 69 #define SMB_CAP_MPX_MODE 0x00000002
117 #define SMB_CAP_UNICODE 0x00000004 70 #define SMB_CAP_UNICODE 0x00000004
118 #define SMB_CAP_LARGE_FILES 0x00000008 71 #define SMB_CAP_LARGE_FILES 0x00000008
119 #define SMB_CAP_NT_SMBS 0x00000010 72 #define SMB_CAP_NT_SMBS 0x00000010
120 #define SMB_CAP_RPC_REMOTE_APIS 0x00000020 73 #define SMB_CAP_RPC_REMOTE_APIS 0x00000020
121 #define SMB_CAP_STATUS32 0x00000040 74 #define SMB_CAP_STATUS32 0x00000040
122 #define SMB_CAP_LEVEL_II_OPLOCKS 0x00000080 75 #define SMB_CAP_LEVEL_II_OPLOCKS 0x00000080
123 #define SMB_CAP_LOCK_AND_READ 0x00000100 76 #define SMB_CAP_LOCK_AND_READ 0x00000100
124 #define SMB_CAP_NT_FIND 0x00000200 77 #define SMB_CAP_NT_FIND 0x00000200
125 #define SMB_CAP_DFS 0x00001000 78 #define SMB_CAP_DFS 0x00001000
126 #define SMB_CAP_LARGE_READX 0x00004000 79 #define SMB_CAP_LARGE_READX 0x00004000
127 #define SMB_CAP_LARGE_WRITEX 0x00008000 80 #define SMB_CAP_LARGE_WRITEX 0x00008000
128 #define SMB_CAP_UNIX 0x00800000 /* unofficial ... */ 81 #define SMB_CAP_UNIX 0x00800000 /* unofficial ... */
129 82
130 83
131 /* 84 /*
132 * This is the time we allow an inode, dentry or dir cache to live. It is bad 85 * This is the time we allow an inode, dentry or dir cache to live. It is bad
133 * for performance to have shorter ttl on an inode than on the cache. It can 86 * for performance to have shorter ttl on an inode than on the cache. It can
134 * cause refresh on each inode for a dir listing ... one-by-one 87 * cause refresh on each inode for a dir listing ... one-by-one
135 */ 88 */
136 #define SMB_MAX_AGE(server) (((server)->mnt->ttl * HZ) / 1000) 89 #define SMB_MAX_AGE(server) (((server)->mnt->ttl * HZ) / 1000)
137 90
138 static inline void 91 static inline void
139 smb_age_dentry(struct smb_sb_info *server, struct dentry *dentry) 92 smb_age_dentry(struct smb_sb_info *server, struct dentry *dentry)
140 { 93 {
141 dentry->d_time = jiffies - SMB_MAX_AGE(server); 94 dentry->d_time = jiffies - SMB_MAX_AGE(server);
142 } 95 }
143 96
144 struct smb_cache_head { 97 struct smb_cache_head {
145 time_t mtime; /* unused */ 98 time_t mtime; /* unused */
146 unsigned long time; /* cache age */ 99 unsigned long time; /* cache age */
147 unsigned long end; /* last valid fpos in cache */ 100 unsigned long end; /* last valid fpos in cache */
148 int eof; 101 int eof;
149 }; 102 };
150 103
151 #define SMB_DIRCACHE_SIZE ((int)(PAGE_CACHE_SIZE/sizeof(struct dentry *))) 104 #define SMB_DIRCACHE_SIZE ((int)(PAGE_CACHE_SIZE/sizeof(struct dentry *)))
152 union smb_dir_cache { 105 union smb_dir_cache {
153 struct smb_cache_head head; 106 struct smb_cache_head head;
154 struct dentry *dentry[SMB_DIRCACHE_SIZE]; 107 struct dentry *dentry[SMB_DIRCACHE_SIZE];
155 }; 108 };
156 109
157 #define SMB_FIRSTCACHE_SIZE ((int)((SMB_DIRCACHE_SIZE * \ 110 #define SMB_FIRSTCACHE_SIZE ((int)((SMB_DIRCACHE_SIZE * \
158 sizeof(struct dentry *) - sizeof(struct smb_cache_head)) / \ 111 sizeof(struct dentry *) - sizeof(struct smb_cache_head)) / \
159 sizeof(struct dentry *))) 112 sizeof(struct dentry *)))
160 113
161 #define SMB_DIRCACHE_START (SMB_DIRCACHE_SIZE - SMB_FIRSTCACHE_SIZE) 114 #define SMB_DIRCACHE_START (SMB_DIRCACHE_SIZE - SMB_FIRSTCACHE_SIZE)
162 115
163 struct smb_cache_control { 116 struct smb_cache_control {
164 struct smb_cache_head head; 117 struct smb_cache_head head;
165 struct page *page; 118 struct page *page;
166 union smb_dir_cache *cache; 119 union smb_dir_cache *cache;
167 unsigned long fpos, ofs; 120 unsigned long fpos, ofs;
168 int filled, valid, idx; 121 int filled, valid, idx;
169 }; 122 };
170 123
171 #define SMB_OPS_NUM_STATIC 5 124 #define SMB_OPS_NUM_STATIC 5
172 struct smb_ops { 125 struct smb_ops {
173 int (*read)(struct inode *inode, loff_t offset, int count, 126 int (*read)(struct inode *inode, loff_t offset, int count,
174 char *data); 127 char *data);
175 int (*write)(struct inode *inode, loff_t offset, int count, const 128 int (*write)(struct inode *inode, loff_t offset, int count, const
176 char *data); 129 char *data);
177 int (*readdir)(struct file *filp, void *dirent, filldir_t filldir, 130 int (*readdir)(struct file *filp, void *dirent, filldir_t filldir,
178 struct smb_cache_control *ctl); 131 struct smb_cache_control *ctl);
179 132
180 int (*getattr)(struct smb_sb_info *server, struct dentry *dir, 133 int (*getattr)(struct smb_sb_info *server, struct dentry *dir,
181 struct smb_fattr *fattr); 134 struct smb_fattr *fattr);
182 /* int (*setattr)(...); */ /* setattr is really icky! */ 135 /* int (*setattr)(...); */ /* setattr is really icky! */
183 136
184 int (*truncate)(struct inode *inode, loff_t length); 137 int (*truncate)(struct inode *inode, loff_t length);
185 138
186 139
187 /* --- --- --- end of "static" entries --- --- --- */ 140 /* --- --- --- end of "static" entries --- --- --- */
188 141
189 int (*convert)(unsigned char *output, int olen, 142 int (*convert)(unsigned char *output, int olen,
190 const unsigned char *input, int ilen, 143 const unsigned char *input, int ilen,
191 struct nls_table *nls_from, 144 struct nls_table *nls_from,
192 struct nls_table *nls_to); 145 struct nls_table *nls_to);
193 }; 146 };
194 147
195 static inline int 148 static inline int
196 smb_is_open(struct inode *i) 149 smb_is_open(struct inode *i)
197 { 150 {
198 return (SMB_I(i)->open == server_from_inode(i)->generation); 151 return (SMB_I(i)->open == server_from_inode(i)->generation);
199 } 152 }
200 153
201 extern void smb_install_null_ops(struct smb_ops *); 154 extern void smb_install_null_ops(struct smb_ops *);
202 #endif /* __KERNEL__ */ 155 #endif /* __KERNEL__ */
203 156
204 #endif /* _LINUX_SMB_FS_H */ 157 #endif /* _LINUX_SMB_FS_H */
205 158