diff options
Diffstat (limited to 'fs/ext4/dir.c')
-rw-r--r-- | fs/ext4/dir.c | 102 |
1 files changed, 51 insertions, 51 deletions
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index d0b54f30b914..ec114d7886cc 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/ext3/dir.c | 2 | * linux/fs/ext4/dir.c |
3 | * | 3 | * |
4 | * Copyright (C) 1992, 1993, 1994, 1995 | 4 | * Copyright (C) 1992, 1993, 1994, 1995 |
5 | * Remy Card (card@masi.ibp.fr) | 5 | * Remy Card (card@masi.ibp.fr) |
@@ -12,7 +12,7 @@ | |||
12 | * | 12 | * |
13 | * Copyright (C) 1991, 1992 Linus Torvalds | 13 | * Copyright (C) 1991, 1992 Linus Torvalds |
14 | * | 14 | * |
15 | * ext3 directory handling functions | 15 | * ext4 directory handling functions |
16 | * | 16 | * |
17 | * Big-endian to little-endian byte-swapping/bitmaps by | 17 | * Big-endian to little-endian byte-swapping/bitmaps by |
18 | * David S. Miller (davem@caip.rutgers.edu), 1995 | 18 | * David S. Miller (davem@caip.rutgers.edu), 1995 |
@@ -23,69 +23,69 @@ | |||
23 | 23 | ||
24 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
25 | #include <linux/jbd.h> | 25 | #include <linux/jbd.h> |
26 | #include <linux/ext3_fs.h> | 26 | #include <linux/ext4_fs.h> |
27 | #include <linux/buffer_head.h> | 27 | #include <linux/buffer_head.h> |
28 | #include <linux/smp_lock.h> | 28 | #include <linux/smp_lock.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/rbtree.h> | 30 | #include <linux/rbtree.h> |
31 | 31 | ||
32 | static unsigned char ext3_filetype_table[] = { | 32 | static unsigned char ext4_filetype_table[] = { |
33 | DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK | 33 | DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK |
34 | }; | 34 | }; |
35 | 35 | ||
36 | static int ext3_readdir(struct file *, void *, filldir_t); | 36 | static int ext4_readdir(struct file *, void *, filldir_t); |
37 | static int ext3_dx_readdir(struct file * filp, | 37 | static int ext4_dx_readdir(struct file * filp, |
38 | void * dirent, filldir_t filldir); | 38 | void * dirent, filldir_t filldir); |
39 | static int ext3_release_dir (struct inode * inode, | 39 | static int ext4_release_dir (struct inode * inode, |
40 | struct file * filp); | 40 | struct file * filp); |
41 | 41 | ||
42 | const struct file_operations ext3_dir_operations = { | 42 | const struct file_operations ext4_dir_operations = { |
43 | .llseek = generic_file_llseek, | 43 | .llseek = generic_file_llseek, |
44 | .read = generic_read_dir, | 44 | .read = generic_read_dir, |
45 | .readdir = ext3_readdir, /* we take BKL. needed?*/ | 45 | .readdir = ext4_readdir, /* we take BKL. needed?*/ |
46 | .ioctl = ext3_ioctl, /* BKL held */ | 46 | .ioctl = ext4_ioctl, /* BKL held */ |
47 | #ifdef CONFIG_COMPAT | 47 | #ifdef CONFIG_COMPAT |
48 | .compat_ioctl = ext3_compat_ioctl, | 48 | .compat_ioctl = ext4_compat_ioctl, |
49 | #endif | 49 | #endif |
50 | .fsync = ext3_sync_file, /* BKL held */ | 50 | .fsync = ext4_sync_file, /* BKL held */ |
51 | #ifdef CONFIG_EXT3_INDEX | 51 | #ifdef CONFIG_EXT4_INDEX |
52 | .release = ext3_release_dir, | 52 | .release = ext4_release_dir, |
53 | #endif | 53 | #endif |
54 | }; | 54 | }; |
55 | 55 | ||
56 | 56 | ||
57 | static unsigned char get_dtype(struct super_block *sb, int filetype) | 57 | static unsigned char get_dtype(struct super_block *sb, int filetype) |
58 | { | 58 | { |
59 | if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) || | 59 | if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FILETYPE) || |
60 | (filetype >= EXT3_FT_MAX)) | 60 | (filetype >= EXT4_FT_MAX)) |
61 | return DT_UNKNOWN; | 61 | return DT_UNKNOWN; |
62 | 62 | ||
63 | return (ext3_filetype_table[filetype]); | 63 | return (ext4_filetype_table[filetype]); |
64 | } | 64 | } |
65 | 65 | ||
66 | 66 | ||
67 | int ext3_check_dir_entry (const char * function, struct inode * dir, | 67 | int ext4_check_dir_entry (const char * function, struct inode * dir, |
68 | struct ext3_dir_entry_2 * de, | 68 | struct ext4_dir_entry_2 * de, |
69 | struct buffer_head * bh, | 69 | struct buffer_head * bh, |
70 | unsigned long offset) | 70 | unsigned long offset) |
71 | { | 71 | { |
72 | const char * error_msg = NULL; | 72 | const char * error_msg = NULL; |
73 | const int rlen = le16_to_cpu(de->rec_len); | 73 | const int rlen = le16_to_cpu(de->rec_len); |
74 | 74 | ||
75 | if (rlen < EXT3_DIR_REC_LEN(1)) | 75 | if (rlen < EXT4_DIR_REC_LEN(1)) |
76 | error_msg = "rec_len is smaller than minimal"; | 76 | error_msg = "rec_len is smaller than minimal"; |
77 | else if (rlen % 4 != 0) | 77 | else if (rlen % 4 != 0) |
78 | error_msg = "rec_len % 4 != 0"; | 78 | error_msg = "rec_len % 4 != 0"; |
79 | else if (rlen < EXT3_DIR_REC_LEN(de->name_len)) | 79 | else if (rlen < EXT4_DIR_REC_LEN(de->name_len)) |
80 | error_msg = "rec_len is too small for name_len"; | 80 | error_msg = "rec_len is too small for name_len"; |
81 | else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize) | 81 | else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize) |
82 | error_msg = "directory entry across blocks"; | 82 | error_msg = "directory entry across blocks"; |
83 | else if (le32_to_cpu(de->inode) > | 83 | else if (le32_to_cpu(de->inode) > |
84 | le32_to_cpu(EXT3_SB(dir->i_sb)->s_es->s_inodes_count)) | 84 | le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count)) |
85 | error_msg = "inode out of bounds"; | 85 | error_msg = "inode out of bounds"; |
86 | 86 | ||
87 | if (error_msg != NULL) | 87 | if (error_msg != NULL) |
88 | ext3_error (dir->i_sb, function, | 88 | ext4_error (dir->i_sb, function, |
89 | "bad entry in directory #%lu: %s - " | 89 | "bad entry in directory #%lu: %s - " |
90 | "offset=%lu, inode=%lu, rec_len=%d, name_len=%d", | 90 | "offset=%lu, inode=%lu, rec_len=%d, name_len=%d", |
91 | dir->i_ino, error_msg, offset, | 91 | dir->i_ino, error_msg, offset, |
@@ -94,13 +94,13 @@ int ext3_check_dir_entry (const char * function, struct inode * dir, | |||
94 | return error_msg == NULL ? 1 : 0; | 94 | return error_msg == NULL ? 1 : 0; |
95 | } | 95 | } |
96 | 96 | ||
97 | static int ext3_readdir(struct file * filp, | 97 | static int ext4_readdir(struct file * filp, |
98 | void * dirent, filldir_t filldir) | 98 | void * dirent, filldir_t filldir) |
99 | { | 99 | { |
100 | int error = 0; | 100 | int error = 0; |
101 | unsigned long offset; | 101 | unsigned long offset; |
102 | int i, stored; | 102 | int i, stored; |
103 | struct ext3_dir_entry_2 *de; | 103 | struct ext4_dir_entry_2 *de; |
104 | struct super_block *sb; | 104 | struct super_block *sb; |
105 | int err; | 105 | int err; |
106 | struct inode *inode = filp->f_dentry->d_inode; | 106 | struct inode *inode = filp->f_dentry->d_inode; |
@@ -108,12 +108,12 @@ static int ext3_readdir(struct file * filp, | |||
108 | 108 | ||
109 | sb = inode->i_sb; | 109 | sb = inode->i_sb; |
110 | 110 | ||
111 | #ifdef CONFIG_EXT3_INDEX | 111 | #ifdef CONFIG_EXT4_INDEX |
112 | if (EXT3_HAS_COMPAT_FEATURE(inode->i_sb, | 112 | if (EXT4_HAS_COMPAT_FEATURE(inode->i_sb, |
113 | EXT3_FEATURE_COMPAT_DIR_INDEX) && | 113 | EXT4_FEATURE_COMPAT_DIR_INDEX) && |
114 | ((EXT3_I(inode)->i_flags & EXT3_INDEX_FL) || | 114 | ((EXT4_I(inode)->i_flags & EXT4_INDEX_FL) || |
115 | ((inode->i_size >> sb->s_blocksize_bits) == 1))) { | 115 | ((inode->i_size >> sb->s_blocksize_bits) == 1))) { |
116 | err = ext3_dx_readdir(filp, dirent, filldir); | 116 | err = ext4_dx_readdir(filp, dirent, filldir); |
117 | if (err != ERR_BAD_DX_DIR) { | 117 | if (err != ERR_BAD_DX_DIR) { |
118 | ret = err; | 118 | ret = err; |
119 | goto out; | 119 | goto out; |
@@ -122,19 +122,19 @@ static int ext3_readdir(struct file * filp, | |||
122 | * We don't set the inode dirty flag since it's not | 122 | * We don't set the inode dirty flag since it's not |
123 | * critical that it get flushed back to the disk. | 123 | * critical that it get flushed back to the disk. |
124 | */ | 124 | */ |
125 | EXT3_I(filp->f_dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL; | 125 | EXT4_I(filp->f_dentry->d_inode)->i_flags &= ~EXT4_INDEX_FL; |
126 | } | 126 | } |
127 | #endif | 127 | #endif |
128 | stored = 0; | 128 | stored = 0; |
129 | offset = filp->f_pos & (sb->s_blocksize - 1); | 129 | offset = filp->f_pos & (sb->s_blocksize - 1); |
130 | 130 | ||
131 | while (!error && !stored && filp->f_pos < inode->i_size) { | 131 | while (!error && !stored && filp->f_pos < inode->i_size) { |
132 | unsigned long blk = filp->f_pos >> EXT3_BLOCK_SIZE_BITS(sb); | 132 | unsigned long blk = filp->f_pos >> EXT4_BLOCK_SIZE_BITS(sb); |
133 | struct buffer_head map_bh; | 133 | struct buffer_head map_bh; |
134 | struct buffer_head *bh = NULL; | 134 | struct buffer_head *bh = NULL; |
135 | 135 | ||
136 | map_bh.b_state = 0; | 136 | map_bh.b_state = 0; |
137 | err = ext3_get_blocks_handle(NULL, inode, blk, 1, | 137 | err = ext4_get_blocks_handle(NULL, inode, blk, 1, |
138 | &map_bh, 0, 0); | 138 | &map_bh, 0, 0); |
139 | if (err > 0) { | 139 | if (err > 0) { |
140 | page_cache_readahead(sb->s_bdev->bd_inode->i_mapping, | 140 | page_cache_readahead(sb->s_bdev->bd_inode->i_mapping, |
@@ -143,7 +143,7 @@ static int ext3_readdir(struct file * filp, | |||
143 | map_bh.b_blocknr >> | 143 | map_bh.b_blocknr >> |
144 | (PAGE_CACHE_SHIFT - inode->i_blkbits), | 144 | (PAGE_CACHE_SHIFT - inode->i_blkbits), |
145 | 1); | 145 | 1); |
146 | bh = ext3_bread(NULL, inode, blk, 0, &err); | 146 | bh = ext4_bread(NULL, inode, blk, 0, &err); |
147 | } | 147 | } |
148 | 148 | ||
149 | /* | 149 | /* |
@@ -151,7 +151,7 @@ static int ext3_readdir(struct file * filp, | |||
151 | * of recovering data when there's a bad sector | 151 | * of recovering data when there's a bad sector |
152 | */ | 152 | */ |
153 | if (!bh) { | 153 | if (!bh) { |
154 | ext3_error (sb, "ext3_readdir", | 154 | ext4_error (sb, "ext4_readdir", |
155 | "directory #%lu contains a hole at offset %lu", | 155 | "directory #%lu contains a hole at offset %lu", |
156 | inode->i_ino, (unsigned long)filp->f_pos); | 156 | inode->i_ino, (unsigned long)filp->f_pos); |
157 | filp->f_pos += sb->s_blocksize - offset; | 157 | filp->f_pos += sb->s_blocksize - offset; |
@@ -165,7 +165,7 @@ revalidate: | |||
165 | * to make sure. */ | 165 | * to make sure. */ |
166 | if (filp->f_version != inode->i_version) { | 166 | if (filp->f_version != inode->i_version) { |
167 | for (i = 0; i < sb->s_blocksize && i < offset; ) { | 167 | for (i = 0; i < sb->s_blocksize && i < offset; ) { |
168 | de = (struct ext3_dir_entry_2 *) | 168 | de = (struct ext4_dir_entry_2 *) |
169 | (bh->b_data + i); | 169 | (bh->b_data + i); |
170 | /* It's too expensive to do a full | 170 | /* It's too expensive to do a full |
171 | * dirent test each time round this | 171 | * dirent test each time round this |
@@ -174,7 +174,7 @@ revalidate: | |||
174 | * failure will be detected in the | 174 | * failure will be detected in the |
175 | * dirent test below. */ | 175 | * dirent test below. */ |
176 | if (le16_to_cpu(de->rec_len) < | 176 | if (le16_to_cpu(de->rec_len) < |
177 | EXT3_DIR_REC_LEN(1)) | 177 | EXT4_DIR_REC_LEN(1)) |
178 | break; | 178 | break; |
179 | i += le16_to_cpu(de->rec_len); | 179 | i += le16_to_cpu(de->rec_len); |
180 | } | 180 | } |
@@ -186,8 +186,8 @@ revalidate: | |||
186 | 186 | ||
187 | while (!error && filp->f_pos < inode->i_size | 187 | while (!error && filp->f_pos < inode->i_size |
188 | && offset < sb->s_blocksize) { | 188 | && offset < sb->s_blocksize) { |
189 | de = (struct ext3_dir_entry_2 *) (bh->b_data + offset); | 189 | de = (struct ext4_dir_entry_2 *) (bh->b_data + offset); |
190 | if (!ext3_check_dir_entry ("ext3_readdir", inode, de, | 190 | if (!ext4_check_dir_entry ("ext4_readdir", inode, de, |
191 | bh, offset)) { | 191 | bh, offset)) { |
192 | /* On error, skip the f_pos to the | 192 | /* On error, skip the f_pos to the |
193 | next block. */ | 193 | next block. */ |
@@ -228,7 +228,7 @@ out: | |||
228 | return ret; | 228 | return ret; |
229 | } | 229 | } |
230 | 230 | ||
231 | #ifdef CONFIG_EXT3_INDEX | 231 | #ifdef CONFIG_EXT4_INDEX |
232 | /* | 232 | /* |
233 | * These functions convert from the major/minor hash to an f_pos | 233 | * These functions convert from the major/minor hash to an f_pos |
234 | * value. | 234 | * value. |
@@ -323,7 +323,7 @@ static struct dir_private_info *create_dir_info(loff_t pos) | |||
323 | return p; | 323 | return p; |
324 | } | 324 | } |
325 | 325 | ||
326 | void ext3_htree_free_dir_info(struct dir_private_info *p) | 326 | void ext4_htree_free_dir_info(struct dir_private_info *p) |
327 | { | 327 | { |
328 | free_rb_tree_fname(&p->root); | 328 | free_rb_tree_fname(&p->root); |
329 | kfree(p); | 329 | kfree(p); |
@@ -332,9 +332,9 @@ void ext3_htree_free_dir_info(struct dir_private_info *p) | |||
332 | /* | 332 | /* |
333 | * Given a directory entry, enter it into the fname rb tree. | 333 | * Given a directory entry, enter it into the fname rb tree. |
334 | */ | 334 | */ |
335 | int ext3_htree_store_dirent(struct file *dir_file, __u32 hash, | 335 | int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, |
336 | __u32 minor_hash, | 336 | __u32 minor_hash, |
337 | struct ext3_dir_entry_2 *dirent) | 337 | struct ext4_dir_entry_2 *dirent) |
338 | { | 338 | { |
339 | struct rb_node **p, *parent = NULL; | 339 | struct rb_node **p, *parent = NULL; |
340 | struct fname * fname, *new_fn; | 340 | struct fname * fname, *new_fn; |
@@ -390,7 +390,7 @@ int ext3_htree_store_dirent(struct file *dir_file, __u32 hash, | |||
390 | 390 | ||
391 | 391 | ||
392 | /* | 392 | /* |
393 | * This is a helper function for ext3_dx_readdir. It calls filldir | 393 | * This is a helper function for ext4_dx_readdir. It calls filldir |
394 | * for all entres on the fname linked list. (Normally there is only | 394 | * for all entres on the fname linked list. (Normally there is only |
395 | * one entry on the linked list, unless there are 62 bit hash collisions.) | 395 | * one entry on the linked list, unless there are 62 bit hash collisions.) |
396 | */ | 396 | */ |
@@ -425,7 +425,7 @@ static int call_filldir(struct file * filp, void * dirent, | |||
425 | return 0; | 425 | return 0; |
426 | } | 426 | } |
427 | 427 | ||
428 | static int ext3_dx_readdir(struct file * filp, | 428 | static int ext4_dx_readdir(struct file * filp, |
429 | void * dirent, filldir_t filldir) | 429 | void * dirent, filldir_t filldir) |
430 | { | 430 | { |
431 | struct dir_private_info *info = filp->private_data; | 431 | struct dir_private_info *info = filp->private_data; |
@@ -440,7 +440,7 @@ static int ext3_dx_readdir(struct file * filp, | |||
440 | filp->private_data = info; | 440 | filp->private_data = info; |
441 | } | 441 | } |
442 | 442 | ||
443 | if (filp->f_pos == EXT3_HTREE_EOF) | 443 | if (filp->f_pos == EXT4_HTREE_EOF) |
444 | return 0; /* EOF */ | 444 | return 0; /* EOF */ |
445 | 445 | ||
446 | /* Some one has messed with f_pos; reset the world */ | 446 | /* Some one has messed with f_pos; reset the world */ |
@@ -474,13 +474,13 @@ static int ext3_dx_readdir(struct file * filp, | |||
474 | info->curr_node = NULL; | 474 | info->curr_node = NULL; |
475 | free_rb_tree_fname(&info->root); | 475 | free_rb_tree_fname(&info->root); |
476 | filp->f_version = inode->i_version; | 476 | filp->f_version = inode->i_version; |
477 | ret = ext3_htree_fill_tree(filp, info->curr_hash, | 477 | ret = ext4_htree_fill_tree(filp, info->curr_hash, |
478 | info->curr_minor_hash, | 478 | info->curr_minor_hash, |
479 | &info->next_hash); | 479 | &info->next_hash); |
480 | if (ret < 0) | 480 | if (ret < 0) |
481 | return ret; | 481 | return ret; |
482 | if (ret == 0) { | 482 | if (ret == 0) { |
483 | filp->f_pos = EXT3_HTREE_EOF; | 483 | filp->f_pos = EXT4_HTREE_EOF; |
484 | break; | 484 | break; |
485 | } | 485 | } |
486 | info->curr_node = rb_first(&info->root); | 486 | info->curr_node = rb_first(&info->root); |
@@ -495,7 +495,7 @@ static int ext3_dx_readdir(struct file * filp, | |||
495 | info->curr_node = rb_next(info->curr_node); | 495 | info->curr_node = rb_next(info->curr_node); |
496 | if (!info->curr_node) { | 496 | if (!info->curr_node) { |
497 | if (info->next_hash == ~0) { | 497 | if (info->next_hash == ~0) { |
498 | filp->f_pos = EXT3_HTREE_EOF; | 498 | filp->f_pos = EXT4_HTREE_EOF; |
499 | break; | 499 | break; |
500 | } | 500 | } |
501 | info->curr_hash = info->next_hash; | 501 | info->curr_hash = info->next_hash; |
@@ -507,10 +507,10 @@ finished: | |||
507 | return 0; | 507 | return 0; |
508 | } | 508 | } |
509 | 509 | ||
510 | static int ext3_release_dir (struct inode * inode, struct file * filp) | 510 | static int ext4_release_dir (struct inode * inode, struct file * filp) |
511 | { | 511 | { |
512 | if (filp->private_data) | 512 | if (filp->private_data) |
513 | ext3_htree_free_dir_info(filp->private_data); | 513 | ext4_htree_free_dir_info(filp->private_data); |
514 | 514 | ||
515 | return 0; | 515 | return 0; |
516 | } | 516 | } |