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