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
254
255
256
257 error = smb_proc_connect(server);
258
259 unlock_super(sb);
260
261 if (error < 0) {
262 sb->s_dev = 0;
263 printk("smb_read_super: Failed connection, bailing out "
264 "(error = %d).\n", -error);
265 goto fail;
266 }
267
268 if (server->protocol >= PROTOCOL_LANMAN2)
269 server->case_handling = CASE_DEFAULT;
270 else
271 server->case_handling = CASE_LOWER;
272
273 if ((error = smb_proc_dskattr(sb, &(SMB_SBP(sb)->s_attr))) < 0) {
274 sb->s_dev = 0;
275 printk("smb_read_super: could not get super block "
276 "attributes\n");
277 smb_kfree_s(server->packet, server->max_xmit);
278 goto fail;
279 }
280
281 DPRINTK("smb_read_super : %u %u %u %u\n",
282 SMB_SBP(sb)->s_attr.total,
283 SMB_SBP(sb)->s_attr.blocksize,
284 SMB_SBP(sb)->s_attr.allocblocks,
285 SMB_SBP(sb)->s_attr.free);
286
287 if (smb_init_root(server) != 0) {
288 sb->s_dev = 0;
289 printk("smb_read_super: invalid root directory\n");
290 smb_kfree_s(server->packet, server->max_xmit);
291 goto fail;
292 }
293
294 DPRINTK("smb_read_super: SMB_SBP(sb) = %x\n", (int)SMB_SBP(sb));
295
296 if (!(sb->s_mounted = iget(sb, (int)&(server->root)))) {
297 sb->s_dev = 0;
298 printk("smb_read_super: get root inode failed\n");
299 smb_kfree_s(server->packet, server->max_xmit);
300 goto fail;
301 }
302
303 MOD_INC_USE_COUNT;
304 return sb;
305
306 fail:
307 filp->f_count -= 1;
308 smb_kfree_s(SMB_SBP(sb), sizeof(struct smb_sb_info));
309 return NULL;
310 }
311
312 static void
313 smb_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
314 {
315 int error;
316 struct smb_dskattr attr;
317 struct statfs tmp;
318
319 error = smb_proc_dskattr(sb, &attr);
320
321 if (error) {
322 printk("smb_statfs: dskattr error = %d\n", -error);
323 attr.total = attr.allocblocks = attr.blocksize =
324 attr.free = 0;
325 }
326
327 tmp.f_type = SMB_SUPER_MAGIC;
328 tmp.f_bsize = attr.blocksize*attr.allocblocks;
329 tmp.f_blocks = attr.total;
330 tmp.f_bfree = attr.free;
331 tmp.f_bavail = attr.free;
332 tmp.f_files = -1;
333 tmp.f_ffree = -1;
334 tmp.f_namelen = SMB_MAXPATHLEN;
335 memcpy_tofs(buf, &tmp, bufsiz);
336 }
337
338
339 int
340 smb_notify_change(struct inode *inode, struct iattr *attr)
341 {
342 int error = 0;
343
344 if ((error = inode_change_ok(inode, attr)) < 0)
345 return error;
346
347 if (!S_ISREG(inode->i_mode))
348 return -EPERM;
349
350 if ((attr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)) != 0) {
351 return -EPERM;
352 }
353
354 if ((attr->ia_valid & ATTR_SIZE) != 0) {
355
356 if ((error = smb_make_open(inode, O_WRONLY)) < 0)
357 goto fail;
358
359 if ((error = smb_proc_trunc(SMB_SERVER(inode),
360 SMB_FINFO(inode)->fileid,
361 attr->ia_size)) < 0)
362 goto fail;
363
364 }
365
366 if ((attr->ia_valid & (ATTR_CTIME | ATTR_MTIME | ATTR_ATIME)) != 0) {
367
368 struct smb_dirent finfo;
369
370 finfo.attr = 0;
371
372 if ((attr->ia_valid & ATTR_CTIME) != 0)
373 finfo.ctime = attr->ia_ctime;
374 else
375 finfo.ctime = inode->i_ctime;
376
377 if ((attr->ia_valid & ATTR_MTIME) != 0)
378 finfo.mtime = attr->ia_mtime;
379 else
380 finfo.mtime = inode->i_mtime;
381
382 if ((attr->ia_valid & ATTR_ATIME) != 0)
383 finfo.atime = attr->ia_atime;
384 else
385 finfo.atime = inode->i_atime;
386
387 if ((error = smb_proc_setattr(SMB_SERVER(inode),
388 inode, &finfo)) >= 0) {
389 inode->i_ctime = finfo.ctime;
390 inode->i_mtime = finfo.mtime;
391 inode->i_atime = finfo.atime;
392 }
393 }
394
395 fail:
396 smb_invalid_dir_cache((unsigned long)(SMB_INOP(inode)->dir));
397
398 return error;
399 }
400
401
402 #ifdef DEBUG_SMB_MALLOC
403 int smb_malloced;
404 int smb_current_malloced;
405 #endif
406
407 #ifdef MODULE
408
409 static char kernel_version[] = UTS_RELEASE;
410
411
412 static void *shut_up_gcc = (&shut_up_gcc, kernel_version);
413
414 static struct file_system_type smb_fs_type = {
415 smb_read_super, "smbfs", 0, NULL
416 };
417
418 int
419 init_module( void)
420 {
421 DPRINTK("smbfs: init_module called\n");
422
423 #ifdef DEBUG_SMB_MALLOC
424 smb_malloced = 0;
425 smb_current_malloced = 0;
426 #endif
427
428 smb_init_dir_cache();
429 register_filesystem(&smb_fs_type);
430 return 0;
431 }
432
433 void
434 cleanup_module(void)
435 {
436 DPRINTK("smbfs: cleanup_module called\n");
437 smb_free_dir_cache();
438 unregister_filesystem(&smb_fs_type);
439 #ifdef DEBUG_SMB_MALLOC
440 printk("smb_malloced: %d\n", smb_malloced);
441 printk("smb_current_malloced: %d\n", smb_current_malloced);
442 #endif
443 }
444
445 #endif
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462