fs: push sync_filesystem() down to the file system's remount_fs()
[deliverable/linux.git] / fs / ncpfs / inode.c
1 /*
2 * inode.c
3 *
4 * Copyright (C) 1995, 1996 by Volker Lendecke
5 * Modified for big endian by J.F. Chadima and David S. Miller
6 * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
7 * Modified 1998 Wolfram Pienkoss for NLS
8 * Modified 2000 Ben Harris, University of Cambridge for NFS NS meta-info
9 *
10 */
11
12 #include <linux/module.h>
13
14 #include <asm/uaccess.h>
15 #include <asm/byteorder.h>
16
17 #include <linux/time.h>
18 #include <linux/kernel.h>
19 #include <linux/mm.h>
20 #include <linux/string.h>
21 #include <linux/stat.h>
22 #include <linux/errno.h>
23 #include <linux/file.h>
24 #include <linux/fcntl.h>
25 #include <linux/slab.h>
26 #include <linux/vmalloc.h>
27 #include <linux/init.h>
28 #include <linux/vfs.h>
29 #include <linux/mount.h>
30 #include <linux/seq_file.h>
31 #include <linux/namei.h>
32
33 #include <net/sock.h>
34
35 #include "ncp_fs.h"
36 #include "getopt.h"
37
38 #define NCP_DEFAULT_FILE_MODE 0600
39 #define NCP_DEFAULT_DIR_MODE 0700
40 #define NCP_DEFAULT_TIME_OUT 10
41 #define NCP_DEFAULT_RETRY_COUNT 20
42
43 static void ncp_evict_inode(struct inode *);
44 static void ncp_put_super(struct super_block *);
45 static int ncp_statfs(struct dentry *, struct kstatfs *);
46 static int ncp_show_options(struct seq_file *, struct dentry *);
47
48 static struct kmem_cache * ncp_inode_cachep;
49
50 static struct inode *ncp_alloc_inode(struct super_block *sb)
51 {
52 struct ncp_inode_info *ei;
53 ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL);
54 if (!ei)
55 return NULL;
56 return &ei->vfs_inode;
57 }
58
59 static void ncp_i_callback(struct rcu_head *head)
60 {
61 struct inode *inode = container_of(head, struct inode, i_rcu);
62 kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
63 }
64
65 static void ncp_destroy_inode(struct inode *inode)
66 {
67 call_rcu(&inode->i_rcu, ncp_i_callback);
68 }
69
70 static void init_once(void *foo)
71 {
72 struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
73
74 mutex_init(&ei->open_mutex);
75 inode_init_once(&ei->vfs_inode);
76 }
77
78 static int init_inodecache(void)
79 {
80 ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
81 sizeof(struct ncp_inode_info),
82 0, (SLAB_RECLAIM_ACCOUNT|
83 SLAB_MEM_SPREAD),
84 init_once);
85 if (ncp_inode_cachep == NULL)
86 return -ENOMEM;
87 return 0;
88 }
89
90 static void destroy_inodecache(void)
91 {
92 /*
93 * Make sure all delayed rcu free inodes are flushed before we
94 * destroy cache.
95 */
96 rcu_barrier();
97 kmem_cache_destroy(ncp_inode_cachep);
98 }
99
100 static int ncp_remount(struct super_block *sb, int *flags, char* data)
101 {
102 sync_filesystem(sb);
103 *flags |= MS_NODIRATIME;
104 return 0;
105 }
106
107 static const struct super_operations ncp_sops =
108 {
109 .alloc_inode = ncp_alloc_inode,
110 .destroy_inode = ncp_destroy_inode,
111 .drop_inode = generic_delete_inode,
112 .evict_inode = ncp_evict_inode,
113 .put_super = ncp_put_super,
114 .statfs = ncp_statfs,
115 .remount_fs = ncp_remount,
116 .show_options = ncp_show_options,
117 };
118
119 /*
120 * Fill in the ncpfs-specific information in the inode.
121 */
122 static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
123 {
124 NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
125 NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
126 NCP_FINFO(inode)->volNumber = nwinfo->volume;
127 }
128
129 void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
130 {
131 ncp_update_dirent(inode, nwinfo);
132 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
133 NCP_FINFO(inode)->access = nwinfo->access;
134 memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
135 sizeof(nwinfo->file_handle));
136 DPRINTK("ncp_update_inode: updated %s, volnum=%d, dirent=%u\n",
137 nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
138 NCP_FINFO(inode)->dirEntNum);
139 }
140
141 static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
142 {
143 /* NFS namespace mode overrides others if it's set. */
144 DPRINTK(KERN_DEBUG "ncp_update_dates_and_mode: (%s) nfs.mode=0%o\n",
145 nwi->entryName, nwi->nfs.mode);
146 if (nwi->nfs.mode) {
147 /* XXX Security? */
148 inode->i_mode = nwi->nfs.mode;
149 }
150
151 inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
152
153 inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
154 inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
155 inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
156 inode->i_atime.tv_nsec = 0;
157 inode->i_mtime.tv_nsec = 0;
158 inode->i_ctime.tv_nsec = 0;
159 }
160
161 static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
162 {
163 struct nw_info_struct *nwi = &nwinfo->i;
164 struct ncp_server *server = NCP_SERVER(inode);
165
166 if (nwi->attributes & aDIR) {
167 inode->i_mode = server->m.dir_mode;
168 /* for directories dataStreamSize seems to be some
169 Object ID ??? */
170 i_size_write(inode, NCP_BLOCK_SIZE);
171 } else {
172 u32 size;
173
174 inode->i_mode = server->m.file_mode;
175 size = le32_to_cpu(nwi->dataStreamSize);
176 i_size_write(inode, size);
177 #ifdef CONFIG_NCPFS_EXTRAS
178 if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
179 && (nwi->attributes & aSHARED)) {
180 switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
181 case aHIDDEN:
182 if (server->m.flags & NCP_MOUNT_SYMLINKS) {
183 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
184 && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
185 inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
186 NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
187 break;
188 }
189 }
190 /* FALLTHROUGH */
191 case 0:
192 if (server->m.flags & NCP_MOUNT_EXTRAS)
193 inode->i_mode |= S_IRUGO;
194 break;
195 case aSYSTEM:
196 if (server->m.flags & NCP_MOUNT_EXTRAS)
197 inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
198 break;
199 /* case aSYSTEM|aHIDDEN: */
200 default:
201 /* reserved combination */
202 break;
203 }
204 }
205 #endif
206 }
207 if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
208 }
209
210 void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
211 {
212 NCP_FINFO(inode)->flags = 0;
213 if (!atomic_read(&NCP_FINFO(inode)->opened)) {
214 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
215 ncp_update_attrs(inode, nwinfo);
216 }
217
218 ncp_update_dates(inode, &nwinfo->i);
219 ncp_update_dirent(inode, nwinfo);
220 }
221
222 /*
223 * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
224 */
225 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
226 {
227 struct ncp_server *server = NCP_SERVER(inode);
228
229 NCP_FINFO(inode)->flags = 0;
230
231 ncp_update_attrs(inode, nwinfo);
232
233 DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
234
235 set_nlink(inode, 1);
236 inode->i_uid = server->m.uid;
237 inode->i_gid = server->m.gid;
238
239 ncp_update_dates(inode, &nwinfo->i);
240 ncp_update_inode(inode, nwinfo);
241 }
242
243 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
244 static const struct inode_operations ncp_symlink_inode_operations = {
245 .readlink = generic_readlink,
246 .follow_link = page_follow_link_light,
247 .put_link = page_put_link,
248 .setattr = ncp_notify_change,
249 };
250 #endif
251
252 /*
253 * Get a new inode.
254 */
255 struct inode *
256 ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
257 {
258 struct inode *inode;
259
260 if (info == NULL) {
261 printk(KERN_ERR "ncp_iget: info is NULL\n");
262 return NULL;
263 }
264
265 inode = new_inode(sb);
266 if (inode) {
267 atomic_set(&NCP_FINFO(inode)->opened, info->opened);
268
269 inode->i_mapping->backing_dev_info = sb->s_bdi;
270 inode->i_ino = info->ino;
271 ncp_set_attr(inode, info);
272 if (S_ISREG(inode->i_mode)) {
273 inode->i_op = &ncp_file_inode_operations;
274 inode->i_fop = &ncp_file_operations;
275 } else if (S_ISDIR(inode->i_mode)) {
276 inode->i_op = &ncp_dir_inode_operations;
277 inode->i_fop = &ncp_dir_operations;
278 #ifdef CONFIG_NCPFS_NFS_NS
279 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
280 init_special_inode(inode, inode->i_mode,
281 new_decode_dev(info->i.nfs.rdev));
282 #endif
283 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
284 } else if (S_ISLNK(inode->i_mode)) {
285 inode->i_op = &ncp_symlink_inode_operations;
286 inode->i_data.a_ops = &ncp_symlink_aops;
287 #endif
288 } else {
289 make_bad_inode(inode);
290 }
291 insert_inode_hash(inode);
292 } else
293 printk(KERN_ERR "ncp_iget: iget failed!\n");
294 return inode;
295 }
296
297 static void
298 ncp_evict_inode(struct inode *inode)
299 {
300 truncate_inode_pages(&inode->i_data, 0);
301 clear_inode(inode);
302
303 if (S_ISDIR(inode->i_mode)) {
304 DDPRINTK("ncp_evict_inode: put directory %ld\n", inode->i_ino);
305 }
306
307 if (ncp_make_closed(inode) != 0) {
308 /* We can't do anything but complain. */
309 printk(KERN_ERR "ncp_evict_inode: could not close\n");
310 }
311 }
312
313 static void ncp_stop_tasks(struct ncp_server *server) {
314 struct sock* sk = server->ncp_sock->sk;
315
316 lock_sock(sk);
317 sk->sk_error_report = server->error_report;
318 sk->sk_data_ready = server->data_ready;
319 sk->sk_write_space = server->write_space;
320 release_sock(sk);
321 del_timer_sync(&server->timeout_tm);
322
323 flush_work(&server->rcv.tq);
324 if (sk->sk_socket->type == SOCK_STREAM)
325 flush_work(&server->tx.tq);
326 else
327 flush_work(&server->timeout_tq);
328 }
329
330 static int ncp_show_options(struct seq_file *seq, struct dentry *root)
331 {
332 struct ncp_server *server = NCP_SBP(root->d_sb);
333 unsigned int tmp;
334
335 if (!uid_eq(server->m.uid, GLOBAL_ROOT_UID))
336 seq_printf(seq, ",uid=%u",
337 from_kuid_munged(&init_user_ns, server->m.uid));
338 if (!gid_eq(server->m.gid, GLOBAL_ROOT_GID))
339 seq_printf(seq, ",gid=%u",
340 from_kgid_munged(&init_user_ns, server->m.gid));
341 if (!uid_eq(server->m.mounted_uid, GLOBAL_ROOT_UID))
342 seq_printf(seq, ",owner=%u",
343 from_kuid_munged(&init_user_ns, server->m.mounted_uid));
344 tmp = server->m.file_mode & S_IALLUGO;
345 if (tmp != NCP_DEFAULT_FILE_MODE)
346 seq_printf(seq, ",mode=0%o", tmp);
347 tmp = server->m.dir_mode & S_IALLUGO;
348 if (tmp != NCP_DEFAULT_DIR_MODE)
349 seq_printf(seq, ",dirmode=0%o", tmp);
350 if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) {
351 tmp = server->m.time_out * 100 / HZ;
352 seq_printf(seq, ",timeout=%u", tmp);
353 }
354 if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT)
355 seq_printf(seq, ",retry=%u", server->m.retry_count);
356 if (server->m.flags != 0)
357 seq_printf(seq, ",flags=%lu", server->m.flags);
358 if (server->m.wdog_pid != NULL)
359 seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid));
360
361 return 0;
362 }
363
364 static const struct ncp_option ncp_opts[] = {
365 { "uid", OPT_INT, 'u' },
366 { "gid", OPT_INT, 'g' },
367 { "owner", OPT_INT, 'o' },
368 { "mode", OPT_INT, 'm' },
369 { "dirmode", OPT_INT, 'd' },
370 { "timeout", OPT_INT, 't' },
371 { "retry", OPT_INT, 'r' },
372 { "flags", OPT_INT, 'f' },
373 { "wdogpid", OPT_INT, 'w' },
374 { "ncpfd", OPT_INT, 'n' },
375 { "infofd", OPT_INT, 'i' }, /* v5 */
376 { "version", OPT_INT, 'v' },
377 { NULL, 0, 0 } };
378
379 static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
380 int optval;
381 char *optarg;
382 unsigned long optint;
383 int version = 0;
384 int ret;
385
386 data->flags = 0;
387 data->int_flags = 0;
388 data->mounted_uid = GLOBAL_ROOT_UID;
389 data->wdog_pid = NULL;
390 data->ncp_fd = ~0;
391 data->time_out = NCP_DEFAULT_TIME_OUT;
392 data->retry_count = NCP_DEFAULT_RETRY_COUNT;
393 data->uid = GLOBAL_ROOT_UID;
394 data->gid = GLOBAL_ROOT_GID;
395 data->file_mode = NCP_DEFAULT_FILE_MODE;
396 data->dir_mode = NCP_DEFAULT_DIR_MODE;
397 data->info_fd = -1;
398 data->mounted_vol[0] = 0;
399
400 while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
401 ret = optval;
402 if (ret < 0)
403 goto err;
404 switch (optval) {
405 case 'u':
406 data->uid = make_kuid(current_user_ns(), optint);
407 if (!uid_valid(data->uid)) {
408 ret = -EINVAL;
409 goto err;
410 }
411 break;
412 case 'g':
413 data->gid = make_kgid(current_user_ns(), optint);
414 if (!gid_valid(data->gid)) {
415 ret = -EINVAL;
416 goto err;
417 }
418 break;
419 case 'o':
420 data->mounted_uid = make_kuid(current_user_ns(), optint);
421 if (!uid_valid(data->mounted_uid)) {
422 ret = -EINVAL;
423 goto err;
424 }
425 break;
426 case 'm':
427 data->file_mode = optint;
428 break;
429 case 'd':
430 data->dir_mode = optint;
431 break;
432 case 't':
433 data->time_out = optint;
434 break;
435 case 'r':
436 data->retry_count = optint;
437 break;
438 case 'f':
439 data->flags = optint;
440 break;
441 case 'w':
442 data->wdog_pid = find_get_pid(optint);
443 break;
444 case 'n':
445 data->ncp_fd = optint;
446 break;
447 case 'i':
448 data->info_fd = optint;
449 break;
450 case 'v':
451 ret = -ECHRNG;
452 if (optint < NCP_MOUNT_VERSION_V4)
453 goto err;
454 if (optint > NCP_MOUNT_VERSION_V5)
455 goto err;
456 version = optint;
457 break;
458
459 }
460 }
461 return 0;
462 err:
463 put_pid(data->wdog_pid);
464 data->wdog_pid = NULL;
465 return ret;
466 }
467
468 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
469 {
470 struct ncp_mount_data_kernel data;
471 struct ncp_server *server;
472 struct file *ncp_filp;
473 struct inode *root_inode;
474 struct inode *sock_inode;
475 struct socket *sock;
476 int error;
477 int default_bufsize;
478 #ifdef CONFIG_NCPFS_PACKET_SIGNING
479 int options;
480 #endif
481 struct ncp_entry_info finfo;
482
483 memset(&data, 0, sizeof(data));
484 server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
485 if (!server)
486 return -ENOMEM;
487 sb->s_fs_info = server;
488
489 error = -EFAULT;
490 if (raw_data == NULL)
491 goto out;
492 switch (*(int*)raw_data) {
493 case NCP_MOUNT_VERSION:
494 {
495 struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
496
497 data.flags = md->flags;
498 data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
499 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
500 data.wdog_pid = find_get_pid(md->wdog_pid);
501 data.ncp_fd = md->ncp_fd;
502 data.time_out = md->time_out;
503 data.retry_count = md->retry_count;
504 data.uid = make_kuid(current_user_ns(), md->uid);
505 data.gid = make_kgid(current_user_ns(), md->gid);
506 data.file_mode = md->file_mode;
507 data.dir_mode = md->dir_mode;
508 data.info_fd = -1;
509 memcpy(data.mounted_vol, md->mounted_vol,
510 NCP_VOLNAME_LEN+1);
511 }
512 break;
513 case NCP_MOUNT_VERSION_V4:
514 {
515 struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
516
517 data.flags = md->flags;
518 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
519 data.wdog_pid = find_get_pid(md->wdog_pid);
520 data.ncp_fd = md->ncp_fd;
521 data.time_out = md->time_out;
522 data.retry_count = md->retry_count;
523 data.uid = make_kuid(current_user_ns(), md->uid);
524 data.gid = make_kgid(current_user_ns(), md->gid);
525 data.file_mode = md->file_mode;
526 data.dir_mode = md->dir_mode;
527 data.info_fd = -1;
528 }
529 break;
530 default:
531 error = -ECHRNG;
532 if (memcmp(raw_data, "vers", 4) == 0) {
533 error = ncp_parse_options(&data, raw_data);
534 }
535 if (error)
536 goto out;
537 break;
538 }
539 error = -EINVAL;
540 if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) ||
541 !gid_valid(data.gid))
542 goto out;
543 error = -EBADF;
544 ncp_filp = fget(data.ncp_fd);
545 if (!ncp_filp)
546 goto out;
547 error = -ENOTSOCK;
548 sock_inode = file_inode(ncp_filp);
549 if (!S_ISSOCK(sock_inode->i_mode))
550 goto out_fput;
551 sock = SOCKET_I(sock_inode);
552 if (!sock)
553 goto out_fput;
554
555 if (sock->type == SOCK_STREAM)
556 default_bufsize = 0xF000;
557 else
558 default_bufsize = 1024;
559
560 sb->s_flags |= MS_NODIRATIME; /* probably even noatime */
561 sb->s_maxbytes = 0xFFFFFFFFU;
562 sb->s_blocksize = 1024; /* Eh... Is this correct? */
563 sb->s_blocksize_bits = 10;
564 sb->s_magic = NCP_SUPER_MAGIC;
565 sb->s_op = &ncp_sops;
566 sb->s_d_op = &ncp_dentry_operations;
567 sb->s_bdi = &server->bdi;
568
569 server = NCP_SBP(sb);
570 memset(server, 0, sizeof(*server));
571
572 error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
573 if (error)
574 goto out_fput;
575
576 server->ncp_filp = ncp_filp;
577 server->ncp_sock = sock;
578
579 if (data.info_fd != -1) {
580 struct socket *info_sock;
581
582 error = -EBADF;
583 server->info_filp = fget(data.info_fd);
584 if (!server->info_filp)
585 goto out_bdi;
586 error = -ENOTSOCK;
587 sock_inode = file_inode(server->info_filp);
588 if (!S_ISSOCK(sock_inode->i_mode))
589 goto out_fput2;
590 info_sock = SOCKET_I(sock_inode);
591 if (!info_sock)
592 goto out_fput2;
593 error = -EBADFD;
594 if (info_sock->type != SOCK_STREAM)
595 goto out_fput2;
596 server->info_sock = info_sock;
597 }
598
599 /* server->lock = 0; */
600 mutex_init(&server->mutex);
601 server->packet = NULL;
602 /* server->buffer_size = 0; */
603 /* server->conn_status = 0; */
604 /* server->root_dentry = NULL; */
605 /* server->root_setuped = 0; */
606 mutex_init(&server->root_setup_lock);
607 #ifdef CONFIG_NCPFS_PACKET_SIGNING
608 /* server->sign_wanted = 0; */
609 /* server->sign_active = 0; */
610 #endif
611 init_rwsem(&server->auth_rwsem);
612 server->auth.auth_type = NCP_AUTH_NONE;
613 /* server->auth.object_name_len = 0; */
614 /* server->auth.object_name = NULL; */
615 /* server->auth.object_type = 0; */
616 /* server->priv.len = 0; */
617 /* server->priv.data = NULL; */
618
619 server->m = data;
620 /* Although anything producing this is buggy, it happens
621 now because of PATH_MAX changes.. */
622 if (server->m.time_out < 1) {
623 server->m.time_out = 10;
624 printk(KERN_INFO "You need to recompile your ncpfs utils..\n");
625 }
626 server->m.time_out = server->m.time_out * HZ / 100;
627 server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
628 server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
629
630 #ifdef CONFIG_NCPFS_NLS
631 /* load the default NLS charsets */
632 server->nls_vol = load_nls_default();
633 server->nls_io = load_nls_default();
634 #endif /* CONFIG_NCPFS_NLS */
635
636 atomic_set(&server->dentry_ttl, 0); /* no caching */
637
638 INIT_LIST_HEAD(&server->tx.requests);
639 mutex_init(&server->rcv.creq_mutex);
640 server->tx.creq = NULL;
641 server->rcv.creq = NULL;
642
643 init_timer(&server->timeout_tm);
644 #undef NCP_PACKET_SIZE
645 #define NCP_PACKET_SIZE 131072
646 error = -ENOMEM;
647 server->packet_size = NCP_PACKET_SIZE;
648 server->packet = vmalloc(NCP_PACKET_SIZE);
649 if (server->packet == NULL)
650 goto out_nls;
651 server->txbuf = vmalloc(NCP_PACKET_SIZE);
652 if (server->txbuf == NULL)
653 goto out_packet;
654 server->rxbuf = vmalloc(NCP_PACKET_SIZE);
655 if (server->rxbuf == NULL)
656 goto out_txbuf;
657
658 lock_sock(sock->sk);
659 server->data_ready = sock->sk->sk_data_ready;
660 server->write_space = sock->sk->sk_write_space;
661 server->error_report = sock->sk->sk_error_report;
662 sock->sk->sk_user_data = server;
663 sock->sk->sk_data_ready = ncp_tcp_data_ready;
664 sock->sk->sk_error_report = ncp_tcp_error_report;
665 if (sock->type == SOCK_STREAM) {
666 server->rcv.ptr = (unsigned char*)&server->rcv.buf;
667 server->rcv.len = 10;
668 server->rcv.state = 0;
669 INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
670 INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
671 sock->sk->sk_write_space = ncp_tcp_write_space;
672 } else {
673 INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
674 INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
675 server->timeout_tm.data = (unsigned long)server;
676 server->timeout_tm.function = ncpdgram_timeout_call;
677 }
678 release_sock(sock->sk);
679
680 ncp_lock_server(server);
681 error = ncp_connect(server);
682 ncp_unlock_server(server);
683 if (error < 0)
684 goto out_rxbuf;
685 DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));
686
687 error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */
688 #ifdef CONFIG_NCPFS_PACKET_SIGNING
689 if (ncp_negotiate_size_and_options(server, default_bufsize,
690 NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
691 {
692 if (options != NCP_DEFAULT_OPTIONS)
693 {
694 if (ncp_negotiate_size_and_options(server,
695 default_bufsize,
696 options & 2,
697 &(server->buffer_size), &options) != 0)
698
699 {
700 goto out_disconnect;
701 }
702 }
703 ncp_lock_server(server);
704 if (options & 2)
705 server->sign_wanted = 1;
706 ncp_unlock_server(server);
707 }
708 else
709 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
710 if (ncp_negotiate_buffersize(server, default_bufsize,
711 &(server->buffer_size)) != 0)
712 goto out_disconnect;
713 DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
714
715 memset(&finfo, 0, sizeof(finfo));
716 finfo.i.attributes = aDIR;
717 finfo.i.dataStreamSize = 0; /* ignored */
718 finfo.i.dirEntNum = 0;
719 finfo.i.DosDirNum = 0;
720 #ifdef CONFIG_NCPFS_SMALLDOS
721 finfo.i.NSCreator = NW_NS_DOS;
722 #endif
723 finfo.volume = NCP_NUMBER_OF_VOLUMES;
724 /* set dates of mountpoint to Jan 1, 1986; 00:00 */
725 finfo.i.creationTime = finfo.i.modifyTime
726 = cpu_to_le16(0x0000);
727 finfo.i.creationDate = finfo.i.modifyDate
728 = finfo.i.lastAccessDate
729 = cpu_to_le16(0x0C21);
730 finfo.i.nameLen = 0;
731 finfo.i.entryName[0] = '\0';
732
733 finfo.opened = 0;
734 finfo.ino = 2; /* tradition */
735
736 server->name_space[finfo.volume] = NW_NS_DOS;
737
738 error = -ENOMEM;
739 root_inode = ncp_iget(sb, &finfo);
740 if (!root_inode)
741 goto out_disconnect;
742 DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
743 sb->s_root = d_make_root(root_inode);
744 if (!sb->s_root)
745 goto out_disconnect;
746 return 0;
747
748 out_disconnect:
749 ncp_lock_server(server);
750 ncp_disconnect(server);
751 ncp_unlock_server(server);
752 out_rxbuf:
753 ncp_stop_tasks(server);
754 vfree(server->rxbuf);
755 out_txbuf:
756 vfree(server->txbuf);
757 out_packet:
758 vfree(server->packet);
759 out_nls:
760 #ifdef CONFIG_NCPFS_NLS
761 unload_nls(server->nls_io);
762 unload_nls(server->nls_vol);
763 #endif
764 mutex_destroy(&server->rcv.creq_mutex);
765 mutex_destroy(&server->root_setup_lock);
766 mutex_destroy(&server->mutex);
767 out_fput2:
768 if (server->info_filp)
769 fput(server->info_filp);
770 out_bdi:
771 bdi_destroy(&server->bdi);
772 out_fput:
773 /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
774 *
775 * The previously used put_filp(ncp_filp); was bogus, since
776 * it doesn't perform proper unlocking.
777 */
778 fput(ncp_filp);
779 out:
780 put_pid(data.wdog_pid);
781 sb->s_fs_info = NULL;
782 kfree(server);
783 return error;
784 }
785
786 static void delayed_free(struct rcu_head *p)
787 {
788 struct ncp_server *server = container_of(p, struct ncp_server, rcu);
789 #ifdef CONFIG_NCPFS_NLS
790 /* unload the NLS charsets */
791 unload_nls(server->nls_vol);
792 unload_nls(server->nls_io);
793 #endif /* CONFIG_NCPFS_NLS */
794 kfree(server);
795 }
796
797 static void ncp_put_super(struct super_block *sb)
798 {
799 struct ncp_server *server = NCP_SBP(sb);
800
801 ncp_lock_server(server);
802 ncp_disconnect(server);
803 ncp_unlock_server(server);
804
805 ncp_stop_tasks(server);
806
807 mutex_destroy(&server->rcv.creq_mutex);
808 mutex_destroy(&server->root_setup_lock);
809 mutex_destroy(&server->mutex);
810
811 if (server->info_filp)
812 fput(server->info_filp);
813 fput(server->ncp_filp);
814 kill_pid(server->m.wdog_pid, SIGTERM, 1);
815 put_pid(server->m.wdog_pid);
816
817 bdi_destroy(&server->bdi);
818 kfree(server->priv.data);
819 kfree(server->auth.object_name);
820 vfree(server->rxbuf);
821 vfree(server->txbuf);
822 vfree(server->packet);
823 call_rcu(&server->rcu, delayed_free);
824 }
825
826 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
827 {
828 struct dentry* d;
829 struct inode* i;
830 struct ncp_inode_info* ni;
831 struct ncp_server* s;
832 struct ncp_volume_info vi;
833 struct super_block *sb = dentry->d_sb;
834 int err;
835 __u8 dh;
836
837 d = sb->s_root;
838 if (!d) {
839 goto dflt;
840 }
841 i = d->d_inode;
842 if (!i) {
843 goto dflt;
844 }
845 ni = NCP_FINFO(i);
846 if (!ni) {
847 goto dflt;
848 }
849 s = NCP_SBP(sb);
850 if (!s) {
851 goto dflt;
852 }
853 if (!s->m.mounted_vol[0]) {
854 goto dflt;
855 }
856
857 err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
858 if (err) {
859 goto dflt;
860 }
861 err = ncp_get_directory_info(s, dh, &vi);
862 ncp_dirhandle_free(s, dh);
863 if (err) {
864 goto dflt;
865 }
866 buf->f_type = NCP_SUPER_MAGIC;
867 buf->f_bsize = vi.sectors_per_block * 512;
868 buf->f_blocks = vi.total_blocks;
869 buf->f_bfree = vi.free_blocks;
870 buf->f_bavail = vi.free_blocks;
871 buf->f_files = vi.total_dir_entries;
872 buf->f_ffree = vi.available_dir_entries;
873 buf->f_namelen = 12;
874 return 0;
875
876 /* We cannot say how much disk space is left on a mounted
877 NetWare Server, because free space is distributed over
878 volumes, and the current user might have disk quotas. So
879 free space is not that simple to determine. Our decision
880 here is to err conservatively. */
881
882 dflt:;
883 buf->f_type = NCP_SUPER_MAGIC;
884 buf->f_bsize = NCP_BLOCK_SIZE;
885 buf->f_blocks = 0;
886 buf->f_bfree = 0;
887 buf->f_bavail = 0;
888 buf->f_namelen = 12;
889 return 0;
890 }
891
892 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
893 {
894 struct inode *inode = dentry->d_inode;
895 int result = 0;
896 __le32 info_mask;
897 struct nw_modify_dos_info info;
898 struct ncp_server *server;
899
900 result = -EIO;
901
902 server = NCP_SERVER(inode);
903 if (!server) /* How this could happen? */
904 goto out;
905
906 result = -EPERM;
907 if (IS_DEADDIR(dentry->d_inode))
908 goto out;
909
910 /* ageing the dentry to force validation */
911 ncp_age_dentry(server, dentry);
912
913 result = inode_change_ok(inode, attr);
914 if (result < 0)
915 goto out;
916
917 result = -EPERM;
918 if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
919 goto out;
920
921 if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
922 goto out;
923
924 if (((attr->ia_valid & ATTR_MODE) &&
925 (attr->ia_mode &
926 ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
927 goto out;
928
929 info_mask = 0;
930 memset(&info, 0, sizeof(info));
931
932 #if 1
933 if ((attr->ia_valid & ATTR_MODE) != 0)
934 {
935 umode_t newmode = attr->ia_mode;
936
937 info_mask |= DM_ATTRIBUTES;
938
939 if (S_ISDIR(inode->i_mode)) {
940 newmode &= server->m.dir_mode;
941 } else {
942 #ifdef CONFIG_NCPFS_EXTRAS
943 if (server->m.flags & NCP_MOUNT_EXTRAS) {
944 /* any non-default execute bit set */
945 if (newmode & ~server->m.file_mode & S_IXUGO)
946 info.attributes |= aSHARED | aSYSTEM;
947 /* read for group/world and not in default file_mode */
948 else if (newmode & ~server->m.file_mode & S_IRUGO)
949 info.attributes |= aSHARED;
950 } else
951 #endif
952 newmode &= server->m.file_mode;
953 }
954 if (newmode & S_IWUGO)
955 info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
956 else
957 info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
958
959 #ifdef CONFIG_NCPFS_NFS_NS
960 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
961 result = ncp_modify_nfs_info(server,
962 NCP_FINFO(inode)->volNumber,
963 NCP_FINFO(inode)->dirEntNum,
964 attr->ia_mode, 0);
965 if (result != 0)
966 goto out;
967 info.attributes &= ~(aSHARED | aSYSTEM);
968 {
969 /* mark partial success */
970 struct iattr tmpattr;
971
972 tmpattr.ia_valid = ATTR_MODE;
973 tmpattr.ia_mode = attr->ia_mode;
974
975 setattr_copy(inode, &tmpattr);
976 mark_inode_dirty(inode);
977 }
978 }
979 #endif
980 }
981 #endif
982
983 /* Do SIZE before attributes, otherwise mtime together with size does not work...
984 */
985 if ((attr->ia_valid & ATTR_SIZE) != 0) {
986 int written;
987
988 DPRINTK("ncpfs: trying to change size to %ld\n",
989 attr->ia_size);
990
991 if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
992 result = -EACCES;
993 goto out;
994 }
995 ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
996 attr->ia_size, 0, "", &written);
997
998 /* According to ndir, the changes only take effect after
999 closing the file */
1000 ncp_inode_close(inode);
1001 result = ncp_make_closed(inode);
1002 if (result)
1003 goto out;
1004
1005 if (attr->ia_size != i_size_read(inode)) {
1006 truncate_setsize(inode, attr->ia_size);
1007 mark_inode_dirty(inode);
1008 }
1009 }
1010 if ((attr->ia_valid & ATTR_CTIME) != 0) {
1011 info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
1012 ncp_date_unix2dos(attr->ia_ctime.tv_sec,
1013 &info.creationTime, &info.creationDate);
1014 }
1015 if ((attr->ia_valid & ATTR_MTIME) != 0) {
1016 info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
1017 ncp_date_unix2dos(attr->ia_mtime.tv_sec,
1018 &info.modifyTime, &info.modifyDate);
1019 }
1020 if ((attr->ia_valid & ATTR_ATIME) != 0) {
1021 __le16 dummy;
1022 info_mask |= (DM_LAST_ACCESS_DATE);
1023 ncp_date_unix2dos(attr->ia_atime.tv_sec,
1024 &dummy, &info.lastAccessDate);
1025 }
1026 if (info_mask != 0) {
1027 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
1028 inode, info_mask, &info);
1029 if (result != 0) {
1030 if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1031 /* NetWare seems not to allow this. I
1032 do not know why. So, just tell the
1033 user everything went fine. This is
1034 a terrible hack, but I do not know
1035 how to do this correctly. */
1036 result = 0;
1037 } else
1038 goto out;
1039 }
1040 #ifdef CONFIG_NCPFS_STRONG
1041 if ((!result) && (info_mask & DM_ATTRIBUTES))
1042 NCP_FINFO(inode)->nwattr = info.attributes;
1043 #endif
1044 }
1045 if (result)
1046 goto out;
1047
1048 setattr_copy(inode, attr);
1049 mark_inode_dirty(inode);
1050
1051 out:
1052 if (result > 0)
1053 result = -EACCES;
1054 return result;
1055 }
1056
1057 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1058 int flags, const char *dev_name, void *data)
1059 {
1060 return mount_nodev(fs_type, flags, data, ncp_fill_super);
1061 }
1062
1063 static struct file_system_type ncp_fs_type = {
1064 .owner = THIS_MODULE,
1065 .name = "ncpfs",
1066 .mount = ncp_mount,
1067 .kill_sb = kill_anon_super,
1068 .fs_flags = FS_BINARY_MOUNTDATA,
1069 };
1070 MODULE_ALIAS_FS("ncpfs");
1071
1072 static int __init init_ncp_fs(void)
1073 {
1074 int err;
1075 DPRINTK("ncpfs: init_ncp_fs called\n");
1076
1077 err = init_inodecache();
1078 if (err)
1079 goto out1;
1080 err = register_filesystem(&ncp_fs_type);
1081 if (err)
1082 goto out;
1083 return 0;
1084 out:
1085 destroy_inodecache();
1086 out1:
1087 return err;
1088 }
1089
1090 static void __exit exit_ncp_fs(void)
1091 {
1092 DPRINTK("ncpfs: exit_ncp_fs called\n");
1093 unregister_filesystem(&ncp_fs_type);
1094 destroy_inodecache();
1095 }
1096
1097 module_init(init_ncp_fs)
1098 module_exit(exit_ncp_fs)
1099 MODULE_LICENSE("GPL");
This page took 0.054678 seconds and 5 git commands to generate.