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