&ei->i_prealloc_count,
&ei->i_prealloc_block, err);
else
- result = ext3_new_block (inode, goal, 0, 0, err);
+ result = ext3_new_block(inode, goal, NULL, NULL, err);
/*
* AKPM: this is somewhat sticky. I'm not surprised it was
* disabled in 2.2's ext3. Need to integrate b_committed_data
*/
}
#else
- result = ext3_new_block (handle, inode, goal, 0, 0, err);
+ result = ext3_new_block(handle, inode, goal, NULL, NULL, err);
#endif
return result;
}
static int ext3_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create)
{
- handle_t *handle = 0;
+ handle_t *handle = NULL;
int ret;
if (create) {
handle_t *handle = journal_current_handle();
int ret = 0;
- if (handle && handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) {
+ if (!handle)
+ goto get_block; /* A read */
+
+ if (handle->h_transaction->t_state == T_LOCKED) {
+ /*
+ * Huge direct-io writes can hold off commits for long
+ * periods of time. Let this commit run.
+ */
+ ext3_journal_stop(handle);
+ handle = ext3_journal_start(inode, DIO_CREDITS);
+ if (IS_ERR(handle))
+ ret = PTR_ERR(handle);
+ goto get_block;
+ }
+
+ if (handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) {
/*
* Getting low on buffer credits...
*/
- if (!ext3_journal_extend(handle, DIO_CREDITS)) {
+ ret = ext3_journal_extend(handle, DIO_CREDITS);
+ if (ret > 0) {
/*
- * Couldn't extend the transaction. Start a new one
+ * Couldn't extend the transaction. Start a new one.
*/
ret = ext3_journal_restart(handle, DIO_CREDITS);
}
}
+
+get_block:
if (ret == 0)
ret = ext3_get_block_handle(handle, inode, iblock,
bh_result, create, 0);
- if (ret == 0)
- bh_result->b_size = (1 << inode->i_blkbits);
+ bh_result->b_size = (1 << inode->i_blkbits);
return ret;
}
-
/*
* `handle' can be NULL if create is zero
*/
struct inode *inode = page->mapping->host;
int ret, needed_blocks = ext3_writepage_trans_blocks(inode);
handle_t *handle;
- int tried_commit = 0;
+ int retries = 0;
retry:
handle = ext3_journal_start(inode, needed_blocks);
goto out;
}
ret = block_prepare_write(page, from, to, ext3_get_block);
- if (ret) {
- if (ret != -ENOSPC || tried_commit)
- goto prepare_write_failed;
- /*
- * It could be that there _is_ free space, but it's all tied up
- * in uncommitted bitmaps. So force a commit here, which makes
- * those blocks allocatable and try again.
- */
- tried_commit = 1;
- handle->h_sync = 1;
- ext3_journal_stop(handle);
- goto retry;
- }
+ if (ret)
+ goto prepare_write_failed;
if (ext3_should_journal_data(inode)) {
ret = walk_page_buffers(handle, page_buffers(page),
prepare_write_failed:
if (ret)
ext3_journal_stop(handle);
+ if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
+ goto retry;
out:
return ret;
}
uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
}
- inode->i_uid = INOXID_UID(uid, gid);
- inode->i_gid = INOXID_GID(uid, gid);
- if (inode->i_sb->s_flags & MS_TAGXID)
- inode->i_xid = INOXID_XID(uid, gid, le16_to_cpu(raw_inode->i_raw_xid));
+ inode->i_uid = INOXID_UID(XID_TAG(inode), uid, gid);
+ inode->i_gid = INOXID_GID(XID_TAG(inode), uid, gid);
+ inode->i_xid = INOXID_XID(XID_TAG(inode), uid, gid,
+ le16_to_cpu(raw_inode->i_raw_xid));
inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
inode->i_size = le32_to_cpu(raw_inode->i_size);
struct ext3_inode *raw_inode = ext3_raw_inode(iloc);
struct ext3_inode_info *ei = EXT3_I(inode);
struct buffer_head *bh = iloc->bh;
- uid_t uid = XIDINO_UID(inode->i_uid, inode->i_xid);
- gid_t gid = XIDINO_GID(inode->i_gid, inode->i_xid);
+ uid_t uid = XIDINO_UID(XID_TAG(inode), inode->i_uid, inode->i_xid);
+ gid_t gid = XIDINO_GID(XID_TAG(inode), inode->i_gid, inode->i_xid);
int err = 0, rc, block;
/* For fields not not tracking in the in-memory inode,
inode->i_uid = attr->ia_uid;
if (attr->ia_valid & ATTR_GID)
inode->i_gid = attr->ia_gid;
- if (attr->ia_valid & ATTR_XID)
+ if ((attr->ia_valid & ATTR_XID)
+ && inode->i_sb
+ && (inode->i_sb->s_flags & MS_TAGXID))
inode->i_xid = attr->ia_xid;
error = ext3_mark_inode_dirty(handle, inode);
ext3_journal_stop(handle);