namei.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:15k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/fs/hpfs/namei.c
  3.  *
  4.  *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
  5.  *
  6.  *  adding & removing files & directories
  7.  */
  8. #include <linux/string.h>
  9. #include "hpfs_fn.h"
  10. int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
  11. {
  12. const char *name = dentry->d_name.name;
  13. unsigned len = dentry->d_name.len;
  14. struct quad_buffer_head qbh0;
  15. struct buffer_head *bh;
  16. struct hpfs_dirent *de;
  17. struct fnode *fnode;
  18. struct dnode *dnode;
  19. struct inode *result;
  20. fnode_secno fno;
  21. dnode_secno dno;
  22. int r;
  23. struct hpfs_dirent dee;
  24. int err;
  25. if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
  26. if (!(fnode = hpfs_alloc_fnode(dir->i_sb, dir->i_hpfs_dno, &fno, &bh))) goto bail;
  27. if (!(dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0, 1))) goto bail1;
  28. memset(&dee, 0, sizeof dee);
  29. dee.directory = 1;
  30. if (!(mode & 0222)) dee.read_only = 1;
  31. /*dee.archive = 0;*/
  32. dee.hidden = name[0] == '.';
  33. dee.fnode = fno;
  34. dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, CURRENT_TIME);
  35. hpfs_lock_inode(dir);
  36. r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
  37. if (r == 1) goto bail2;
  38. if (r == -1) {
  39. brelse(bh);
  40. hpfs_brelse4(&qbh0);
  41. hpfs_free_sectors(dir->i_sb, fno, 1);
  42. hpfs_free_dnode(dir->i_sb, dno);
  43. hpfs_unlock_inode(dir);
  44. return -EEXIST;
  45. }
  46. fnode->len = len;
  47. memcpy(fnode->name, name, len > 15 ? 15 : len);
  48. fnode->up = dir->i_ino;
  49. fnode->dirflag = 1;
  50. fnode->btree.n_free_nodes = 7;
  51. fnode->btree.n_used_nodes = 1;
  52. fnode->btree.first_free = 0x14;
  53. fnode->u.external[0].disk_secno = dno;
  54. fnode->u.external[0].file_secno = -1;
  55. dnode->root_dnode = 1;
  56. dnode->up = fno;
  57. de = hpfs_add_de(dir->i_sb, dnode, "0101", 2, 0);
  58. de->creation_date = de->write_date = de->read_date = gmt_to_local(dir->i_sb, CURRENT_TIME);
  59. if (!(mode & 0222)) de->read_only = 1;
  60. de->first = de->directory = 1;
  61. /*de->hidden = de->system = 0;*/
  62. de->fnode = fno;
  63. mark_buffer_dirty(bh);
  64. brelse(bh);
  65. hpfs_mark_4buffers_dirty(&qbh0);
  66. hpfs_brelse4(&qbh0);
  67. dir->i_nlink++;
  68. hpfs_lock_iget(dir->i_sb, 1);
  69. if ((result = iget(dir->i_sb, fno))) {
  70. result->i_hpfs_parent_dir = dir->i_ino;
  71. result->i_ctime = result->i_mtime = result->i_atime = local_to_gmt(dir->i_sb, dee.creation_date);
  72. result->i_hpfs_ea_size = 0;
  73. if (dee.read_only) result->i_mode &= ~0222;
  74. if (result->i_uid != current->fsuid ||
  75.     result->i_gid != current->fsgid ||
  76.     result->i_mode != (mode | S_IFDIR)) {
  77. result->i_uid = current->fsuid;
  78. result->i_gid = current->fsgid;
  79. result->i_mode = mode | S_IFDIR;
  80. hpfs_write_inode_nolock(result);
  81. }
  82. d_instantiate(dentry, result);
  83. }
  84. hpfs_unlock_iget(dir->i_sb);
  85. hpfs_unlock_inode(dir);
  86. return 0;
  87. bail2:
  88. hpfs_brelse4(&qbh0);
  89. hpfs_free_dnode(dir->i_sb, dno);
  90. hpfs_unlock_inode(dir);
  91. bail1:
  92. brelse(bh);
  93. hpfs_free_sectors(dir->i_sb, fno, 1);
  94. bail:
  95. return -ENOSPC;
  96. }
  97. int hpfs_create(struct inode *dir, struct dentry *dentry, int mode)
  98. {
  99. const char *name = dentry->d_name.name;
  100. unsigned len = dentry->d_name.len;
  101. struct inode *result = NULL;
  102. struct buffer_head *bh;
  103. struct fnode *fnode;
  104. fnode_secno fno;
  105. int r;
  106. struct hpfs_dirent dee;
  107. int err;
  108. if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
  109. if (!(fnode = hpfs_alloc_fnode(dir->i_sb, dir->i_hpfs_dno, &fno, &bh))) goto bail;
  110. memset(&dee, 0, sizeof dee);
  111. if (!(mode & 0222)) dee.read_only = 1;
  112. dee.archive = 1;
  113. dee.hidden = name[0] == '.';
  114. dee.fnode = fno;
  115. dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, CURRENT_TIME);
  116. hpfs_lock_inode(dir);
  117. r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
  118. if (r == 1) goto bail1;
  119. if (r == -1) {
  120. brelse(bh);
  121. hpfs_free_sectors(dir->i_sb, fno, 1);
  122. hpfs_unlock_inode(dir);
  123. return -EEXIST;
  124. }
  125. fnode->len = len;
  126. memcpy(fnode->name, name, len > 15 ? 15 : len);
  127. fnode->up = dir->i_ino;
  128. mark_buffer_dirty(bh);
  129. brelse(bh);
  130. hpfs_lock_iget(dir->i_sb, 2);
  131. if ((result = iget(dir->i_sb, fno))) {
  132. hpfs_decide_conv(result, (char *)name, len);
  133. result->i_hpfs_parent_dir = dir->i_ino;
  134. result->i_ctime = result->i_mtime = result->i_atime = local_to_gmt(dir->i_sb, dee.creation_date);
  135. result->i_hpfs_ea_size = 0;
  136. if (dee.read_only) result->i_mode &= ~0222;
  137. if (result->i_blocks == -1) result->i_blocks = 1;
  138. if (result->i_size == -1) {
  139. result->i_size = 0;
  140. result->i_data.a_ops = &hpfs_aops;
  141. result->u.hpfs_i.mmu_private = 0;
  142. }
  143. if (result->i_uid != current->fsuid ||
  144.     result->i_gid != current->fsgid ||
  145.     result->i_mode != (mode | S_IFREG)) {
  146. result->i_uid = current->fsuid;
  147. result->i_gid = current->fsgid;
  148. result->i_mode = mode | S_IFREG;
  149. hpfs_write_inode_nolock(result);
  150. }
  151. d_instantiate(dentry, result);
  152. }
  153. hpfs_unlock_iget(dir->i_sb);
  154. hpfs_unlock_inode(dir);
  155. return 0;
  156. bail1:
  157. brelse(bh);
  158. hpfs_free_sectors(dir->i_sb, fno, 1);
  159. hpfs_unlock_inode(dir);
  160. bail:
  161. return -ENOSPC;
  162. }
  163. int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
  164. {
  165. const char *name = dentry->d_name.name;
  166. unsigned len = dentry->d_name.len;
  167. struct buffer_head *bh;
  168. struct fnode *fnode;
  169. fnode_secno fno;
  170. int r;
  171. struct hpfs_dirent dee;
  172. struct inode *result = NULL;
  173. int err;
  174. if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
  175. if (dir->i_sb->s_hpfs_eas < 2) return -EPERM;
  176. if (!(fnode = hpfs_alloc_fnode(dir->i_sb, dir->i_hpfs_dno, &fno, &bh))) goto bail;
  177. memset(&dee, 0, sizeof dee);
  178. if (!(mode & 0222)) dee.read_only = 1;
  179. dee.archive = 1;
  180. dee.hidden = name[0] == '.';
  181. dee.fnode = fno;
  182. dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, CURRENT_TIME);
  183. hpfs_lock_inode(dir);
  184. r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
  185. if (r == 1) goto bail1;
  186. if (r == -1) {
  187. brelse(bh);
  188. hpfs_free_sectors(dir->i_sb, fno, 1);
  189. hpfs_unlock_inode(dir);
  190. return -EEXIST;
  191. }
  192. fnode->len = len;
  193. memcpy(fnode->name, name, len > 15 ? 15 : len);
  194. fnode->up = dir->i_ino;
  195. mark_buffer_dirty(bh);
  196. hpfs_lock_iget(dir->i_sb, 2);
  197. if ((result = iget(dir->i_sb, fno))) {
  198. result->i_hpfs_parent_dir = dir->i_ino;
  199. result->i_ctime = result->i_mtime = result->i_atime = local_to_gmt(dir->i_sb, dee.creation_date);
  200. result->i_hpfs_ea_size = 0;
  201. /*if (result->i_blocks == -1) result->i_blocks = 1;
  202. if (result->i_size == -1) result->i_size = 0;*/
  203. result->i_uid = current->fsuid;
  204. result->i_gid = current->fsgid;
  205. result->i_nlink = 1;
  206. result->i_size = 0;
  207. result->i_blocks = 1;
  208. init_special_inode(result, mode, rdev);
  209. hpfs_write_inode_nolock(result);
  210. d_instantiate(dentry, result);
  211. }
  212. hpfs_unlock_iget(dir->i_sb);
  213. hpfs_unlock_inode(dir);
  214. brelse(bh);
  215. return 0;
  216. bail1:
  217. brelse(bh);
  218. hpfs_free_sectors(dir->i_sb, fno, 1);
  219. hpfs_unlock_inode(dir);
  220. bail:
  221. return -ENOSPC;
  222. }
  223. extern struct address_space_operations hpfs_symlink_aops;
  224. int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *symlink)
  225. {
  226. const char *name = dentry->d_name.name;
  227. unsigned len = dentry->d_name.len;
  228. struct buffer_head *bh;
  229. struct fnode *fnode;
  230. fnode_secno fno;
  231. int r;
  232. struct hpfs_dirent dee;
  233. struct inode *result;
  234. int err;
  235. if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
  236. if (dir->i_sb->s_hpfs_eas < 2) return -EPERM;
  237. if (!(fnode = hpfs_alloc_fnode(dir->i_sb, dir->i_hpfs_dno, &fno, &bh))) goto bail;
  238. memset(&dee, 0, sizeof dee);
  239. dee.archive = 1;
  240. dee.hidden = name[0] == '.';
  241. dee.fnode = fno;
  242. dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, CURRENT_TIME);
  243. hpfs_lock_inode(dir);
  244. r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
  245. if (r == 1) goto bail1;
  246. if (r == -1) {
  247. brelse(bh);
  248. hpfs_free_sectors(dir->i_sb, fno, 1);
  249. hpfs_unlock_inode(dir);
  250. return -EEXIST;
  251. }
  252. fnode->len = len;
  253. memcpy(fnode->name, name, len > 15 ? 15 : len);
  254. fnode->up = dir->i_ino;
  255. mark_buffer_dirty(bh);
  256. brelse(bh);
  257. hpfs_lock_iget(dir->i_sb, 2);
  258. if ((result = iget(dir->i_sb, fno))) {
  259. result->i_hpfs_parent_dir = dir->i_ino;
  260. result->i_ctime = result->i_mtime = result->i_atime = local_to_gmt(dir->i_sb, dee.creation_date);
  261. result->i_hpfs_ea_size = 0;
  262. /*if (result->i_blocks == -1) result->i_blocks = 1;
  263. if (result->i_size == -1) result->i_size = 0;*/
  264. result->i_mode = S_IFLNK | 0777;
  265. result->i_uid = current->fsuid;
  266. result->i_gid = current->fsgid;
  267. result->i_blocks = 1;
  268. result->i_size = strlen(symlink);
  269. result->i_op = &page_symlink_inode_operations;
  270. result->i_data.a_ops = &hpfs_symlink_aops;
  271. if ((fnode = hpfs_map_fnode(dir->i_sb, fno, &bh))) {
  272. hpfs_set_ea(result, fnode, "SYMLINK", (char *)symlink, strlen(symlink));
  273. mark_buffer_dirty(bh);
  274. brelse(bh);
  275. }
  276. hpfs_write_inode_nolock(result);
  277. d_instantiate(dentry, result);
  278. }
  279. hpfs_unlock_iget(dir->i_sb);
  280. hpfs_unlock_inode(dir);
  281. return 0;
  282. bail1:
  283. brelse(bh);
  284. hpfs_free_sectors(dir->i_sb, fno, 1);
  285. hpfs_unlock_inode(dir);
  286. bail:
  287. return -ENOSPC;
  288. }
  289. int hpfs_unlink(struct inode *dir, struct dentry *dentry)
  290. {
  291. const char *name = dentry->d_name.name;
  292. unsigned len = dentry->d_name.len;
  293. struct quad_buffer_head qbh;
  294. struct hpfs_dirent *de;
  295. struct inode *inode = dentry->d_inode;
  296. dnode_secno dno;
  297. fnode_secno fno;
  298. int r;
  299. int rep = 0;
  300. hpfs_adjust_length((char *)name, &len);
  301. again:
  302. hpfs_lock_2inodes(dir, inode);
  303. if (!(de = map_dirent(dir, dir->i_hpfs_dno, (char *)name, len, &dno, &qbh))) {
  304. hpfs_unlock_2inodes(dir, inode);
  305. return -ENOENT;
  306. }
  307. if (de->first) {
  308. hpfs_brelse4(&qbh);
  309. hpfs_unlock_2inodes(dir, inode);
  310. return -EPERM;
  311. }
  312. if (de->directory) {
  313. hpfs_brelse4(&qbh);
  314. hpfs_unlock_2inodes(dir, inode);
  315. return -EISDIR;
  316. }
  317. fno = de->fnode;
  318. if ((r = hpfs_remove_dirent(dir, dno, de, &qbh, 1)) == 1) hpfs_error(dir->i_sb, "there was error when removing dirent");
  319. if (r != 2) {
  320. inode->i_nlink--;
  321. hpfs_unlock_2inodes(dir, inode);
  322. } else { /* no space for deleting, try to truncate file */
  323. struct iattr newattrs;
  324. int err;
  325. hpfs_unlock_2inodes(dir, inode);
  326. if (rep)
  327. goto ret;
  328. d_drop(dentry);
  329. if (atomic_read(&dentry->d_count) > 1 ||
  330.     permission(inode, MAY_WRITE) ||
  331.     get_write_access(inode)) {
  332. d_rehash(dentry);
  333. goto ret;
  334. }
  335. /*printk("HPFS: truncating file before delete.n");*/
  336. down(&inode->i_sem);
  337. newattrs.ia_size = 0;
  338. newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
  339. err = notify_change(dentry, &newattrs);
  340. up(&inode->i_sem);
  341. put_write_access(inode);
  342. if (err)
  343. goto ret;
  344. rep = 1;
  345. goto again;
  346. }
  347. ret:
  348. return r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
  349. }
  350. int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
  351. {
  352. const char *name = dentry->d_name.name;
  353. unsigned len = dentry->d_name.len;
  354. struct quad_buffer_head qbh;
  355. struct hpfs_dirent *de;
  356. struct inode *inode = dentry->d_inode;
  357. dnode_secno dno;
  358. fnode_secno fno;
  359. int n_items = 0;
  360. int r;
  361. hpfs_adjust_length((char *)name, &len);
  362. hpfs_lock_2inodes(dir, inode);
  363. if (!(de = map_dirent(dir, dir->i_hpfs_dno, (char *)name, len, &dno, &qbh))) {
  364. hpfs_unlock_2inodes(dir, inode);
  365. return -ENOENT;
  366. }
  367. if (de->first) {
  368. hpfs_brelse4(&qbh);
  369. hpfs_unlock_2inodes(dir, inode);
  370. return -EPERM;
  371. }
  372. if (!de->directory) {
  373. hpfs_brelse4(&qbh);
  374. hpfs_unlock_2inodes(dir, inode);
  375. return -ENOTDIR;
  376. }
  377. hpfs_count_dnodes(dir->i_sb, inode->i_hpfs_dno, NULL, NULL, &n_items);
  378. if (n_items) {
  379. hpfs_brelse4(&qbh);
  380. hpfs_unlock_2inodes(dir, inode);
  381. return -ENOTEMPTY;
  382. }
  383. fno = de->fnode;
  384. if ((r = hpfs_remove_dirent(dir, dno, de, &qbh, 1)) == 1)
  385. hpfs_error(dir->i_sb, "there was error when removing dirent");
  386. if (r != 2) {
  387. dir->i_nlink--;
  388. inode->i_nlink = 0;
  389. hpfs_unlock_2inodes(dir, inode);
  390. } else hpfs_unlock_2inodes(dir, inode);
  391. return r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
  392. }
  393. int hpfs_symlink_readpage(struct file *file, struct page *page)
  394. {
  395. char *link = kmap(page);
  396. struct inode *i = page->mapping->host;
  397. struct fnode *fnode;
  398. struct buffer_head *bh;
  399. int err;
  400. err = -EIO;
  401. lock_kernel();
  402. if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh)))
  403. goto fail;
  404. err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE);
  405. brelse(bh);
  406. if (err)
  407. goto fail;
  408. unlock_kernel();
  409. SetPageUptodate(page);
  410. kunmap(page);
  411. UnlockPage(page);
  412. return 0;
  413. fail:
  414. unlock_kernel();
  415. SetPageError(page);
  416. kunmap(page);
  417. UnlockPage(page);
  418. return err;
  419. }
  420. int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
  421. struct inode *new_dir, struct dentry *new_dentry)
  422. {
  423. char *old_name = (char *)old_dentry->d_name.name;
  424. int old_len = old_dentry->d_name.len;
  425. char *new_name = (char *)new_dentry->d_name.name;
  426. int new_len = new_dentry->d_name.len;
  427. struct inode *i = old_dentry->d_inode;
  428. struct inode *new_inode = new_dentry->d_inode;
  429. struct quad_buffer_head qbh, qbh1;
  430. struct hpfs_dirent *dep, *nde;
  431. struct hpfs_dirent de;
  432. dnode_secno dno;
  433. int r;
  434. struct buffer_head *bh;
  435. struct fnode *fnode;
  436. int err;
  437. if ((err = hpfs_chk_name((char *)new_name, &new_len))) return err;
  438. err = 0;
  439. hpfs_adjust_length((char *)old_name, &old_len);
  440. hpfs_lock_3inodes(old_dir, new_dir, i);
  441. /* Erm? Moving over the empty non-busy directory is perfectly legal */
  442. if (new_inode && S_ISDIR(new_inode->i_mode)) {
  443. err = -EINVAL;
  444. goto end1;
  445. }
  446. if (!(dep = map_dirent(old_dir, old_dir->i_hpfs_dno, (char *)old_name, old_len, &dno, &qbh))) {
  447. hpfs_error(i->i_sb, "lookup succeeded but map dirent failed");
  448. err = -ENOENT;
  449. goto end1;
  450. }
  451. copy_de(&de, dep);
  452. de.hidden = new_name[0] == '.';
  453. if (new_inode) {
  454. int r;
  455. if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) {
  456. if ((nde = map_dirent(new_dir, new_dir->i_hpfs_dno, (char *)new_name, new_len, NULL, &qbh1))) {
  457. new_inode->i_nlink = 0;
  458. copy_de(nde, &de);
  459. memcpy(nde->name, new_name, new_len);
  460. hpfs_mark_4buffers_dirty(&qbh1);
  461. hpfs_brelse4(&qbh1);
  462. goto end;
  463. }
  464. hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent");
  465. err = -EFSERROR;
  466. goto end1;
  467. }
  468. err = r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
  469. goto end1;
  470. }
  471. if (new_dir == old_dir) hpfs_brelse4(&qbh);
  472. hpfs_lock_creation(i->i_sb);
  473. if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de, 1))) {
  474. hpfs_unlock_creation(i->i_sb);
  475. if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!");
  476. err = r == 1 ? -ENOSPC : -EFSERROR;
  477. if (new_dir != old_dir) hpfs_brelse4(&qbh);
  478. goto end1;
  479. }
  480. if (new_dir == old_dir)
  481. if (!(dep = map_dirent(old_dir, old_dir->i_hpfs_dno, (char *)old_name, old_len, &dno, &qbh))) {
  482. hpfs_unlock_creation(i->i_sb);
  483. hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2");
  484. err = -ENOENT;
  485. goto end1;
  486. }
  487. if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) {
  488. hpfs_unlock_creation(i->i_sb);
  489. hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent");
  490. err = r == 2 ? -ENOSPC : -EFSERROR;
  491. goto end1;
  492. }
  493. hpfs_unlock_creation(i->i_sb);
  494. end:
  495. i->i_hpfs_parent_dir = new_dir->i_ino;
  496. if (S_ISDIR(i->i_mode)) {
  497. new_dir->i_nlink++;
  498. old_dir->i_nlink--;
  499. }
  500. if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) {
  501. fnode->up = new_dir->i_ino;
  502. fnode->len = new_len;
  503. memcpy(fnode->name, new_name, new_len>15?15:new_len);
  504. if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len);
  505. mark_buffer_dirty(bh);
  506. brelse(bh);
  507. }
  508. i->i_hpfs_conv = i->i_sb->s_hpfs_conv;
  509. hpfs_decide_conv(i, (char *)new_name, new_len);
  510. end1:
  511. hpfs_unlock_3inodes(old_dir, new_dir, i);
  512. return err;
  513. }