Commit b33cc8f7 authored by Russell Cattelan's avatar Russell Cattelan Committed by Christoph Hellwig

[XFS] "merge" the 2.4 fsx fix for block size < page size to 2.5. This needed

major changes to actually fit.

SGI Modid: 2.5.x-xfs:slinx:132210a
parent 3b1b949f
......@@ -1453,6 +1453,7 @@ static inline void discard_buffer(struct buffer_head * bh)
clear_buffer_mapped(bh);
clear_buffer_req(bh);
clear_buffer_new(bh);
clear_buffer_delay(bh);
unlock_buffer(bh);
}
......@@ -1871,7 +1872,7 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
set_buffer_uptodate(bh);
continue;
}
if (!buffer_uptodate(bh) &&
if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
(block_start < from || block_end > to)) {
ll_rw_block(READ, 1, &bh);
*wait_bh++=bh;
......@@ -2457,7 +2458,7 @@ int block_truncate_page(struct address_space *mapping,
if (PageUptodate(page))
set_buffer_uptodate(bh);
if (!buffer_uptodate(bh)) {
if (!buffer_uptodate(bh) && !buffer_delay(bh)) {
err = -EIO;
ll_rw_block(READ, 1, &bh);
wait_on_buffer(bh);
......
......@@ -51,23 +51,22 @@ export-objs := pagebuf/page_buf.o support/ktrace.o \
obj-$(CONFIG_XFS_FS) += xfs.o
xfs-obj-$(CONFIG_XFS_RT) += xfs_rtalloc.o
xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o
xfs-obj-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \
xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \
xfs_dquot_item.o \
xfs_trans_dquot.o \
xfs_qm_syscalls.o \
xfs_qm.o
xfs-obj-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
xfs-obj-$(CONFIG_FS_POSIX_CAP) += xfs_cap.o
xfs-obj-$(CONFIG_FS_POSIX_MAC) += xfs_mac.o
xfs-obj-$(CONFIG_PROC_FS) += linux/xfs_stats.o
xfs-obj-$(CONFIG_SYSCTL) += linux/xfs_sysctl.o
xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o
xfs-$(CONFIG_FS_POSIX_CAP) += xfs_cap.o
xfs-$(CONFIG_FS_POSIX_MAC) += xfs_mac.o
xfs-$(CONFIG_PROC_FS) += linux/xfs_stats.o
xfs-$(CONFIG_SYSCTL) += linux/xfs_sysctl.o
xfs-objs += $(xfs-obj-y) \
xfs_alloc.o \
xfs-y += xfs_alloc.o \
xfs_alloc_btree.o \
xfs_attr.o \
xfs_attr_fetch.o \
......@@ -115,12 +114,12 @@ xfs-objs += $(xfs-obj-y) \
xfs_rw.o
# Objects in pagebuf/
xfs-objs += $(addprefix pagebuf/, \
xfs-y += $(addprefix pagebuf/, \
page_buf.o \
page_buf_locking.o)
# Objects in linux/
xfs-objs += $(addprefix linux/, \
xfs-y += $(addprefix linux/, \
xfs_aops.o \
xfs_behavior.o \
xfs_file.o \
......@@ -134,7 +133,7 @@ xfs-objs += $(addprefix linux/, \
xfs_vnode.o)
# Objects in support/
xfs-objs += $(addprefix support/, \
xfs-y += $(addprefix support/, \
debug.o \
kmem.o \
ktrace.o \
......
......@@ -148,9 +148,8 @@ probe_unmapped_page(
struct buffer_head *bh, *head;
bh = head = page_buffers(page);
do {
if (buffer_mapped(bh) || !buffer_uptodate(bh)) {
if (buffer_mapped(bh) || !buffer_uptodate(bh))
break;
}
ret += bh->b_size;
if (ret >= pg_offset)
break;
......@@ -292,7 +291,7 @@ convert_page(
bh = head = page_buffers(page);
do {
offset = i << bbits;
if (!buffer_uptodate(bh))
if (!(PageUptodate(page) || buffer_uptodate(bh)))
continue;
if (buffer_mapped(bh) && !buffer_delay(bh) && all_bh) {
if (startio && (offset < end)) {
......@@ -375,7 +374,7 @@ delalloc_convert(
page_buf_bmap_t *mp, map;
unsigned long p_offset = 0, end_index;
loff_t offset, end_offset;
int len, err, i, cnt = 0;
int len, err, i, cnt = 0, uptodate = 1;
/* Are we off the end of the file ? */
end_index = inode->i_size >> PAGE_CACHE_SHIFT;
......@@ -399,7 +398,7 @@ delalloc_convert(
len = bh->b_size;
do {
if (!buffer_uptodate(bh) && !startio) {
if (!(PageUptodate(page) || buffer_uptodate(bh)) && !startio) {
goto next_bh;
}
......@@ -426,48 +425,57 @@ delalloc_convert(
unlock_buffer(bh);
}
}
} else if (!buffer_mapped(bh) &&
(buffer_uptodate(bh) || PageUptodate(page))
&& (allocate_space || startio)) {
int size;
/* Getting here implies an unmapped buffer was found,
* and we are in a path where we need to write the
* whole page out.
*/
if (!mp) {
size = probe_unmapped_cluster(inode, page,
bh, head);
err = map_blocks(inode, offset, size, &map,
PBF_WRITE|PBF_DIRECT);
if (err) {
goto error;
} else if ((buffer_uptodate(bh) || PageUptodate(page)) &&
(allocate_space || startio)) {
if (!buffer_mapped(bh)) {
int size;
/*
* Getting here implies an unmapped buffer
* was found, and we are in a path where we
* need to write the whole page out.
*/
if (!mp) {
size = probe_unmapped_cluster(
inode, page, bh, head);
err = map_blocks(inode, offset,
size, &map,
PBF_WRITE | PBF_DIRECT);
if (err) {
goto error;
}
mp = match_offset_to_mapping(page, &map,
p_offset);
}
mp = match_offset_to_mapping(page, &map,
p_offset);
}
if (mp) {
map_buffer_at_offset(page, bh, p_offset,
inode->i_blkbits, mp);
if (startio) {
if (mp) {
map_buffer_at_offset(page,
bh, p_offset,
inode->i_blkbits, mp);
if (startio) {
bh_arr[cnt++] = bh;
} else {
unlock_buffer(bh);
}
}
} else if (startio && buffer_mapped(bh)) {
if (buffer_uptodate(bh) && allocate_space) {
lock_buffer(bh);
bh_arr[cnt++] = bh;
} else {
unlock_buffer(bh);
}
}
} else if (startio && buffer_mapped(bh)) {
if(buffer_uptodate(bh) && allocate_space) {
lock_buffer(bh);
bh_arr[cnt++] = bh;
}
}
next_bh:
if (!buffer_uptodate(bh))
uptodate = 0;
offset += len;
p_offset += len;
bh = bh->b_this_page;
} while (offset < end_offset);
if (uptodate)
SetPageUptodate(page);
if (startio) {
submit_page(page, bh_arr, cnt);
}
......@@ -512,17 +520,15 @@ linvfs_get_block_core(
ssize_t size;
loff_t offset = (loff_t)iblock << inode->i_blkbits;
if (blocks) {
/* If we are doing writes at the end of the file,
* allocate in chunks
*/
if (blocks)
size = blocks << inode->i_blkbits;
} else {
/* If we are doing writes at the end of the file,
* allocate in chunks
*/
if (create && (offset >= inode->i_size))
size = 1 << XFS_WRITE_IO_LOG;
else
size = 1 << inode->i_blkbits;
}
else if (create && (offset >= inode->i_size))
size = 1 << XFS_WRITE_IO_LOG;
else
size = 1 << inode->i_blkbits;
VOP_BMAP(vp, offset, size,
create ? flags : PBF_READ,
......
......@@ -48,9 +48,6 @@
#include <linux/buffer_head.h>
#include <linux/uio.h>
enum xfs_buffer_state { BH_Delay = BH_PrivateStart };
BUFFER_FNS(Delay, delay);
/*
* Turn this on to get pagebuf lock ownership
#define PAGEBUF_LOCK_TRACKING
......
......@@ -22,6 +22,7 @@ enum bh_state_bits {
BH_New, /* Disk mapping was newly created by get_block */
BH_Async_Read, /* Is under end_buffer_async_read I/O */
BH_Async_Write, /* Is under end_buffer_async_write I/O */
BH_Delay, /* Buffer is not yet allocated on disk */
BH_Boundary, /* Block is followed by a discontiguity */
BH_PrivateStart,/* not a state bit, but the first bit available
......@@ -105,6 +106,7 @@ BUFFER_FNS(Mapped, mapped)
BUFFER_FNS(New, new)
BUFFER_FNS(Async_Read, async_read)
BUFFER_FNS(Async_Write, async_write)
BUFFER_FNS(Delay, delay);
BUFFER_FNS(Boundary, boundary)
#define bh_offset(bh) ((unsigned long)(bh)->b_data & ~PAGE_MASK)
......
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