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