aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/dir.c')
-rw-r--r--fs/ext4/dir.c102
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
32static unsigned char ext3_filetype_table[] = { 32static 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
36static int ext3_readdir(struct file *, void *, filldir_t); 36static int ext4_readdir(struct file *, void *, filldir_t);
37static int ext3_dx_readdir(struct file * filp, 37static int ext4_dx_readdir(struct file * filp,
38 void * dirent, filldir_t filldir); 38 void * dirent, filldir_t filldir);
39static int ext3_release_dir (struct inode * inode, 39static int ext4_release_dir (struct inode * inode,
40 struct file * filp); 40 struct file * filp);
41 41
42const struct file_operations ext3_dir_operations = { 42const 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
57static unsigned char get_dtype(struct super_block *sb, int filetype) 57static 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
67int ext3_check_dir_entry (const char * function, struct inode * dir, 67int 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
97static int ext3_readdir(struct file * filp, 97static 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
326void ext3_htree_free_dir_info(struct dir_private_info *p) 326void 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 */
335int ext3_htree_store_dirent(struct file *dir_file, __u32 hash, 335int 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
428static int ext3_dx_readdir(struct file * filp, 428static 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
510static int ext3_release_dir (struct inode * inode, struct file * filp) 510static 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}