Commit 547b39b5 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://oss.sgi.com:8090/xfs-linux-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 342ba15e 8ff67cb2
/* /*
* Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as * under the terms of version 2 of the GNU General Public License as
...@@ -156,9 +156,7 @@ linvfs_unwritten_convert_direct( ...@@ -156,9 +156,7 @@ linvfs_unwritten_convert_direct(
{ {
ASSERT(!private || inode == (struct inode *)private); ASSERT(!private || inode == (struct inode *)private);
/* private indicates an unwritten extent lay beneath this IO, /* private indicates an unwritten extent lay beneath this IO */
* see linvfs_get_block_core.
*/
if (private && size > 0) { if (private && size > 0) {
vnode_t *vp = LINVFS_GET_VP(inode); vnode_t *vp = LINVFS_GET_VP(inode);
int error; int error;
...@@ -728,11 +726,9 @@ xfs_page_state_convert( ...@@ -728,11 +726,9 @@ xfs_page_state_convert(
pgoff_t end_index, last_index, tlast; pgoff_t end_index, last_index, tlast;
int len, err, i, cnt = 0, uptodate = 1; int len, err, i, cnt = 0, uptodate = 1;
int flags = startio ? 0 : BMAPI_TRYLOCK; int flags = startio ? 0 : BMAPI_TRYLOCK;
int page_dirty = 1; int page_dirty, delalloc = 0;
int delalloc = 0;
/* Are we off the end of the file ? */ /* Is this page beyond the end of the file? */
offset = i_size_read(inode); offset = i_size_read(inode);
end_index = offset >> PAGE_CACHE_SHIFT; end_index = offset >> PAGE_CACHE_SHIFT;
last_index = (offset - 1) >> PAGE_CACHE_SHIFT; last_index = (offset - 1) >> PAGE_CACHE_SHIFT;
...@@ -751,7 +747,13 @@ xfs_page_state_convert( ...@@ -751,7 +747,13 @@ xfs_page_state_convert(
bh = head = page_buffers(page); bh = head = page_buffers(page);
iomp = NULL; iomp = NULL;
/*
* page_dirty is initially a count of buffers on the page and
* is decrememted as we move each into a cleanable state.
*/
len = bh->b_size; len = bh->b_size;
page_dirty = PAGE_CACHE_SIZE / len;
do { do {
if (offset >= end_offset) if (offset >= end_offset)
break; break;
...@@ -794,7 +796,7 @@ xfs_page_state_convert( ...@@ -794,7 +796,7 @@ xfs_page_state_convert(
} }
BUG_ON(!buffer_locked(bh)); BUG_ON(!buffer_locked(bh));
bh_arr[cnt++] = bh; bh_arr[cnt++] = bh;
page_dirty = 0; page_dirty--;
} }
/* /*
* Second case, allocate space for a delalloc buffer. * Second case, allocate space for a delalloc buffer.
...@@ -821,7 +823,7 @@ xfs_page_state_convert( ...@@ -821,7 +823,7 @@ xfs_page_state_convert(
unlock_buffer(bh); unlock_buffer(bh);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
} }
page_dirty = 0; page_dirty--;
} }
} else if ((buffer_uptodate(bh) || PageUptodate(page)) && } else if ((buffer_uptodate(bh) || PageUptodate(page)) &&
(unmapped || startio)) { (unmapped || startio)) {
...@@ -857,13 +859,13 @@ xfs_page_state_convert( ...@@ -857,13 +859,13 @@ xfs_page_state_convert(
unlock_buffer(bh); unlock_buffer(bh);
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
} }
page_dirty = 0; page_dirty--;
} }
} else if (startio) { } else if (startio) {
if (buffer_uptodate(bh) && if (buffer_uptodate(bh) &&
!test_and_set_bit(BH_Lock, &bh->b_state)) { !test_and_set_bit(BH_Lock, &bh->b_state)) {
bh_arr[cnt++] = bh; bh_arr[cnt++] = bh;
page_dirty = 0; page_dirty--;
} }
} }
} }
...@@ -907,7 +909,7 @@ xfs_page_state_convert( ...@@ -907,7 +909,7 @@ xfs_page_state_convert(
} }
STATIC int STATIC int
linvfs_get_block_core( __linvfs_get_block(
struct inode *inode, struct inode *inode,
sector_t iblock, sector_t iblock,
unsigned long blocks, unsigned long blocks,
...@@ -977,10 +979,10 @@ linvfs_get_block_core( ...@@ -977,10 +979,10 @@ linvfs_get_block_core(
if (iomap.iomap_flags & IOMAP_DELAY) { if (iomap.iomap_flags & IOMAP_DELAY) {
BUG_ON(direct); BUG_ON(direct);
if (create) { if (create) {
set_buffer_mapped(bh_result);
set_buffer_uptodate(bh_result); set_buffer_uptodate(bh_result);
set_buffer_mapped(bh_result);
set_buffer_delay(bh_result);
} }
set_buffer_delay(bh_result);
} }
if (blocks) { if (blocks) {
...@@ -999,7 +1001,7 @@ linvfs_get_block( ...@@ -999,7 +1001,7 @@ linvfs_get_block(
struct buffer_head *bh_result, struct buffer_head *bh_result,
int create) int create)
{ {
return linvfs_get_block_core(inode, iblock, 0, bh_result, return __linvfs_get_block(inode, iblock, 0, bh_result,
create, 0, BMAPI_WRITE); create, 0, BMAPI_WRITE);
} }
...@@ -1011,7 +1013,7 @@ linvfs_get_blocks_direct( ...@@ -1011,7 +1013,7 @@ linvfs_get_blocks_direct(
struct buffer_head *bh_result, struct buffer_head *bh_result,
int create) int create)
{ {
return linvfs_get_block_core(inode, iblock, max_blocks, bh_result, return __linvfs_get_block(inode, iblock, max_blocks, bh_result,
create, 1, BMAPI_WRITE|BMAPI_DIRECT); create, 1, BMAPI_WRITE|BMAPI_DIRECT);
} }
......
...@@ -676,6 +676,8 @@ xfs_write( ...@@ -676,6 +676,8 @@ xfs_write(
if (XFS_FORCED_SHUTDOWN(mp)) if (XFS_FORCED_SHUTDOWN(mp))
return -EIO; return -EIO;
fs_check_frozen(vp->v_vfsp, SB_FREEZE_WRITE);
if (ioflags & IO_ISDIRECT) { if (ioflags & IO_ISDIRECT) {
xfs_buftarg_t *target = xfs_buftarg_t *target =
(xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
...@@ -960,9 +962,9 @@ xfs_write( ...@@ -960,9 +962,9 @@ xfs_write(
xfs_trans_set_sync(tp); xfs_trans_set_sync(tp);
error = xfs_trans_commit(tp, 0, NULL); error = xfs_trans_commit(tp, 0, NULL);
xfs_iunlock(xip, XFS_ILOCK_EXCL); xfs_iunlock(xip, XFS_ILOCK_EXCL);
if (error)
goto out_unlock_internal;
} }
if (error)
goto out_unlock_internal;
} }
xfs_rwunlock(bdp, locktype); xfs_rwunlock(bdp, locktype);
......
...@@ -348,6 +348,12 @@ linvfs_write_inode( ...@@ -348,6 +348,12 @@ linvfs_write_inode(
if (sync) if (sync)
flags |= FLUSH_SYNC; flags |= FLUSH_SYNC;
VOP_IFLUSH(vp, flags, error); VOP_IFLUSH(vp, flags, error);
if (error == EAGAIN) {
if (sync)
VOP_IFLUSH(vp, flags | FLUSH_LOG, error);
else
error = 0;
}
} }
return -error; return -error;
......
...@@ -3681,27 +3681,27 @@ xfs_inode_flush( ...@@ -3681,27 +3681,27 @@ xfs_inode_flush(
{ {
xfs_inode_t *ip; xfs_inode_t *ip;
xfs_mount_t *mp; xfs_mount_t *mp;
xfs_inode_log_item_t *iip;
int error = 0; int error = 0;
ip = XFS_BHVTOI(bdp); ip = XFS_BHVTOI(bdp);
mp = ip->i_mount; mp = ip->i_mount;
iip = ip->i_itemp;
if (XFS_FORCED_SHUTDOWN(mp)) if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO); return XFS_ERROR(EIO);
/* Bypass inodes which have already been cleaned by /*
* Bypass inodes which have already been cleaned by
* the inode flush clustering code inside xfs_iflush * the inode flush clustering code inside xfs_iflush
*/ */
if ((ip->i_update_core == 0) && if ((ip->i_update_core == 0) &&
((ip->i_itemp == NULL) || ((iip == NULL) || !(iip->ili_format.ilf_fields & XFS_ILOG_ALL)))
!(ip->i_itemp->ili_format.ilf_fields & XFS_ILOG_ALL)))
return 0; return 0;
if (flags & FLUSH_LOG) { if (flags & FLUSH_LOG) {
xfs_inode_log_item_t *iip = ip->i_itemp;
if (iip && iip->ili_last_lsn) { if (iip && iip->ili_last_lsn) {
xlog_t *log = mp->m_log; xlog_t *log = mp->m_log;
xfs_lsn_t sync_lsn; xfs_lsn_t sync_lsn;
int s, log_flags = XFS_LOG_FORCE; int s, log_flags = XFS_LOG_FORCE;
...@@ -3714,12 +3714,12 @@ xfs_inode_flush( ...@@ -3714,12 +3714,12 @@ xfs_inode_flush(
if (flags & FLUSH_SYNC) if (flags & FLUSH_SYNC)
log_flags |= XFS_LOG_SYNC; log_flags |= XFS_LOG_SYNC;
return xfs_log_force(mp, iip->ili_last_lsn, return xfs_log_force(mp, iip->ili_last_lsn, log_flags);
log_flags);
} }
} }
/* We make this non-blocking if the inode is contended, /*
* We make this non-blocking if the inode is contended,
* return EAGAIN to indicate to the caller that they * return EAGAIN to indicate to the caller that they
* did not succeed. This prevents the flush path from * did not succeed. This prevents the flush path from
* blocking on inodes inside another operation right * blocking on inodes inside another operation right
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment