This source file includes following definitions.
- smb_read_inode
- smb_put_inode
- smb_put_super
- smb_read_super
- smb_statfs
- smb_notify_change
- init_module
- cleanup_module
1
2
3
4
5
6
7
8 #include <linux/config.h>
9 #ifdef MODULE
10 #include <linux/module.h>
11 #include <linux/version.h>
12 #else
13 #define MOD_INC_USE_COUNT
14 #define MOD_DEC_USE_COUNT
15 #endif
16
17 #include <asm/system.h>
18 #include <asm/segment.h>
19
20 #include <linux/sched.h>
21 #include <linux/smb_fs.h>
22 #include <linux/smbno.h>
23 #include <linux/kernel.h>
24 #include <linux/mm.h>
25 #include <linux/string.h>
26 #include <linux/stat.h>
27 #include <linux/errno.h>
28 #include <linux/locks.h>
29 #include <linux/fcntl.h>
30 #include <linux/malloc.h>
31
32 extern int close_fp(struct file *filp);
33
34 static void smb_put_inode(struct inode *);
35 static void smb_read_inode(struct inode *);
36 static void smb_put_super(struct super_block *);
37 static void smb_statfs(struct super_block *, struct statfs *, int bufsiz);
38
39 static struct super_operations smb_sops = {
40 smb_read_inode,
41 smb_notify_change,
42 NULL,
43 smb_put_inode,
44 smb_put_super,
45 NULL,
46 smb_statfs,
47 NULL
48 };
49
50
51
52
53
54 static void
55 smb_read_inode(struct inode *inode)
56 {
57
58
59
60
61
62
63 struct smb_inode_info *inode_info
64 = (struct smb_inode_info *)(inode->i_ino);
65
66 #if 1
67 struct smb_inode_info *root = &(SMB_SERVER(inode)->root);
68 struct smb_inode_info *check_info = root;
69
70 do {
71 if (inode_info == check_info) {
72 if (check_info->state == INODE_LOOKED_UP) {
73 DDPRINTK("smb_read_inode: found it!\n");
74 goto good;
75 }
76 else {
77 printk("smb_read_inode: "
78 "state != INODE_LOOKED_UP\n");
79 return;
80 }
81 }
82 check_info = check_info->next;
83 } while (check_info != root);
84
85
86
87 printk("smb_read_inode: inode info not found\n");
88 return;
89
90 good:
91 #endif
92 inode_info->state = INODE_VALID;
93
94 SMB_INOP(inode) = inode_info;
95
96 if (SMB_INOP(inode)->finfo.attr & aDIR)
97 inode->i_mode = SMB_SERVER(inode)->m.dir_mode;
98 else
99 inode->i_mode = SMB_SERVER(inode)->m.file_mode;
100
101 DDPRINTK("smb_read_inode: inode->i_mode = %u\n", inode->i_mode);
102
103 inode->i_nlink = 1;
104 inode->i_uid = SMB_SERVER(inode)->m.uid;
105 inode->i_gid = SMB_SERVER(inode)->m.gid;
106 inode->i_size = SMB_INOP(inode)->finfo.size;
107 inode->i_blksize = 1024;
108 inode->i_rdev = 0;
109 if ((inode->i_blksize != 0) && (inode->i_size != 0))
110 inode->i_blocks =
111 (inode->i_size - 1) / inode->i_blksize + 1;
112 else
113 inode->i_blocks = 0;
114
115 inode->i_mtime = SMB_INOP(inode)->finfo.mtime;
116 inode->i_ctime = SMB_INOP(inode)->finfo.ctime;
117 inode->i_atime = SMB_INOP(inode)->finfo.atime;
118
119 if (S_ISREG(inode->i_mode))
120 inode->i_op = &smb_file_inode_operations;
121 else if (S_ISDIR(inode->i_mode))
122 inode->i_op = &smb_dir_inode_operations;
123 else
124 inode->i_op = NULL;
125
126 }
127
128 static void
129 smb_put_inode(struct inode *inode)
130 {
131 struct smb_dirent *finfo = SMB_FINFO(inode);
132
133 if (finfo->opened != 0) {
134
135
136 finfo->mtime = inode->i_mtime;
137
138 if (smb_proc_close(SMB_SERVER(inode), finfo)) {
139
140 printk("smb_put_inode: could not close\n");
141 }
142 }
143
144 smb_free_inode_info(SMB_INOP(inode));
145
146 if (S_ISDIR(inode->i_mode)) {
147 DDPRINTK("smb_put_inode: put directory %ld\n",
148 inode->i_ino);
149 smb_invalid_dir_cache(inode->i_ino);
150 }
151
152 clear_inode(inode);
153 }
154
155 static void
156 smb_put_super(struct super_block *sb)
157 {
158 struct smb_server *server = &(SMB_SBP(sb)->s_server);
159
160 smb_proc_disconnect(server);
161 close_fp(server->sock_file);
162
163 lock_super(sb);
164
165 smb_free_all_inodes(server);
166
167 smb_kfree_s(server->packet, server->max_xmit);
168
169 sb->s_dev = 0;
170 smb_kfree_s(SMB_SBP(sb), sizeof(struct smb_sb_info));
171
172 unlock_super(sb);
173
174 MOD_DEC_USE_COUNT;
175 }
176
177
178
179 struct super_block *
180 smb_read_super(struct super_block *sb, void *raw_data, int silent)
181 {
182 struct smb_mount_data *data = (struct smb_mount_data *) raw_data;
183 struct smb_server *server;
184 struct smb_sb_info *smb_sb;
185 unsigned int fd;
186 struct file *filp;
187 dev_t dev = sb->s_dev;
188 int error;
189
190 if (!data) {
191 printk("smb_read_super: missing data argument\n");
192 sb->s_dev = 0;
193 return NULL;
194 }
195 fd = data->fd;
196 if (data->version != SMB_MOUNT_VERSION) {
197 printk("smb warning: mount version %s than kernel\n",
198 (data->version < SMB_MOUNT_VERSION) ?
199 "older" : "newer");
200 }
201 if (fd >= NR_OPEN || !(filp = current->files->fd[fd])) {
202 printk("smb_read_super: invalid file descriptor\n");
203 sb->s_dev = 0;
204 return NULL;
205 }
206 if (!S_ISSOCK(filp->f_inode->i_mode)) {
207 printk("smb_read_super: not a socket!\n");
208 sb->s_dev = 0;
209 return NULL;
210 }
211
212
213 smb_sb = (struct smb_sb_info *)smb_kmalloc(sizeof(struct smb_sb_info),
214 GFP_KERNEL);
215
216 if (smb_sb == NULL) {
217 printk("smb_read_super: could not alloc smb_sb_info\n");
218 return NULL;
219 }
220
221 filp->f_count += 1;
222
223 lock_super(sb);
224
225 SMB_SBP(sb) = smb_sb;
226
227 sb->s_blocksize = 1024;
228 sb->s_blocksize_bits = 10;
229 sb->s_magic = SMB_SUPER_MAGIC;
230 sb->s_dev = dev;
231 sb->s_op = &smb_sops;
232
233 server = &(SMB_SBP(sb)->s_server);
234 server->sock_file = filp;
235 server->lock = 0;
236 server->wait = NULL;
237 server->packet = NULL;
238 server->max_xmit = data->max_xmit;
239 if (server->max_xmit <= 0)
240 server->max_xmit = SMB_DEF_MAX_XMIT;
241
242 server->tid = 0;
243 server->pid = current->pid;
244 server->mid = current->pid + 20;
245
246 server->m = *data;
247 server->m.file_mode = (server->m.file_mode &
248 (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFREG;
249 server->m.dir_mode = (server->m.dir_mode &
250 (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR;
251
252 smb_init_root(server);
253
254
255
256
257
258 error = smb_proc_connect(server);
259
260 unlock_super(sb);
261
262 if (error < 0) {
263 sb->s_dev = 0;
264 printk("smb_read_super: Failed connection, bailing out "
265 "(error = %d).\n", -error);
266 goto fail;
267 }
268
269 if (server->protocol >= PROTOCOL_LANMAN2)
270 server->case_handling = CASE_DEFAULT;
271 else
272 server->case_handling = CASE_LOWER;
273
274 if ((error = smb_proc_dskattr(sb, &(SMB_SBP(sb)->s_attr))) < 0) {
275 sb->s_dev = 0;
276 printk("smb_read_super: could not get super block "
277 "attributes\n");
278 smb_kfree_s(server->packet, server->max_xmit);
279 goto fail;
280 }
281
282 if ((error = smb_stat_root(server)) < 0) {
283 sb->s_dev = 0;
284 printk("smb_read_super: could not get root dir attributes\n");
285 smb_kfree_s(server->packet, server->max_xmit);
286 goto fail;
287 }
288
289 DPRINTK("smb_read_super : %u %u %u %u\n",
290 SMB_SBP(sb)->s_attr.total,
291 SMB_SBP(sb)->s_attr.blocksize,
292 SMB_SBP(sb)->s_attr.allocblocks,
293 SMB_SBP(sb)->s_attr.free);
294
295 DPRINTK("smb_read_super: SMB_SBP(sb) = %x\n", (int)SMB_SBP(sb));
296
297 if (!(sb->s_mounted = iget(sb, (int)&(server->root)))) {
298 sb->s_dev = 0;
299 printk("smb_read_super: get root inode failed\n");
300 smb_kfree_s(server->packet, server->max_xmit);
301 goto fail;
302 }
303
304 MOD_INC_USE_COUNT;
305 return sb;
306
307 fail:
308 filp->f_count -= 1;
309 smb_kfree_s(SMB_SBP(sb), sizeof(struct smb_sb_info));
310 return NULL;
311 }
312
313 static void
314 smb_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
315 {
316 int error;
317 struct smb_dskattr attr;
318 struct statfs tmp;
319
320 error = smb_proc_dskattr(sb, &attr);
321
322 if (error) {
323 printk("smb_statfs: dskattr error = %d\n", -error);
324 attr.total = attr.allocblocks = attr.blocksize =
325 attr.free = 0;
326 }
327
328 tmp.f_type = SMB_SUPER_MAGIC;
329 tmp.f_bsize = attr.blocksize*attr.allocblocks;
330 tmp.f_blocks = attr.total;
331 tmp.f_bfree = attr.free;
332 tmp.f_bavail = attr.free;
333 tmp.f_files = -1;
334 tmp.f_ffree = -1;
335 tmp.f_namelen = SMB_MAXPATHLEN;
336 memcpy_tofs(buf, &tmp, bufsiz);
337 }
338
339
340 int
341 smb_notify_change(struct inode *inode, struct iattr *attr)
342 {
343 int error = 0;
344
345 if ((error = inode_change_ok(inode, attr)) < 0)
346 return error;
347
348 if (!S_ISREG(inode->i_mode))
349 return -EPERM;
350
351 if ((attr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)) != 0) {
352 return -EPERM;
353 }
354
355 if ((attr->ia_valid & ATTR_SIZE) != 0) {
356
357 if ((error = smb_make_open(inode, O_WRONLY)) < 0)
358 goto fail;
359
360 if ((error = smb_proc_trunc(SMB_SERVER(inode),
361 SMB_FINFO(inode)->fileid,
362 attr->ia_size)) < 0)
363 goto fail;
364
365 }
366
367 if ((attr->ia_valid & (ATTR_CTIME | ATTR_MTIME | ATTR_ATIME)) != 0) {
368
369 struct smb_dirent finfo;
370
371 finfo.attr = 0;
372
373 if ((attr->ia_valid & ATTR_CTIME) != 0)
374 finfo.ctime = attr->ia_ctime;
375 else
376 finfo.ctime = inode->i_ctime;
377
378 if ((attr->ia_valid & ATTR_MTIME) != 0)
379 finfo.mtime = attr->ia_mtime;
380 else
381 finfo.mtime = inode->i_mtime;
382
383 if ((attr->ia_valid & ATTR_ATIME) != 0)
384 finfo.atime = attr->ia_atime;
385 else
386 finfo.atime = inode->i_atime;
387
388 if ((error = smb_proc_setattr(SMB_SERVER(inode),
389 inode, &finfo)) >= 0) {
390 inode->i_ctime = finfo.ctime;
391 inode->i_mtime = finfo.mtime;
392 inode->i_atime = finfo.atime;
393 }
394 }
395
396 fail:
397 smb_invalid_dir_cache((unsigned long)(SMB_INOP(inode)->dir));
398
399 return error;
400 }
401
402
403 #ifdef DEBUG_SMB_MALLOC
404 int smb_malloced;
405 int smb_current_malloced;
406 #endif
407
408 #ifdef MODULE
409
410 char kernel_version[] = UTS_RELEASE;
411
412
413 static void *shut_up_gcc = (&shut_up_gcc, kernel_version);
414
415 static struct file_system_type smb_fs_type = {
416 smb_read_super, "smbfs", 0, NULL
417 };
418
419 int
420 init_module( void)
421 {
422 DPRINTK("smbfs: init_module called\n");
423
424 #ifdef DEBUG_SMB_MALLOC
425 smb_malloced = 0;
426 smb_current_malloced = 0;
427 #endif
428
429 smb_init_dir_cache();
430 register_filesystem(&smb_fs_type);
431 return 0;
432 }
433
434 void
435 cleanup_module(void)
436 {
437 DPRINTK("smbfs: cleanup_module called\n");
438 smb_free_dir_cache();
439 unregister_filesystem(&smb_fs_type);
440 #ifdef DEBUG_SMB_MALLOC
441 printk("smb_malloced: %d\n", smb_malloced);
442 printk("smb_current_malloced: %d\n", smb_current_malloced);
443 #endif
444 }
445
446 #endif
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463