--------------------- PatchSet 893 Date: 2002/08/09 22:29:47 Author: sct Log: Update ext3_write_inode to work properly with the new inode writeback scheme. Members: fs/ext3/inode.c:1.64.2.16.2.4->1.64.2.16.2.5 [quota-branch] --- linux-2.4.21-pre3-rmap-ext3merge/fs/ext3/inode.c.=K0024=.orig 2003-01-23 16:30:32.000000000 +0000 +++ linux-2.4.21-pre3-rmap-ext3merge/fs/ext3/inode.c 2003-01-23 16:30:32.000000000 +0000 @@ -2322,16 +2322,15 @@ * trasnaction to commit. * * - Within sys_sync(), kupdate and such. - * We wait on commit, if tol to. + * We wait on commit, if told to. * * - Within prune_icache() (PF_MEMALLOC == true) - * Here we simply return. We can't afford to block kswapd on the - * journal commit. - * - * In all cases it is actually safe for us to return without doing anything, - * because the inode has been copied into a raw inode buffer in - * ext3_mark_inode_dirty(). This is a correctness thing for O_SYNC and for - * knfsd. + * Here we used to return, but that is no longer an option: we don't keep the + * buffer cache copy of the inode permanently synchronised with the inode + * cache any longer so we _have_ to propagate that information when told to + * do so. However, prune_icache currently delegates the write to a keventd + * event so this won't block kswapd. (Blocking keventd is not nice either, + * though.) * * Note that we are absolutely dependent upon all inode dirtiers doing the * right thing: they *must* call mark_inode_dirty() after dirtying info in @@ -2349,18 +2348,25 @@ */ void ext3_write_inode(struct inode *inode, int wait) { - if (current->flags & PF_MEMALLOC) - return; + handle_t *handle; + + J_ASSERT(!ext3_journal_current_handle()); + J_ASSERT(!(current->flags & PF_MEMALLOC)); - if (ext3_journal_current_handle()) { - jbd_debug(0, "called recursively, non-PF_MEMALLOC!\n"); - return; - } + lock_kernel(); + handle = ext3_journal_start(inode, 1); + if (IS_ERR(handle)) + goto out; - if (!wait) - return; + add_inode_to_commit_queue(handle, inode); + ext3_flush_inode_reservation(handle, inode); - ext3_force_commit(inode->i_sb); + if (wait) + handle->h_sync = 1; + + ext3_journal_stop(handle, inode); +out: + unlock_kernel(); } /* @@ -2496,6 +2502,8 @@ int err = 0; struct ext3_iloc *where = &EXT3_I(inode)->i_where; + J_ASSERT(handle->h_transaction->t_state != T_RUNDOWN); + if (test_and_set_bit(EXT3_STATE_INODE_RESERVATION, &EXT3_I(inode)->i_state)) return 0; @@ -2511,32 +2519,24 @@ /* Find the inode's on-disk and in-core location, and cache that * in the inode so that on commit, we can flush it to disk. */ - err = ext3_get_inode_loc(inode, &iloc); + err = ext3_get_inode_loc(inode, where); jbd_debug(3, "located inode %ld at %p\n", - inode->i_ino, iloc.raw_inode); + inode->i_ino, where->raw_inode); - if (err) - goto error; + if (!err) { + BUFFER_TRACE(where->bh, "get_write_access"); + err = ext3_journal_get_write_access(handle, where->bh); + if (err) + brelse(where->bh); + } - BUFFER_TRACE(iloc.>bh, "get_write_access"); - err = ext3_journal_get_write_access(handle, iloc.bh); if (err) - goto err_brelse; + /* FIXME --- flush will need to deal with this later. */ + where->bh = NULL; - /* Did somebody beat us to this? */ - if (test_and_set_bit(EXT3_STATE_INODE_RESERVATION, - &EXT3_I(inode)->i_state)) - goto err_brelse; - - EXT3_I(inode)->i_where = iloc; - -error: ext3_std_error(inode->i_sb, err); return err; -err_brelse: - brelse(iloc.bh); - goto error; } @@ -2604,6 +2604,7 @@ handle = ext3_journal_start(inode, 2); if (IS_ERR(handle)) goto out; + if (current_handle && current_handle->h_transaction != handle->h_transaction) { /* This task has a transaction open against a different fs */