2 --- linux-2.4.18/fs/ext3/inode.c~ext3-o_direct-1-2.4.18-chaos Mon Jul 28 14:13:05 2003
3 +++ linux-2.4.18-alexey/fs/ext3/inode.c Mon Jul 28 15:50:14 2003
5 #include <linux/ext3_jbd.h>
7 #include <linux/locks.h>
8 +#include <linux/iobuf.h>
9 #include <linux/smp_lock.h>
10 #include <linux/highuid.h>
11 #include <linux/quotaops.h>
12 @@ -733,9 +734,9 @@ err_out:
13 * The BKL may not be held on entry here. Be sure to take it early.
16 -static int ext3_get_block_handle(handle_t *handle, struct inode *inode,
18 - struct buffer_head *bh_result, int create)
20 +ext3_get_block_handle(handle_t *handle, struct inode *inode, long iblock,
21 + struct buffer_head *bh_result, int create, int extend_disksize)
25 @@ -816,16 +817,18 @@ out:
29 - new_size = inode->i_size;
31 - * This is not racy against ext3_truncate's modification of i_disksize
32 - * because VM/VFS ensures that the file cannot be extended while
33 - * truncate is in progress. It is racy between multiple parallel
34 - * instances of get_block, but we have the BKL.
36 - if (new_size > ei->i_disksize)
37 - ei->i_disksize = new_size;
39 + if (extend_disksize) {
41 + * This is not racy against ext3_truncate's modification of
42 + * i_disksize because VM/VFS ensures that the file cannot be
43 + * extended while truncate is in progress. It is racy between
44 + * multiple parallel instances of get_block, but we have BKL.
46 + struct ext3_inode_info *ei = EXT3_I(inode);
47 + new_size = inode->i_size;
48 + if (new_size > ei->i_disksize)
49 + ei->i_disksize = new_size;
51 bh_result->b_state |= (1UL << BH_New);
54 @@ -852,7 +855,38 @@ static int ext3_get_block(struct inode *
55 handle = ext3_journal_current_handle();
56 J_ASSERT(handle != 0);
58 - ret = ext3_get_block_handle(handle, inode, iblock, bh_result, create);
59 + ret = ext3_get_block_handle(handle, inode, iblock,
60 + bh_result, create, 1);
64 +#define DIO_CREDITS (EXT3_RESERVE_TRANS_BLOCKS + 32)
67 +ext3_direct_io_get_block(struct inode *inode, long iblock,
68 + struct buffer_head *bh_result, int create)
70 + handle_t *handle = journal_current_handle();
74 + if (handle && handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) {
76 + * Getting low on buffer credits...
78 + if (!ext3_journal_extend(handle, DIO_CREDITS)) {
80 + * Couldn't extend the transaction. Start a new one
82 + ret = ext3_journal_restart(handle, DIO_CREDITS);
86 + ret = ext3_get_block_handle(handle, inode, iblock,
87 + bh_result, create, 0);
89 + bh_result->b_size = (1 << inode->i_blkbits);
94 @@ -870,7 +904,7 @@ struct buffer_head *ext3_getblk(handle_t
96 dummy.b_blocknr = -1000;
97 buffer_trace_init(&dummy.b_history);
98 - *errp = ext3_get_block_handle(handle, inode, block, &dummy, create);
99 + *errp = ext3_get_block_handle(handle, inode, block, &dummy, create, 1);
100 if (!*errp && buffer_mapped(&dummy)) {
101 struct buffer_head *bh;
102 bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
103 @@ -1380,6 +1414,67 @@ static int ext3_releasepage(struct page
104 return journal_try_to_free_buffers(journal, page, wait);
108 +ext3_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf,
109 + unsigned long blocknr, int blocksize)
111 + struct ext3_inode_info *ei = EXT3_I(inode);
112 + handle_t *handle = NULL;
115 + loff_t offset = blocknr << inode->i_blkbits; /* ugh */
116 + ssize_t count = iobuf->length; /* ditto */
119 + loff_t final_size = offset + count;
122 + handle = ext3_journal_start(inode, DIO_CREDITS);
124 + if (IS_ERR(handle)) {
125 + ret = PTR_ERR(handle);
128 + if (final_size > inode->i_size) {
130 + ret = ext3_orphan_add(handle, inode);
135 + ei->i_disksize = inode->i_size;
139 + ret = generic_direct_IO(rw, inode, iobuf, blocknr,
140 + blocksize, ext3_direct_io_get_block);
148 + ext3_orphan_del(handle, inode);
149 + if (orphan && ret > 0) {
150 + loff_t end = offset + ret;
151 + if (end > inode->i_size) {
152 + ei->i_disksize = end;
153 + inode->i_size = end;
154 + err = ext3_mark_inode_dirty(handle, inode);
159 + err = ext3_journal_stop(handle, inode);
169 struct address_space_operations ext3_aops = {
170 readpage: ext3_readpage, /* BKL not held. Don't need */
171 @@ -1390,6 +1485,7 @@ struct address_space_operations ext3_aop
172 bmap: ext3_bmap, /* BKL held */
173 flushpage: ext3_flushpage, /* BKL not held. Don't need */
174 releasepage: ext3_releasepage, /* BKL not held. Don't need */
175 + direct_IO: ext3_direct_IO, /* BKL not held. Don't need */
179 @@ -2987,7 +3083,7 @@ int ext3_prep_san_write(struct inode *in
180 /* alloc blocks one by one */
181 for (i = 0; i < nblocks; i++) {
182 ret = ext3_get_block_handle(handle, inode, blocks[i],
188 @@ -3047,7 +3143,7 @@ int ext3_map_inode_page(struct inode *in
192 - rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1);
193 + rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1, 1);
195 printk(KERN_INFO "ext3_map_inode_page: error %d "
196 "allocating block %ld\n", rc, iblock);