Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
inode.c
Go to the documentation of this file.
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);
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),
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 = {
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 *
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)) {
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 (server->m.uid != 0)
335  seq_printf(seq, ",uid=%u", server->m.uid);
336  if (server->m.gid != 0)
337  seq_printf(seq, ",gid=%u", server->m.gid);
338  if (server->m.mounted_uid != 0)
339  seq_printf(seq, ",owner=%u", server->m.mounted_uid);
340  tmp = server->m.file_mode & S_IALLUGO;
341  if (tmp != NCP_DEFAULT_FILE_MODE)
342  seq_printf(seq, ",mode=0%o", tmp);
343  tmp = server->m.dir_mode & S_IALLUGO;
344  if (tmp != NCP_DEFAULT_DIR_MODE)
345  seq_printf(seq, ",dirmode=0%o", tmp);
346  if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) {
347  tmp = server->m.time_out * 100 / HZ;
348  seq_printf(seq, ",timeout=%u", tmp);
349  }
350  if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT)
351  seq_printf(seq, ",retry=%u", server->m.retry_count);
352  if (server->m.flags != 0)
353  seq_printf(seq, ",flags=%lu", server->m.flags);
354  if (server->m.wdog_pid != NULL)
355  seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid));
356 
357  return 0;
358 }
359 
360 static const struct ncp_option ncp_opts[] = {
361  { "uid", OPT_INT, 'u' },
362  { "gid", OPT_INT, 'g' },
363  { "owner", OPT_INT, 'o' },
364  { "mode", OPT_INT, 'm' },
365  { "dirmode", OPT_INT, 'd' },
366  { "timeout", OPT_INT, 't' },
367  { "retry", OPT_INT, 'r' },
368  { "flags", OPT_INT, 'f' },
369  { "wdogpid", OPT_INT, 'w' },
370  { "ncpfd", OPT_INT, 'n' },
371  { "infofd", OPT_INT, 'i' }, /* v5 */
372  { "version", OPT_INT, 'v' },
373  { NULL, 0, 0 } };
374 
375 static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
376  int optval;
377  char *optarg;
378  unsigned long optint;
379  int version = 0;
380  int ret;
381 
382  data->flags = 0;
383  data->int_flags = 0;
384  data->mounted_uid = 0;
385  data->wdog_pid = NULL;
386  data->ncp_fd = ~0;
389  data->uid = 0;
390  data->gid = 0;
393  data->info_fd = -1;
394  data->mounted_vol[0] = 0;
395 
396  while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
397  ret = optval;
398  if (ret < 0)
399  goto err;
400  switch (optval) {
401  case 'u':
402  data->uid = optint;
403  break;
404  case 'g':
405  data->gid = optint;
406  break;
407  case 'o':
408  data->mounted_uid = optint;
409  break;
410  case 'm':
411  data->file_mode = optint;
412  break;
413  case 'd':
414  data->dir_mode = optint;
415  break;
416  case 't':
417  data->time_out = optint;
418  break;
419  case 'r':
420  data->retry_count = optint;
421  break;
422  case 'f':
423  data->flags = optint;
424  break;
425  case 'w':
426  data->wdog_pid = find_get_pid(optint);
427  break;
428  case 'n':
429  data->ncp_fd = optint;
430  break;
431  case 'i':
432  data->info_fd = optint;
433  break;
434  case 'v':
435  ret = -ECHRNG;
436  if (optint < NCP_MOUNT_VERSION_V4)
437  goto err;
438  if (optint > NCP_MOUNT_VERSION_V5)
439  goto err;
440  version = optint;
441  break;
442 
443  }
444  }
445  return 0;
446 err:
447  put_pid(data->wdog_pid);
448  data->wdog_pid = NULL;
449  return ret;
450 }
451 
452 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
453 {
454  struct ncp_mount_data_kernel data;
455  struct ncp_server *server;
456  struct file *ncp_filp;
457  struct inode *root_inode;
458  struct inode *sock_inode;
459  struct socket *sock;
460  int error;
461  int default_bufsize;
462 #ifdef CONFIG_NCPFS_PACKET_SIGNING
463  int options;
464 #endif
465  struct ncp_entry_info finfo;
466 
467  memset(&data, 0, sizeof(data));
468  server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
469  if (!server)
470  return -ENOMEM;
471  sb->s_fs_info = server;
472 
473  error = -EFAULT;
474  if (raw_data == NULL)
475  goto out;
476  switch (*(int*)raw_data) {
477  case NCP_MOUNT_VERSION:
478  {
479  struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
480 
481  data.flags = md->flags;
483  data.mounted_uid = md->mounted_uid;
484  data.wdog_pid = find_get_pid(md->wdog_pid);
485  data.ncp_fd = md->ncp_fd;
486  data.time_out = md->time_out;
487  data.retry_count = md->retry_count;
488  data.uid = md->uid;
489  data.gid = md->gid;
490  data.file_mode = md->file_mode;
491  data.dir_mode = md->dir_mode;
492  data.info_fd = -1;
493  memcpy(data.mounted_vol, md->mounted_vol,
494  NCP_VOLNAME_LEN+1);
495  }
496  break;
498  {
499  struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
500 
501  data.flags = md->flags;
502  data.mounted_uid = md->mounted_uid;
503  data.wdog_pid = find_get_pid(md->wdog_pid);
504  data.ncp_fd = md->ncp_fd;
505  data.time_out = md->time_out;
506  data.retry_count = md->retry_count;
507  data.uid = md->uid;
508  data.gid = md->gid;
509  data.file_mode = md->file_mode;
510  data.dir_mode = md->dir_mode;
511  data.info_fd = -1;
512  }
513  break;
514  default:
515  error = -ECHRNG;
516  if (memcmp(raw_data, "vers", 4) == 0) {
517  error = ncp_parse_options(&data, raw_data);
518  }
519  if (error)
520  goto out;
521  break;
522  }
523  error = -EBADF;
524  ncp_filp = fget(data.ncp_fd);
525  if (!ncp_filp)
526  goto out;
527  error = -ENOTSOCK;
528  sock_inode = ncp_filp->f_path.dentry->d_inode;
529  if (!S_ISSOCK(sock_inode->i_mode))
530  goto out_fput;
531  sock = SOCKET_I(sock_inode);
532  if (!sock)
533  goto out_fput;
534 
535  if (sock->type == SOCK_STREAM)
536  default_bufsize = 0xF000;
537  else
538  default_bufsize = 1024;
539 
540  sb->s_flags |= MS_NODIRATIME; /* probably even noatime */
541  sb->s_maxbytes = 0xFFFFFFFFU;
542  sb->s_blocksize = 1024; /* Eh... Is this correct? */
543  sb->s_blocksize_bits = 10;
544  sb->s_magic = NCP_SUPER_MAGIC;
545  sb->s_op = &ncp_sops;
547  sb->s_bdi = &server->bdi;
548 
549  server = NCP_SBP(sb);
550  memset(server, 0, sizeof(*server));
551 
552  error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
553  if (error)
554  goto out_fput;
555 
556  server->ncp_filp = ncp_filp;
557  server->ncp_sock = sock;
558 
559  if (data.info_fd != -1) {
560  struct socket *info_sock;
561 
562  error = -EBADF;
563  server->info_filp = fget(data.info_fd);
564  if (!server->info_filp)
565  goto out_bdi;
566  error = -ENOTSOCK;
567  sock_inode = server->info_filp->f_path.dentry->d_inode;
568  if (!S_ISSOCK(sock_inode->i_mode))
569  goto out_fput2;
570  info_sock = SOCKET_I(sock_inode);
571  if (!info_sock)
572  goto out_fput2;
573  error = -EBADFD;
574  if (info_sock->type != SOCK_STREAM)
575  goto out_fput2;
576  server->info_sock = info_sock;
577  }
578 
579 /* server->lock = 0; */
580  mutex_init(&server->mutex);
581  server->packet = NULL;
582 /* server->buffer_size = 0; */
583 /* server->conn_status = 0; */
584 /* server->root_dentry = NULL; */
585 /* server->root_setuped = 0; */
586  mutex_init(&server->root_setup_lock);
587 #ifdef CONFIG_NCPFS_PACKET_SIGNING
588 /* server->sign_wanted = 0; */
589 /* server->sign_active = 0; */
590 #endif
591  init_rwsem(&server->auth_rwsem);
592  server->auth.auth_type = NCP_AUTH_NONE;
593 /* server->auth.object_name_len = 0; */
594 /* server->auth.object_name = NULL; */
595 /* server->auth.object_type = 0; */
596 /* server->priv.len = 0; */
597 /* server->priv.data = NULL; */
598 
599  server->m = data;
600  /* Although anything producing this is buggy, it happens
601  now because of PATH_MAX changes.. */
602  if (server->m.time_out < 1) {
603  server->m.time_out = 10;
604  printk(KERN_INFO "You need to recompile your ncpfs utils..\n");
605  }
606  server->m.time_out = server->m.time_out * HZ / 100;
607  server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
608  server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
609 
610 #ifdef CONFIG_NCPFS_NLS
611  /* load the default NLS charsets */
612  server->nls_vol = load_nls_default();
613  server->nls_io = load_nls_default();
614 #endif /* CONFIG_NCPFS_NLS */
615 
616  atomic_set(&server->dentry_ttl, 0); /* no caching */
617 
618  INIT_LIST_HEAD(&server->tx.requests);
619  mutex_init(&server->rcv.creq_mutex);
620  server->tx.creq = NULL;
621  server->rcv.creq = NULL;
622 
623  init_timer(&server->timeout_tm);
624 #undef NCP_PACKET_SIZE
625 #define NCP_PACKET_SIZE 131072
626  error = -ENOMEM;
627  server->packet_size = NCP_PACKET_SIZE;
628  server->packet = vmalloc(NCP_PACKET_SIZE);
629  if (server->packet == NULL)
630  goto out_nls;
631  server->txbuf = vmalloc(NCP_PACKET_SIZE);
632  if (server->txbuf == NULL)
633  goto out_packet;
634  server->rxbuf = vmalloc(NCP_PACKET_SIZE);
635  if (server->rxbuf == NULL)
636  goto out_txbuf;
637 
638  lock_sock(sock->sk);
639  server->data_ready = sock->sk->sk_data_ready;
640  server->write_space = sock->sk->sk_write_space;
641  server->error_report = sock->sk->sk_error_report;
642  sock->sk->sk_user_data = server;
643  sock->sk->sk_data_ready = ncp_tcp_data_ready;
644  sock->sk->sk_error_report = ncp_tcp_error_report;
645  if (sock->type == SOCK_STREAM) {
646  server->rcv.ptr = (unsigned char*)&server->rcv.buf;
647  server->rcv.len = 10;
648  server->rcv.state = 0;
649  INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
650  INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
651  sock->sk->sk_write_space = ncp_tcp_write_space;
652  } else {
653  INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
655  server->timeout_tm.data = (unsigned long)server;
656  server->timeout_tm.function = ncpdgram_timeout_call;
657  }
658  release_sock(sock->sk);
659 
660  ncp_lock_server(server);
661  error = ncp_connect(server);
662  ncp_unlock_server(server);
663  if (error < 0)
664  goto out_rxbuf;
665  DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));
666 
667  error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */
668 #ifdef CONFIG_NCPFS_PACKET_SIGNING
669  if (ncp_negotiate_size_and_options(server, default_bufsize,
670  NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
671  {
672  if (options != NCP_DEFAULT_OPTIONS)
673  {
674  if (ncp_negotiate_size_and_options(server,
675  default_bufsize,
676  options & 2,
677  &(server->buffer_size), &options) != 0)
678 
679  {
680  goto out_disconnect;
681  }
682  }
683  ncp_lock_server(server);
684  if (options & 2)
685  server->sign_wanted = 1;
686  ncp_unlock_server(server);
687  }
688  else
689 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
690  if (ncp_negotiate_buffersize(server, default_bufsize,
691  &(server->buffer_size)) != 0)
692  goto out_disconnect;
693  DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);
694 
695  memset(&finfo, 0, sizeof(finfo));
696  finfo.i.attributes = aDIR;
697  finfo.i.dataStreamSize = 0; /* ignored */
698  finfo.i.dirEntNum = 0;
699  finfo.i.DosDirNum = 0;
700 #ifdef CONFIG_NCPFS_SMALLDOS
701  finfo.i.NSCreator = NW_NS_DOS;
702 #endif
703  finfo.volume = NCP_NUMBER_OF_VOLUMES;
704  /* set dates of mountpoint to Jan 1, 1986; 00:00 */
705  finfo.i.creationTime = finfo.i.modifyTime
706  = cpu_to_le16(0x0000);
707  finfo.i.creationDate = finfo.i.modifyDate
708  = finfo.i.lastAccessDate
709  = cpu_to_le16(0x0C21);
710  finfo.i.nameLen = 0;
711  finfo.i.entryName[0] = '\0';
712 
713  finfo.opened = 0;
714  finfo.ino = 2; /* tradition */
715 
716  server->name_space[finfo.volume] = NW_NS_DOS;
717 
718  error = -ENOMEM;
719  root_inode = ncp_iget(sb, &finfo);
720  if (!root_inode)
721  goto out_disconnect;
722  DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
723  sb->s_root = d_make_root(root_inode);
724  if (!sb->s_root)
725  goto out_disconnect;
726  return 0;
727 
728 out_disconnect:
729  ncp_lock_server(server);
730  ncp_disconnect(server);
731  ncp_unlock_server(server);
732 out_rxbuf:
733  ncp_stop_tasks(server);
734  vfree(server->rxbuf);
735 out_txbuf:
736  vfree(server->txbuf);
737 out_packet:
738  vfree(server->packet);
739 out_nls:
740 #ifdef CONFIG_NCPFS_NLS
741  unload_nls(server->nls_io);
742  unload_nls(server->nls_vol);
743 #endif
744  mutex_destroy(&server->rcv.creq_mutex);
745  mutex_destroy(&server->root_setup_lock);
746  mutex_destroy(&server->mutex);
747 out_fput2:
748  if (server->info_filp)
749  fput(server->info_filp);
750 out_bdi:
751  bdi_destroy(&server->bdi);
752 out_fput:
753  /* 23/12/1998 Marcin Dalecki <[email protected]>:
754  *
755  * The previously used put_filp(ncp_filp); was bogus, since
756  * it doesn't perform proper unlocking.
757  */
758  fput(ncp_filp);
759 out:
760  put_pid(data.wdog_pid);
761  sb->s_fs_info = NULL;
762  kfree(server);
763  return error;
764 }
765 
766 static void ncp_put_super(struct super_block *sb)
767 {
768  struct ncp_server *server = NCP_SBP(sb);
769 
770  ncp_lock_server(server);
771  ncp_disconnect(server);
772  ncp_unlock_server(server);
773 
774  ncp_stop_tasks(server);
775 
776 #ifdef CONFIG_NCPFS_NLS
777  /* unload the NLS charsets */
778  unload_nls(server->nls_vol);
779  unload_nls(server->nls_io);
780 #endif /* CONFIG_NCPFS_NLS */
781  mutex_destroy(&server->rcv.creq_mutex);
782  mutex_destroy(&server->root_setup_lock);
783  mutex_destroy(&server->mutex);
784 
785  if (server->info_filp)
786  fput(server->info_filp);
787  fput(server->ncp_filp);
788  kill_pid(server->m.wdog_pid, SIGTERM, 1);
789  put_pid(server->m.wdog_pid);
790 
791  bdi_destroy(&server->bdi);
792  kfree(server->priv.data);
793  kfree(server->auth.object_name);
794  vfree(server->rxbuf);
795  vfree(server->txbuf);
796  vfree(server->packet);
797  sb->s_fs_info = NULL;
798  kfree(server);
799 }
800 
801 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
802 {
803  struct dentry* d;
804  struct inode* i;
805  struct ncp_inode_info* ni;
806  struct ncp_server* s;
807  struct ncp_volume_info vi;
808  struct super_block *sb = dentry->d_sb;
809  int err;
810  __u8 dh;
811 
812  d = sb->s_root;
813  if (!d) {
814  goto dflt;
815  }
816  i = d->d_inode;
817  if (!i) {
818  goto dflt;
819  }
820  ni = NCP_FINFO(i);
821  if (!ni) {
822  goto dflt;
823  }
824  s = NCP_SBP(sb);
825  if (!s) {
826  goto dflt;
827  }
828  if (!s->m.mounted_vol[0]) {
829  goto dflt;
830  }
831 
832  err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
833  if (err) {
834  goto dflt;
835  }
836  err = ncp_get_directory_info(s, dh, &vi);
837  ncp_dirhandle_free(s, dh);
838  if (err) {
839  goto dflt;
840  }
841  buf->f_type = NCP_SUPER_MAGIC;
842  buf->f_bsize = vi.sectors_per_block * 512;
843  buf->f_blocks = vi.total_blocks;
844  buf->f_bfree = vi.free_blocks;
845  buf->f_bavail = vi.free_blocks;
846  buf->f_files = vi.total_dir_entries;
847  buf->f_ffree = vi.available_dir_entries;
848  buf->f_namelen = 12;
849  return 0;
850 
851  /* We cannot say how much disk space is left on a mounted
852  NetWare Server, because free space is distributed over
853  volumes, and the current user might have disk quotas. So
854  free space is not that simple to determine. Our decision
855  here is to err conservatively. */
856 
857 dflt:;
858  buf->f_type = NCP_SUPER_MAGIC;
859  buf->f_bsize = NCP_BLOCK_SIZE;
860  buf->f_blocks = 0;
861  buf->f_bfree = 0;
862  buf->f_bavail = 0;
863  buf->f_namelen = 12;
864  return 0;
865 }
866 
867 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
868 {
869  struct inode *inode = dentry->d_inode;
870  int result = 0;
871  __le32 info_mask;
872  struct nw_modify_dos_info info;
873  struct ncp_server *server;
874 
875  result = -EIO;
876 
877  server = NCP_SERVER(inode);
878  if (!server) /* How this could happen? */
879  goto out;
880 
881  /* ageing the dentry to force validation */
882  ncp_age_dentry(server, dentry);
883 
884  result = inode_change_ok(inode, attr);
885  if (result < 0)
886  goto out;
887 
888  result = -EPERM;
889  if (((attr->ia_valid & ATTR_UID) &&
890  (attr->ia_uid != server->m.uid)))
891  goto out;
892 
893  if (((attr->ia_valid & ATTR_GID) &&
894  (attr->ia_gid != server->m.gid)))
895  goto out;
896 
897  if (((attr->ia_valid & ATTR_MODE) &&
898  (attr->ia_mode &
899  ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
900  goto out;
901 
902  info_mask = 0;
903  memset(&info, 0, sizeof(info));
904 
905 #if 1
906  if ((attr->ia_valid & ATTR_MODE) != 0)
907  {
908  umode_t newmode = attr->ia_mode;
909 
910  info_mask |= DM_ATTRIBUTES;
911 
912  if (S_ISDIR(inode->i_mode)) {
913  newmode &= server->m.dir_mode;
914  } else {
915 #ifdef CONFIG_NCPFS_EXTRAS
916  if (server->m.flags & NCP_MOUNT_EXTRAS) {
917  /* any non-default execute bit set */
918  if (newmode & ~server->m.file_mode & S_IXUGO)
919  info.attributes |= aSHARED | aSYSTEM;
920  /* read for group/world and not in default file_mode */
921  else if (newmode & ~server->m.file_mode & S_IRUGO)
922  info.attributes |= aSHARED;
923  } else
924 #endif
925  newmode &= server->m.file_mode;
926  }
927  if (newmode & S_IWUGO)
929  else
931 
932 #ifdef CONFIG_NCPFS_NFS_NS
933  if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
934  result = ncp_modify_nfs_info(server,
935  NCP_FINFO(inode)->volNumber,
936  NCP_FINFO(inode)->dirEntNum,
937  attr->ia_mode, 0);
938  if (result != 0)
939  goto out;
940  info.attributes &= ~(aSHARED | aSYSTEM);
941  {
942  /* mark partial success */
943  struct iattr tmpattr;
944 
945  tmpattr.ia_valid = ATTR_MODE;
946  tmpattr.ia_mode = attr->ia_mode;
947 
948  setattr_copy(inode, &tmpattr);
949  mark_inode_dirty(inode);
950  }
951  }
952 #endif
953  }
954 #endif
955 
956  /* Do SIZE before attributes, otherwise mtime together with size does not work...
957  */
958  if ((attr->ia_valid & ATTR_SIZE) != 0) {
959  int written;
960 
961  DPRINTK("ncpfs: trying to change size to %ld\n",
962  attr->ia_size);
963 
964  if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
965  result = -EACCES;
966  goto out;
967  }
968  ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
969  attr->ia_size, 0, "", &written);
970 
971  /* According to ndir, the changes only take effect after
972  closing the file */
973  ncp_inode_close(inode);
974  result = ncp_make_closed(inode);
975  if (result)
976  goto out;
977 
978  if (attr->ia_size != i_size_read(inode)) {
979  result = vmtruncate(inode, attr->ia_size);
980  if (result)
981  goto out;
982  mark_inode_dirty(inode);
983  }
984  }
985  if ((attr->ia_valid & ATTR_CTIME) != 0) {
986  info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
987  ncp_date_unix2dos(attr->ia_ctime.tv_sec,
988  &info.creationTime, &info.creationDate);
989  }
990  if ((attr->ia_valid & ATTR_MTIME) != 0) {
991  info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
992  ncp_date_unix2dos(attr->ia_mtime.tv_sec,
993  &info.modifyTime, &info.modifyDate);
994  }
995  if ((attr->ia_valid & ATTR_ATIME) != 0) {
996  __le16 dummy;
997  info_mask |= (DM_LAST_ACCESS_DATE);
998  ncp_date_unix2dos(attr->ia_atime.tv_sec,
999  &dummy, &info.lastAccessDate);
1000  }
1001  if (info_mask != 0) {
1003  inode, info_mask, &info);
1004  if (result != 0) {
1005  if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1006  /* NetWare seems not to allow this. I
1007  do not know why. So, just tell the
1008  user everything went fine. This is
1009  a terrible hack, but I do not know
1010  how to do this correctly. */
1011  result = 0;
1012  } else
1013  goto out;
1014  }
1015 #ifdef CONFIG_NCPFS_STRONG
1016  if ((!result) && (info_mask & DM_ATTRIBUTES))
1017  NCP_FINFO(inode)->nwattr = info.attributes;
1018 #endif
1019  }
1020  if (result)
1021  goto out;
1022 
1023  setattr_copy(inode, attr);
1024  mark_inode_dirty(inode);
1025 
1026 out:
1027  if (result > 0)
1028  result = -EACCES;
1029  return result;
1030 }
1031 
1032 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1033  int flags, const char *dev_name, void *data)
1034 {
1035  return mount_nodev(fs_type, flags, data, ncp_fill_super);
1036 }
1037 
1038 static struct file_system_type ncp_fs_type = {
1039  .owner = THIS_MODULE,
1040  .name = "ncpfs",
1041  .mount = ncp_mount,
1042  .kill_sb = kill_anon_super,
1043  .fs_flags = FS_BINARY_MOUNTDATA,
1044 };
1045 
1046 static int __init init_ncp_fs(void)
1047 {
1048  int err;
1049  DPRINTK("ncpfs: init_ncp_fs called\n");
1050 
1051  err = init_inodecache();
1052  if (err)
1053  goto out1;
1054  err = register_filesystem(&ncp_fs_type);
1055  if (err)
1056  goto out;
1057  return 0;
1058 out:
1059  destroy_inodecache();
1060 out1:
1061  return err;
1062 }
1063 
1064 static void __exit exit_ncp_fs(void)
1065 {
1066  DPRINTK("ncpfs: exit_ncp_fs called\n");
1067  unregister_filesystem(&ncp_fs_type);
1068  destroy_inodecache();
1069 }
1070 
1071 module_init(init_ncp_fs)
1072 module_exit(exit_ncp_fs)
1073 MODULE_LICENSE("GPL");