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