]> git.karo-electronics.de Git - karo-tx-linux.git/blob - fs/ncpfs/inode.c
Merge tag 'edac_for_4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp
[karo-tx-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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13
14 #include <linux/module.h>
15
16 #include <asm/uaccess.h>
17 #include <asm/byteorder.h>
18
19 #include <linux/time.h>
20 #include <linux/kernel.h>
21 #include <linux/mm.h>
22 #include <linux/string.h>
23 #include <linux/stat.h>
24 #include <linux/errno.h>
25 #include <linux/file.h>
26 #include <linux/fcntl.h>
27 #include <linux/slab.h>
28 #include <linux/vmalloc.h>
29 #include <linux/init.h>
30 #include <linux/vfs.h>
31 #include <linux/mount.h>
32 #include <linux/seq_file.h>
33 #include <linux/namei.h>
34
35 #include <net/sock.h>
36
37 #include "ncp_fs.h"
38 #include "getopt.h"
39
40 #define NCP_DEFAULT_FILE_MODE 0600
41 #define NCP_DEFAULT_DIR_MODE 0700
42 #define NCP_DEFAULT_TIME_OUT 10
43 #define NCP_DEFAULT_RETRY_COUNT 20
44
45 static void ncp_evict_inode(struct inode *);
46 static void ncp_put_super(struct super_block *);
47 static int  ncp_statfs(struct dentry *, struct kstatfs *);
48 static int  ncp_show_options(struct seq_file *, struct dentry *);
49
50 static struct kmem_cache * ncp_inode_cachep;
51
52 static struct inode *ncp_alloc_inode(struct super_block *sb)
53 {
54         struct ncp_inode_info *ei;
55         ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL);
56         if (!ei)
57                 return NULL;
58         return &ei->vfs_inode;
59 }
60
61 static void ncp_i_callback(struct rcu_head *head)
62 {
63         struct inode *inode = container_of(head, struct inode, i_rcu);
64         kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
65 }
66
67 static void ncp_destroy_inode(struct inode *inode)
68 {
69         call_rcu(&inode->i_rcu, ncp_i_callback);
70 }
71
72 static void init_once(void *foo)
73 {
74         struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
75
76         mutex_init(&ei->open_mutex);
77         inode_init_once(&ei->vfs_inode);
78 }
79
80 static int init_inodecache(void)
81 {
82         ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
83                                              sizeof(struct ncp_inode_info),
84                                              0, (SLAB_RECLAIM_ACCOUNT|
85                                                 SLAB_MEM_SPREAD|SLAB_ACCOUNT),
86                                              init_once);
87         if (ncp_inode_cachep == NULL)
88                 return -ENOMEM;
89         return 0;
90 }
91
92 static void destroy_inodecache(void)
93 {
94         /*
95          * Make sure all delayed rcu free inodes are flushed before we
96          * destroy cache.
97          */
98         rcu_barrier();
99         kmem_cache_destroy(ncp_inode_cachep);
100 }
101
102 static int ncp_remount(struct super_block *sb, int *flags, char* data)
103 {
104         sync_filesystem(sb);
105         *flags |= MS_NODIRATIME;
106         return 0;
107 }
108
109 static const struct super_operations ncp_sops =
110 {
111         .alloc_inode    = ncp_alloc_inode,
112         .destroy_inode  = ncp_destroy_inode,
113         .drop_inode     = generic_delete_inode,
114         .evict_inode    = ncp_evict_inode,
115         .put_super      = ncp_put_super,
116         .statfs         = ncp_statfs,
117         .remount_fs     = ncp_remount,
118         .show_options   = ncp_show_options,
119 };
120
121 /*
122  * Fill in the ncpfs-specific information in the inode.
123  */
124 static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
125 {
126         NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
127         NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
128         NCP_FINFO(inode)->volNumber = nwinfo->volume;
129 }
130
131 void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
132 {
133         ncp_update_dirent(inode, nwinfo);
134         NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
135         NCP_FINFO(inode)->access = nwinfo->access;
136         memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
137                         sizeof(nwinfo->file_handle));
138         ncp_dbg(1, "updated %s, volnum=%d, dirent=%u\n",
139                 nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
140                 NCP_FINFO(inode)->dirEntNum);
141 }
142
143 static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
144 {
145         /* NFS namespace mode overrides others if it's set. */
146         ncp_dbg(1, "(%s) nfs.mode=0%o\n", nwi->entryName, nwi->nfs.mode);
147         if (nwi->nfs.mode) {
148                 /* XXX Security? */
149                 inode->i_mode = nwi->nfs.mode;
150         }
151
152         inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
153
154         inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
155         inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
156         inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
157         inode->i_atime.tv_nsec = 0;
158         inode->i_mtime.tv_nsec = 0;
159         inode->i_ctime.tv_nsec = 0;
160 }
161
162 static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
163 {
164         struct nw_info_struct *nwi = &nwinfo->i;
165         struct ncp_server *server = NCP_SERVER(inode);
166
167         if (nwi->attributes & aDIR) {
168                 inode->i_mode = server->m.dir_mode;
169                 /* for directories dataStreamSize seems to be some
170                    Object ID ??? */
171                 i_size_write(inode, NCP_BLOCK_SIZE);
172         } else {
173                 u32 size;
174
175                 inode->i_mode = server->m.file_mode;
176                 size = le32_to_cpu(nwi->dataStreamSize);
177                 i_size_write(inode, size);
178 #ifdef CONFIG_NCPFS_EXTRAS
179                 if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS)) 
180                  && (nwi->attributes & aSHARED)) {
181                         switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
182                                 case aHIDDEN:
183                                         if (server->m.flags & NCP_MOUNT_SYMLINKS) {
184                                                 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
185                                                  && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
186                                                         inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
187                                                         NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
188                                                         break;
189                                                 }
190                                         }
191                                         /* FALLTHROUGH */
192                                 case 0:
193                                         if (server->m.flags & NCP_MOUNT_EXTRAS)
194                                                 inode->i_mode |= S_IRUGO;
195                                         break;
196                                 case aSYSTEM:
197                                         if (server->m.flags & NCP_MOUNT_EXTRAS)
198                                                 inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
199                                         break;
200                                 /* case aSYSTEM|aHIDDEN: */
201                                 default:
202                                         /* reserved combination */
203                                         break;
204                         }
205                 }
206 #endif
207         }
208         if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
209 }
210
211 void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
212 {
213         NCP_FINFO(inode)->flags = 0;
214         if (!atomic_read(&NCP_FINFO(inode)->opened)) {
215                 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
216                 ncp_update_attrs(inode, nwinfo);
217         }
218
219         ncp_update_dates(inode, &nwinfo->i);
220         ncp_update_dirent(inode, nwinfo);
221 }
222
223 /*
224  * Fill in the inode based on the ncp_entry_info structure.  Used only for brand new inodes.
225  */
226 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
227 {
228         struct ncp_server *server = NCP_SERVER(inode);
229
230         NCP_FINFO(inode)->flags = 0;
231         
232         ncp_update_attrs(inode, nwinfo);
233
234         ncp_dbg(2, "inode->i_mode = %u\n", inode->i_mode);
235
236         set_nlink(inode, 1);
237         inode->i_uid = server->m.uid;
238         inode->i_gid = server->m.gid;
239
240         ncp_update_dates(inode, &nwinfo->i);
241         ncp_update_inode(inode, nwinfo);
242 }
243
244 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
245 static const struct inode_operations ncp_symlink_inode_operations = {
246         .readlink       = generic_readlink,
247         .get_link       = page_get_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                 pr_err("%s: info is NULL\n", __func__);
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_ino = info->ino;
270                 ncp_set_attr(inode, info);
271                 if (S_ISREG(inode->i_mode)) {
272                         inode->i_op = &ncp_file_inode_operations;
273                         inode->i_fop = &ncp_file_operations;
274                 } else if (S_ISDIR(inode->i_mode)) {
275                         inode->i_op = &ncp_dir_inode_operations;
276                         inode->i_fop = &ncp_dir_operations;
277 #ifdef CONFIG_NCPFS_NFS_NS
278                 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
279                         init_special_inode(inode, inode->i_mode,
280                                 new_decode_dev(info->i.nfs.rdev));
281 #endif
282 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
283                 } else if (S_ISLNK(inode->i_mode)) {
284                         inode->i_op = &ncp_symlink_inode_operations;
285                         inode_nohighmem(inode);
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                 pr_err("%s: iget failed!\n", __func__);
294         return inode;
295 }
296
297 static void
298 ncp_evict_inode(struct inode *inode)
299 {
300         truncate_inode_pages_final(&inode->i_data);
301         clear_inode(inode);
302
303         if (S_ISDIR(inode->i_mode)) {
304                 ncp_dbg(2, "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                 pr_err("%s: could not close\n", __func__);
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 inode *root_inode;
473         struct socket *sock;
474         int error;
475         int default_bufsize;
476 #ifdef CONFIG_NCPFS_PACKET_SIGNING
477         int options;
478 #endif
479         struct ncp_entry_info finfo;
480
481         memset(&data, 0, sizeof(data));
482         server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
483         if (!server)
484                 return -ENOMEM;
485         sb->s_fs_info = server;
486
487         error = -EFAULT;
488         if (raw_data == NULL)
489                 goto out;
490         switch (*(int*)raw_data) {
491                 case NCP_MOUNT_VERSION:
492                         {
493                                 struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
494
495                                 data.flags = md->flags;
496                                 data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
497                                 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
498                                 data.wdog_pid = find_get_pid(md->wdog_pid);
499                                 data.ncp_fd = md->ncp_fd;
500                                 data.time_out = md->time_out;
501                                 data.retry_count = md->retry_count;
502                                 data.uid = make_kuid(current_user_ns(), md->uid);
503                                 data.gid = make_kgid(current_user_ns(), md->gid);
504                                 data.file_mode = md->file_mode;
505                                 data.dir_mode = md->dir_mode;
506                                 data.info_fd = -1;
507                                 memcpy(data.mounted_vol, md->mounted_vol,
508                                         NCP_VOLNAME_LEN+1);
509                         }
510                         break;
511                 case NCP_MOUNT_VERSION_V4:
512                         {
513                                 struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
514
515                                 data.flags = md->flags;
516                                 data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
517                                 data.wdog_pid = find_get_pid(md->wdog_pid);
518                                 data.ncp_fd = md->ncp_fd;
519                                 data.time_out = md->time_out;
520                                 data.retry_count = md->retry_count;
521                                 data.uid = make_kuid(current_user_ns(), md->uid);
522                                 data.gid = make_kgid(current_user_ns(), md->gid);
523                                 data.file_mode = md->file_mode;
524                                 data.dir_mode = md->dir_mode;
525                                 data.info_fd = -1;
526                         }
527                         break;
528                 default:
529                         error = -ECHRNG;
530                         if (memcmp(raw_data, "vers", 4) == 0) {
531                                 error = ncp_parse_options(&data, raw_data);
532                         }
533                         if (error)
534                                 goto out;
535                         break;
536         }
537         error = -EINVAL;
538         if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) ||
539             !gid_valid(data.gid))
540                 goto out;
541         sock = sockfd_lookup(data.ncp_fd, &error);
542         if (!sock)
543                 goto out;
544
545         if (sock->type == SOCK_STREAM)
546                 default_bufsize = 0xF000;
547         else
548                 default_bufsize = 1024;
549
550         sb->s_flags |= MS_NODIRATIME;   /* probably even noatime */
551         sb->s_maxbytes = 0xFFFFFFFFU;
552         sb->s_blocksize = 1024; /* Eh...  Is this correct? */
553         sb->s_blocksize_bits = 10;
554         sb->s_magic = NCP_SUPER_MAGIC;
555         sb->s_op = &ncp_sops;
556         sb->s_d_op = &ncp_dentry_operations;
557         sb->s_bdi = &server->bdi;
558
559         server = NCP_SBP(sb);
560         memset(server, 0, sizeof(*server));
561
562         error = bdi_setup_and_register(&server->bdi, "ncpfs");
563         if (error)
564                 goto out_fput;
565
566         server->ncp_sock = sock;
567         
568         if (data.info_fd != -1) {
569                 struct socket *info_sock = sockfd_lookup(data.info_fd, &error);
570                 if (!info_sock)
571                         goto out_bdi;
572                 server->info_sock = info_sock;
573                 error = -EBADFD;
574                 if (info_sock->type != SOCK_STREAM)
575                         goto out_fput2;
576         }
577
578 /*      server->lock = 0;       */
579         mutex_init(&server->mutex);
580         server->packet = NULL;
581 /*      server->buffer_size = 0;        */
582 /*      server->conn_status = 0;        */
583 /*      server->root_dentry = NULL;     */
584 /*      server->root_setuped = 0;       */
585         mutex_init(&server->root_setup_lock);
586 #ifdef CONFIG_NCPFS_PACKET_SIGNING
587 /*      server->sign_wanted = 0;        */
588 /*      server->sign_active = 0;        */
589 #endif
590         init_rwsem(&server->auth_rwsem);
591         server->auth.auth_type = NCP_AUTH_NONE;
592 /*      server->auth.object_name_len = 0;       */
593 /*      server->auth.object_name = NULL;        */
594 /*      server->auth.object_type = 0;           */
595 /*      server->priv.len = 0;                   */
596 /*      server->priv.data = NULL;               */
597
598         server->m = data;
599         /* Although anything producing this is buggy, it happens
600            now because of PATH_MAX changes.. */
601         if (server->m.time_out < 1) {
602                 server->m.time_out = 10;
603                 pr_info("You need to recompile your ncpfs utils..\n");
604         }
605         server->m.time_out = server->m.time_out * HZ / 100;
606         server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
607         server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
608
609 #ifdef CONFIG_NCPFS_NLS
610         /* load the default NLS charsets */
611         server->nls_vol = load_nls_default();
612         server->nls_io = load_nls_default();
613 #endif /* CONFIG_NCPFS_NLS */
614
615         atomic_set(&server->dentry_ttl, 0);     /* no caching */
616
617         INIT_LIST_HEAD(&server->tx.requests);
618         mutex_init(&server->rcv.creq_mutex);
619         server->tx.creq         = NULL;
620         server->rcv.creq        = NULL;
621
622         init_timer(&server->timeout_tm);
623 #undef NCP_PACKET_SIZE
624 #define NCP_PACKET_SIZE 131072
625         error = -ENOMEM;
626         server->packet_size = NCP_PACKET_SIZE;
627         server->packet = vmalloc(NCP_PACKET_SIZE);
628         if (server->packet == NULL)
629                 goto out_nls;
630         server->txbuf = vmalloc(NCP_PACKET_SIZE);
631         if (server->txbuf == NULL)
632                 goto out_packet;
633         server->rxbuf = vmalloc(NCP_PACKET_SIZE);
634         if (server->rxbuf == NULL)
635                 goto out_txbuf;
636
637         lock_sock(sock->sk);
638         server->data_ready      = sock->sk->sk_data_ready;
639         server->write_space     = sock->sk->sk_write_space;
640         server->error_report    = sock->sk->sk_error_report;
641         sock->sk->sk_user_data  = server;
642         sock->sk->sk_data_ready   = ncp_tcp_data_ready;
643         sock->sk->sk_error_report = ncp_tcp_error_report;
644         if (sock->type == SOCK_STREAM) {
645                 server->rcv.ptr = (unsigned char*)&server->rcv.buf;
646                 server->rcv.len = 10;
647                 server->rcv.state = 0;
648                 INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
649                 INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
650                 sock->sk->sk_write_space = ncp_tcp_write_space;
651         } else {
652                 INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
653                 INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
654                 server->timeout_tm.data = (unsigned long)server;
655                 server->timeout_tm.function = ncpdgram_timeout_call;
656         }
657         release_sock(sock->sk);
658
659         ncp_lock_server(server);
660         error = ncp_connect(server);
661         ncp_unlock_server(server);
662         if (error < 0)
663                 goto out_rxbuf;
664         ncp_dbg(1, "NCP_SBP(sb) = %p\n", NCP_SBP(sb));
665
666         error = -EMSGSIZE;      /* -EREMOTESIDEINCOMPATIBLE */
667 #ifdef CONFIG_NCPFS_PACKET_SIGNING
668         if (ncp_negotiate_size_and_options(server, default_bufsize,
669                 NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
670         {
671                 if (options != NCP_DEFAULT_OPTIONS)
672                 {
673                         if (ncp_negotiate_size_and_options(server, 
674                                 default_bufsize,
675                                 options & 2, 
676                                 &(server->buffer_size), &options) != 0)
677                                 
678                         {
679                                 goto out_disconnect;
680                         }
681                 }
682                 ncp_lock_server(server);
683                 if (options & 2)
684                         server->sign_wanted = 1;
685                 ncp_unlock_server(server);
686         }
687         else 
688 #endif  /* CONFIG_NCPFS_PACKET_SIGNING */
689         if (ncp_negotiate_buffersize(server, default_bufsize,
690                                      &(server->buffer_size)) != 0)
691                 goto out_disconnect;
692         ncp_dbg(1, "bufsize = %d\n", server->buffer_size);
693
694         memset(&finfo, 0, sizeof(finfo));
695         finfo.i.attributes      = aDIR;
696         finfo.i.dataStreamSize  = 0;    /* ignored */
697         finfo.i.dirEntNum       = 0;
698         finfo.i.DosDirNum       = 0;
699 #ifdef CONFIG_NCPFS_SMALLDOS
700         finfo.i.NSCreator       = NW_NS_DOS;
701 #endif
702         finfo.volume            = NCP_NUMBER_OF_VOLUMES;
703         /* set dates of mountpoint to Jan 1, 1986; 00:00 */
704         finfo.i.creationTime    = finfo.i.modifyTime
705                                 = cpu_to_le16(0x0000);
706         finfo.i.creationDate    = finfo.i.modifyDate
707                                 = finfo.i.lastAccessDate
708                                 = cpu_to_le16(0x0C21);
709         finfo.i.nameLen         = 0;
710         finfo.i.entryName[0]    = '\0';
711
712         finfo.opened            = 0;
713         finfo.ino               = 2;    /* tradition */
714
715         server->name_space[finfo.volume] = NW_NS_DOS;
716
717         error = -ENOMEM;
718         root_inode = ncp_iget(sb, &finfo);
719         if (!root_inode)
720                 goto out_disconnect;
721         ncp_dbg(1, "root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
722         sb->s_root = d_make_root(root_inode);
723         if (!sb->s_root)
724                 goto out_disconnect;
725         return 0;
726
727 out_disconnect:
728         ncp_lock_server(server);
729         ncp_disconnect(server);
730         ncp_unlock_server(server);
731 out_rxbuf:
732         ncp_stop_tasks(server);
733         vfree(server->rxbuf);
734 out_txbuf:
735         vfree(server->txbuf);
736 out_packet:
737         vfree(server->packet);
738 out_nls:
739 #ifdef CONFIG_NCPFS_NLS
740         unload_nls(server->nls_io);
741         unload_nls(server->nls_vol);
742 #endif
743         mutex_destroy(&server->rcv.creq_mutex);
744         mutex_destroy(&server->root_setup_lock);
745         mutex_destroy(&server->mutex);
746 out_fput2:
747         if (server->info_sock)
748                 sockfd_put(server->info_sock);
749 out_bdi:
750         bdi_destroy(&server->bdi);
751 out_fput:
752         sockfd_put(sock);
753 out:
754         put_pid(data.wdog_pid);
755         sb->s_fs_info = NULL;
756         kfree(server);
757         return error;
758 }
759
760 static void delayed_free(struct rcu_head *p)
761 {
762         struct ncp_server *server = container_of(p, struct ncp_server, rcu);
763 #ifdef CONFIG_NCPFS_NLS
764         /* unload the NLS charsets */
765         unload_nls(server->nls_vol);
766         unload_nls(server->nls_io);
767 #endif /* CONFIG_NCPFS_NLS */
768         kfree(server);
769 }
770
771 static void ncp_put_super(struct super_block *sb)
772 {
773         struct ncp_server *server = NCP_SBP(sb);
774
775         ncp_lock_server(server);
776         ncp_disconnect(server);
777         ncp_unlock_server(server);
778
779         ncp_stop_tasks(server);
780
781         mutex_destroy(&server->rcv.creq_mutex);
782         mutex_destroy(&server->root_setup_lock);
783         mutex_destroy(&server->mutex);
784
785         if (server->info_sock)
786                 sockfd_put(server->info_sock);
787         sockfd_put(server->ncp_sock);
788         kill_pid(server->m.wdog_pid, SIGTERM, 1);
789         put_pid(server->m.wdog_pid);
790
791         bdi_destroy(&server->bdi);
792         kfree(server->priv.data);
793         kfree(server->auth.object_name);
794         vfree(server->rxbuf);
795         vfree(server->txbuf);
796         vfree(server->packet);
797         call_rcu(&server->rcu, delayed_free);
798 }
799
800 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
801 {
802         struct dentry* d;
803         struct inode* i;
804         struct ncp_inode_info* ni;
805         struct ncp_server* s;
806         struct ncp_volume_info vi;
807         struct super_block *sb = dentry->d_sb;
808         int err;
809         __u8 dh;
810         
811         d = sb->s_root;
812         if (!d) {
813                 goto dflt;
814         }
815         i = d_inode(d);
816         if (!i) {
817                 goto dflt;
818         }
819         ni = NCP_FINFO(i);
820         if (!ni) {
821                 goto dflt;
822         }
823         s = NCP_SBP(sb);
824         if (!s) {
825                 goto dflt;
826         }
827         if (!s->m.mounted_vol[0]) {
828                 goto dflt;
829         }
830
831         err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
832         if (err) {
833                 goto dflt;
834         }
835         err = ncp_get_directory_info(s, dh, &vi);
836         ncp_dirhandle_free(s, dh);
837         if (err) {
838                 goto dflt;
839         }
840         buf->f_type = NCP_SUPER_MAGIC;
841         buf->f_bsize = vi.sectors_per_block * 512;
842         buf->f_blocks = vi.total_blocks;
843         buf->f_bfree = vi.free_blocks;
844         buf->f_bavail = vi.free_blocks;
845         buf->f_files = vi.total_dir_entries;
846         buf->f_ffree = vi.available_dir_entries;
847         buf->f_namelen = 12;
848         return 0;
849
850         /* We cannot say how much disk space is left on a mounted
851            NetWare Server, because free space is distributed over
852            volumes, and the current user might have disk quotas. So
853            free space is not that simple to determine. Our decision
854            here is to err conservatively. */
855
856 dflt:;
857         buf->f_type = NCP_SUPER_MAGIC;
858         buf->f_bsize = NCP_BLOCK_SIZE;
859         buf->f_blocks = 0;
860         buf->f_bfree = 0;
861         buf->f_bavail = 0;
862         buf->f_namelen = 12;
863         return 0;
864 }
865
866 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
867 {
868         struct inode *inode = d_inode(dentry);
869         int result = 0;
870         __le32 info_mask;
871         struct nw_modify_dos_info info;
872         struct ncp_server *server;
873
874         result = -EIO;
875
876         server = NCP_SERVER(inode);
877         if (!server)    /* How this could happen? */
878                 goto out;
879
880         result = -EPERM;
881         if (IS_DEADDIR(d_inode(dentry)))
882                 goto out;
883
884         /* ageing the dentry to force validation */
885         ncp_age_dentry(server, dentry);
886
887         result = inode_change_ok(inode, attr);
888         if (result < 0)
889                 goto out;
890
891         result = -EPERM;
892         if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
893                 goto out;
894
895         if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
896                 goto out;
897
898         if (((attr->ia_valid & ATTR_MODE) &&
899              (attr->ia_mode &
900               ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
901                 goto out;
902
903         info_mask = 0;
904         memset(&info, 0, sizeof(info));
905
906 #if 1 
907         if ((attr->ia_valid & ATTR_MODE) != 0)
908         {
909                 umode_t newmode = attr->ia_mode;
910
911                 info_mask |= DM_ATTRIBUTES;
912
913                 if (S_ISDIR(inode->i_mode)) {
914                         newmode &= server->m.dir_mode;
915                 } else {
916 #ifdef CONFIG_NCPFS_EXTRAS                      
917                         if (server->m.flags & NCP_MOUNT_EXTRAS) {
918                                 /* any non-default execute bit set */
919                                 if (newmode & ~server->m.file_mode & S_IXUGO)
920                                         info.attributes |= aSHARED | aSYSTEM;
921                                 /* read for group/world and not in default file_mode */
922                                 else if (newmode & ~server->m.file_mode & S_IRUGO)
923                                         info.attributes |= aSHARED;
924                         } else
925 #endif
926                                 newmode &= server->m.file_mode;                 
927                 }
928                 if (newmode & S_IWUGO)
929                         info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
930                 else
931                         info.attributes |=  (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
932
933 #ifdef CONFIG_NCPFS_NFS_NS
934                 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
935                         result = ncp_modify_nfs_info(server,
936                                                      NCP_FINFO(inode)->volNumber,
937                                                      NCP_FINFO(inode)->dirEntNum,
938                                                      attr->ia_mode, 0);
939                         if (result != 0)
940                                 goto out;
941                         info.attributes &= ~(aSHARED | aSYSTEM);
942                         {
943                                 /* mark partial success */
944                                 struct iattr tmpattr;
945                                 
946                                 tmpattr.ia_valid = ATTR_MODE;
947                                 tmpattr.ia_mode = attr->ia_mode;
948
949                                 setattr_copy(inode, &tmpattr);
950                                 mark_inode_dirty(inode);
951                         }
952                 }
953 #endif
954         }
955 #endif
956
957         /* Do SIZE before attributes, otherwise mtime together with size does not work...
958          */
959         if ((attr->ia_valid & ATTR_SIZE) != 0) {
960                 int written;
961
962                 ncp_dbg(1, "trying to change size to %llu\n", attr->ia_size);
963
964                 if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
965                         result = -EACCES;
966                         goto out;
967                 }
968                 ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
969                           attr->ia_size, 0, "", &written);
970
971                 /* According to ndir, the changes only take effect after
972                    closing the file */
973                 ncp_inode_close(inode);
974                 result = ncp_make_closed(inode);
975                 if (result)
976                         goto out;
977
978                 if (attr->ia_size != i_size_read(inode)) {
979                         truncate_setsize(inode, attr->ia_size);
980                         mark_inode_dirty(inode);
981                 }
982         }
983         if ((attr->ia_valid & ATTR_CTIME) != 0) {
984                 info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
985                 ncp_date_unix2dos(attr->ia_ctime.tv_sec,
986                              &info.creationTime, &info.creationDate);
987         }
988         if ((attr->ia_valid & ATTR_MTIME) != 0) {
989                 info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
990                 ncp_date_unix2dos(attr->ia_mtime.tv_sec,
991                                   &info.modifyTime, &info.modifyDate);
992         }
993         if ((attr->ia_valid & ATTR_ATIME) != 0) {
994                 __le16 dummy;
995                 info_mask |= (DM_LAST_ACCESS_DATE);
996                 ncp_date_unix2dos(attr->ia_atime.tv_sec,
997                                   &dummy, &info.lastAccessDate);
998         }
999         if (info_mask != 0) {
1000                 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
1001                                       inode, info_mask, &info);
1002                 if (result != 0) {
1003                         if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1004                                 /* NetWare seems not to allow this. I
1005                                    do not know why. So, just tell the
1006                                    user everything went fine. This is
1007                                    a terrible hack, but I do not know
1008                                    how to do this correctly. */
1009                                 result = 0;
1010                         } else
1011                                 goto out;
1012                 }
1013 #ifdef CONFIG_NCPFS_STRONG              
1014                 if ((!result) && (info_mask & DM_ATTRIBUTES))
1015                         NCP_FINFO(inode)->nwattr = info.attributes;
1016 #endif
1017         }
1018         if (result)
1019                 goto out;
1020
1021         setattr_copy(inode, attr);
1022         mark_inode_dirty(inode);
1023
1024 out:
1025         if (result > 0)
1026                 result = -EACCES;
1027         return result;
1028 }
1029
1030 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1031         int flags, const char *dev_name, void *data)
1032 {
1033         return mount_nodev(fs_type, flags, data, ncp_fill_super);
1034 }
1035
1036 static struct file_system_type ncp_fs_type = {
1037         .owner          = THIS_MODULE,
1038         .name           = "ncpfs",
1039         .mount          = ncp_mount,
1040         .kill_sb        = kill_anon_super,
1041         .fs_flags       = FS_BINARY_MOUNTDATA,
1042 };
1043 MODULE_ALIAS_FS("ncpfs");
1044
1045 static int __init init_ncp_fs(void)
1046 {
1047         int err;
1048         ncp_dbg(1, "called\n");
1049
1050         err = init_inodecache();
1051         if (err)
1052                 goto out1;
1053         err = register_filesystem(&ncp_fs_type);
1054         if (err)
1055                 goto out;
1056         return 0;
1057 out:
1058         destroy_inodecache();
1059 out1:
1060         return err;
1061 }
1062
1063 static void __exit exit_ncp_fs(void)
1064 {
1065         ncp_dbg(1, "called\n");
1066         unregister_filesystem(&ncp_fs_type);
1067         destroy_inodecache();
1068 }
1069
1070 module_init(init_ncp_fs)
1071 module_exit(exit_ncp_fs)
1072 MODULE_LICENSE("GPL");