dir.c 31 KB

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