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