diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-04-05 19:41:22 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-05 19:41:22 -0400 |
commit | 9efe21cb82b5dbe3b0b2ae4de4eccc64ecb94e95 (patch) | |
tree | 7ff8833745d2f268f897f6fa4a27263b4a572245 /fs/ext3/namei.c | |
parent | de18836e447c2dc30120c0919b8db8ddc0401cc4 (diff) | |
parent | 0221c81b1b8eb0cbb6b30a0ced52ead32d2b4e4c (diff) |
Merge branch 'linus' into irq/threaded
Conflicts:
include/linux/irq.h
kernel/irq/handle.c
Diffstat (limited to 'fs/ext3/namei.c')
-rw-r--r-- | fs/ext3/namei.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 4db4ffa1edad..6ff7b9730234 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -161,12 +161,12 @@ static struct dx_frame *dx_probe(struct qstr *entry, | |||
161 | struct dx_frame *frame, | 161 | struct dx_frame *frame, |
162 | int *err); | 162 | int *err); |
163 | static void dx_release (struct dx_frame *frames); | 163 | static void dx_release (struct dx_frame *frames); |
164 | static int dx_make_map (struct ext3_dir_entry_2 *de, int size, | 164 | static int dx_make_map(struct ext3_dir_entry_2 *de, unsigned blocksize, |
165 | struct dx_hash_info *hinfo, struct dx_map_entry map[]); | 165 | struct dx_hash_info *hinfo, struct dx_map_entry map[]); |
166 | static void dx_sort_map(struct dx_map_entry *map, unsigned count); | 166 | static void dx_sort_map(struct dx_map_entry *map, unsigned count); |
167 | static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to, | 167 | static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to, |
168 | struct dx_map_entry *offsets, int count); | 168 | struct dx_map_entry *offsets, int count); |
169 | static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size); | 169 | static struct ext3_dir_entry_2 *dx_pack_dirents(char *base, unsigned blocksize); |
170 | static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block); | 170 | static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block); |
171 | static int ext3_htree_next_block(struct inode *dir, __u32 hash, | 171 | static int ext3_htree_next_block(struct inode *dir, __u32 hash, |
172 | struct dx_frame *frame, | 172 | struct dx_frame *frame, |
@@ -708,14 +708,14 @@ errout: | |||
708 | * Create map of hash values, offsets, and sizes, stored at end of block. | 708 | * Create map of hash values, offsets, and sizes, stored at end of block. |
709 | * Returns number of entries mapped. | 709 | * Returns number of entries mapped. |
710 | */ | 710 | */ |
711 | static int dx_make_map (struct ext3_dir_entry_2 *de, int size, | 711 | static int dx_make_map(struct ext3_dir_entry_2 *de, unsigned blocksize, |
712 | struct dx_hash_info *hinfo, struct dx_map_entry *map_tail) | 712 | struct dx_hash_info *hinfo, struct dx_map_entry *map_tail) |
713 | { | 713 | { |
714 | int count = 0; | 714 | int count = 0; |
715 | char *base = (char *) de; | 715 | char *base = (char *) de; |
716 | struct dx_hash_info h = *hinfo; | 716 | struct dx_hash_info h = *hinfo; |
717 | 717 | ||
718 | while ((char *) de < base + size) | 718 | while ((char *) de < base + blocksize) |
719 | { | 719 | { |
720 | if (de->name_len && de->inode) { | 720 | if (de->name_len && de->inode) { |
721 | ext3fs_dirhash(de->name, de->name_len, &h); | 721 | ext3fs_dirhash(de->name, de->name_len, &h); |
@@ -1047,8 +1047,16 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, str | |||
1047 | return ERR_PTR(-EIO); | 1047 | return ERR_PTR(-EIO); |
1048 | } | 1048 | } |
1049 | inode = ext3_iget(dir->i_sb, ino); | 1049 | inode = ext3_iget(dir->i_sb, ino); |
1050 | if (IS_ERR(inode)) | 1050 | if (unlikely(IS_ERR(inode))) { |
1051 | return ERR_CAST(inode); | 1051 | if (PTR_ERR(inode) == -ESTALE) { |
1052 | ext3_error(dir->i_sb, __func__, | ||
1053 | "deleted inode referenced: %lu", | ||
1054 | ino); | ||
1055 | return ERR_PTR(-EIO); | ||
1056 | } else { | ||
1057 | return ERR_CAST(inode); | ||
1058 | } | ||
1059 | } | ||
1052 | } | 1060 | } |
1053 | return d_splice_alias(inode, dentry); | 1061 | return d_splice_alias(inode, dentry); |
1054 | } | 1062 | } |
@@ -1120,13 +1128,14 @@ dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count) | |||
1120 | * Compact each dir entry in the range to the minimal rec_len. | 1128 | * Compact each dir entry in the range to the minimal rec_len. |
1121 | * Returns pointer to last entry in range. | 1129 | * Returns pointer to last entry in range. |
1122 | */ | 1130 | */ |
1123 | static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size) | 1131 | static struct ext3_dir_entry_2 *dx_pack_dirents(char *base, unsigned blocksize) |
1124 | { | 1132 | { |
1125 | struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base; | 1133 | struct ext3_dir_entry_2 *next, *to, *prev; |
1134 | struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *)base; | ||
1126 | unsigned rec_len = 0; | 1135 | unsigned rec_len = 0; |
1127 | 1136 | ||
1128 | prev = to = de; | 1137 | prev = to = de; |
1129 | while ((char*)de < base + size) { | 1138 | while ((char *)de < base + blocksize) { |
1130 | next = ext3_next_entry(de); | 1139 | next = ext3_next_entry(de); |
1131 | if (de->inode && de->name_len) { | 1140 | if (de->inode && de->name_len) { |
1132 | rec_len = EXT3_DIR_REC_LEN(de->name_len); | 1141 | rec_len = EXT3_DIR_REC_LEN(de->name_len); |
@@ -2049,7 +2058,7 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry) | |||
2049 | 2058 | ||
2050 | /* Initialize quotas before so that eventual writes go in | 2059 | /* Initialize quotas before so that eventual writes go in |
2051 | * separate transaction */ | 2060 | * separate transaction */ |
2052 | DQUOT_INIT(dentry->d_inode); | 2061 | vfs_dq_init(dentry->d_inode); |
2053 | handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); | 2062 | handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); |
2054 | if (IS_ERR(handle)) | 2063 | if (IS_ERR(handle)) |
2055 | return PTR_ERR(handle); | 2064 | return PTR_ERR(handle); |
@@ -2108,7 +2117,7 @@ static int ext3_unlink(struct inode * dir, struct dentry *dentry) | |||
2108 | 2117 | ||
2109 | /* Initialize quotas before so that eventual writes go | 2118 | /* Initialize quotas before so that eventual writes go |
2110 | * in separate transaction */ | 2119 | * in separate transaction */ |
2111 | DQUOT_INIT(dentry->d_inode); | 2120 | vfs_dq_init(dentry->d_inode); |
2112 | handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); | 2121 | handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); |
2113 | if (IS_ERR(handle)) | 2122 | if (IS_ERR(handle)) |
2114 | return PTR_ERR(handle); | 2123 | return PTR_ERR(handle); |
@@ -2265,14 +2274,14 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, | |||
2265 | struct inode * old_inode, * new_inode; | 2274 | struct inode * old_inode, * new_inode; |
2266 | struct buffer_head * old_bh, * new_bh, * dir_bh; | 2275 | struct buffer_head * old_bh, * new_bh, * dir_bh; |
2267 | struct ext3_dir_entry_2 * old_de, * new_de; | 2276 | struct ext3_dir_entry_2 * old_de, * new_de; |
2268 | int retval; | 2277 | int retval, flush_file = 0; |
2269 | 2278 | ||
2270 | old_bh = new_bh = dir_bh = NULL; | 2279 | old_bh = new_bh = dir_bh = NULL; |
2271 | 2280 | ||
2272 | /* Initialize quotas before so that eventual writes go | 2281 | /* Initialize quotas before so that eventual writes go |
2273 | * in separate transaction */ | 2282 | * in separate transaction */ |
2274 | if (new_dentry->d_inode) | 2283 | if (new_dentry->d_inode) |
2275 | DQUOT_INIT(new_dentry->d_inode); | 2284 | vfs_dq_init(new_dentry->d_inode); |
2276 | handle = ext3_journal_start(old_dir, 2 * | 2285 | handle = ext3_journal_start(old_dir, 2 * |
2277 | EXT3_DATA_TRANS_BLOCKS(old_dir->i_sb) + | 2286 | EXT3_DATA_TRANS_BLOCKS(old_dir->i_sb) + |
2278 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2); | 2287 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2); |
@@ -2401,6 +2410,8 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, | |||
2401 | ext3_mark_inode_dirty(handle, new_inode); | 2410 | ext3_mark_inode_dirty(handle, new_inode); |
2402 | if (!new_inode->i_nlink) | 2411 | if (!new_inode->i_nlink) |
2403 | ext3_orphan_add(handle, new_inode); | 2412 | ext3_orphan_add(handle, new_inode); |
2413 | if (ext3_should_writeback_data(new_inode)) | ||
2414 | flush_file = 1; | ||
2404 | } | 2415 | } |
2405 | retval = 0; | 2416 | retval = 0; |
2406 | 2417 | ||
@@ -2409,6 +2420,8 @@ end_rename: | |||
2409 | brelse (old_bh); | 2420 | brelse (old_bh); |
2410 | brelse (new_bh); | 2421 | brelse (new_bh); |
2411 | ext3_journal_stop(handle); | 2422 | ext3_journal_stop(handle); |
2423 | if (retval == 0 && flush_file) | ||
2424 | filemap_flush(old_inode->i_mapping); | ||
2412 | return retval; | 2425 | return retval; |
2413 | } | 2426 | } |
2414 | 2427 | ||