Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6:
jbd: Fix comment to match the code in journal_start()
jbd/jbd2: remove obsolete summarise_journal_usage.
jbd: Fix forever sleeping process in do_get_write_access()
ext2: fix error msg when mounting fs with too-large blocksize
jbd: fix fsync() tid wraparound bug
ext3: Fix fs corruption when make_indexed_dir() fails
ext3: Fix lock inversion in ext3_symlink()

+91 -32
+2 -1
fs/ext2/super.c
··· 898 898 brelse(bh); 899 899 900 900 if (!sb_set_blocksize(sb, blocksize)) { 901 - ext2_msg(sb, KERN_ERR, "error: blocksize is too small"); 901 + ext2_msg(sb, KERN_ERR, 902 + "error: bad blocksize %d", blocksize); 902 903 goto failed_sbi; 903 904 } 904 905
+67 -13
fs/ext3/namei.c
··· 1416 1416 frame->at = entries; 1417 1417 frame->bh = bh; 1418 1418 bh = bh2; 1419 + /* 1420 + * Mark buffers dirty here so that if do_split() fails we write a 1421 + * consistent set of buffers to disk. 1422 + */ 1423 + ext3_journal_dirty_metadata(handle, frame->bh); 1424 + ext3_journal_dirty_metadata(handle, bh); 1419 1425 de = do_split(handle,dir, &bh, frame, &hinfo, &retval); 1420 - dx_release (frames); 1421 - if (!(de)) 1426 + if (!de) { 1427 + ext3_mark_inode_dirty(handle, dir); 1428 + dx_release(frames); 1422 1429 return retval; 1430 + } 1431 + dx_release(frames); 1423 1432 1424 1433 return add_dirent_to_buf(handle, dentry, inode, de, bh); 1425 1434 } ··· 2198 2189 handle_t *handle; 2199 2190 struct inode * inode; 2200 2191 int l, err, retries = 0; 2192 + int credits; 2201 2193 2202 2194 l = strlen(symname)+1; 2203 2195 if (l > dir->i_sb->s_blocksize) ··· 2206 2196 2207 2197 dquot_initialize(dir); 2208 2198 2199 + if (l > EXT3_N_BLOCKS * 4) { 2200 + /* 2201 + * For non-fast symlinks, we just allocate inode and put it on 2202 + * orphan list in the first transaction => we need bitmap, 2203 + * group descriptor, sb, inode block, quota blocks. 2204 + */ 2205 + credits = 4 + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb); 2206 + } else { 2207 + /* 2208 + * Fast symlink. We have to add entry to directory 2209 + * (EXT3_DATA_TRANS_BLOCKS + EXT3_INDEX_EXTRA_TRANS_BLOCKS), 2210 + * allocate new inode (bitmap, group descriptor, inode block, 2211 + * quota blocks, sb is already counted in previous macros). 2212 + */ 2213 + credits = EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + 2214 + EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + 2215 + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb); 2216 + } 2209 2217 retry: 2210 - handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + 2211 - EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 + 2212 - EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb)); 2218 + handle = ext3_journal_start(dir, credits); 2213 2219 if (IS_ERR(handle)) 2214 2220 return PTR_ERR(handle); 2215 2221 ··· 2237 2211 if (IS_ERR(inode)) 2238 2212 goto out_stop; 2239 2213 2240 - if (l > sizeof (EXT3_I(inode)->i_data)) { 2214 + if (l > EXT3_N_BLOCKS * 4) { 2241 2215 inode->i_op = &ext3_symlink_inode_operations; 2242 2216 ext3_set_aops(inode); 2243 2217 /* 2244 - * page_symlink() calls into ext3_prepare/commit_write. 2245 - * We have a transaction open. All is sweetness. It also sets 2246 - * i_size in generic_commit_write(). 2218 + * We cannot call page_symlink() with transaction started 2219 + * because it calls into ext3_write_begin() which acquires page 2220 + * lock which ranks below transaction start (and it can also 2221 + * wait for journal commit if we are running out of space). So 2222 + * we have to stop transaction now and restart it when symlink 2223 + * contents is written. 2224 + * 2225 + * To keep fs consistent in case of crash, we have to put inode 2226 + * to orphan list in the mean time. 2247 2227 */ 2228 + drop_nlink(inode); 2229 + err = ext3_orphan_add(handle, inode); 2230 + ext3_journal_stop(handle); 2231 + if (err) 2232 + goto err_drop_inode; 2248 2233 err = __page_symlink(inode, symname, l, 1); 2234 + if (err) 2235 + goto err_drop_inode; 2236 + /* 2237 + * Now inode is being linked into dir (EXT3_DATA_TRANS_BLOCKS 2238 + * + EXT3_INDEX_EXTRA_TRANS_BLOCKS), inode is also modified 2239 + */ 2240 + handle = ext3_journal_start(dir, 2241 + EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + 2242 + EXT3_INDEX_EXTRA_TRANS_BLOCKS + 1); 2243 + if (IS_ERR(handle)) { 2244 + err = PTR_ERR(handle); 2245 + goto err_drop_inode; 2246 + } 2247 + inc_nlink(inode); 2248 + err = ext3_orphan_del(handle, inode); 2249 2249 if (err) { 2250 + ext3_journal_stop(handle); 2250 2251 drop_nlink(inode); 2251 - unlock_new_inode(inode); 2252 - ext3_mark_inode_dirty(handle, inode); 2253 - iput (inode); 2254 - goto out_stop; 2252 + goto err_drop_inode; 2255 2253 } 2256 2254 } else { 2257 2255 inode->i_op = &ext3_fast_symlink_inode_operations; ··· 2288 2238 ext3_journal_stop(handle); 2289 2239 if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) 2290 2240 goto retry; 2241 + return err; 2242 + err_drop_inode: 2243 + unlock_new_inode(inode); 2244 + iput(inode); 2291 2245 return err; 2292 2246 } 2293 2247
+7 -8
fs/jbd/commit.c
··· 302 302 * all outstanding updates to complete. 303 303 */ 304 304 305 - #ifdef COMMIT_STATS 306 - spin_lock(&journal->j_list_lock); 307 - summarise_journal_usage(journal); 308 - spin_unlock(&journal->j_list_lock); 309 - #endif 310 - 311 305 /* Do we need to erase the effects of a prior journal_flush? */ 312 306 if (journal->j_flags & JFS_FLUSHED) { 313 307 jbd_debug(3, "super block updated\n"); ··· 716 722 required. */ 717 723 JBUFFER_TRACE(jh, "file as BJ_Forget"); 718 724 journal_file_buffer(jh, commit_transaction, BJ_Forget); 719 - /* Wake up any transactions which were waiting for this 720 - IO to complete */ 725 + /* 726 + * Wake up any transactions which were waiting for this 727 + * IO to complete. The barrier must be here so that changes 728 + * by journal_file_buffer() take effect before wake_up_bit() 729 + * does the waitqueue check. 730 + */ 731 + smp_mb(); 721 732 wake_up_bit(&bh->b_state, BH_Unshadow); 722 733 JBUFFER_TRACE(jh, "brelse shadowed buffer"); 723 734 __brelse(bh);
+13 -3
fs/jbd/journal.c
··· 437 437 int __log_start_commit(journal_t *journal, tid_t target) 438 438 { 439 439 /* 440 - * Are we already doing a recent enough commit? 440 + * The only transaction we can possibly wait upon is the 441 + * currently running transaction (if it exists). Otherwise, 442 + * the target tid must be an old one. 441 443 */ 442 - if (!tid_geq(journal->j_commit_request, target)) { 444 + if (journal->j_running_transaction && 445 + journal->j_running_transaction->t_tid == target) { 443 446 /* 444 447 * We want a new commit: OK, mark the request and wakeup the 445 448 * commit thread. We do _not_ do the commit ourselves. ··· 454 451 journal->j_commit_sequence); 455 452 wake_up(&journal->j_wait_commit); 456 453 return 1; 457 - } 454 + } else if (!tid_geq(journal->j_commit_request, target)) 455 + /* This should never happen, but if it does, preserve 456 + the evidence before kjournald goes into a loop and 457 + increments j_commit_sequence beyond all recognition. */ 458 + WARN_ONCE(1, "jbd: bad log_start_commit: %u %u %u %u\n", 459 + journal->j_commit_request, journal->j_commit_sequence, 460 + target, journal->j_running_transaction ? 461 + journal->j_running_transaction->t_tid : 0); 458 462 return 0; 459 463 } 460 464
+2 -1
fs/jbd/transaction.c
··· 266 266 * This function is visible to journal users (like ext3fs), so is not 267 267 * called with the journal already locked. 268 268 * 269 - * Return a pointer to a newly allocated handle, or NULL on failure 269 + * Return a pointer to a newly allocated handle, or an ERR_PTR() value 270 + * on failure. 270 271 */ 271 272 handle_t *journal_start(journal_t *journal, int nblocks) 272 273 {
-6
fs/jbd2/commit.c
··· 338 338 * all outstanding updates to complete. 339 339 */ 340 340 341 - #ifdef COMMIT_STATS 342 - spin_lock(&journal->j_list_lock); 343 - summarise_journal_usage(journal); 344 - spin_unlock(&journal->j_list_lock); 345 - #endif 346 - 347 341 /* Do we need to erase the effects of a prior jbd2_journal_flush? */ 348 342 if (journal->j_flags & JBD2_FLUSHED) { 349 343 jbd_debug(3, "super block updated\n");