1 --- 2.4.20-pre2/fs/ext3/inode.c~ext3-o_direct Thu Aug 15 01:11:02 2002
2 +++ 2.4.20-pre2-akpm/fs/ext3/inode.c Thu Aug 15 01:25:55 2002
4 #include <linux/ext3_jbd.h>
6 #include <linux/locks.h>
7 +#include <linux/iobuf.h>
8 #include <linux/smp_lock.h>
9 #include <linux/highuid.h>
10 #include <linux/quotaops.h>
11 @@ -716,9 +717,9 @@ err_out:
12 * The BKL may not be held on entry here. Be sure to take it early.
15 -static int ext3_get_block_handle(handle_t *handle, struct inode *inode,
17 - struct buffer_head *bh_result, int create)
19 +ext3_get_block_handle(handle_t *handle, struct inode *inode, long iblock,
20 + struct buffer_head *bh_result, int create, int extend_disksize)
24 @@ -798,16 +799,18 @@ out:
28 - new_size = inode->i_size;
30 - * This is not racy against ext3_truncate's modification of i_disksize
31 - * because VM/VFS ensures that the file cannot be extended while
32 - * truncate is in progress. It is racy between multiple parallel
33 - * instances of get_block, but we have the BKL.
35 - if (new_size > inode->u.ext3_i.i_disksize)
36 - inode->u.ext3_i.i_disksize = new_size;
38 + if (extend_disksize) {
40 + * This is not racy against ext3_truncate's modification of
41 + * i_disksize because VM/VFS ensures that the file cannot be
42 + * extended while truncate is in progress. It is racy between
43 + * multiple parallel instances of get_block, but we have BKL.
45 + struct ext3_inode_info *ei = EXT3_I(inode);
46 + new_size = inode->i_size;
47 + if (new_size > ei->i_disksize)
48 + ei->i_disksize = new_size;
50 bh_result->b_state |= (1UL << BH_New);
53 @@ -834,7 +837,38 @@ static int ext3_get_block(struct inode *
54 handle = ext3_journal_current_handle();
55 J_ASSERT(handle != 0);
57 - ret = ext3_get_block_handle(handle, inode, iblock, bh_result, create);
58 + ret = ext3_get_block_handle(handle, inode, iblock,
59 + bh_result, create, 1);
63 +#define DIO_CREDITS (EXT3_RESERVE_TRANS_BLOCKS + 32)
66 +ext3_direct_io_get_block(struct inode *inode, long iblock,
67 + struct buffer_head *bh_result, int create)
69 + handle_t *handle = journal_current_handle();
73 + if (handle && handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) {
75 + * Getting low on buffer credits...
77 + if (!ext3_journal_extend(handle, DIO_CREDITS)) {
79 + * Couldn't extend the transaction. Start a new one
81 + ret = ext3_journal_restart(handle, DIO_CREDITS);
85 + ret = ext3_get_block_handle(handle, inode, iblock,
86 + bh_result, create, 0);
88 + bh_result->b_size = (1 << inode->i_blkbits);
93 @@ -852,7 +886,7 @@ struct buffer_head *ext3_getblk(handle_t
95 dummy.b_blocknr = -1000;
96 buffer_trace_init(&dummy.b_history);
97 - *errp = ext3_get_block_handle(handle, inode, block, &dummy, create);
98 + *errp = ext3_get_block_handle(handle, inode, block, &dummy, create, 1);
99 if (!*errp && buffer_mapped(&dummy)) {
100 struct buffer_head *bh;
101 bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
102 @@ -1349,6 +1383,67 @@ static int ext3_releasepage(struct page
103 return journal_try_to_free_buffers(journal, page, wait);
107 +ext3_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf,
108 + unsigned long blocknr, int blocksize)
110 + struct ext3_inode_info *ei = EXT3_I(inode);
111 + handle_t *handle = NULL;
114 + loff_t offset = blocknr << inode->i_blkbits; /* ugh */
115 + ssize_t count = iobuf->length; /* ditto */
118 + loff_t final_size = offset + count;
121 + handle = ext3_journal_start(inode, DIO_CREDITS);
123 + if (IS_ERR(handle)) {
124 + ret = PTR_ERR(handle);
127 + if (final_size > inode->i_size) {
129 + ret = ext3_orphan_add(handle, inode);
134 + ei->i_disksize = inode->i_size;
138 + ret = generic_direct_IO(rw, inode, iobuf, blocknr,
139 + blocksize, ext3_direct_io_get_block);
147 + ext3_orphan_del(handle, inode);
148 + if (orphan && ret > 0) {
149 + loff_t end = offset + ret;
150 + if (end > inode->i_size) {
151 + ei->i_disksize = end;
152 + inode->i_size = end;
153 + err = ext3_mark_inode_dirty(handle, inode);
158 + err = ext3_journal_stop(handle, inode);
168 struct address_space_operations ext3_aops = {
169 readpage: ext3_readpage, /* BKL not held. Don't need */
170 @@ -1359,6 +1454,7 @@ struct address_space_operations ext3_aop
171 bmap: ext3_bmap, /* BKL held */
172 flushpage: ext3_flushpage, /* BKL not held. Don't need */
173 releasepage: ext3_releasepage, /* BKL not held. Don't need */
174 + direct_IO: ext3_direct_IO, /* BKL not held. Don't need */