Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dir.c
Go to the documentation of this file.
1 /*
2  * dir.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, 1999 Wolfram Pienkoss for NLS
8  * Modified 1999 Wolfram Pienkoss for directory caching
9  * Modified 2000 Ben Harris, University of Cambridge for NFS NS meta-info
10  *
11  */
12 
13 
14 #include <linux/time.h>
15 #include <linux/errno.h>
16 #include <linux/stat.h>
17 #include <linux/kernel.h>
18 #include <linux/vmalloc.h>
19 #include <linux/mm.h>
20 #include <linux/namei.h>
21 #include <asm/uaccess.h>
22 #include <asm/byteorder.h>
23 
24 #include "ncp_fs.h"
25 
26 static void ncp_read_volume_list(struct file *, void *, filldir_t,
27  struct ncp_cache_control *);
28 static void ncp_do_readdir(struct file *, void *, filldir_t,
29  struct ncp_cache_control *);
30 
31 static int ncp_readdir(struct file *, void *, filldir_t);
32 
33 static int ncp_create(struct inode *, struct dentry *, umode_t, bool);
34 static struct dentry *ncp_lookup(struct inode *, struct dentry *, unsigned int);
35 static int ncp_unlink(struct inode *, struct dentry *);
36 static int ncp_mkdir(struct inode *, struct dentry *, umode_t);
37 static int ncp_rmdir(struct inode *, struct dentry *);
38 static int ncp_rename(struct inode *, struct dentry *,
39  struct inode *, struct dentry *);
40 static int ncp_mknod(struct inode * dir, struct dentry *dentry,
42 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
43 extern int ncp_symlink(struct inode *, struct dentry *, const char *);
44 #else
45 #define ncp_symlink NULL
46 #endif
47 
49 {
50  .llseek = generic_file_llseek,
51  .read = generic_read_dir,
52  .readdir = ncp_readdir,
53  .unlocked_ioctl = ncp_ioctl,
54 #ifdef CONFIG_COMPAT
55  .compat_ioctl = ncp_compat_ioctl,
56 #endif
57 };
58 
60 {
61  .create = ncp_create,
62  .lookup = ncp_lookup,
63  .unlink = ncp_unlink,
64  .symlink = ncp_symlink,
65  .mkdir = ncp_mkdir,
66  .rmdir = ncp_rmdir,
67  .mknod = ncp_mknod,
68  .rename = ncp_rename,
69  .setattr = ncp_notify_change,
70 };
71 
72 /*
73  * Dentry operations routines
74  */
75 static int ncp_lookup_validate(struct dentry *, unsigned int);
76 static int ncp_hash_dentry(const struct dentry *, const struct inode *,
77  struct qstr *);
78 static int ncp_compare_dentry(const struct dentry *, const struct inode *,
79  const struct dentry *, const struct inode *,
80  unsigned int, const char *, const struct qstr *);
81 static int ncp_delete_dentry(const struct dentry *);
82 
84 {
85  .d_revalidate = ncp_lookup_validate,
86  .d_hash = ncp_hash_dentry,
87  .d_compare = ncp_compare_dentry,
88  .d_delete = ncp_delete_dentry,
89 };
90 
91 #define ncp_namespace(i) (NCP_SERVER(i)->name_space[NCP_FINFO(i)->volNumber])
92 
93 static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator)
94 {
95 #ifdef CONFIG_NCPFS_SMALLDOS
96  int ns = ncp_namespace(i);
97 
98  if ((ns == NW_NS_DOS)
99 #ifdef CONFIG_NCPFS_OS2_NS
100  || ((ns == NW_NS_OS2) && (nscreator == NW_NS_DOS))
101 #endif /* CONFIG_NCPFS_OS2_NS */
102  )
103  return 0;
104 #endif /* CONFIG_NCPFS_SMALLDOS */
105  return 1;
106 }
107 
108 #define ncp_preserve_case(i) (ncp_namespace(i) != NW_NS_DOS)
109 
110 static inline int ncp_case_sensitive(const struct inode *i)
111 {
112 #ifdef CONFIG_NCPFS_NFS_NS
113  return ncp_namespace(i) == NW_NS_NFS;
114 #else
115  return 0;
116 #endif /* CONFIG_NCPFS_NFS_NS */
117 }
118 
119 /*
120  * Note: leave the hash unchanged if the directory
121  * is case-sensitive.
122  */
123 static int
124 ncp_hash_dentry(const struct dentry *dentry, const struct inode *inode,
125  struct qstr *this)
126 {
127  if (!ncp_case_sensitive(inode)) {
128  struct super_block *sb = dentry->d_sb;
129  struct nls_table *t;
130  unsigned long hash;
131  int i;
132 
133  t = NCP_IO_TABLE(sb);
134  hash = init_name_hash();
135  for (i=0; i<this->len ; i++)
136  hash = partial_name_hash(ncp_tolower(t, this->name[i]),
137  hash);
138  this->hash = end_name_hash(hash);
139  }
140  return 0;
141 }
142 
143 static int
144 ncp_compare_dentry(const struct dentry *parent, const struct inode *pinode,
145  const struct dentry *dentry, const struct inode *inode,
146  unsigned int len, const char *str, const struct qstr *name)
147 {
148  if (len != name->len)
149  return 1;
150 
151  if (ncp_case_sensitive(pinode))
152  return strncmp(str, name->name, len);
153 
154  return ncp_strnicmp(NCP_IO_TABLE(pinode->i_sb), str, name->name, len);
155 }
156 
157 /*
158  * This is the callback from dput() when d_count is going to 0.
159  * We use this to unhash dentries with bad inodes.
160  * Closing files can be safely postponed until iput() - it's done there anyway.
161  */
162 static int
163 ncp_delete_dentry(const struct dentry * dentry)
164 {
165  struct inode *inode = dentry->d_inode;
166 
167  if (inode) {
168  if (is_bad_inode(inode))
169  return 1;
170  } else
171  {
172  /* N.B. Unhash negative dentries? */
173  }
174  return 0;
175 }
176 
177 static inline int
178 ncp_single_volume(struct ncp_server *server)
179 {
180  return (server->m.mounted_vol[0] != '\0');
181 }
182 
183 static inline int ncp_is_server_root(struct inode *inode)
184 {
185  return (!ncp_single_volume(NCP_SERVER(inode)) &&
186  inode == inode->i_sb->s_root->d_inode);
187 }
188 
189 
190 /*
191  * This is the callback when the dcache has a lookup hit.
192  */
193 
194 
195 #ifdef CONFIG_NCPFS_STRONG
196 /* try to delete a readonly file (NW R bit set) */
197 
198 static int
199 ncp_force_unlink(struct inode *dir, struct dentry* dentry)
200 {
201  int res=0x9c,res2;
202  struct nw_modify_dos_info info;
203  __le32 old_nwattr;
204  struct inode *inode;
205 
206  memset(&info, 0, sizeof(info));
207 
208  /* remove the Read-Only flag on the NW server */
209  inode = dentry->d_inode;
210 
211  old_nwattr = NCP_FINFO(inode)->nwattr;
212  info.attributes = old_nwattr & ~(aRONLY|aDELETEINHIBIT|aRENAMEINHIBIT);
214  if (res2)
215  goto leave_me;
216 
217  /* now try again the delete operation */
218  res = ncp_del_file_or_subdir2(NCP_SERVER(dir), dentry);
219 
220  if (res) /* delete failed, set R bit again */
221  {
222  info.attributes = old_nwattr;
224  if (res2)
225  goto leave_me;
226  }
227 leave_me:
228  return(res);
229 }
230 #endif /* CONFIG_NCPFS_STRONG */
231 
232 #ifdef CONFIG_NCPFS_STRONG
233 static int
234 ncp_force_rename(struct inode *old_dir, struct dentry* old_dentry, char *_old_name,
235  struct inode *new_dir, struct dentry* new_dentry, char *_new_name)
236 {
237  struct nw_modify_dos_info info;
238  int res=0x90,res2;
239  struct inode *old_inode = old_dentry->d_inode;
240  __le32 old_nwattr = NCP_FINFO(old_inode)->nwattr;
241  __le32 new_nwattr = 0; /* shut compiler warning */
242  int old_nwattr_changed = 0;
243  int new_nwattr_changed = 0;
244 
245  memset(&info, 0, sizeof(info));
246 
247  /* remove the Read-Only flag on the NW server */
248 
249  info.attributes = old_nwattr & ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
251  if (!res2)
252  old_nwattr_changed = 1;
253  if (new_dentry && new_dentry->d_inode) {
254  new_nwattr = NCP_FINFO(new_dentry->d_inode)->nwattr;
255  info.attributes = new_nwattr & ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
256  res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(new_dir), new_dir, _new_name, DM_ATTRIBUTES, &info);
257  if (!res2)
258  new_nwattr_changed = 1;
259  }
260  /* now try again the rename operation */
261  /* but only if something really happened */
262  if (new_nwattr_changed || old_nwattr_changed) {
264  old_dir, _old_name,
265  new_dir, _new_name);
266  }
267  if (res)
268  goto leave_me;
269  /* file was successfully renamed, so:
270  do not set attributes on old file - it no longer exists
271  copy attributes from old file to new */
272  new_nwattr_changed = old_nwattr_changed;
273  new_nwattr = old_nwattr;
274  old_nwattr_changed = 0;
275 
276 leave_me:;
277  if (old_nwattr_changed) {
278  info.attributes = old_nwattr;
280  /* ignore errors */
281  }
282  if (new_nwattr_changed) {
283  info.attributes = new_nwattr;
284  res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(new_dir), new_dir, _new_name, DM_ATTRIBUTES, &info);
285  /* ignore errors */
286  }
287  return(res);
288 }
289 #endif /* CONFIG_NCPFS_STRONG */
290 
291 
292 static int
293 ncp_lookup_validate(struct dentry *dentry, unsigned int flags)
294 {
295  struct ncp_server *server;
296  struct dentry *parent;
297  struct inode *dir;
298  struct ncp_entry_info finfo;
299  int res, val = 0, len;
300  __u8 __name[NCP_MAXPATHLEN + 1];
301 
302  if (dentry == dentry->d_sb->s_root)
303  return 1;
304 
305  if (flags & LOOKUP_RCU)
306  return -ECHILD;
307 
308  parent = dget_parent(dentry);
309  dir = parent->d_inode;
310 
311  if (!dentry->d_inode)
312  goto finished;
313 
314  server = NCP_SERVER(dir);
315 
316  /*
317  * Inspired by smbfs:
318  * The default validation is based on dentry age:
319  * We set the max age at mount time. (But each
320  * successful server lookup renews the timestamp.)
321  */
322  val = NCP_TEST_AGE(server, dentry);
323  if (val)
324  goto finished;
325 
326  DDPRINTK("ncp_lookup_validate: %s/%s not valid, age=%ld, server lookup\n",
327  dentry->d_parent->d_name.name, dentry->d_name.name,
328  NCP_GET_AGE(dentry));
329 
330  len = sizeof(__name);
331  if (ncp_is_server_root(dir)) {
332  res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
333  dentry->d_name.len, 1);
334  if (!res) {
335  res = ncp_lookup_volume(server, __name, &(finfo.i));
336  if (!res)
337  ncp_update_known_namespace(server, finfo.i.volNumber, NULL);
338  }
339  } else {
340  res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
341  dentry->d_name.len, !ncp_preserve_case(dir));
342  if (!res)
343  res = ncp_obtain_info(server, dir, __name, &(finfo.i));
344  }
345  finfo.volume = finfo.i.volNumber;
346  DDPRINTK("ncp_lookup_validate: looked for %s/%s, res=%d\n",
347  dentry->d_parent->d_name.name, __name, res);
348  /*
349  * If we didn't find it, or if it has a different dirEntNum to
350  * what we remember, it's not valid any more.
351  */
352  if (!res) {
353  struct inode *inode = dentry->d_inode;
354 
355  mutex_lock(&inode->i_mutex);
356  if (finfo.i.dirEntNum == NCP_FINFO(inode)->dirEntNum) {
357  ncp_new_dentry(dentry);
358  val=1;
359  } else
360  DDPRINTK("ncp_lookup_validate: found, but dirEntNum changed\n");
361 
362  ncp_update_inode2(inode, &finfo);
363  mutex_unlock(&inode->i_mutex);
364  }
365 
366 finished:
367  DDPRINTK("ncp_lookup_validate: result=%d\n", val);
368  dput(parent);
369  return val;
370 }
371 
372 static struct dentry *
373 ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
374 {
375  struct dentry *dent = dentry;
376  struct list_head *next;
377 
378  if (d_validate(dent, parent)) {
379  if (dent->d_name.len <= NCP_MAXPATHLEN &&
380  (unsigned long)dent->d_fsdata == fpos) {
381  if (!dent->d_inode) {
382  dput(dent);
383  dent = NULL;
384  }
385  return dent;
386  }
387  dput(dent);
388  }
389 
390  /* If a pointer is invalid, we search the dentry. */
391  spin_lock(&parent->d_lock);
392  next = parent->d_subdirs.next;
393  while (next != &parent->d_subdirs) {
394  dent = list_entry(next, struct dentry, d_u.d_child);
395  if ((unsigned long)dent->d_fsdata == fpos) {
396  if (dent->d_inode)
397  dget(dent);
398  else
399  dent = NULL;
400  spin_unlock(&parent->d_lock);
401  goto out;
402  }
403  next = next->next;
404  }
405  spin_unlock(&parent->d_lock);
406  return NULL;
407 
408 out:
409  return dent;
410 }
411 
412 static time_t ncp_obtain_mtime(struct dentry *dentry)
413 {
414  struct inode *inode = dentry->d_inode;
415  struct ncp_server *server = NCP_SERVER(inode);
416  struct nw_info_struct i;
417 
418  if (!ncp_conn_valid(server) || ncp_is_server_root(inode))
419  return 0;
420 
421  if (ncp_obtain_info(server, inode, NULL, &i))
422  return 0;
423 
424  return ncp_date_dos2unix(i.modifyTime, i.modifyDate);
425 }
426 
427 static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
428 {
429  struct dentry *dentry = filp->f_path.dentry;
430  struct inode *inode = dentry->d_inode;
431  struct page *page = NULL;
432  struct ncp_server *server = NCP_SERVER(inode);
433  union ncp_dir_cache *cache = NULL;
434  struct ncp_cache_control ctl;
435  int result, mtime_valid = 0;
436  time_t mtime = 0;
437 
438  ctl.page = NULL;
439  ctl.cache = NULL;
440 
441  DDPRINTK("ncp_readdir: reading %s/%s, pos=%d\n",
442  dentry->d_parent->d_name.name, dentry->d_name.name,
443  (int) filp->f_pos);
444 
445  result = -EIO;
446  /* Do not generate '.' and '..' when server is dead. */
447  if (!ncp_conn_valid(server))
448  goto out;
449 
450  result = 0;
451  if (filp->f_pos == 0) {
452  if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR))
453  goto out;
454  filp->f_pos = 1;
455  }
456  if (filp->f_pos == 1) {
457  if (filldir(dirent, "..", 2, 1, parent_ino(dentry), DT_DIR))
458  goto out;
459  filp->f_pos = 2;
460  }
461 
462  page = grab_cache_page(&inode->i_data, 0);
463  if (!page)
464  goto read_really;
465 
466  ctl.cache = cache = kmap(page);
467  ctl.head = cache->head;
468 
469  if (!PageUptodate(page) || !ctl.head.eof)
470  goto init_cache;
471 
472  if (filp->f_pos == 2) {
473  if (jiffies - ctl.head.time >= NCP_MAX_AGE(server))
474  goto init_cache;
475 
476  mtime = ncp_obtain_mtime(dentry);
477  mtime_valid = 1;
478  if ((!mtime) || (mtime != ctl.head.mtime))
479  goto init_cache;
480  }
481 
482  if (filp->f_pos > ctl.head.end)
483  goto finished;
484 
485  ctl.fpos = filp->f_pos + (NCP_DIRCACHE_START - 2);
486  ctl.ofs = ctl.fpos / NCP_DIRCACHE_SIZE;
487  ctl.idx = ctl.fpos % NCP_DIRCACHE_SIZE;
488 
489  for (;;) {
490  if (ctl.ofs != 0) {
491  ctl.page = find_lock_page(&inode->i_data, ctl.ofs);
492  if (!ctl.page)
493  goto invalid_cache;
494  ctl.cache = kmap(ctl.page);
495  if (!PageUptodate(ctl.page))
496  goto invalid_cache;
497  }
498  while (ctl.idx < NCP_DIRCACHE_SIZE) {
499  struct dentry *dent;
500  int res;
501 
502  dent = ncp_dget_fpos(ctl.cache->dentry[ctl.idx],
503  dentry, filp->f_pos);
504  if (!dent)
505  goto invalid_cache;
506  res = filldir(dirent, dent->d_name.name,
507  dent->d_name.len, filp->f_pos,
508  dent->d_inode->i_ino, DT_UNKNOWN);
509  dput(dent);
510  if (res)
511  goto finished;
512  filp->f_pos += 1;
513  ctl.idx += 1;
514  if (filp->f_pos > ctl.head.end)
515  goto finished;
516  }
517  if (ctl.page) {
518  kunmap(ctl.page);
519  SetPageUptodate(ctl.page);
520  unlock_page(ctl.page);
521  page_cache_release(ctl.page);
522  ctl.page = NULL;
523  }
524  ctl.idx = 0;
525  ctl.ofs += 1;
526  }
527 invalid_cache:
528  if (ctl.page) {
529  kunmap(ctl.page);
530  unlock_page(ctl.page);
531  page_cache_release(ctl.page);
532  ctl.page = NULL;
533  }
534  ctl.cache = cache;
535 init_cache:
536  ncp_invalidate_dircache_entries(dentry);
537  if (!mtime_valid) {
538  mtime = ncp_obtain_mtime(dentry);
539  mtime_valid = 1;
540  }
541  ctl.head.mtime = mtime;
542  ctl.head.time = jiffies;
543  ctl.head.eof = 0;
544  ctl.fpos = 2;
545  ctl.ofs = 0;
546  ctl.idx = NCP_DIRCACHE_START;
547  ctl.filled = 0;
548  ctl.valid = 1;
549 read_really:
550  if (ncp_is_server_root(inode)) {
551  ncp_read_volume_list(filp, dirent, filldir, &ctl);
552  } else {
553  ncp_do_readdir(filp, dirent, filldir, &ctl);
554  }
555  ctl.head.end = ctl.fpos - 1;
556  ctl.head.eof = ctl.valid;
557 finished:
558  if (ctl.page) {
559  kunmap(ctl.page);
560  SetPageUptodate(ctl.page);
561  unlock_page(ctl.page);
562  page_cache_release(ctl.page);
563  }
564  if (page) {
565  cache->head = ctl.head;
566  kunmap(page);
567  SetPageUptodate(page);
568  unlock_page(page);
569  page_cache_release(page);
570  }
571 out:
572  return result;
573 }
574 
575 static int
576 ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
577  struct ncp_cache_control *ctrl, struct ncp_entry_info *entry,
578  int inval_childs)
579 {
580  struct dentry *newdent, *dentry = filp->f_path.dentry;
581  struct inode *dir = dentry->d_inode;
582  struct ncp_cache_control ctl = *ctrl;
583  struct qstr qname;
584  int valid = 0;
585  int hashed = 0;
586  ino_t ino = 0;
587  __u8 __name[NCP_MAXPATHLEN + 1];
588 
589  qname.len = sizeof(__name);
590  if (ncp_vol2io(NCP_SERVER(dir), __name, &qname.len,
591  entry->i.entryName, entry->i.nameLen,
592  !ncp_preserve_entry_case(dir, entry->i.NSCreator)))
593  return 1; /* I'm not sure */
594 
595  qname.name = __name;
596  qname.hash = full_name_hash(qname.name, qname.len);
597 
598  if (dentry->d_op && dentry->d_op->d_hash)
599  if (dentry->d_op->d_hash(dentry, dentry->d_inode, &qname) != 0)
600  goto end_advance;
601 
602  newdent = d_lookup(dentry, &qname);
603 
604  if (!newdent) {
605  newdent = d_alloc(dentry, &qname);
606  if (!newdent)
607  goto end_advance;
608  } else {
609  hashed = 1;
610 
611  /* If case sensitivity changed for this volume, all entries below this one
612  should be thrown away. This entry itself is not affected, as its case
613  sensitivity is controlled by its own parent. */
614  if (inval_childs)
615  shrink_dcache_parent(newdent);
616 
617  /*
618  * NetWare's OS2 namespace is case preserving yet case
619  * insensitive. So we update dentry's name as received from
620  * server. Parent dir's i_mutex is locked because we're in
621  * readdir.
622  */
623  dentry_update_name_case(newdent, &qname);
624  }
625 
626  if (!newdent->d_inode) {
627  struct inode *inode;
628 
629  entry->opened = 0;
630  entry->ino = iunique(dir->i_sb, 2);
631  inode = ncp_iget(dir->i_sb, entry);
632  if (inode) {
633  d_instantiate(newdent, inode);
634  if (!hashed)
635  d_rehash(newdent);
636  }
637  } else {
638  struct inode *inode = newdent->d_inode;
639 
641  ncp_update_inode2(inode, entry);
642  mutex_unlock(&inode->i_mutex);
643  }
644 
645  if (newdent->d_inode) {
646  ino = newdent->d_inode->i_ino;
647  newdent->d_fsdata = (void *) ctl.fpos;
648  ncp_new_dentry(newdent);
649  }
650 
651  if (ctl.idx >= NCP_DIRCACHE_SIZE) {
652  if (ctl.page) {
653  kunmap(ctl.page);
654  SetPageUptodate(ctl.page);
655  unlock_page(ctl.page);
657  }
658  ctl.cache = NULL;
659  ctl.idx -= NCP_DIRCACHE_SIZE;
660  ctl.ofs += 1;
661  ctl.page = grab_cache_page(&dir->i_data, ctl.ofs);
662  if (ctl.page)
663  ctl.cache = kmap(ctl.page);
664  }
665  if (ctl.cache) {
666  ctl.cache->dentry[ctl.idx] = newdent;
667  valid = 1;
668  }
669  dput(newdent);
670 end_advance:
671  if (!valid)
672  ctl.valid = 0;
673  if (!ctl.filled && (ctl.fpos == filp->f_pos)) {
674  if (!ino)
675  ino = find_inode_number(dentry, &qname);
676  if (!ino)
677  ino = iunique(dir->i_sb, 2);
678  ctl.filled = filldir(dirent, qname.name, qname.len,
679  filp->f_pos, ino, DT_UNKNOWN);
680  if (!ctl.filled)
681  filp->f_pos += 1;
682  }
683  ctl.fpos += 1;
684  ctl.idx += 1;
685  *ctrl = ctl;
686  return (ctl.valid || !ctl.filled);
687 }
688 
689 static void
690 ncp_read_volume_list(struct file *filp, void *dirent, filldir_t filldir,
691  struct ncp_cache_control *ctl)
692 {
693  struct dentry *dentry = filp->f_path.dentry;
694  struct inode *inode = dentry->d_inode;
695  struct ncp_server *server = NCP_SERVER(inode);
696  struct ncp_volume_info info;
697  struct ncp_entry_info entry;
698  int i;
699 
700  DPRINTK("ncp_read_volume_list: pos=%ld\n",
701  (unsigned long) filp->f_pos);
702 
703  for (i = 0; i < NCP_NUMBER_OF_VOLUMES; i++) {
704  int inval_dentry;
705 
706  if (ncp_get_volume_info_with_number(server, i, &info) != 0)
707  return;
708  if (!strlen(info.volume_name))
709  continue;
710 
711  DPRINTK("ncp_read_volume_list: found vol: %s\n",
712  info.volume_name);
713 
714  if (ncp_lookup_volume(server, info.volume_name,
715  &entry.i)) {
716  DPRINTK("ncpfs: could not lookup vol %s\n",
717  info.volume_name);
718  continue;
719  }
720  inval_dentry = ncp_update_known_namespace(server, entry.i.volNumber, NULL);
721  entry.volume = entry.i.volNumber;
722  if (!ncp_fill_cache(filp, dirent, filldir, ctl, &entry, inval_dentry))
723  return;
724  }
725 }
726 
727 static void
728 ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir,
729  struct ncp_cache_control *ctl)
730 {
731  struct dentry *dentry = filp->f_path.dentry;
732  struct inode *dir = dentry->d_inode;
733  struct ncp_server *server = NCP_SERVER(dir);
734  struct nw_search_sequence seq;
735  struct ncp_entry_info entry;
736  int err;
737  void* buf;
738  int more;
739  size_t bufsize;
740 
741  DPRINTK("ncp_do_readdir: %s/%s, fpos=%ld\n",
742  dentry->d_parent->d_name.name, dentry->d_name.name,
743  (unsigned long) filp->f_pos);
744  PPRINTK("ncp_do_readdir: init %s, volnum=%d, dirent=%u\n",
745  dentry->d_name.name, NCP_FINFO(dir)->volNumber,
746  NCP_FINFO(dir)->dirEntNum);
747 
748  err = ncp_initialize_search(server, dir, &seq);
749  if (err) {
750  DPRINTK("ncp_do_readdir: init failed, err=%d\n", err);
751  return;
752  }
753  /* We MUST NOT use server->buffer_size handshaked with server if we are
754  using UDP, as for UDP server uses max. buffer size determined by
755  MTU, and for TCP server uses hardwired value 65KB (== 66560 bytes).
756  So we use 128KB, just to be sure, as there is no way how to know
757  this value in advance. */
758  bufsize = 131072;
759  buf = vmalloc(bufsize);
760  if (!buf)
761  return;
762  do {
763  int cnt;
764  char* rpl;
765  size_t rpls;
766 
767  err = ncp_search_for_fileset(server, &seq, &more, &cnt, buf, bufsize, &rpl, &rpls);
768  if (err) /* Error */
769  break;
770  if (!cnt) /* prevent endless loop */
771  break;
772  while (cnt--) {
773  size_t onerpl;
774 
775  if (rpls < offsetof(struct nw_info_struct, entryName))
776  break; /* short packet */
777  ncp_extract_file_info(rpl, &entry.i);
778  onerpl = offsetof(struct nw_info_struct, entryName) + entry.i.nameLen;
779  if (rpls < onerpl)
780  break; /* short packet */
781  (void)ncp_obtain_nfs_info(server, &entry.i);
782  rpl += onerpl;
783  rpls -= onerpl;
784  entry.volume = entry.i.volNumber;
785  if (!ncp_fill_cache(filp, dirent, filldir, ctl, &entry, 0))
786  break;
787  }
788  } while (more);
789  vfree(buf);
790  return;
791 }
792 
794 {
795  struct ncp_server* server = NCP_SBP(sb);
796  int result;
797 
798  if (ncp_single_volume(server)) {
799  int len;
800  struct dentry* dent;
804  __u8 __name[NCP_MAXPATHLEN + 1];
805 
806  len = sizeof(__name);
807  result = ncp_io2vol(server, __name, &len, server->m.mounted_vol,
808  strlen(server->m.mounted_vol), 1);
809  if (result)
810  goto out;
811  result = -ENOENT;
812  if (ncp_get_volume_root(server, __name, &volNumber, &dirEntNum, &DosDirNum)) {
813  PPRINTK("ncp_conn_logged_in: %s not found\n",
814  server->m.mounted_vol);
815  goto out;
816  }
817  dent = sb->s_root;
818  if (dent) {
819  struct inode* ino = dent->d_inode;
820  if (ino) {
821  ncp_update_known_namespace(server, volNumber, NULL);
822  NCP_FINFO(ino)->volNumber = volNumber;
823  NCP_FINFO(ino)->dirEntNum = dirEntNum;
824  NCP_FINFO(ino)->DosDirNum = DosDirNum;
825  result = 0;
826  } else {
827  DPRINTK("ncpfs: sb->s_root->d_inode == NULL!\n");
828  }
829  } else {
830  DPRINTK("ncpfs: sb->s_root == NULL!\n");
831  }
832  } else
833  result = 0;
834 
835 out:
836  return result;
837 }
838 
839 static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
840 {
841  struct ncp_server *server = NCP_SERVER(dir);
842  struct inode *inode = NULL;
843  struct ncp_entry_info finfo;
844  int error, res, len;
845  __u8 __name[NCP_MAXPATHLEN + 1];
846 
847  error = -EIO;
848  if (!ncp_conn_valid(server))
849  goto finished;
850 
851  PPRINTK("ncp_lookup: server lookup for %s/%s\n",
852  dentry->d_parent->d_name.name, dentry->d_name.name);
853 
854  len = sizeof(__name);
855  if (ncp_is_server_root(dir)) {
856  res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
857  dentry->d_name.len, 1);
858  if (!res)
859  res = ncp_lookup_volume(server, __name, &(finfo.i));
860  if (!res)
861  ncp_update_known_namespace(server, finfo.i.volNumber, NULL);
862  } else {
863  res = ncp_io2vol(server, __name, &len, dentry->d_name.name,
864  dentry->d_name.len, !ncp_preserve_case(dir));
865  if (!res)
866  res = ncp_obtain_info(server, dir, __name, &(finfo.i));
867  }
868  PPRINTK("ncp_lookup: looked for %s/%s, res=%d\n",
869  dentry->d_parent->d_name.name, __name, res);
870  /*
871  * If we didn't find an entry, make a negative dentry.
872  */
873  if (res)
874  goto add_entry;
875 
876  /*
877  * Create an inode for the entry.
878  */
879  finfo.opened = 0;
880  finfo.ino = iunique(dir->i_sb, 2);
881  finfo.volume = finfo.i.volNumber;
882  error = -EACCES;
883  inode = ncp_iget(dir->i_sb, &finfo);
884 
885  if (inode) {
886  ncp_new_dentry(dentry);
887 add_entry:
888  d_add(dentry, inode);
889  error = 0;
890  }
891 
892 finished:
893  PPRINTK("ncp_lookup: result=%d\n", error);
894  return ERR_PTR(error);
895 }
896 
897 /*
898  * This code is common to create, mkdir, and mknod.
899  */
900 static int ncp_instantiate(struct inode *dir, struct dentry *dentry,
901  struct ncp_entry_info *finfo)
902 {
903  struct inode *inode;
904  int error = -EINVAL;
905 
906  finfo->ino = iunique(dir->i_sb, 2);
907  inode = ncp_iget(dir->i_sb, finfo);
908  if (!inode)
909  goto out_close;
910  d_instantiate(dentry,inode);
911  error = 0;
912 out:
913  return error;
914 
915 out_close:
916  PPRINTK("ncp_instantiate: %s/%s failed, closing file\n",
917  dentry->d_parent->d_name.name, dentry->d_name.name);
918  ncp_close_file(NCP_SERVER(dir), finfo->file_handle);
919  goto out;
920 }
921 
922 int ncp_create_new(struct inode *dir, struct dentry *dentry, umode_t mode,
924 {
925  struct ncp_server *server = NCP_SERVER(dir);
926  struct ncp_entry_info finfo;
927  int error, result, len;
928  int opmode;
929  __u8 __name[NCP_MAXPATHLEN + 1];
930 
931  PPRINTK("ncp_create_new: creating %s/%s, mode=%hx\n",
932  dentry->d_parent->d_name.name, dentry->d_name.name, mode);
933 
934  ncp_age_dentry(server, dentry);
935  len = sizeof(__name);
936  error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
937  dentry->d_name.len, !ncp_preserve_case(dir));
938  if (error)
939  goto out;
940 
941  error = -EACCES;
942 
943  if (S_ISREG(mode) &&
944  (server->m.flags & NCP_MOUNT_EXTRAS) &&
945  (mode & S_IXUGO))
946  attributes |= aSYSTEM | aSHARED;
947 
948  result = ncp_open_create_file_or_subdir(server, dir, __name,
950  attributes, AR_READ | AR_WRITE, &finfo);
951  opmode = O_RDWR;
952  if (result) {
953  result = ncp_open_create_file_or_subdir(server, dir, __name,
955  attributes, AR_WRITE, &finfo);
956  if (result) {
957  if (result == 0x87)
958  error = -ENAMETOOLONG;
959  else if (result < 0)
960  error = result;
961  DPRINTK("ncp_create: %s/%s failed\n",
962  dentry->d_parent->d_name.name, dentry->d_name.name);
963  goto out;
964  }
965  opmode = O_WRONLY;
966  }
967  finfo.access = opmode;
968  if (ncp_is_nfs_extras(server, finfo.volume)) {
969  finfo.i.nfs.mode = mode;
970  finfo.i.nfs.rdev = new_encode_dev(rdev);
971  if (ncp_modify_nfs_info(server, finfo.volume,
972  finfo.i.dirEntNum,
973  mode, new_encode_dev(rdev)) != 0)
974  goto out;
975  }
976 
977  error = ncp_instantiate(dir, dentry, &finfo);
978 out:
979  return error;
980 }
981 
982 static int ncp_create(struct inode *dir, struct dentry *dentry, umode_t mode,
983  bool excl)
984 {
985  return ncp_create_new(dir, dentry, mode, 0, 0);
986 }
987 
988 static int ncp_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
989 {
990  struct ncp_entry_info finfo;
991  struct ncp_server *server = NCP_SERVER(dir);
992  int error, len;
993  __u8 __name[NCP_MAXPATHLEN + 1];
994 
995  DPRINTK("ncp_mkdir: making %s/%s\n",
996  dentry->d_parent->d_name.name, dentry->d_name.name);
997 
998  ncp_age_dentry(server, dentry);
999  len = sizeof(__name);
1000  error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
1001  dentry->d_name.len, !ncp_preserve_case(dir));
1002  if (error)
1003  goto out;
1004 
1005  error = ncp_open_create_file_or_subdir(server, dir, __name,
1007  cpu_to_le16(0xffff),
1008  &finfo);
1009  if (error == 0) {
1010  if (ncp_is_nfs_extras(server, finfo.volume)) {
1011  mode |= S_IFDIR;
1012  finfo.i.nfs.mode = mode;
1013  if (ncp_modify_nfs_info(server,
1014  finfo.volume,
1015  finfo.i.dirEntNum,
1016  mode, 0) != 0)
1017  goto out;
1018  }
1019  error = ncp_instantiate(dir, dentry, &finfo);
1020  } else if (error > 0) {
1021  error = -EACCES;
1022  }
1023 out:
1024  return error;
1025 }
1026 
1027 static int ncp_rmdir(struct inode *dir, struct dentry *dentry)
1028 {
1029  struct ncp_server *server = NCP_SERVER(dir);
1030  int error, result, len;
1031  __u8 __name[NCP_MAXPATHLEN + 1];
1032 
1033  DPRINTK("ncp_rmdir: removing %s/%s\n",
1034  dentry->d_parent->d_name.name, dentry->d_name.name);
1035 
1036  /*
1037  * fail with EBUSY if there are still references to this
1038  * directory.
1039  */
1040  dentry_unhash(dentry);
1041  error = -EBUSY;
1042  if (!d_unhashed(dentry))
1043  goto out;
1044 
1045  len = sizeof(__name);
1046  error = ncp_io2vol(server, __name, &len, dentry->d_name.name,
1047  dentry->d_name.len, !ncp_preserve_case(dir));
1048  if (error)
1049  goto out;
1050 
1051  result = ncp_del_file_or_subdir(server, dir, __name);
1052  switch (result) {
1053  case 0x00:
1054  error = 0;
1055  break;
1056  case 0x85: /* unauthorized to delete file */
1057  case 0x8A: /* unauthorized to delete file */
1058  error = -EACCES;
1059  break;
1060  case 0x8F:
1061  case 0x90: /* read only */
1062  error = -EPERM;
1063  break;
1064  case 0x9F: /* in use by another client */
1065  error = -EBUSY;
1066  break;
1067  case 0xA0: /* directory not empty */
1068  error = -ENOTEMPTY;
1069  break;
1070  case 0xFF: /* someone deleted file */
1071  error = -ENOENT;
1072  break;
1073  default:
1074  error = result < 0 ? result : -EACCES;
1075  break;
1076  }
1077 out:
1078  return error;
1079 }
1080 
1081 static int ncp_unlink(struct inode *dir, struct dentry *dentry)
1082 {
1083  struct inode *inode = dentry->d_inode;
1084  struct ncp_server *server;
1085  int error;
1086 
1087  server = NCP_SERVER(dir);
1088  DPRINTK("ncp_unlink: unlinking %s/%s\n",
1089  dentry->d_parent->d_name.name, dentry->d_name.name);
1090 
1091  /*
1092  * Check whether to close the file ...
1093  */
1094  if (inode) {
1095  PPRINTK("ncp_unlink: closing file\n");
1096  ncp_make_closed(inode);
1097  }
1098 
1099  error = ncp_del_file_or_subdir2(server, dentry);
1100 #ifdef CONFIG_NCPFS_STRONG
1101  /* 9C is Invalid path.. It should be 8F, 90 - read only, but
1102  it is not :-( */
1103  if ((error == 0x9C || error == 0x90) && server->m.flags & NCP_MOUNT_STRONG) { /* R/O */
1104  error = ncp_force_unlink(dir, dentry);
1105  }
1106 #endif
1107  switch (error) {
1108  case 0x00:
1109  DPRINTK("ncp: removed %s/%s\n",
1110  dentry->d_parent->d_name.name, dentry->d_name.name);
1111  break;
1112  case 0x85:
1113  case 0x8A:
1114  error = -EACCES;
1115  break;
1116  case 0x8D: /* some files in use */
1117  case 0x8E: /* all files in use */
1118  error = -EBUSY;
1119  break;
1120  case 0x8F: /* some read only */
1121  case 0x90: /* all read only */
1122  case 0x9C: /* !!! returned when in-use or read-only by NW4 */
1123  error = -EPERM;
1124  break;
1125  case 0xFF:
1126  error = -ENOENT;
1127  break;
1128  default:
1129  error = error < 0 ? error : -EACCES;
1130  break;
1131  }
1132  return error;
1133 }
1134 
1135 static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry,
1136  struct inode *new_dir, struct dentry *new_dentry)
1137 {
1138  struct ncp_server *server = NCP_SERVER(old_dir);
1139  int error;
1140  int old_len, new_len;
1141  __u8 __old_name[NCP_MAXPATHLEN + 1], __new_name[NCP_MAXPATHLEN + 1];
1142 
1143  DPRINTK("ncp_rename: %s/%s to %s/%s\n",
1144  old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
1145  new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
1146 
1147  if (new_dentry->d_inode && S_ISDIR(new_dentry->d_inode->i_mode)) {
1148  /*
1149  * fail with EBUSY if there are still references to this
1150  * directory.
1151  */
1152  dentry_unhash(new_dentry);
1153  error = -EBUSY;
1154  if (!d_unhashed(new_dentry))
1155  goto out;
1156  }
1157 
1158  ncp_age_dentry(server, old_dentry);
1159  ncp_age_dentry(server, new_dentry);
1160 
1161  old_len = sizeof(__old_name);
1162  error = ncp_io2vol(server, __old_name, &old_len,
1163  old_dentry->d_name.name, old_dentry->d_name.len,
1164  !ncp_preserve_case(old_dir));
1165  if (error)
1166  goto out;
1167 
1168  new_len = sizeof(__new_name);
1169  error = ncp_io2vol(server, __new_name, &new_len,
1170  new_dentry->d_name.name, new_dentry->d_name.len,
1171  !ncp_preserve_case(new_dir));
1172  if (error)
1173  goto out;
1174 
1175  error = ncp_ren_or_mov_file_or_subdir(server, old_dir, __old_name,
1176  new_dir, __new_name);
1177 #ifdef CONFIG_NCPFS_STRONG
1178  if ((error == 0x90 || error == 0x8B || error == -EACCES) &&
1179  server->m.flags & NCP_MOUNT_STRONG) { /* RO */
1180  error = ncp_force_rename(old_dir, old_dentry, __old_name,
1181  new_dir, new_dentry, __new_name);
1182  }
1183 #endif
1184  switch (error) {
1185  case 0x00:
1186  DPRINTK("ncp renamed %s -> %s.\n",
1187  old_dentry->d_name.name,new_dentry->d_name.name);
1188  break;
1189  case 0x9E:
1190  error = -ENAMETOOLONG;
1191  break;
1192  case 0xFF:
1193  error = -ENOENT;
1194  break;
1195  default:
1196  error = error < 0 ? error : -EACCES;
1197  break;
1198  }
1199 out:
1200  return error;
1201 }
1202 
1203 static int ncp_mknod(struct inode * dir, struct dentry *dentry,
1204  umode_t mode, dev_t rdev)
1205 {
1206  if (!new_valid_dev(rdev))
1207  return -EINVAL;
1208  if (ncp_is_nfs_extras(NCP_SERVER(dir), NCP_FINFO(dir)->volNumber)) {
1209  DPRINTK(KERN_DEBUG "ncp_mknod: mode = 0%ho\n", mode);
1210  return ncp_create_new(dir, dentry, mode, rdev, 0);
1211  }
1212  return -EPERM; /* Strange, but true */
1213 }
1214 
1215 /* The following routines are taken directly from msdos-fs */
1216 
1217 /* Linear day numbers of the respective 1sts in non-leap years. */
1218 
1219 static int day_n[] =
1220 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0};
1221 /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
1222 
1223 
1224 extern struct timezone sys_tz;
1225 
1226 static int utc2local(int time)
1227 {
1228  return time - sys_tz.tz_minuteswest * 60;
1229 }
1230 
1231 static int local2utc(int time)
1232 {
1233  return time + sys_tz.tz_minuteswest * 60;
1234 }
1235 
1236 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
1237 int
1239 {
1240  unsigned short time = le16_to_cpu(t), date = le16_to_cpu(d);
1241  int month, year, secs;
1242 
1243  /* first subtract and mask after that... Otherwise, if
1244  date == 0, bad things happen */
1245  month = ((date >> 5) - 1) & 15;
1246  year = date >> 9;
1247  secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 +
1248  86400 * ((date & 31) - 1 + day_n[month] + (year / 4) +
1249  year * 365 - ((year & 3) == 0 && month < 2 ? 1 : 0) + 3653);
1250  /* days since 1.1.70 plus 80's leap day */
1251  return local2utc(secs);
1252 }
1253 
1254 
1255 /* Convert linear UNIX date to a MS-DOS time/date pair. */
1256 void
1258 {
1259  int day, year, nl_day, month;
1260 
1261  unix_date = utc2local(unix_date);
1262  *time = cpu_to_le16(
1263  (unix_date % 60) / 2 + (((unix_date / 60) % 60) << 5) +
1264  (((unix_date / 3600) % 24) << 11));
1265  day = unix_date / 86400 - 3652;
1266  year = day / 365;
1267  if ((year + 3) / 4 + 365 * year > day)
1268  year--;
1269  day -= (year + 3) / 4 + 365 * year;
1270  if (day == 59 && !(year & 3)) {
1271  nl_day = day;
1272  month = 2;
1273  } else {
1274  nl_day = (year & 3) || day <= 59 ? day : day - 1;
1275  for (month = 1; month < 12; month++)
1276  if (day_n[month] > nl_day)
1277  break;
1278  }
1279  *date = cpu_to_le16(nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9));
1280 }