diff options
author | H. Peter Anvin <hpa@zytor.com> | 2012-05-30 15:11:26 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2012-05-30 15:11:32 -0400 |
commit | bbd771474ec44b516107685d77e1c80bbe09f141 (patch) | |
tree | 0cb15781539a68f27b4ea6c89f827282630cbce6 /fs/ext3 | |
parent | 403e1c5b7495d7b80fae9fc4d0a7a6f5abdc3307 (diff) | |
parent | 319b6ffc6df892e4ccffff823cc5521a4a5d2dca (diff) |
Merge branch 'x86/trampoline' into x86/urgent
x86/trampoline contains an urgent commit which is necessarily on a
newer baseline.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'fs/ext3')
-rw-r--r-- | fs/ext3/dir.c | 167 | ||||
-rw-r--r-- | fs/ext3/ext3.h | 6 | ||||
-rw-r--r-- | fs/ext3/hash.c | 4 | ||||
-rw-r--r-- | fs/ext3/ialloc.c | 20 | ||||
-rw-r--r-- | fs/ext3/inode.c | 6 | ||||
-rw-r--r-- | fs/ext3/super.c | 6 |
6 files changed, 135 insertions, 74 deletions
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index cc761ad8fa57..92490e9f85ca 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c | |||
@@ -21,30 +21,15 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/compat.h> | ||
24 | #include "ext3.h" | 25 | #include "ext3.h" |
25 | 26 | ||
26 | static unsigned char ext3_filetype_table[] = { | 27 | static unsigned char ext3_filetype_table[] = { |
27 | DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK | 28 | DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK |
28 | }; | 29 | }; |
29 | 30 | ||
30 | static int ext3_readdir(struct file *, void *, filldir_t); | ||
31 | static int ext3_dx_readdir(struct file * filp, | 31 | static int ext3_dx_readdir(struct file * filp, |
32 | void * dirent, filldir_t filldir); | 32 | void * dirent, filldir_t filldir); |
33 | static int ext3_release_dir (struct inode * inode, | ||
34 | struct file * filp); | ||
35 | |||
36 | const struct file_operations ext3_dir_operations = { | ||
37 | .llseek = generic_file_llseek, | ||
38 | .read = generic_read_dir, | ||
39 | .readdir = ext3_readdir, /* we take BKL. needed?*/ | ||
40 | .unlocked_ioctl = ext3_ioctl, | ||
41 | #ifdef CONFIG_COMPAT | ||
42 | .compat_ioctl = ext3_compat_ioctl, | ||
43 | #endif | ||
44 | .fsync = ext3_sync_file, /* BKL held */ | ||
45 | .release = ext3_release_dir, | ||
46 | }; | ||
47 | |||
48 | 33 | ||
49 | static unsigned char get_dtype(struct super_block *sb, int filetype) | 34 | static unsigned char get_dtype(struct super_block *sb, int filetype) |
50 | { | 35 | { |
@@ -55,6 +40,25 @@ static unsigned char get_dtype(struct super_block *sb, int filetype) | |||
55 | return (ext3_filetype_table[filetype]); | 40 | return (ext3_filetype_table[filetype]); |
56 | } | 41 | } |
57 | 42 | ||
43 | /** | ||
44 | * Check if the given dir-inode refers to an htree-indexed directory | ||
45 | * (or a directory which chould potentially get coverted to use htree | ||
46 | * indexing). | ||
47 | * | ||
48 | * Return 1 if it is a dx dir, 0 if not | ||
49 | */ | ||
50 | static int is_dx_dir(struct inode *inode) | ||
51 | { | ||
52 | struct super_block *sb = inode->i_sb; | ||
53 | |||
54 | if (EXT3_HAS_COMPAT_FEATURE(inode->i_sb, | ||
55 | EXT3_FEATURE_COMPAT_DIR_INDEX) && | ||
56 | ((EXT3_I(inode)->i_flags & EXT3_INDEX_FL) || | ||
57 | ((inode->i_size >> sb->s_blocksize_bits) == 1))) | ||
58 | return 1; | ||
59 | |||
60 | return 0; | ||
61 | } | ||
58 | 62 | ||
59 | int ext3_check_dir_entry (const char * function, struct inode * dir, | 63 | int ext3_check_dir_entry (const char * function, struct inode * dir, |
60 | struct ext3_dir_entry_2 * de, | 64 | struct ext3_dir_entry_2 * de, |
@@ -94,18 +98,13 @@ static int ext3_readdir(struct file * filp, | |||
94 | unsigned long offset; | 98 | unsigned long offset; |
95 | int i, stored; | 99 | int i, stored; |
96 | struct ext3_dir_entry_2 *de; | 100 | struct ext3_dir_entry_2 *de; |
97 | struct super_block *sb; | ||
98 | int err; | 101 | int err; |
99 | struct inode *inode = filp->f_path.dentry->d_inode; | 102 | struct inode *inode = filp->f_path.dentry->d_inode; |
103 | struct super_block *sb = inode->i_sb; | ||
100 | int ret = 0; | 104 | int ret = 0; |
101 | int dir_has_error = 0; | 105 | int dir_has_error = 0; |
102 | 106 | ||
103 | sb = inode->i_sb; | 107 | if (is_dx_dir(inode)) { |
104 | |||
105 | if (EXT3_HAS_COMPAT_FEATURE(inode->i_sb, | ||
106 | EXT3_FEATURE_COMPAT_DIR_INDEX) && | ||
107 | ((EXT3_I(inode)->i_flags & EXT3_INDEX_FL) || | ||
108 | ((inode->i_size >> sb->s_blocksize_bits) == 1))) { | ||
109 | err = ext3_dx_readdir(filp, dirent, filldir); | 108 | err = ext3_dx_readdir(filp, dirent, filldir); |
110 | if (err != ERR_BAD_DX_DIR) { | 109 | if (err != ERR_BAD_DX_DIR) { |
111 | ret = err; | 110 | ret = err; |
@@ -227,22 +226,87 @@ out: | |||
227 | return ret; | 226 | return ret; |
228 | } | 227 | } |
229 | 228 | ||
229 | static inline int is_32bit_api(void) | ||
230 | { | ||
231 | #ifdef CONFIG_COMPAT | ||
232 | return is_compat_task(); | ||
233 | #else | ||
234 | return (BITS_PER_LONG == 32); | ||
235 | #endif | ||
236 | } | ||
237 | |||
230 | /* | 238 | /* |
231 | * These functions convert from the major/minor hash to an f_pos | 239 | * These functions convert from the major/minor hash to an f_pos |
232 | * value. | 240 | * value for dx directories |
233 | * | 241 | * |
234 | * Currently we only use major hash numer. This is unfortunate, but | 242 | * Upper layer (for example NFS) should specify FMODE_32BITHASH or |
235 | * on 32-bit machines, the same VFS interface is used for lseek and | 243 | * FMODE_64BITHASH explicitly. On the other hand, we allow ext3 to be mounted |
236 | * llseek, so if we use the 64 bit offset, then the 32-bit versions of | 244 | * directly on both 32-bit and 64-bit nodes, under such case, neither |
237 | * lseek/telldir/seekdir will blow out spectacularly, and from within | 245 | * FMODE_32BITHASH nor FMODE_64BITHASH is specified. |
238 | * the ext2 low-level routine, we don't know if we're being called by | ||
239 | * a 64-bit version of the system call or the 32-bit version of the | ||
240 | * system call. Worse yet, NFSv2 only allows for a 32-bit readdir | ||
241 | * cookie. Sigh. | ||
242 | */ | 246 | */ |
243 | #define hash2pos(major, minor) (major >> 1) | 247 | static inline loff_t hash2pos(struct file *filp, __u32 major, __u32 minor) |
244 | #define pos2maj_hash(pos) ((pos << 1) & 0xffffffff) | 248 | { |
245 | #define pos2min_hash(pos) (0) | 249 | if ((filp->f_mode & FMODE_32BITHASH) || |
250 | (!(filp->f_mode & FMODE_64BITHASH) && is_32bit_api())) | ||
251 | return major >> 1; | ||
252 | else | ||
253 | return ((__u64)(major >> 1) << 32) | (__u64)minor; | ||
254 | } | ||
255 | |||
256 | static inline __u32 pos2maj_hash(struct file *filp, loff_t pos) | ||
257 | { | ||
258 | if ((filp->f_mode & FMODE_32BITHASH) || | ||
259 | (!(filp->f_mode & FMODE_64BITHASH) && is_32bit_api())) | ||
260 | return (pos << 1) & 0xffffffff; | ||
261 | else | ||
262 | return ((pos >> 32) << 1) & 0xffffffff; | ||
263 | } | ||
264 | |||
265 | static inline __u32 pos2min_hash(struct file *filp, loff_t pos) | ||
266 | { | ||
267 | if ((filp->f_mode & FMODE_32BITHASH) || | ||
268 | (!(filp->f_mode & FMODE_64BITHASH) && is_32bit_api())) | ||
269 | return 0; | ||
270 | else | ||
271 | return pos & 0xffffffff; | ||
272 | } | ||
273 | |||
274 | /* | ||
275 | * Return 32- or 64-bit end-of-file for dx directories | ||
276 | */ | ||
277 | static inline loff_t ext3_get_htree_eof(struct file *filp) | ||
278 | { | ||
279 | if ((filp->f_mode & FMODE_32BITHASH) || | ||
280 | (!(filp->f_mode & FMODE_64BITHASH) && is_32bit_api())) | ||
281 | return EXT3_HTREE_EOF_32BIT; | ||
282 | else | ||
283 | return EXT3_HTREE_EOF_64BIT; | ||
284 | } | ||
285 | |||
286 | |||
287 | /* | ||
288 | * ext3_dir_llseek() calls generic_file_llseek[_size]() to handle both | ||
289 | * non-htree and htree directories, where the "offset" is in terms | ||
290 | * of the filename hash value instead of the byte offset. | ||
291 | * | ||
292 | * Because we may return a 64-bit hash that is well beyond s_maxbytes, | ||
293 | * we need to pass the max hash as the maximum allowable offset in | ||
294 | * the htree directory case. | ||
295 | * | ||
296 | * NOTE: offsets obtained *before* ext3_set_inode_flag(dir, EXT3_INODE_INDEX) | ||
297 | * will be invalid once the directory was converted into a dx directory | ||
298 | */ | ||
299 | loff_t ext3_dir_llseek(struct file *file, loff_t offset, int origin) | ||
300 | { | ||
301 | struct inode *inode = file->f_mapping->host; | ||
302 | int dx_dir = is_dx_dir(inode); | ||
303 | |||
304 | if (likely(dx_dir)) | ||
305 | return generic_file_llseek_size(file, offset, origin, | ||
306 | ext3_get_htree_eof(file)); | ||
307 | else | ||
308 | return generic_file_llseek(file, offset, origin); | ||
309 | } | ||
246 | 310 | ||
247 | /* | 311 | /* |
248 | * This structure holds the nodes of the red-black tree used to store | 312 | * This structure holds the nodes of the red-black tree used to store |
@@ -303,15 +367,16 @@ static void free_rb_tree_fname(struct rb_root *root) | |||
303 | } | 367 | } |
304 | 368 | ||
305 | 369 | ||
306 | static struct dir_private_info *ext3_htree_create_dir_info(loff_t pos) | 370 | static struct dir_private_info *ext3_htree_create_dir_info(struct file *filp, |
371 | loff_t pos) | ||
307 | { | 372 | { |
308 | struct dir_private_info *p; | 373 | struct dir_private_info *p; |
309 | 374 | ||
310 | p = kzalloc(sizeof(struct dir_private_info), GFP_KERNEL); | 375 | p = kzalloc(sizeof(struct dir_private_info), GFP_KERNEL); |
311 | if (!p) | 376 | if (!p) |
312 | return NULL; | 377 | return NULL; |
313 | p->curr_hash = pos2maj_hash(pos); | 378 | p->curr_hash = pos2maj_hash(filp, pos); |
314 | p->curr_minor_hash = pos2min_hash(pos); | 379 | p->curr_minor_hash = pos2min_hash(filp, pos); |
315 | return p; | 380 | return p; |
316 | } | 381 | } |
317 | 382 | ||
@@ -401,7 +466,7 @@ static int call_filldir(struct file * filp, void * dirent, | |||
401 | printk("call_filldir: called with null fname?!?\n"); | 466 | printk("call_filldir: called with null fname?!?\n"); |
402 | return 0; | 467 | return 0; |
403 | } | 468 | } |
404 | curr_pos = hash2pos(fname->hash, fname->minor_hash); | 469 | curr_pos = hash2pos(filp, fname->hash, fname->minor_hash); |
405 | while (fname) { | 470 | while (fname) { |
406 | error = filldir(dirent, fname->name, | 471 | error = filldir(dirent, fname->name, |
407 | fname->name_len, curr_pos, | 472 | fname->name_len, curr_pos, |
@@ -426,13 +491,13 @@ static int ext3_dx_readdir(struct file * filp, | |||
426 | int ret; | 491 | int ret; |
427 | 492 | ||
428 | if (!info) { | 493 | if (!info) { |
429 | info = ext3_htree_create_dir_info(filp->f_pos); | 494 | info = ext3_htree_create_dir_info(filp, filp->f_pos); |
430 | if (!info) | 495 | if (!info) |
431 | return -ENOMEM; | 496 | return -ENOMEM; |
432 | filp->private_data = info; | 497 | filp->private_data = info; |
433 | } | 498 | } |
434 | 499 | ||
435 | if (filp->f_pos == EXT3_HTREE_EOF) | 500 | if (filp->f_pos == ext3_get_htree_eof(filp)) |
436 | return 0; /* EOF */ | 501 | return 0; /* EOF */ |
437 | 502 | ||
438 | /* Some one has messed with f_pos; reset the world */ | 503 | /* Some one has messed with f_pos; reset the world */ |
@@ -440,8 +505,8 @@ static int ext3_dx_readdir(struct file * filp, | |||
440 | free_rb_tree_fname(&info->root); | 505 | free_rb_tree_fname(&info->root); |
441 | info->curr_node = NULL; | 506 | info->curr_node = NULL; |
442 | info->extra_fname = NULL; | 507 | info->extra_fname = NULL; |
443 | info->curr_hash = pos2maj_hash(filp->f_pos); | 508 | info->curr_hash = pos2maj_hash(filp, filp->f_pos); |
444 | info->curr_minor_hash = pos2min_hash(filp->f_pos); | 509 | info->curr_minor_hash = pos2min_hash(filp, filp->f_pos); |
445 | } | 510 | } |
446 | 511 | ||
447 | /* | 512 | /* |
@@ -473,7 +538,7 @@ static int ext3_dx_readdir(struct file * filp, | |||
473 | if (ret < 0) | 538 | if (ret < 0) |
474 | return ret; | 539 | return ret; |
475 | if (ret == 0) { | 540 | if (ret == 0) { |
476 | filp->f_pos = EXT3_HTREE_EOF; | 541 | filp->f_pos = ext3_get_htree_eof(filp); |
477 | break; | 542 | break; |
478 | } | 543 | } |
479 | info->curr_node = rb_first(&info->root); | 544 | info->curr_node = rb_first(&info->root); |
@@ -493,7 +558,7 @@ static int ext3_dx_readdir(struct file * filp, | |||
493 | info->curr_minor_hash = fname->minor_hash; | 558 | info->curr_minor_hash = fname->minor_hash; |
494 | } else { | 559 | } else { |
495 | if (info->next_hash == ~0) { | 560 | if (info->next_hash == ~0) { |
496 | filp->f_pos = EXT3_HTREE_EOF; | 561 | filp->f_pos = ext3_get_htree_eof(filp); |
497 | break; | 562 | break; |
498 | } | 563 | } |
499 | info->curr_hash = info->next_hash; | 564 | info->curr_hash = info->next_hash; |
@@ -512,3 +577,15 @@ static int ext3_release_dir (struct inode * inode, struct file * filp) | |||
512 | 577 | ||
513 | return 0; | 578 | return 0; |
514 | } | 579 | } |
580 | |||
581 | const struct file_operations ext3_dir_operations = { | ||
582 | .llseek = ext3_dir_llseek, | ||
583 | .read = generic_read_dir, | ||
584 | .readdir = ext3_readdir, | ||
585 | .unlocked_ioctl = ext3_ioctl, | ||
586 | #ifdef CONFIG_COMPAT | ||
587 | .compat_ioctl = ext3_compat_ioctl, | ||
588 | #endif | ||
589 | .fsync = ext3_sync_file, | ||
590 | .release = ext3_release_dir, | ||
591 | }; | ||
diff --git a/fs/ext3/ext3.h b/fs/ext3/ext3.h index 7977973a24f0..e85ff15a060e 100644 --- a/fs/ext3/ext3.h +++ b/fs/ext3/ext3.h | |||
@@ -920,7 +920,11 @@ struct dx_hash_info | |||
920 | u32 *seed; | 920 | u32 *seed; |
921 | }; | 921 | }; |
922 | 922 | ||
923 | #define EXT3_HTREE_EOF 0x7fffffff | 923 | |
924 | /* 32 and 64 bit signed EOF for dx directories */ | ||
925 | #define EXT3_HTREE_EOF_32BIT ((1UL << (32 - 1)) - 1) | ||
926 | #define EXT3_HTREE_EOF_64BIT ((1ULL << (64 - 1)) - 1) | ||
927 | |||
924 | 928 | ||
925 | /* | 929 | /* |
926 | * Control parameters used by ext3_htree_next_block | 930 | * Control parameters used by ext3_htree_next_block |
diff --git a/fs/ext3/hash.c b/fs/ext3/hash.c index d10231ddcf8a..ede315cdf126 100644 --- a/fs/ext3/hash.c +++ b/fs/ext3/hash.c | |||
@@ -198,8 +198,8 @@ int ext3fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo) | |||
198 | return -1; | 198 | return -1; |
199 | } | 199 | } |
200 | hash = hash & ~1; | 200 | hash = hash & ~1; |
201 | if (hash == (EXT3_HTREE_EOF << 1)) | 201 | if (hash == (EXT3_HTREE_EOF_32BIT << 1)) |
202 | hash = (EXT3_HTREE_EOF-1) << 1; | 202 | hash = (EXT3_HTREE_EOF_32BIT - 1) << 1; |
203 | hinfo->hash = hash; | 203 | hinfo->hash = hash; |
204 | hinfo->minor_hash = minor_hash; | 204 | hinfo->minor_hash = minor_hash; |
205 | return 0; | 205 | return 0; |
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index e3c39e4cec19..082afd78b107 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c | |||
@@ -180,8 +180,7 @@ error_return: | |||
180 | * It's OK to put directory into a group unless | 180 | * It's OK to put directory into a group unless |
181 | * it has too many directories already (max_dirs) or | 181 | * it has too many directories already (max_dirs) or |
182 | * it has too few free inodes left (min_inodes) or | 182 | * it has too few free inodes left (min_inodes) or |
183 | * it has too few free blocks left (min_blocks) or | 183 | * it has too few free blocks left (min_blocks). |
184 | * it's already running too large debt (max_debt). | ||
185 | * Parent's group is preferred, if it doesn't satisfy these | 184 | * Parent's group is preferred, if it doesn't satisfy these |
186 | * conditions we search cyclically through the rest. If none | 185 | * conditions we search cyclically through the rest. If none |
187 | * of the groups look good we just look for a group with more | 186 | * of the groups look good we just look for a group with more |
@@ -191,21 +190,16 @@ error_return: | |||
191 | * when we allocate an inode, within 0--255. | 190 | * when we allocate an inode, within 0--255. |
192 | */ | 191 | */ |
193 | 192 | ||
194 | #define INODE_COST 64 | ||
195 | #define BLOCK_COST 256 | ||
196 | |||
197 | static int find_group_orlov(struct super_block *sb, struct inode *parent) | 193 | static int find_group_orlov(struct super_block *sb, struct inode *parent) |
198 | { | 194 | { |
199 | int parent_group = EXT3_I(parent)->i_block_group; | 195 | int parent_group = EXT3_I(parent)->i_block_group; |
200 | struct ext3_sb_info *sbi = EXT3_SB(sb); | 196 | struct ext3_sb_info *sbi = EXT3_SB(sb); |
201 | struct ext3_super_block *es = sbi->s_es; | ||
202 | int ngroups = sbi->s_groups_count; | 197 | int ngroups = sbi->s_groups_count; |
203 | int inodes_per_group = EXT3_INODES_PER_GROUP(sb); | 198 | int inodes_per_group = EXT3_INODES_PER_GROUP(sb); |
204 | unsigned int freei, avefreei; | 199 | unsigned int freei, avefreei; |
205 | ext3_fsblk_t freeb, avefreeb; | 200 | ext3_fsblk_t freeb, avefreeb; |
206 | ext3_fsblk_t blocks_per_dir; | ||
207 | unsigned int ndirs; | 201 | unsigned int ndirs; |
208 | int max_debt, max_dirs, min_inodes; | 202 | int max_dirs, min_inodes; |
209 | ext3_grpblk_t min_blocks; | 203 | ext3_grpblk_t min_blocks; |
210 | int group = -1, i; | 204 | int group = -1, i; |
211 | struct ext3_group_desc *desc; | 205 | struct ext3_group_desc *desc; |
@@ -242,20 +236,10 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent) | |||
242 | goto fallback; | 236 | goto fallback; |
243 | } | 237 | } |
244 | 238 | ||
245 | blocks_per_dir = (le32_to_cpu(es->s_blocks_count) - freeb) / ndirs; | ||
246 | |||
247 | max_dirs = ndirs / ngroups + inodes_per_group / 16; | 239 | max_dirs = ndirs / ngroups + inodes_per_group / 16; |
248 | min_inodes = avefreei - inodes_per_group / 4; | 240 | min_inodes = avefreei - inodes_per_group / 4; |
249 | min_blocks = avefreeb - EXT3_BLOCKS_PER_GROUP(sb) / 4; | 241 | min_blocks = avefreeb - EXT3_BLOCKS_PER_GROUP(sb) / 4; |
250 | 242 | ||
251 | max_debt = EXT3_BLOCKS_PER_GROUP(sb) / max(blocks_per_dir, (ext3_fsblk_t)BLOCK_COST); | ||
252 | if (max_debt * INODE_COST > inodes_per_group) | ||
253 | max_debt = inodes_per_group / INODE_COST; | ||
254 | if (max_debt > 255) | ||
255 | max_debt = 255; | ||
256 | if (max_debt == 0) | ||
257 | max_debt = 1; | ||
258 | |||
259 | for (i = 0; i < ngroups; i++) { | 243 | for (i = 0; i < ngroups; i++) { |
260 | group = (parent_group + i) % ngroups; | 244 | group = (parent_group + i) % ngroups; |
261 | desc = ext3_get_group_desc (sb, group, NULL); | 245 | desc = ext3_get_group_desc (sb, group, NULL); |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index a09790a412b1..9a4a5c48b1c9 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -272,18 +272,18 @@ void ext3_evict_inode (struct inode *inode) | |||
272 | if (ext3_mark_inode_dirty(handle, inode)) { | 272 | if (ext3_mark_inode_dirty(handle, inode)) { |
273 | /* If that failed, just dquot_drop() and be done with that */ | 273 | /* If that failed, just dquot_drop() and be done with that */ |
274 | dquot_drop(inode); | 274 | dquot_drop(inode); |
275 | end_writeback(inode); | 275 | clear_inode(inode); |
276 | } else { | 276 | } else { |
277 | ext3_xattr_delete_inode(handle, inode); | 277 | ext3_xattr_delete_inode(handle, inode); |
278 | dquot_free_inode(inode); | 278 | dquot_free_inode(inode); |
279 | dquot_drop(inode); | 279 | dquot_drop(inode); |
280 | end_writeback(inode); | 280 | clear_inode(inode); |
281 | ext3_free_inode(handle, inode); | 281 | ext3_free_inode(handle, inode); |
282 | } | 282 | } |
283 | ext3_journal_stop(handle); | 283 | ext3_journal_stop(handle); |
284 | return; | 284 | return; |
285 | no_delete: | 285 | no_delete: |
286 | end_writeback(inode); | 286 | clear_inode(inode); |
287 | dquot_drop(inode); | 287 | dquot_drop(inode); |
288 | } | 288 | } |
289 | 289 | ||
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 94ef7e616129..8c3a44b7c375 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -3015,7 +3015,6 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, | |||
3015 | (unsigned long long)off, (unsigned long long)len); | 3015 | (unsigned long long)off, (unsigned long long)len); |
3016 | return -EIO; | 3016 | return -EIO; |
3017 | } | 3017 | } |
3018 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); | ||
3019 | bh = ext3_bread(handle, inode, blk, 1, &err); | 3018 | bh = ext3_bread(handle, inode, blk, 1, &err); |
3020 | if (!bh) | 3019 | if (!bh) |
3021 | goto out; | 3020 | goto out; |
@@ -3039,10 +3038,8 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, | |||
3039 | } | 3038 | } |
3040 | brelse(bh); | 3039 | brelse(bh); |
3041 | out: | 3040 | out: |
3042 | if (err) { | 3041 | if (err) |
3043 | mutex_unlock(&inode->i_mutex); | ||
3044 | return err; | 3042 | return err; |
3045 | } | ||
3046 | if (inode->i_size < off + len) { | 3043 | if (inode->i_size < off + len) { |
3047 | i_size_write(inode, off + len); | 3044 | i_size_write(inode, off + len); |
3048 | EXT3_I(inode)->i_disksize = inode->i_size; | 3045 | EXT3_I(inode)->i_disksize = inode->i_size; |
@@ -3050,7 +3047,6 @@ out: | |||
3050 | inode->i_version++; | 3047 | inode->i_version++; |
3051 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 3048 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
3052 | ext3_mark_inode_dirty(handle, inode); | 3049 | ext3_mark_inode_dirty(handle, inode); |
3053 | mutex_unlock(&inode->i_mutex); | ||
3054 | return len; | 3050 | return len; |
3055 | } | 3051 | } |
3056 | 3052 | ||