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