dir.c 31 KB

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