patch-2.4.0-prerelease linux/fs/buffer.c
Next file: linux/fs/coda/Makefile
Previous file: linux/fs/bfs/Makefile
Back to the patch index
Back to the overall index
- Lines: 228
- Date:
Sat Dec 30 11:19:13 2000
- Orig file:
v2.4.0-test12/linux/fs/buffer.c
- Orig date:
Mon Dec 11 17:59:45 2000
diff -u --recursive --new-file v2.4.0-test12/linux/fs/buffer.c linux/fs/buffer.c
@@ -122,16 +122,17 @@
when trying to refill buffers. */
int interval; /* jiffies delay between kupdate flushes */
int age_buffer; /* Time for normal buffer to age before we flush it */
- int dummy1; /* unused, was age_super */
+ int nfract_sync; /* Percentage of buffer cache dirty to
+ activate bdflush synchronously */
int dummy2; /* unused */
int dummy3; /* unused */
} b_un;
unsigned int data[N_PARAM];
-} bdf_prm = {{40, 500, 64, 256, 5*HZ, 30*HZ, 5*HZ, 1884, 2}};
+} bdf_prm = {{40, 500, 64, 256, 5*HZ, 30*HZ, 80, 0, 0}};
/* These are the min and max parameter values that we will allow to be assigned */
-int bdflush_min[N_PARAM] = { 0, 10, 5, 25, 0, 1*HZ, 1*HZ, 1, 1};
-int bdflush_max[N_PARAM] = {100,50000, 20000, 20000,600*HZ, 6000*HZ, 6000*HZ, 2047, 5};
+int bdflush_min[N_PARAM] = { 0, 10, 5, 25, 0, 1*HZ, 0, 0, 0};
+int bdflush_max[N_PARAM] = {100,50000, 20000, 20000,600*HZ, 6000*HZ, 100, 0, 0};
/*
* Rewrote the wait-routines to use the "new" wait-queue functionality,
@@ -337,9 +338,10 @@
/* sync the superblock to buffers */
sb = inode->i_sb;
- wait_on_super(sb);
+ lock_super(sb);
if (sb->s_op && sb->s_op->write_super)
sb->s_op->write_super(sb);
+ unlock_super(sb);
/* .. finally sync the buffers to disk */
dev = inode->i_dev;
@@ -369,7 +371,9 @@
/* We need to protect against concurrent writers.. */
down(&inode->i_sem);
+ filemap_fdatasync(inode->i_mapping);
err = file->f_op->fsync(file, dentry, 0);
+ filemap_fdatawait(inode->i_mapping);
up(&inode->i_sem);
out_putf:
@@ -398,7 +402,9 @@
goto out_putf;
down(&inode->i_sem);
+ filemap_fdatasync(inode->i_mapping);
err = file->f_op->fsync(file, dentry, 1);
+ filemap_fdatawait(inode->i_mapping);
up(&inode->i_sem);
out_putf:
@@ -639,8 +645,13 @@
continue;
for (i = nr_buffers_type[nlist]; i > 0 ; bh = bh_next, i--) {
bh_next = bh->b_next_free;
+
+ /* Another device? */
if (bh->b_dev != dev)
continue;
+ /* Part of a mapping? */
+ if (bh->b_page->mapping)
+ continue;
if (buffer_locked(bh)) {
atomic_inc(&bh->b_count);
spin_unlock(&lru_list_lock);
@@ -758,13 +769,6 @@
bh->b_private = private;
}
-static void end_buffer_io_bad(struct buffer_head *bh, int uptodate)
-{
- mark_buffer_uptodate(bh, uptodate);
- unlock_buffer(bh);
- BUG();
-}
-
static void end_buffer_io_async(struct buffer_head * bh, int uptodate)
{
static spinlock_t page_uptodate_lock = SPIN_LOCK_UNLOCKED;
@@ -995,7 +999,7 @@
* and it is clean.
*/
if (bh) {
- init_buffer(bh, end_buffer_io_bad, NULL);
+ init_buffer(bh, NULL, NULL);
bh->b_dev = dev;
bh->b_blocknr = block;
bh->b_state = 1 << BH_Mapped;
@@ -1030,9 +1034,9 @@
dirty = size_buffers_type[BUF_DIRTY] >> PAGE_SHIFT;
tot = nr_free_buffer_pages();
- dirty *= 200;
+ dirty *= 100;
soft_dirty_limit = tot * bdf_prm.b_un.nfract;
- hard_dirty_limit = soft_dirty_limit * 2;
+ hard_dirty_limit = tot * bdf_prm.b_un.nfract_sync;
/* First, check for the "real" dirty limit. */
if (dirty > soft_dirty_limit) {
@@ -1305,7 +1309,7 @@
set_bh_page(bh, page, offset);
bh->b_list = BUF_CLEAN;
- bh->b_end_io = end_buffer_io_bad;
+ bh->b_end_io = NULL;
}
return head;
/*
@@ -1426,7 +1430,7 @@
do {
bh->b_dev = dev;
bh->b_blocknr = 0;
- bh->b_end_io = end_buffer_io_bad;
+ bh->b_end_io = NULL;
tail = bh;
bh = bh->b_this_page;
} while (bh);
@@ -1519,13 +1523,13 @@
block++;
} while (bh != head);
- /* Stage 2: lock the buffers, mark them dirty */
+ /* Stage 2: lock the buffers, mark them clean */
do {
lock_buffer(bh);
bh->b_end_io = end_buffer_io_async;
atomic_inc(&bh->b_count);
set_bit(BH_Uptodate, &bh->b_state);
- set_bit(BH_Dirty, &bh->b_state);
+ clear_bit(BH_Dirty, &bh->b_state);
bh = bh->b_this_page;
} while (bh != head);
@@ -1664,7 +1668,7 @@
*/
int block_read_full_page(struct page *page, get_block_t *get_block)
{
- struct inode *inode = (struct inode*)page->mapping->host;
+ struct inode *inode = page->mapping->host;
unsigned long iblock, lblock;
struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
unsigned int blocksize, blocks;
@@ -1700,6 +1704,9 @@
set_bit(BH_Uptodate, &bh->b_state);
continue;
}
+ /* get_block() might have updated the buffer synchronously */
+ if (buffer_uptodate(bh))
+ continue;
}
arr[nr] = bh;
@@ -1739,7 +1746,7 @@
int cont_prepare_write(struct page *page, unsigned offset, unsigned to, get_block_t *get_block, unsigned long *bytes)
{
struct address_space *mapping = page->mapping;
- struct inode *inode = (struct inode*)mapping->host;
+ struct inode *inode = mapping->host;
struct page *new_page;
unsigned long pgpos;
long status;
@@ -1820,7 +1827,7 @@
int block_prepare_write(struct page *page, unsigned from, unsigned to,
get_block_t *get_block)
{
- struct inode *inode = (struct inode*)page->mapping->host;
+ struct inode *inode = page->mapping->host;
int err = __block_prepare_write(inode, page, from, to, get_block);
if (err) {
ClearPageUptodate(page);
@@ -1832,7 +1839,7 @@
int generic_commit_write(struct file *file, struct page *page,
unsigned from, unsigned to)
{
- struct inode *inode = (struct inode*)page->mapping->host;
+ struct inode *inode = page->mapping->host;
loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
__block_commit_write(inode,page,from,to);
kunmap(page);
@@ -1848,7 +1855,7 @@
unsigned long index = from >> PAGE_CACHE_SHIFT;
unsigned offset = from & (PAGE_CACHE_SIZE-1);
unsigned blocksize, iblock, length, pos;
- struct inode *inode = (struct inode *)mapping->host;
+ struct inode *inode = mapping->host;
struct page *page;
struct buffer_head *bh;
int err;
@@ -1908,7 +1915,7 @@
flush_dcache_page(page);
kunmap(page);
- mark_buffer_dirty(bh);
+ __mark_buffer_dirty(bh);
err = 0;
unlock:
@@ -1920,7 +1927,7 @@
int block_write_full_page(struct page *page, get_block_t *get_block)
{
- struct inode *inode = (struct inode*)page->mapping->host;
+ struct inode *inode = page->mapping->host;
unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT;
unsigned offset;
int err;
@@ -1955,7 +1962,7 @@
int generic_block_bmap(struct address_space *mapping, long block, get_block_t *get_block)
{
struct buffer_head tmp;
- struct inode *inode = (struct inode*)mapping->host;
+ struct inode *inode = mapping->host;
tmp.b_state = 0;
tmp.b_blocknr = 0;
get_block(inode, block, &tmp, 0);
@@ -2097,7 +2104,7 @@
if (rw == WRITE) {
set_bit(BH_Uptodate, &tmp->b_state);
- set_bit(BH_Dirty, &tmp->b_state);
+ clear_bit(BH_Dirty, &tmp->b_state);
}
bh[bhind++] = tmp;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)