dir.c 31 KB

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