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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/fs/ext2/dir.c
  3.  *
  4.  * Copyright (C) 1992, 1993, 1994, 1995
  5.  * Remy Card (card@masi.ibp.fr)
  6.  * Laboratoire MASI - Institut Blaise Pascal
  7.  * Universite Pierre et Marie Curie (Paris VI)
  8.  *
  9.  *  from
  10.  *
  11.  *  linux/fs/minix/dir.c
  12.  *
  13.  *  Copyright (C) 1991, 1992  Linus Torvalds
  14.  *
  15.  *  ext2 directory handling functions
  16.  *
  17.  *  Big-endian to little-endian byte-swapping/bitmaps by
  18.  *        David S. Miller (davem@caip.rutgers.edu), 1995
  19.  *
  20.  * All code that works with directory layout had been switched to pagecache
  21.  * and moved here. AV
  22.  */
  23. #include <linux/fs.h>
  24. #include <linux/ext2_fs.h>
  25. #include <linux/pagemap.h>
  26. typedef struct ext2_dir_entry_2 ext2_dirent;
  27. /*
  28.  * ext2 uses block-sized chunks. Arguably, sector-sized ones would be
  29.  * more robust, but we have what we have
  30.  */
  31. static inline unsigned ext2_chunk_size(struct inode *inode)
  32. {
  33. return inode->i_sb->s_blocksize;
  34. }
  35. static inline void ext2_put_page(struct page *page)
  36. {
  37. kunmap(page);
  38. page_cache_release(page);
  39. }
  40. static inline unsigned long dir_pages(struct inode *inode)
  41. {
  42. return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
  43. }
  44. static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to)
  45. {
  46. struct inode *dir = page->mapping->host;
  47. int err = 0;
  48. dir->i_version = ++event;
  49. page->mapping->a_ops->commit_write(NULL, page, from, to);
  50. if (IS_SYNC(dir)) {
  51. int err2;
  52. err = writeout_one_page(page);
  53. err2 = waitfor_one_page(page);
  54. if (err == 0)
  55. err = err2;
  56. }
  57. return err;
  58. }
  59. static void ext2_check_page(struct page *page)
  60. {
  61. struct inode *dir = page->mapping->host;
  62. struct super_block *sb = dir->i_sb;
  63. unsigned chunk_size = ext2_chunk_size(dir);
  64. char *kaddr = page_address(page);
  65. u32 max_inumber = le32_to_cpu(sb->u.ext2_sb.s_es->s_inodes_count);
  66. unsigned offs, rec_len;
  67. unsigned limit = PAGE_CACHE_SIZE;
  68. ext2_dirent *p;
  69. char *error;
  70. if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) {
  71. limit = dir->i_size & ~PAGE_CACHE_MASK;
  72. if (limit & (chunk_size - 1))
  73. goto Ebadsize;
  74. for (offs = limit; offs<PAGE_CACHE_SIZE; offs += chunk_size) {
  75. ext2_dirent *p = (ext2_dirent*)(kaddr + offs);
  76. p->rec_len = cpu_to_le16(chunk_size);
  77. }
  78. if (!limit)
  79. goto out;
  80. }
  81. for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) {
  82. p = (ext2_dirent *)(kaddr + offs);
  83. rec_len = le16_to_cpu(p->rec_len);
  84. if (rec_len < EXT2_DIR_REC_LEN(1))
  85. goto Eshort;
  86. if (rec_len & 3)
  87. goto Ealign;
  88. if (rec_len < EXT2_DIR_REC_LEN(p->name_len))
  89. goto Enamelen;
  90. if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1))
  91. goto Espan;
  92. if (le32_to_cpu(p->inode) > max_inumber)
  93. goto Einumber;
  94. }
  95. if (offs != limit)
  96. goto Eend;
  97. out:
  98. SetPageChecked(page);
  99. return;
  100. /* Too bad, we had an error */
  101. Ebadsize:
  102. ext2_error(sb, "ext2_check_page",
  103. "size of directory #%lu is not a multiple of chunk size",
  104. dir->i_ino
  105. );
  106. goto fail;
  107. Eshort:
  108. error = "rec_len is smaller than minimal";
  109. goto bad_entry;
  110. Ealign:
  111. error = "unaligned directory entry";
  112. goto bad_entry;
  113. Enamelen:
  114. error = "rec_len is too small for name_len";
  115. goto bad_entry;
  116. Espan:
  117. error = "directory entry across blocks";
  118. goto bad_entry;
  119. Einumber:
  120. error = "inode out of bounds";
  121. bad_entry:
  122. ext2_error (sb, "ext2_check_page", "bad entry in directory #%lu: %s - "
  123. "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
  124. dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
  125. (unsigned long) le32_to_cpu(p->inode),
  126. rec_len, p->name_len);
  127. goto fail;
  128. Eend:
  129. p = (ext2_dirent *)(kaddr + offs);
  130. ext2_error (sb, "ext2_check_page",
  131. "entry in directory #%lu spans the page boundary"
  132. "offset=%lu, inode=%lu",
  133. dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
  134. (unsigned long) le32_to_cpu(p->inode));
  135. fail:
  136. SetPageChecked(page);
  137. SetPageError(page);
  138. }
  139. static struct page * ext2_get_page(struct inode *dir, unsigned long n)
  140. {
  141. struct address_space *mapping = dir->i_mapping;
  142. struct page *page = read_cache_page(mapping, n,
  143. (filler_t*)mapping->a_ops->readpage, NULL);
  144. if (!IS_ERR(page)) {
  145. wait_on_page(page);
  146. kmap(page);
  147. if (!Page_Uptodate(page))
  148. goto fail;
  149. if (!PageChecked(page))
  150. ext2_check_page(page);
  151. if (PageError(page))
  152. goto fail;
  153. }
  154. return page;
  155. fail:
  156. ext2_put_page(page);
  157. return ERR_PTR(-EIO);
  158. }
  159. /*
  160.  * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
  161.  *
  162.  * len <= EXT2_NAME_LEN and de != NULL are guaranteed by caller.
  163.  */
  164. static inline int ext2_match (int len, const char * const name,
  165. struct ext2_dir_entry_2 * de)
  166. {
  167. if (len != de->name_len)
  168. return 0;
  169. if (!de->inode)
  170. return 0;
  171. return !memcmp(name, de->name, len);
  172. }
  173. /*
  174.  * p is at least 6 bytes before the end of page
  175.  */
  176. static inline ext2_dirent *ext2_next_entry(ext2_dirent *p)
  177. {
  178. return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len));
  179. }
  180. static inline unsigned 
  181. ext2_validate_entry(char *base, unsigned offset, unsigned mask)
  182. {
  183. ext2_dirent *de = (ext2_dirent*)(base + offset);
  184. ext2_dirent *p = (ext2_dirent*)(base + (offset&mask));
  185. while ((char*)p < (char*)de)
  186. p = ext2_next_entry(p);
  187. return (char *)p - base;
  188. }
  189. static unsigned char ext2_filetype_table[EXT2_FT_MAX] = {
  190. [EXT2_FT_UNKNOWN] DT_UNKNOWN,
  191. [EXT2_FT_REG_FILE] DT_REG,
  192. [EXT2_FT_DIR] DT_DIR,
  193. [EXT2_FT_CHRDEV] DT_CHR,
  194. [EXT2_FT_BLKDEV] DT_BLK,
  195. [EXT2_FT_FIFO] DT_FIFO,
  196. [EXT2_FT_SOCK] DT_SOCK,
  197. [EXT2_FT_SYMLINK] DT_LNK,
  198. };
  199. #define S_SHIFT 12
  200. static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = {
  201. [S_IFREG >> S_SHIFT] EXT2_FT_REG_FILE,
  202. [S_IFDIR >> S_SHIFT] EXT2_FT_DIR,
  203. [S_IFCHR >> S_SHIFT] EXT2_FT_CHRDEV,
  204. [S_IFBLK >> S_SHIFT] EXT2_FT_BLKDEV,
  205. [S_IFIFO >> S_SHIFT] EXT2_FT_FIFO,
  206. [S_IFSOCK >> S_SHIFT] EXT2_FT_SOCK,
  207. [S_IFLNK >> S_SHIFT] EXT2_FT_SYMLINK,
  208. };
  209. static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode)
  210. {
  211. mode_t mode = inode->i_mode;
  212. if (EXT2_HAS_INCOMPAT_FEATURE(inode->i_sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
  213. de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
  214. else
  215. de->file_type = 0;
  216. }
  217. static int
  218. ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
  219. {
  220. loff_t pos = filp->f_pos;
  221. struct inode *inode = filp->f_dentry->d_inode;
  222. struct super_block *sb = inode->i_sb;
  223. unsigned offset = pos & ~PAGE_CACHE_MASK;
  224. unsigned long n = pos >> PAGE_CACHE_SHIFT;
  225. unsigned long npages = dir_pages(inode);
  226. unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
  227. unsigned char *types = NULL;
  228. int need_revalidate = (filp->f_version != inode->i_version);
  229. if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
  230. goto done;
  231. if (EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
  232. types = ext2_filetype_table;
  233. for ( ; n < npages; n++, offset = 0) {
  234. char *kaddr, *limit;
  235. ext2_dirent *de;
  236. struct page *page = ext2_get_page(inode, n);
  237. if (IS_ERR(page))
  238. continue;
  239. kaddr = page_address(page);
  240. if (need_revalidate) {
  241. offset = ext2_validate_entry(kaddr, offset, chunk_mask);
  242. need_revalidate = 0;
  243. }
  244. de = (ext2_dirent *)(kaddr+offset);
  245. limit = kaddr + PAGE_CACHE_SIZE - EXT2_DIR_REC_LEN(1);
  246. for ( ;(char*)de <= limit; de = ext2_next_entry(de))
  247. if (de->inode) {
  248. int over;
  249. unsigned char d_type = DT_UNKNOWN;
  250. if (types && de->file_type < EXT2_FT_MAX)
  251. d_type = types[de->file_type];
  252. offset = (char *)de - kaddr;
  253. over = filldir(dirent, de->name, de->name_len,
  254. (n<<PAGE_CACHE_SHIFT) | offset,
  255. le32_to_cpu(de->inode), d_type);
  256. if (over) {
  257. ext2_put_page(page);
  258. goto done;
  259. }
  260. }
  261. ext2_put_page(page);
  262. }
  263. done:
  264. filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
  265. filp->f_version = inode->i_version;
  266. UPDATE_ATIME(inode);
  267. return 0;
  268. }
  269. /*
  270.  * ext2_find_entry()
  271.  *
  272.  * finds an entry in the specified directory with the wanted name. It
  273.  * returns the page in which the entry was found, and the entry itself
  274.  * (as a parameter - res_dir). Page is returned mapped and unlocked.
  275.  * Entry is guaranteed to be valid.
  276.  */
  277. struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
  278. struct dentry *dentry, struct page ** res_page)
  279. {
  280. const char *name = dentry->d_name.name;
  281. int namelen = dentry->d_name.len;
  282. unsigned reclen = EXT2_DIR_REC_LEN(namelen);
  283. unsigned long start, n;
  284. unsigned long npages = dir_pages(dir);
  285. struct page *page = NULL;
  286. ext2_dirent * de;
  287. /* OFFSET_CACHE */
  288. *res_page = NULL;
  289. start = dir->u.ext2_i.i_dir_start_lookup;
  290. if (start >= npages)
  291. start = 0;
  292. n = start;
  293. do {
  294. char *kaddr;
  295. page = ext2_get_page(dir, n);
  296. if (!IS_ERR(page)) {
  297. kaddr = page_address(page);
  298. de = (ext2_dirent *) kaddr;
  299. kaddr += PAGE_CACHE_SIZE - reclen;
  300. while ((char *) de <= kaddr) {
  301. if (ext2_match (namelen, name, de))
  302. goto found;
  303. de = ext2_next_entry(de);
  304. }
  305. ext2_put_page(page);
  306. }
  307. if (++n >= npages)
  308. n = 0;
  309. } while (n != start);
  310. return NULL;
  311. found:
  312. *res_page = page;
  313. dir->u.ext2_i.i_dir_start_lookup = n;
  314. return de;
  315. }
  316. struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
  317. {
  318. struct page *page = ext2_get_page(dir, 0);
  319. ext2_dirent *de = NULL;
  320. if (!IS_ERR(page)) {
  321. de = ext2_next_entry((ext2_dirent *) page_address(page));
  322. *p = page;
  323. }
  324. return de;
  325. }
  326. ino_t ext2_inode_by_name(struct inode * dir, struct dentry *dentry)
  327. {
  328. ino_t res = 0;
  329. struct ext2_dir_entry_2 * de;
  330. struct page *page;
  331. de = ext2_find_entry (dir, dentry, &page);
  332. if (de) {
  333. res = le32_to_cpu(de->inode);
  334. kunmap(page);
  335. page_cache_release(page);
  336. }
  337. return res;
  338. }
  339. /* Releases the page */
  340. void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
  341. struct page *page, struct inode *inode)
  342. {
  343. unsigned from = (char *) de - (char *) page_address(page);
  344. unsigned to = from + le16_to_cpu(de->rec_len);
  345. int err;
  346. lock_page(page);
  347. err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
  348. if (err)
  349. BUG();
  350. de->inode = cpu_to_le32(inode->i_ino);
  351. ext2_set_de_type (de, inode);
  352. err = ext2_commit_chunk(page, from, to);
  353. UnlockPage(page);
  354. ext2_put_page(page);
  355. dir->i_mtime = dir->i_ctime = CURRENT_TIME;
  356. mark_inode_dirty(dir);
  357. }
  358. /*
  359.  * Parent is locked.
  360.  */
  361. int ext2_add_link (struct dentry *dentry, struct inode *inode)
  362. {
  363. struct inode *dir = dentry->d_parent->d_inode;
  364. const char *name = dentry->d_name.name;
  365. int namelen = dentry->d_name.len;
  366. unsigned reclen = EXT2_DIR_REC_LEN(namelen);
  367. unsigned short rec_len, name_len;
  368. struct page *page = NULL;
  369. ext2_dirent * de;
  370. unsigned long npages = dir_pages(dir);
  371. unsigned long n;
  372. char *kaddr;
  373. unsigned from, to;
  374. int err;
  375. /* We take care of directory expansion in the same loop */
  376. for (n = 0; n <= npages; n++) {
  377. page = ext2_get_page(dir, n);
  378. err = PTR_ERR(page);
  379. if (IS_ERR(page))
  380. goto out;
  381. kaddr = page_address(page);
  382. de = (ext2_dirent *)kaddr;
  383. kaddr += PAGE_CACHE_SIZE - reclen;
  384. while ((char *)de <= kaddr) {
  385. err = -EEXIST;
  386. if (ext2_match (namelen, name, de))
  387. goto out_page;
  388. name_len = EXT2_DIR_REC_LEN(de->name_len);
  389. rec_len = le16_to_cpu(de->rec_len);
  390. if (!de->inode && rec_len >= reclen)
  391. goto got_it;
  392. if (rec_len >= name_len + reclen)
  393. goto got_it;
  394. de = (ext2_dirent *) ((char *) de + rec_len);
  395. }
  396. ext2_put_page(page);
  397. }
  398. BUG();
  399. return -EINVAL;
  400. got_it:
  401. from = (char*)de - (char*)page_address(page);
  402. to = from + rec_len;
  403. lock_page(page);
  404. err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
  405. if (err)
  406. goto out_unlock;
  407. if (de->inode) {
  408. ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
  409. de1->rec_len = cpu_to_le16(rec_len - name_len);
  410. de->rec_len = cpu_to_le16(name_len);
  411. de = de1;
  412. }
  413. de->name_len = namelen;
  414. memcpy (de->name, name, namelen);
  415. de->inode = cpu_to_le32(inode->i_ino);
  416. ext2_set_de_type (de, inode);
  417. err = ext2_commit_chunk(page, from, to);
  418. dir->i_mtime = dir->i_ctime = CURRENT_TIME;
  419. mark_inode_dirty(dir);
  420. /* OFFSET_CACHE */
  421. out_unlock:
  422. UnlockPage(page);
  423. out_page:
  424. ext2_put_page(page);
  425. out:
  426. return err;
  427. }
  428. /*
  429.  * ext2_delete_entry deletes a directory entry by merging it with the
  430.  * previous entry. Page is up-to-date. Releases the page.
  431.  */
  432. int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
  433. {
  434. struct address_space *mapping = page->mapping;
  435. struct inode *inode = mapping->host;
  436. char *kaddr = page_address(page);
  437. unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
  438. unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
  439. ext2_dirent * pde = NULL;
  440. ext2_dirent * de = (ext2_dirent *) (kaddr + from);
  441. int err;
  442. while ((char*)de < (char*)dir) {
  443. pde = de;
  444. de = ext2_next_entry(de);
  445. }
  446. if (pde)
  447. from = (char*)pde - (char*)page_address(page);
  448. lock_page(page);
  449. err = mapping->a_ops->prepare_write(NULL, page, from, to);
  450. if (err)
  451. BUG();
  452. if (pde)
  453. pde->rec_len = cpu_to_le16(to-from);
  454. dir->inode = 0;
  455. err = ext2_commit_chunk(page, from, to);
  456. UnlockPage(page);
  457. ext2_put_page(page);
  458. inode->i_ctime = inode->i_mtime = CURRENT_TIME;
  459. mark_inode_dirty(inode);
  460. return err;
  461. }
  462. /*
  463.  * Set the first fragment of directory.
  464.  */
  465. int ext2_make_empty(struct inode *inode, struct inode *parent)
  466. {
  467. struct address_space *mapping = inode->i_mapping;
  468. struct page *page = grab_cache_page(mapping, 0);
  469. unsigned chunk_size = ext2_chunk_size(inode);
  470. struct ext2_dir_entry_2 * de;
  471. char *base;
  472. int err;
  473. if (!page)
  474. return -ENOMEM;
  475. err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size);
  476. if (err)
  477. goto fail;
  478. base = page_address(page);
  479. de = (struct ext2_dir_entry_2 *) base;
  480. de->name_len = 1;
  481. de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));
  482. memcpy (de->name, ".", 4);
  483. de->inode = cpu_to_le32(inode->i_ino);
  484. ext2_set_de_type (de, inode);
  485. de = (struct ext2_dir_entry_2 *) (base + EXT2_DIR_REC_LEN(1));
  486. de->name_len = 2;
  487. de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1));
  488. de->inode = cpu_to_le32(parent->i_ino);
  489. memcpy (de->name, "..", 4);
  490. ext2_set_de_type (de, inode);
  491. err = ext2_commit_chunk(page, 0, chunk_size);
  492. fail:
  493. UnlockPage(page);
  494. page_cache_release(page);
  495. return err;
  496. }
  497. /*
  498.  * routine to check that the specified directory is empty (for rmdir)
  499.  */
  500. int ext2_empty_dir (struct inode * inode)
  501. {
  502. struct page *page = NULL;
  503. unsigned long i, npages = dir_pages(inode);
  504. for (i = 0; i < npages; i++) {
  505. char *kaddr;
  506. ext2_dirent * de;
  507. page = ext2_get_page(inode, i);
  508. if (IS_ERR(page))
  509. continue;
  510. kaddr = page_address(page);
  511. de = (ext2_dirent *)kaddr;
  512. kaddr += PAGE_CACHE_SIZE-EXT2_DIR_REC_LEN(1);
  513. while ((char *)de <= kaddr) {
  514. if (de->inode != 0) {
  515. /* check for . and .. */
  516. if (de->name[0] != '.')
  517. goto not_empty;
  518. if (de->name_len > 2)
  519. goto not_empty;
  520. if (de->name_len < 2) {
  521. if (de->inode !=
  522.     cpu_to_le32(inode->i_ino))
  523. goto not_empty;
  524. } else if (de->name[1] != '.')
  525. goto not_empty;
  526. }
  527. de = ext2_next_entry(de);
  528. }
  529. ext2_put_page(page);
  530. }
  531. return 1;
  532. not_empty:
  533. ext2_put_page(page);
  534. return 0;
  535. }
  536. struct file_operations ext2_dir_operations = {
  537. read: generic_read_dir,
  538. readdir: ext2_readdir,
  539. ioctl: ext2_ioctl,
  540. fsync: ext2_sync_file,
  541. };