]> Git Repo - linux.git/blob - drivers/staging/ncpfs/inode.c
mm: disable interrupts while initializing deferred pages
[linux.git] / drivers / staging / 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 <linux/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/sched/signal.h>
34 #include <linux/namei.h>
35
36 #include <net/sock.h>
37
38 #include "ncp_fs.h"
39 #include "getopt.h"
40
41 #define NCP_DEFAULT_FILE_MODE 0600
42 #define NCP_DEFAULT_DIR_MODE 0700
43 #define NCP_DEFAULT_TIME_OUT 10
44 #define NCP_DEFAULT_RETRY_COUNT 20
45
46 static void ncp_evict_inode(struct inode *);
47 static void ncp_put_super(struct super_block *);
48 static int  ncp_statfs(struct dentry *, struct kstatfs *);
49 static int  ncp_show_options(struct seq_file *, struct dentry *);
50
51 static struct kmem_cache * ncp_inode_cachep;
52
53 static struct inode *ncp_alloc_inode(struct super_block *sb)
54 {
55         struct ncp_inode_info *ei;
56
57         ei = kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL);
58         if (!ei)
59                 return NULL;
60         return &ei->vfs_inode;
61 }
62
63 static void ncp_i_callback(struct rcu_head *head)
64 {
65         struct inode *inode = container_of(head, struct inode, i_rcu);
66         kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
67 }
68
69 static void ncp_destroy_inode(struct inode *inode)
70 {
71         call_rcu(&inode->i_rcu, ncp_i_callback);
72 }
73
74 static void init_once(void *foo)
75 {
76         struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
77
78         mutex_init(&ei->open_mutex);
79         inode_init_once(&ei->vfs_inode);
80 }
81
82 static int init_inodecache(void)
83 {
84         ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
85                                              sizeof(struct ncp_inode_info),
86                                              0, (SLAB_RECLAIM_ACCOUNT|
87                                                 SLAB_MEM_SPREAD|SLAB_ACCOUNT),
88                                              init_once);
89         if (ncp_inode_cachep == NULL)
90                 return -ENOMEM;
91         return 0;
92 }
93
94 static void destroy_inodecache(void)
95 {
96         /*
97          * Make sure all delayed rcu free inodes are flushed before we
98          * destroy cache.
99          */
100         rcu_barrier();
101         kmem_cache_destroy(ncp_inode_cachep);
102 }
103
104 static int ncp_remount(struct super_block *sb, int *flags, char* data)
105 {
106         sync_filesystem(sb);
107         *flags |= SB_NODIRATIME;
108         return 0;
109 }
110
111 static const struct super_operations ncp_sops =
112 {
113         .alloc_inode    = ncp_alloc_inode,
114         .destroy_inode  = ncp_destroy_inode,
115         .drop_inode     = generic_delete_inode,
116         .evict_inode    = ncp_evict_inode,
117         .put_super      = ncp_put_super,
118         .statfs         = ncp_statfs,
119         .remount_fs     = ncp_remount,
120         .show_options   = ncp_show_options,
121 };
122
123 /*
124  * Fill in the ncpfs-specific information in the inode.
125  */
126 static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
127 {
128         NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
129         NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
130         NCP_FINFO(inode)->volNumber = nwinfo->volume;
131 }
132
133 void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
134 {
135         ncp_update_dirent(inode, nwinfo);
136         NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
137         NCP_FINFO(inode)->access = nwinfo->access;
138         memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
139                         sizeof(nwinfo->file_handle));
140         ncp_dbg(1, "updated %s, volnum=%d, dirent=%u\n",
141                 nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
142                 NCP_FINFO(inode)->dirEntNum);
143 }
144
145 static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
146 {
147         /* NFS namespace mode overrides others if it's set. */
148         ncp_dbg(1, "(%s) nfs.mode=0%o\n", nwi->entryName, nwi->nfs.mode);
149         if (nwi->nfs.mode) {
150                 /* XXX Security? */
151                 inode->i_mode = nwi->nfs.mode;
152         }
153
154         inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
155
156         inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
157         inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
158         inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
159         inode->i_atime.tv_nsec = 0;
160         inode->i_mtime.tv_nsec = 0;
161         inode->i_ctime.tv_nsec = 0;
162 }
163
164 static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
165 {
166         struct nw_info_struct *nwi = &nwinfo->i;
167         struct ncp_server *server = NCP_SERVER(inode);
168
169         if (nwi->attributes & aDIR) {
170                 inode->i_mode = server->m.dir_mode;
171                 /* for directories dataStreamSize seems to be some
172                    Object ID ??? */
173                 i_size_write(inode, NCP_BLOCK_SIZE);
174         } else {
175                 u32 size;
176
177                 inode->i_mode = server->m.file_mode;
178                 size = le32_to_cpu(nwi->dataStreamSize);
179                 i_size_write(inode, size);
180 #ifdef CONFIG_NCPFS_EXTRAS
181                 if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS)) 
182                  && (nwi->attributes & aSHARED)) {
183                         switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
184                                 case aHIDDEN:
185                                         if (server->m.flags & NCP_MOUNT_SYMLINKS) {
186                                                 if (/* (size >= NCP_MIN_SYMLINK_SIZE)
187                                                  && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
188                                                         inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
189                                                         NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
190                                                         break;
191                                                 }
192                                         }
193                                         /* FALLTHROUGH */
194                                 case 0:
195                                         if (server->m.flags & NCP_MOUNT_EXTRAS)
196                                                 inode->i_mode |= S_IRUGO;
197                                         break;
198                                 case aSYSTEM:
199                                         if (server->m.flags & NCP_MOUNT_EXTRAS)
200                                                 inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
201                                         break;
202                                 /* case aSYSTEM|aHIDDEN: */
203                                 default:
204                                         /* reserved combination */
205                                         break;
206                         }
207                 }
208 #endif
209         }
210         if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
211 }
212
213 void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
214 {
215         NCP_FINFO(inode)->flags = 0;
216         if (!atomic_read(&NCP_FINFO(inode)->opened)) {
217                 NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
218                 ncp_update_attrs(inode, nwinfo);
219         }
220
221         ncp_update_dates(inode, &nwinfo->i);
222         ncp_update_dirent(inode, nwinfo);
223 }
224
225 /*
226  * Fill in the inode based on the ncp_entry_info structure.  Used only for brand new inodes.
227  */
228 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
229 {
230         struct ncp_server *server = NCP_SERVER(inode);
231
232         NCP_FINFO(inode)->flags = 0;
233         
234         ncp_update_attrs(inode, nwinfo);
235
236         ncp_dbg(2, "inode->i_mode = %u\n", inode->i_mode);
237
238         set_nlink(inode, 1);
239         inode->i_uid = server->m.uid;
240         inode->i_gid = server->m.gid;
241
242         ncp_update_dates(inode, &nwinfo->i);
243         ncp_update_inode(inode, nwinfo);
244 }
245
246 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
247 static const struct inode_operations ncp_symlink_inode_operations = {
248         .get_link       = page_get_link,
249         .setattr        = ncp_notify_change,
250 };
251 #endif
252
253 /*
254  * Get a new inode.
255  */
256 struct inode * 
257 ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
258 {
259         struct inode *inode;
260
261         if (info == NULL) {
262                 pr_err("%s: info is NULL\n", __func__);
263                 return NULL;
264         }
265
266         inode = new_inode(sb);
267         if (inode) {
268                 atomic_set(&NCP_FINFO(inode)->opened, info->opened);
269
270                 inode->i_ino = info->ino;
271                 ncp_set_attr(inode, info);
272                 if (S_ISREG(inode->i_mode)) {
273                         inode->i_op = &ncp_file_inode_operations;
274                         inode->i_fop = &ncp_file_operations;
275                 } else if (S_ISDIR(inode->i_mode)) {
276                         inode->i_op = &ncp_dir_inode_operations;
277                         inode->i_fop = &ncp_dir_operations;
278 #ifdef CONFIG_NCPFS_NFS_NS
279                 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
280                         init_special_inode(inode, inode->i_mode,
281                                 new_decode_dev(info->i.nfs.rdev));
282 #endif
283 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
284                 } else if (S_ISLNK(inode->i_mode)) {
285                         inode->i_op = &ncp_symlink_inode_operations;
286                         inode_nohighmem(inode);
287                         inode->i_data.a_ops = &ncp_symlink_aops;
288 #endif
289                 } else {
290                         make_bad_inode(inode);
291                 }
292                 insert_inode_hash(inode);
293         } else
294                 pr_err("%s: iget failed!\n", __func__);
295         return inode;
296 }
297
298 static void
299 ncp_evict_inode(struct inode *inode)
300 {
301         truncate_inode_pages_final(&inode->i_data);
302         clear_inode(inode);
303
304         if (S_ISDIR(inode->i_mode)) {
305                 ncp_dbg(2, "put directory %ld\n", inode->i_ino);
306         }
307
308         if (ncp_make_closed(inode) != 0) {
309                 /* We can't do anything but complain. */
310                 pr_err("%s: could not close\n", __func__);
311         }
312 }
313
314 static void ncp_stop_tasks(struct ncp_server *server) {
315         struct sock* sk = server->ncp_sock->sk;
316
317         lock_sock(sk);
318         sk->sk_error_report = server->error_report;
319         sk->sk_data_ready   = server->data_ready;
320         sk->sk_write_space  = server->write_space;
321         release_sock(sk);
322         del_timer_sync(&server->timeout_tm);
323
324         flush_work(&server->rcv.tq);
325         if (sk->sk_socket->type == SOCK_STREAM)
326                 flush_work(&server->tx.tq);
327         else
328                 flush_work(&server->timeout_tq);
329 }
330
331 static int  ncp_show_options(struct seq_file *seq, struct dentry *root)
332 {
333         struct ncp_server *server = NCP_SBP(root->d_sb);
334         unsigned int tmp;
335
336         if (!uid_eq(server->m.uid, GLOBAL_ROOT_UID))
337                 seq_printf(seq, ",uid=%u",
338                            from_kuid_munged(&init_user_ns, server->m.uid));
339         if (!gid_eq(server->m.gid, GLOBAL_ROOT_GID))
340                 seq_printf(seq, ",gid=%u",
341                            from_kgid_munged(&init_user_ns, server->m.gid));
342         if (!uid_eq(server->m.mounted_uid, GLOBAL_ROOT_UID))
343                 seq_printf(seq, ",owner=%u",
344                            from_kuid_munged(&init_user_ns, server->m.mounted_uid));
345         tmp = server->m.file_mode & S_IALLUGO;
346         if (tmp != NCP_DEFAULT_FILE_MODE)
347                 seq_printf(seq, ",mode=0%o", tmp);
348         tmp = server->m.dir_mode & S_IALLUGO;
349         if (tmp != NCP_DEFAULT_DIR_MODE)
350                 seq_printf(seq, ",dirmode=0%o", tmp);
351         if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) {
352                 tmp = server->m.time_out * 100 / HZ;
353                 seq_printf(seq, ",timeout=%u", tmp);
354         }
355         if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT)
356                 seq_printf(seq, ",retry=%u", server->m.retry_count);
357         if (server->m.flags != 0)
358                 seq_printf(seq, ",flags=%lu", server->m.flags);
359         if (server->m.wdog_pid != NULL)
360                 seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid));
361
362         return 0;
363 }
364
365 static const struct ncp_option ncp_opts[] = {
366         { "uid",        OPT_INT,        'u' },
367         { "gid",        OPT_INT,        'g' },
368         { "owner",      OPT_INT,        'o' },
369         { "mode",       OPT_INT,        'm' },
370         { "dirmode",    OPT_INT,        'd' },
371         { "timeout",    OPT_INT,        't' },
372         { "retry",      OPT_INT,        'r' },
373         { "flags",      OPT_INT,        'f' },
374         { "wdogpid",    OPT_INT,        'w' },
375         { "ncpfd",      OPT_INT,        'n' },
376         { "infofd",     OPT_INT,        'i' },  /* v5 */
377         { "version",    OPT_INT,        'v' },
378         { NULL,         0,              0 } };
379
380 static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
381         int optval;
382         char *optarg;
383         unsigned long optint;
384         int version = 0;
385         int ret;
386
387         data->flags = 0;
388         data->int_flags = 0;
389         data->mounted_uid = GLOBAL_ROOT_UID;
390         data->wdog_pid = NULL;
391         data->ncp_fd = ~0;
392         data->time_out = NCP_DEFAULT_TIME_OUT;
393         data->retry_count = NCP_DEFAULT_RETRY_COUNT;
394         data->uid = GLOBAL_ROOT_UID;
395         data->gid = GLOBAL_ROOT_GID;
396         data->file_mode = NCP_DEFAULT_FILE_MODE;
397         data->dir_mode = NCP_DEFAULT_DIR_MODE;
398         data->info_fd = -1;
399         data->mounted_vol[0] = 0;
400         
401         while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
402                 ret = optval;
403                 if (ret < 0)
404                         goto err;
405                 switch (optval) {
406                         case 'u':
407                                 data->uid = make_kuid(current_user_ns(), optint);
408                                 if (!uid_valid(data->uid)) {
409                                         ret = -EINVAL;
410                                         goto err;
411                                 }
412                                 break;
413                         case 'g':
414                                 data->gid = make_kgid(current_user_ns(), optint);
415                                 if (!gid_valid(data->gid)) {
416                                         ret = -EINVAL;
417                                         goto err;
418                                 }
419                                 break;
420                         case 'o':
421                                 data->mounted_uid = make_kuid(current_user_ns(), optint);
422                                 if (!uid_valid(data->mounted_uid)) {
423                                         ret = -EINVAL;
424                                         goto err;
425                                 }
426                                 break;
427                         case 'm':
428                                 data->file_mode = optint;
429                                 break;
430                         case 'd':
431                                 data->dir_mode = optint;
432                                 break;
433                         case 't':
434                                 data->time_out = optint;
435                                 break;
436                         case 'r':
437                                 data->retry_count = optint;
438                                 break;
439                         case 'f':
440                                 data->flags = optint;
441                                 break;
442                         case 'w':
443                                 data->wdog_pid = find_get_pid(optint);
444                                 break;
445                         case 'n':
446                                 data->ncp_fd = optint;
447                                 break;
448                         case 'i':
449                                 data->info_fd = optint;
450                                 break;
451                         case 'v':
452                                 ret = -ECHRNG;
453                                 if (optint < NCP_MOUNT_VERSION_V4)
454                                         goto err;
455                                 if (optint > NCP_MOUNT_VERSION_V5)
456                                         goto err;
457                                 version = optint;
458                                 break;
459                         
460                 }
461         }
462         return 0;
463 err:
464         put_pid(data->wdog_pid);
465         data->wdog_pid = NULL;
466         return ret;
467 }
468
469 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
470 {
471         struct ncp_mount_data_kernel data;
472         struct ncp_server *server;
473         struct inode *root_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         sock = sockfd_lookup(data.ncp_fd, &error);
543         if (!sock)
544                 goto out;
545
546         if (sock->type == SOCK_STREAM)
547                 default_bufsize = 0xF000;
548         else
549                 default_bufsize = 1024;
550
551         sb->s_flags |= SB_NODIRATIME;   /* probably even noatime */
552         sb->s_maxbytes = 0xFFFFFFFFU;
553         sb->s_blocksize = 1024; /* Eh...  Is this correct? */
554         sb->s_blocksize_bits = 10;
555         sb->s_magic = NCP_SUPER_MAGIC;
556         sb->s_op = &ncp_sops;
557         sb->s_d_op = &ncp_dentry_operations;
558
559         server = NCP_SBP(sb);
560         memset(server, 0, sizeof(*server));
561
562         error = super_setup_bdi(sb);
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_fput;
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         timer_setup(&server->timeout_tm, ncpdgram_timeout_call, 0);
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         }
655         release_sock(sock->sk);
656
657         ncp_lock_server(server);
658         error = ncp_connect(server);
659         ncp_unlock_server(server);
660         if (error < 0)
661                 goto out_rxbuf;
662         ncp_dbg(1, "NCP_SBP(sb) = %p\n", NCP_SBP(sb));
663
664         error = -EMSGSIZE;      /* -EREMOTESIDEINCOMPATIBLE */
665 #ifdef CONFIG_NCPFS_PACKET_SIGNING
666         if (ncp_negotiate_size_and_options(server, default_bufsize,
667                 NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
668         {
669                 if (options != NCP_DEFAULT_OPTIONS)
670                 {
671                         if (ncp_negotiate_size_and_options(server, 
672                                 default_bufsize,
673                                 options & 2, 
674                                 &(server->buffer_size), &options) != 0)
675                                 
676                         {
677                                 goto out_disconnect;
678                         }
679                 }
680                 ncp_lock_server(server);
681                 if (options & 2)
682                         server->sign_wanted = 1;
683                 ncp_unlock_server(server);
684         }
685         else 
686 #endif  /* CONFIG_NCPFS_PACKET_SIGNING */
687         if (ncp_negotiate_buffersize(server, default_bufsize,
688                                      &(server->buffer_size)) != 0)
689                 goto out_disconnect;
690         ncp_dbg(1, "bufsize = %d\n", server->buffer_size);
691
692         memset(&finfo, 0, sizeof(finfo));
693         finfo.i.attributes      = aDIR;
694         finfo.i.dataStreamSize  = 0;    /* ignored */
695         finfo.i.dirEntNum       = 0;
696         finfo.i.DosDirNum       = 0;
697 #ifdef CONFIG_NCPFS_SMALLDOS
698         finfo.i.NSCreator       = NW_NS_DOS;
699 #endif
700         finfo.volume            = NCP_NUMBER_OF_VOLUMES;
701         /* set dates of mountpoint to Jan 1, 1986; 00:00 */
702         finfo.i.creationTime    = finfo.i.modifyTime
703                                 = cpu_to_le16(0x0000);
704         finfo.i.creationDate    = finfo.i.modifyDate
705                                 = finfo.i.lastAccessDate
706                                 = cpu_to_le16(0x0C21);
707         finfo.i.nameLen         = 0;
708         finfo.i.entryName[0]    = '\0';
709
710         finfo.opened            = 0;
711         finfo.ino               = 2;    /* tradition */
712
713         server->name_space[finfo.volume] = NW_NS_DOS;
714
715         error = -ENOMEM;
716         root_inode = ncp_iget(sb, &finfo);
717         if (!root_inode)
718                 goto out_disconnect;
719         ncp_dbg(1, "root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
720         sb->s_root = d_make_root(root_inode);
721         if (!sb->s_root)
722                 goto out_disconnect;
723         return 0;
724
725 out_disconnect:
726         ncp_lock_server(server);
727         ncp_disconnect(server);
728         ncp_unlock_server(server);
729 out_rxbuf:
730         ncp_stop_tasks(server);
731         vfree(server->rxbuf);
732 out_txbuf:
733         vfree(server->txbuf);
734 out_packet:
735         vfree(server->packet);
736 out_nls:
737 #ifdef CONFIG_NCPFS_NLS
738         unload_nls(server->nls_io);
739         unload_nls(server->nls_vol);
740 #endif
741         mutex_destroy(&server->rcv.creq_mutex);
742         mutex_destroy(&server->root_setup_lock);
743         mutex_destroy(&server->mutex);
744 out_fput2:
745         if (server->info_sock)
746                 sockfd_put(server->info_sock);
747 out_fput:
748         sockfd_put(sock);
749 out:
750         put_pid(data.wdog_pid);
751         sb->s_fs_info = NULL;
752         kfree(server);
753         return error;
754 }
755
756 static void delayed_free(struct rcu_head *p)
757 {
758         struct ncp_server *server = container_of(p, struct ncp_server, rcu);
759 #ifdef CONFIG_NCPFS_NLS
760         /* unload the NLS charsets */
761         unload_nls(server->nls_vol);
762         unload_nls(server->nls_io);
763 #endif /* CONFIG_NCPFS_NLS */
764         kfree(server);
765 }
766
767 static void ncp_put_super(struct super_block *sb)
768 {
769         struct ncp_server *server = NCP_SBP(sb);
770
771         ncp_lock_server(server);
772         ncp_disconnect(server);
773         ncp_unlock_server(server);
774
775         ncp_stop_tasks(server);
776
777         mutex_destroy(&server->rcv.creq_mutex);
778         mutex_destroy(&server->root_setup_lock);
779         mutex_destroy(&server->mutex);
780
781         if (server->info_sock)
782                 sockfd_put(server->info_sock);
783         sockfd_put(server->ncp_sock);
784         kill_pid(server->m.wdog_pid, SIGTERM, 1);
785         put_pid(server->m.wdog_pid);
786
787         kfree(server->priv.data);
788         kfree(server->auth.object_name);
789         vfree(server->rxbuf);
790         vfree(server->txbuf);
791         vfree(server->packet);
792         call_rcu(&server->rcu, delayed_free);
793 }
794
795 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
796 {
797         struct dentry* d;
798         struct inode* i;
799         struct ncp_inode_info* ni;
800         struct ncp_server* s;
801         struct ncp_volume_info vi;
802         struct super_block *sb = dentry->d_sb;
803         int err;
804         __u8 dh;
805         
806         d = sb->s_root;
807         if (!d) {
808                 goto dflt;
809         }
810         i = d_inode(d);
811         if (!i) {
812                 goto dflt;
813         }
814         ni = NCP_FINFO(i);
815         if (!ni) {
816                 goto dflt;
817         }
818         s = NCP_SBP(sb);
819         if (!s) {
820                 goto dflt;
821         }
822         if (!s->m.mounted_vol[0]) {
823                 goto dflt;
824         }
825
826         err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
827         if (err) {
828                 goto dflt;
829         }
830         err = ncp_get_directory_info(s, dh, &vi);
831         ncp_dirhandle_free(s, dh);
832         if (err) {
833                 goto dflt;
834         }
835         buf->f_type = NCP_SUPER_MAGIC;
836         buf->f_bsize = vi.sectors_per_block * 512;
837         buf->f_blocks = vi.total_blocks;
838         buf->f_bfree = vi.free_blocks;
839         buf->f_bavail = vi.free_blocks;
840         buf->f_files = vi.total_dir_entries;
841         buf->f_ffree = vi.available_dir_entries;
842         buf->f_namelen = 12;
843         return 0;
844
845         /* We cannot say how much disk space is left on a mounted
846            NetWare Server, because free space is distributed over
847            volumes, and the current user might have disk quotas. So
848            free space is not that simple to determine. Our decision
849            here is to err conservatively. */
850
851 dflt:;
852         buf->f_type = NCP_SUPER_MAGIC;
853         buf->f_bsize = NCP_BLOCK_SIZE;
854         buf->f_blocks = 0;
855         buf->f_bfree = 0;
856         buf->f_bavail = 0;
857         buf->f_namelen = 12;
858         return 0;
859 }
860
861 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
862 {
863         struct inode *inode = d_inode(dentry);
864         int result = 0;
865         __le32 info_mask;
866         struct nw_modify_dos_info info;
867         struct ncp_server *server;
868
869         result = -EIO;
870
871         server = NCP_SERVER(inode);
872         if (!server)    /* How this could happen? */
873                 goto out;
874
875         result = -EPERM;
876         if (IS_DEADDIR(d_inode(dentry)))
877                 goto out;
878
879         /* ageing the dentry to force validation */
880         ncp_age_dentry(server, dentry);
881
882         result = setattr_prepare(dentry, attr);
883         if (result < 0)
884                 goto out;
885
886         result = -EPERM;
887         if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
888                 goto out;
889
890         if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
891                 goto out;
892
893         if (((attr->ia_valid & ATTR_MODE) &&
894              (attr->ia_mode &
895               ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
896                 goto out;
897
898         info_mask = 0;
899         memset(&info, 0, sizeof(info));
900
901 #if 1 
902         if ((attr->ia_valid & ATTR_MODE) != 0)
903         {
904                 umode_t newmode = attr->ia_mode;
905
906                 info_mask |= DM_ATTRIBUTES;
907
908                 if (S_ISDIR(inode->i_mode)) {
909                         newmode &= server->m.dir_mode;
910                 } else {
911 #ifdef CONFIG_NCPFS_EXTRAS                      
912                         if (server->m.flags & NCP_MOUNT_EXTRAS) {
913                                 /* any non-default execute bit set */
914                                 if (newmode & ~server->m.file_mode & S_IXUGO)
915                                         info.attributes |= aSHARED | aSYSTEM;
916                                 /* read for group/world and not in default file_mode */
917                                 else if (newmode & ~server->m.file_mode & S_IRUGO)
918                                         info.attributes |= aSHARED;
919                         } else
920 #endif
921                                 newmode &= server->m.file_mode;                 
922                 }
923                 if (newmode & S_IWUGO)
924                         info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
925                 else
926                         info.attributes |=  (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
927
928 #ifdef CONFIG_NCPFS_NFS_NS
929                 if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
930                         result = ncp_modify_nfs_info(server,
931                                                      NCP_FINFO(inode)->volNumber,
932                                                      NCP_FINFO(inode)->dirEntNum,
933                                                      attr->ia_mode, 0);
934                         if (result != 0)
935                                 goto out;
936                         info.attributes &= ~(aSHARED | aSYSTEM);
937                         {
938                                 /* mark partial success */
939                                 struct iattr tmpattr;
940                                 
941                                 tmpattr.ia_valid = ATTR_MODE;
942                                 tmpattr.ia_mode = attr->ia_mode;
943
944                                 setattr_copy(inode, &tmpattr);
945                                 mark_inode_dirty(inode);
946                         }
947                 }
948 #endif
949         }
950 #endif
951
952         /* Do SIZE before attributes, otherwise mtime together with size does not work...
953          */
954         if ((attr->ia_valid & ATTR_SIZE) != 0) {
955                 int written;
956
957                 ncp_dbg(1, "trying to change size to %llu\n", attr->ia_size);
958
959                 if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
960                         result = -EACCES;
961                         goto out;
962                 }
963                 ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
964                           attr->ia_size, 0, "", &written);
965
966                 /* According to ndir, the changes only take effect after
967                    closing the file */
968                 ncp_inode_close(inode);
969                 result = ncp_make_closed(inode);
970                 if (result)
971                         goto out;
972
973                 if (attr->ia_size != i_size_read(inode)) {
974                         truncate_setsize(inode, attr->ia_size);
975                         mark_inode_dirty(inode);
976                 }
977         }
978         if ((attr->ia_valid & ATTR_CTIME) != 0) {
979                 info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
980                 ncp_date_unix2dos(attr->ia_ctime.tv_sec,
981                              &info.creationTime, &info.creationDate);
982         }
983         if ((attr->ia_valid & ATTR_MTIME) != 0) {
984                 info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
985                 ncp_date_unix2dos(attr->ia_mtime.tv_sec,
986                                   &info.modifyTime, &info.modifyDate);
987         }
988         if ((attr->ia_valid & ATTR_ATIME) != 0) {
989                 __le16 dummy;
990                 info_mask |= (DM_LAST_ACCESS_DATE);
991                 ncp_date_unix2dos(attr->ia_atime.tv_sec,
992                                   &dummy, &info.lastAccessDate);
993         }
994         if (info_mask != 0) {
995                 result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
996                                       inode, info_mask, &info);
997                 if (result != 0) {
998                         if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
999                                 /* NetWare seems not to allow this. I
1000                                    do not know why. So, just tell the
1001                                    user everything went fine. This is
1002                                    a terrible hack, but I do not know
1003                                    how to do this correctly. */
1004                                 result = 0;
1005                         } else
1006                                 goto out;
1007                 }
1008 #ifdef CONFIG_NCPFS_STRONG              
1009                 if ((!result) && (info_mask & DM_ATTRIBUTES))
1010                         NCP_FINFO(inode)->nwattr = info.attributes;
1011 #endif
1012         }
1013         if (result)
1014                 goto out;
1015
1016         setattr_copy(inode, attr);
1017         mark_inode_dirty(inode);
1018
1019 out:
1020         if (result > 0)
1021                 result = -EACCES;
1022         return result;
1023 }
1024
1025 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1026         int flags, const char *dev_name, void *data)
1027 {
1028         return mount_nodev(fs_type, flags, data, ncp_fill_super);
1029 }
1030
1031 static struct file_system_type ncp_fs_type = {
1032         .owner          = THIS_MODULE,
1033         .name           = "ncpfs",
1034         .mount          = ncp_mount,
1035         .kill_sb        = kill_anon_super,
1036         .fs_flags       = FS_BINARY_MOUNTDATA,
1037 };
1038 MODULE_ALIAS_FS("ncpfs");
1039
1040 static int __init init_ncp_fs(void)
1041 {
1042         int err;
1043         ncp_dbg(1, "called\n");
1044
1045         err = init_inodecache();
1046         if (err)
1047                 goto out1;
1048         err = register_filesystem(&ncp_fs_type);
1049         if (err)
1050                 goto out;
1051         return 0;
1052 out:
1053         destroy_inodecache();
1054 out1:
1055         return err;
1056 }
1057
1058 static void __exit exit_ncp_fs(void)
1059 {
1060         ncp_dbg(1, "called\n");
1061         unregister_filesystem(&ncp_fs_type);
1062         destroy_inodecache();
1063 }
1064
1065 module_init(init_ncp_fs)
1066 module_exit(exit_ncp_fs)
1067 MODULE_LICENSE("GPL");
This page took 0.094959 seconds and 4 git commands to generate.