dir.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  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 "ext2.h"
  24. #include <linux/buffer_head.h>
  25. #include <linux/pagemap.h>
  26. #include <linux/swap.h>
  27. typedef struct ext2_dir_entry_2 ext2_dirent;
  28. /*
  29. * ext2 uses block-sized chunks. Arguably, sector-sized ones would be
  30. * more robust, but we have what we have
  31. */
  32. static inline unsigned ext2_chunk_size(struct inode *inode)
  33. {
  34. return inode->i_sb->s_blocksize;
  35. }
  36. static inline void ext2_put_page(struct page *page)
  37. {
  38. kunmap(page);
  39. page_cache_release(page);
  40. }
  41. static inline unsigned long dir_pages(struct inode *inode)
  42. {
  43. return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
  44. }
  45. /*
  46. * Return the offset into page `page_nr' of the last valid
  47. * byte in that page, plus one.
  48. */
  49. static unsigned
  50. ext2_last_byte(struct inode *inode, unsigned long page_nr)
  51. {
  52. unsigned last_byte = inode->i_size;
  53. last_byte -= page_nr << PAGE_CACHE_SHIFT;
  54. if (last_byte > PAGE_CACHE_SIZE)
  55. last_byte = PAGE_CACHE_SIZE;
  56. return last_byte;
  57. }
  58. static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
  59. {
  60. struct address_space *mapping = page->mapping;
  61. struct inode *dir = mapping->host;
  62. int err = 0;
  63. dir->i_version++;
  64. block_write_end(NULL, mapping, pos, len, len, page, NULL);
  65. if (pos+len > dir->i_size) {
  66. i_size_write(dir, pos+len);
  67. mark_inode_dirty(dir);
  68. }
  69. if (IS_DIRSYNC(dir))
  70. err = write_one_page(page, 1);
  71. else
  72. unlock_page(page);
  73. return err;
  74. }
  75. static void ext2_check_page(struct page *page)
  76. {
  77. struct inode *dir = page->mapping->host;
  78. struct super_block *sb = dir->i_sb;
  79. unsigned chunk_size = ext2_chunk_size(dir);
  80. char *kaddr = page_address(page);
  81. u32 max_inumber = le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count);
  82. unsigned offs, rec_len;
  83. unsigned limit = PAGE_CACHE_SIZE;
  84. ext2_dirent *p;
  85. char *error;
  86. if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) {
  87. limit = dir->i_size & ~PAGE_CACHE_MASK;
  88. if (limit & (chunk_size - 1))
  89. goto Ebadsize;
  90. if (!limit)
  91. goto out;
  92. }
  93. for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) {
  94. p = (ext2_dirent *)(kaddr + offs);
  95. rec_len = le16_to_cpu(p->rec_len);
  96. if (rec_len < EXT2_DIR_REC_LEN(1))
  97. goto Eshort;
  98. if (rec_len & 3)
  99. goto Ealign;
  100. if (rec_len < EXT2_DIR_REC_LEN(p->name_len))
  101. goto Enamelen;
  102. if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1))
  103. goto Espan;
  104. if (le32_to_cpu(p->inode) > max_inumber)
  105. goto Einumber;
  106. }
  107. if (offs != limit)
  108. goto Eend;
  109. out:
  110. SetPageChecked(page);
  111. return;
  112. /* Too bad, we had an error */
  113. Ebadsize:
  114. ext2_error(sb, "ext2_check_page",
  115. "size of directory #%lu is not a multiple of chunk size",
  116. dir->i_ino
  117. );
  118. goto fail;
  119. Eshort:
  120. error = "rec_len is smaller than minimal";
  121. goto bad_entry;
  122. Ealign:
  123. error = "unaligned directory entry";
  124. goto bad_entry;
  125. Enamelen:
  126. error = "rec_len is too small for name_len";
  127. goto bad_entry;
  128. Espan:
  129. error = "directory entry across blocks";
  130. goto bad_entry;
  131. Einumber:
  132. error = "inode out of bounds";
  133. bad_entry:
  134. ext2_error (sb, "ext2_check_page", "bad entry in directory #%lu: %s - "
  135. "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
  136. dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
  137. (unsigned long) le32_to_cpu(p->inode),
  138. rec_len, p->name_len);
  139. goto fail;
  140. Eend:
  141. p = (ext2_dirent *)(kaddr + offs);
  142. ext2_error (sb, "ext2_check_page",
  143. "entry in directory #%lu spans the page boundary"
  144. "offset=%lu, inode=%lu",
  145. dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
  146. (unsigned long) le32_to_cpu(p->inode));
  147. fail:
  148. SetPageChecked(page);
  149. SetPageError(page);
  150. }
  151. static struct page * ext2_get_page(struct inode *dir, unsigned long n)
  152. {
  153. struct address_space *mapping = dir->i_mapping;
  154. struct page *page = read_mapping_page(mapping, n, NULL);
  155. if (!IS_ERR(page)) {
  156. kmap(page);
  157. if (!PageChecked(page))
  158. ext2_check_page(page);
  159. if (PageError(page))
  160. goto fail;
  161. }
  162. return page;
  163. fail:
  164. ext2_put_page(page);
  165. return ERR_PTR(-EIO);
  166. }
  167. /*
  168. * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
  169. *
  170. * len <= EXT2_NAME_LEN and de != NULL are guaranteed by caller.
  171. */
  172. static inline int ext2_match (int len, const char * const name,
  173. struct ext2_dir_entry_2 * de)
  174. {
  175. if (len != de->name_len)
  176. return 0;
  177. if (!de->inode)
  178. return 0;
  179. return !memcmp(name, de->name, len);
  180. }
  181. /*
  182. * p is at least 6 bytes before the end of page
  183. */
  184. static inline ext2_dirent *ext2_next_entry(ext2_dirent *p)
  185. {
  186. return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len));
  187. }
  188. static inline unsigned
  189. ext2_validate_entry(char *base, unsigned offset, unsigned mask)
  190. {
  191. ext2_dirent *de = (ext2_dirent*)(base + offset);
  192. ext2_dirent *p = (ext2_dirent*)(base + (offset&mask));
  193. while ((char*)p < (char*)de) {
  194. if (p->rec_len == 0)
  195. break;
  196. p = ext2_next_entry(p);
  197. }
  198. return (char *)p - base;
  199. }
  200. static unsigned char ext2_filetype_table[EXT2_FT_MAX] = {
  201. [EXT2_FT_UNKNOWN] = DT_UNKNOWN,
  202. [EXT2_FT_REG_FILE] = DT_REG,
  203. [EXT2_FT_DIR] = DT_DIR,
  204. [EXT2_FT_CHRDEV] = DT_CHR,
  205. [EXT2_FT_BLKDEV] = DT_BLK,
  206. [EXT2_FT_FIFO] = DT_FIFO,
  207. [EXT2_FT_SOCK] = DT_SOCK,
  208. [EXT2_FT_SYMLINK] = DT_LNK,
  209. };
  210. #define S_SHIFT 12
  211. static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = {
  212. [S_IFREG >> S_SHIFT] = EXT2_FT_REG_FILE,
  213. [S_IFDIR >> S_SHIFT] = EXT2_FT_DIR,
  214. [S_IFCHR >> S_SHIFT] = EXT2_FT_CHRDEV,
  215. [S_IFBLK >> S_SHIFT] = EXT2_FT_BLKDEV,
  216. [S_IFIFO >> S_SHIFT] = EXT2_FT_FIFO,
  217. [S_IFSOCK >> S_SHIFT] = EXT2_FT_SOCK,
  218. [S_IFLNK >> S_SHIFT] = EXT2_FT_SYMLINK,
  219. };
  220. static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode)
  221. {
  222. mode_t mode = inode->i_mode;
  223. if (EXT2_HAS_INCOMPAT_FEATURE(inode->i_sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
  224. de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
  225. else
  226. de->file_type = 0;
  227. }
  228. static int
  229. ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
  230. {
  231. loff_t pos = filp->f_pos;
  232. struct inode *inode = filp->f_path.dentry->d_inode;
  233. struct super_block *sb = inode->i_sb;
  234. unsigned int offset = pos & ~PAGE_CACHE_MASK;
  235. unsigned long n = pos >> PAGE_CACHE_SHIFT;
  236. unsigned long npages = dir_pages(inode);
  237. unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
  238. unsigned char *types = NULL;
  239. int need_revalidate = filp->f_version != inode->i_version;
  240. if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
  241. return 0;
  242. if (EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
  243. types = ext2_filetype_table;
  244. for ( ; n < npages; n++, offset = 0) {
  245. char *kaddr, *limit;
  246. ext2_dirent *de;
  247. struct page *page = ext2_get_page(inode, n);
  248. if (IS_ERR(page)) {
  249. ext2_error(sb, __FUNCTION__,
  250. "bad page in #%lu",
  251. inode->i_ino);
  252. filp->f_pos += PAGE_CACHE_SIZE - offset;
  253. return -EIO;
  254. }
  255. kaddr = page_address(page);
  256. if (unlikely(need_revalidate)) {
  257. if (offset) {
  258. offset = ext2_validate_entry(kaddr, offset, chunk_mask);
  259. filp->f_pos = (n<<PAGE_CACHE_SHIFT) + offset;
  260. }
  261. filp->f_version = inode->i_version;
  262. need_revalidate = 0;
  263. }
  264. de = (ext2_dirent *)(kaddr+offset);
  265. limit = kaddr + ext2_last_byte(inode, n) - EXT2_DIR_REC_LEN(1);
  266. for ( ;(char*)de <= limit; de = ext2_next_entry(de)) {
  267. if (de->rec_len == 0) {
  268. ext2_error(sb, __FUNCTION__,
  269. "zero-length directory entry");
  270. ext2_put_page(page);
  271. return -EIO;
  272. }
  273. if (de->inode) {
  274. int over;
  275. unsigned char d_type = DT_UNKNOWN;
  276. if (types && de->file_type < EXT2_FT_MAX)
  277. d_type = types[de->file_type];
  278. offset = (char *)de - kaddr;
  279. over = filldir(dirent, de->name, de->name_len,
  280. (n<<PAGE_CACHE_SHIFT) | offset,
  281. le32_to_cpu(de->inode), d_type);
  282. if (over) {
  283. ext2_put_page(page);
  284. return 0;
  285. }
  286. }
  287. filp->f_pos += le16_to_cpu(de->rec_len);
  288. }
  289. ext2_put_page(page);
  290. }
  291. return 0;
  292. }
  293. /*
  294. * ext2_find_entry()
  295. *
  296. * finds an entry in the specified directory with the wanted name. It
  297. * returns the page in which the entry was found, and the entry itself
  298. * (as a parameter - res_dir). Page is returned mapped and unlocked.
  299. * Entry is guaranteed to be valid.
  300. */
  301. struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
  302. struct dentry *dentry, struct page ** res_page)
  303. {
  304. const char *name = dentry->d_name.name;
  305. int namelen = dentry->d_name.len;
  306. unsigned reclen = EXT2_DIR_REC_LEN(namelen);
  307. unsigned long start, n;
  308. unsigned long npages = dir_pages(dir);
  309. struct page *page = NULL;
  310. struct ext2_inode_info *ei = EXT2_I(dir);
  311. ext2_dirent * de;
  312. if (npages == 0)
  313. goto out;
  314. /* OFFSET_CACHE */
  315. *res_page = NULL;
  316. start = ei->i_dir_start_lookup;
  317. if (start >= npages)
  318. start = 0;
  319. n = start;
  320. do {
  321. char *kaddr;
  322. page = ext2_get_page(dir, n);
  323. if (!IS_ERR(page)) {
  324. kaddr = page_address(page);
  325. de = (ext2_dirent *) kaddr;
  326. kaddr += ext2_last_byte(dir, n) - reclen;
  327. while ((char *) de <= kaddr) {
  328. if (de->rec_len == 0) {
  329. ext2_error(dir->i_sb, __FUNCTION__,
  330. "zero-length directory entry");
  331. ext2_put_page(page);
  332. goto out;
  333. }
  334. if (ext2_match (namelen, name, de))
  335. goto found;
  336. de = ext2_next_entry(de);
  337. }
  338. ext2_put_page(page);
  339. }
  340. if (++n >= npages)
  341. n = 0;
  342. /* next page is past the blocks we've got */
  343. if (unlikely(n > (dir->i_blocks >> (PAGE_CACHE_SHIFT - 9)))) {
  344. ext2_error(dir->i_sb, __FUNCTION__,
  345. "dir %lu size %lld exceeds block count %llu",
  346. dir->i_ino, dir->i_size,
  347. (unsigned long long)dir->i_blocks);
  348. goto out;
  349. }
  350. } while (n != start);
  351. out:
  352. return NULL;
  353. found:
  354. *res_page = page;
  355. ei->i_dir_start_lookup = n;
  356. return de;
  357. }
  358. struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
  359. {
  360. struct page *page = ext2_get_page(dir, 0);
  361. ext2_dirent *de = NULL;
  362. if (!IS_ERR(page)) {
  363. de = ext2_next_entry((ext2_dirent *) page_address(page));
  364. *p = page;
  365. }
  366. return de;
  367. }
  368. ino_t ext2_inode_by_name(struct inode * dir, struct dentry *dentry)
  369. {
  370. ino_t res = 0;
  371. struct ext2_dir_entry_2 * de;
  372. struct page *page;
  373. de = ext2_find_entry (dir, dentry, &page);
  374. if (de) {
  375. res = le32_to_cpu(de->inode);
  376. ext2_put_page(page);
  377. }
  378. return res;
  379. }
  380. /* Releases the page */
  381. void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
  382. struct page *page, struct inode *inode)
  383. {
  384. loff_t pos = page_offset(page) +
  385. (char *) de - (char *) page_address(page);
  386. unsigned len = le16_to_cpu(de->rec_len);
  387. int err;
  388. lock_page(page);
  389. err = __ext2_write_begin(NULL, page->mapping, pos, len,
  390. AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
  391. BUG_ON(err);
  392. de->inode = cpu_to_le32(inode->i_ino);
  393. ext2_set_de_type(de, inode);
  394. err = ext2_commit_chunk(page, pos, len);
  395. ext2_put_page(page);
  396. dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
  397. EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
  398. mark_inode_dirty(dir);
  399. }
  400. /*
  401. * Parent is locked.
  402. */
  403. int ext2_add_link (struct dentry *dentry, struct inode *inode)
  404. {
  405. struct inode *dir = dentry->d_parent->d_inode;
  406. const char *name = dentry->d_name.name;
  407. int namelen = dentry->d_name.len;
  408. unsigned chunk_size = ext2_chunk_size(dir);
  409. unsigned reclen = EXT2_DIR_REC_LEN(namelen);
  410. unsigned short rec_len, name_len;
  411. struct page *page = NULL;
  412. ext2_dirent * de;
  413. unsigned long npages = dir_pages(dir);
  414. unsigned long n;
  415. char *kaddr;
  416. loff_t pos;
  417. int err;
  418. /*
  419. * We take care of directory expansion in the same loop.
  420. * This code plays outside i_size, so it locks the page
  421. * to protect that region.
  422. */
  423. for (n = 0; n <= npages; n++) {
  424. char *dir_end;
  425. page = ext2_get_page(dir, n);
  426. err = PTR_ERR(page);
  427. if (IS_ERR(page))
  428. goto out;
  429. lock_page(page);
  430. kaddr = page_address(page);
  431. dir_end = kaddr + ext2_last_byte(dir, n);
  432. de = (ext2_dirent *)kaddr;
  433. kaddr += PAGE_CACHE_SIZE - reclen;
  434. while ((char *)de <= kaddr) {
  435. if ((char *)de == dir_end) {
  436. /* We hit i_size */
  437. name_len = 0;
  438. rec_len = chunk_size;
  439. de->rec_len = cpu_to_le16(chunk_size);
  440. de->inode = 0;
  441. goto got_it;
  442. }
  443. if (de->rec_len == 0) {
  444. ext2_error(dir->i_sb, __FUNCTION__,
  445. "zero-length directory entry");
  446. err = -EIO;
  447. goto out_unlock;
  448. }
  449. err = -EEXIST;
  450. if (ext2_match (namelen, name, de))
  451. goto out_unlock;
  452. name_len = EXT2_DIR_REC_LEN(de->name_len);
  453. rec_len = le16_to_cpu(de->rec_len);
  454. if (!de->inode && rec_len >= reclen)
  455. goto got_it;
  456. if (rec_len >= name_len + reclen)
  457. goto got_it;
  458. de = (ext2_dirent *) ((char *) de + rec_len);
  459. }
  460. unlock_page(page);
  461. ext2_put_page(page);
  462. }
  463. BUG();
  464. return -EINVAL;
  465. got_it:
  466. pos = page_offset(page) +
  467. (char*)de - (char*)page_address(page);
  468. err = __ext2_write_begin(NULL, page->mapping, pos, rec_len, 0,
  469. &page, NULL);
  470. if (err)
  471. goto out_unlock;
  472. if (de->inode) {
  473. ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
  474. de1->rec_len = cpu_to_le16(rec_len - name_len);
  475. de->rec_len = cpu_to_le16(name_len);
  476. de = de1;
  477. }
  478. de->name_len = namelen;
  479. memcpy(de->name, name, namelen);
  480. de->inode = cpu_to_le32(inode->i_ino);
  481. ext2_set_de_type (de, inode);
  482. err = ext2_commit_chunk(page, pos, rec_len);
  483. dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
  484. EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
  485. mark_inode_dirty(dir);
  486. /* OFFSET_CACHE */
  487. out_put:
  488. ext2_put_page(page);
  489. out:
  490. return err;
  491. out_unlock:
  492. unlock_page(page);
  493. goto out_put;
  494. }
  495. /*
  496. * ext2_delete_entry deletes a directory entry by merging it with the
  497. * previous entry. Page is up-to-date. Releases the page.
  498. */
  499. int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
  500. {
  501. struct address_space *mapping = page->mapping;
  502. struct inode *inode = mapping->host;
  503. char *kaddr = page_address(page);
  504. unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
  505. unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
  506. loff_t pos;
  507. ext2_dirent * pde = NULL;
  508. ext2_dirent * de = (ext2_dirent *) (kaddr + from);
  509. int err;
  510. while ((char*)de < (char*)dir) {
  511. if (de->rec_len == 0) {
  512. ext2_error(inode->i_sb, __FUNCTION__,
  513. "zero-length directory entry");
  514. err = -EIO;
  515. goto out;
  516. }
  517. pde = de;
  518. de = ext2_next_entry(de);
  519. }
  520. if (pde)
  521. from = (char*)pde - (char*)page_address(page);
  522. pos = page_offset(page) + from;
  523. lock_page(page);
  524. err = __ext2_write_begin(NULL, page->mapping, pos, to - from, 0,
  525. &page, NULL);
  526. BUG_ON(err);
  527. if (pde)
  528. pde->rec_len = cpu_to_le16(to - from);
  529. dir->inode = 0;
  530. err = ext2_commit_chunk(page, pos, to - from);
  531. inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
  532. EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL;
  533. mark_inode_dirty(inode);
  534. out:
  535. ext2_put_page(page);
  536. return err;
  537. }
  538. /*
  539. * Set the first fragment of directory.
  540. */
  541. int ext2_make_empty(struct inode *inode, struct inode *parent)
  542. {
  543. struct address_space *mapping = inode->i_mapping;
  544. struct page *page = grab_cache_page(mapping, 0);
  545. unsigned chunk_size = ext2_chunk_size(inode);
  546. struct ext2_dir_entry_2 * de;
  547. int err;
  548. void *kaddr;
  549. if (!page)
  550. return -ENOMEM;
  551. err = __ext2_write_begin(NULL, page->mapping, 0, chunk_size, 0,
  552. &page, NULL);
  553. if (err) {
  554. unlock_page(page);
  555. goto fail;
  556. }
  557. kaddr = kmap_atomic(page, KM_USER0);
  558. memset(kaddr, 0, chunk_size);
  559. de = (struct ext2_dir_entry_2 *)kaddr;
  560. de->name_len = 1;
  561. de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));
  562. memcpy (de->name, ".\0\0", 4);
  563. de->inode = cpu_to_le32(inode->i_ino);
  564. ext2_set_de_type (de, inode);
  565. de = (struct ext2_dir_entry_2 *)(kaddr + EXT2_DIR_REC_LEN(1));
  566. de->name_len = 2;
  567. de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1));
  568. de->inode = cpu_to_le32(parent->i_ino);
  569. memcpy (de->name, "..\0", 4);
  570. ext2_set_de_type (de, inode);
  571. kunmap_atomic(kaddr, KM_USER0);
  572. err = ext2_commit_chunk(page, 0, chunk_size);
  573. fail:
  574. page_cache_release(page);
  575. return err;
  576. }
  577. /*
  578. * routine to check that the specified directory is empty (for rmdir)
  579. */
  580. int ext2_empty_dir (struct inode * inode)
  581. {
  582. struct page *page = NULL;
  583. unsigned long i, npages = dir_pages(inode);
  584. for (i = 0; i < npages; i++) {
  585. char *kaddr;
  586. ext2_dirent * de;
  587. page = ext2_get_page(inode, i);
  588. if (IS_ERR(page))
  589. continue;
  590. kaddr = page_address(page);
  591. de = (ext2_dirent *)kaddr;
  592. kaddr += ext2_last_byte(inode, i) - EXT2_DIR_REC_LEN(1);
  593. while ((char *)de <= kaddr) {
  594. if (de->rec_len == 0) {
  595. ext2_error(inode->i_sb, __FUNCTION__,
  596. "zero-length directory entry");
  597. printk("kaddr=%p, de=%p\n", kaddr, de);
  598. goto not_empty;
  599. }
  600. if (de->inode != 0) {
  601. /* check for . and .. */
  602. if (de->name[0] != '.')
  603. goto not_empty;
  604. if (de->name_len > 2)
  605. goto not_empty;
  606. if (de->name_len < 2) {
  607. if (de->inode !=
  608. cpu_to_le32(inode->i_ino))
  609. goto not_empty;
  610. } else if (de->name[1] != '.')
  611. goto not_empty;
  612. }
  613. de = ext2_next_entry(de);
  614. }
  615. ext2_put_page(page);
  616. }
  617. return 1;
  618. not_empty:
  619. ext2_put_page(page);
  620. return 0;
  621. }
  622. const struct file_operations ext2_dir_operations = {
  623. .llseek = generic_file_llseek,
  624. .read = generic_read_dir,
  625. .readdir = ext2_readdir,
  626. .ioctl = ext2_ioctl,
  627. #ifdef CONFIG_COMPAT
  628. .compat_ioctl = ext2_compat_ioctl,
  629. #endif
  630. .fsync = ext2_sync_file,
  631. };