dir.c 31 KB

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