Whamcloud - gitweb
- configurable stack size fo x86_64
[fs/lustre-release.git] / lustre / kernel_patches / patches / ext3-o_direct-1-2.4.18-chaos.patch
1
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
4 @@ -27,6 +27,7 @@
5  #include <linux/ext3_jbd.h>
6  #include <linux/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.
14   */
15  
16 -static int ext3_get_block_handle(handle_t *handle, struct inode *inode, 
17 -                                long iblock,
18 -                                struct buffer_head *bh_result, int create)
19 +static int
20 +ext3_get_block_handle(handle_t *handle, struct inode *inode, long iblock,
21 +               struct buffer_head *bh_result, int create, int extend_disksize)
22  {
23         int err = -EIO;
24         int offsets[4];
25 @@ -816,16 +817,18 @@ out:
26         if (err)
27                 goto cleanup;
28  
29 -       new_size = inode->i_size;
30 -       /*
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.
35 -        */
36 -       if (new_size > ei->i_disksize)
37 -               ei->i_disksize = new_size;
38 -
39 +       if (extend_disksize) {
40 +               /*
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.
45 +                */
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;
50 +       }
51         bh_result->b_state |= (1UL << BH_New);
52         goto got_it;
53  
54 @@ -852,7 +855,38 @@ static int ext3_get_block(struct inode *
55                 handle = ext3_journal_current_handle();
56                 J_ASSERT(handle != 0);
57         }
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);
61 +       return ret;
62 +}
63 +
64 +#define DIO_CREDITS (EXT3_RESERVE_TRANS_BLOCKS + 32)
65 +
66 +static int
67 +ext3_direct_io_get_block(struct inode *inode, long iblock,
68 +               struct buffer_head *bh_result, int create)
69 +{
70 +       handle_t *handle = journal_current_handle();
71 +       int ret = 0;
72 +
73 +       lock_kernel();
74 +       if (handle && handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) {
75 +               /*
76 +                * Getting low on buffer credits...
77 +                */
78 +               if (!ext3_journal_extend(handle, DIO_CREDITS)) {
79 +                       /*
80 +                        * Couldn't extend the transaction.  Start a new one
81 +                        */
82 +                       ret = ext3_journal_restart(handle, DIO_CREDITS);
83 +               }
84 +       }
85 +       if (ret == 0)
86 +               ret = ext3_get_block_handle(handle, inode, iblock,
87 +                                       bh_result, create, 0);
88 +       if (ret == 0)
89 +               bh_result->b_size = (1 << inode->i_blkbits);
90 +       unlock_kernel();
91         return ret;
92  }
93  
94 @@ -870,7 +904,7 @@ struct buffer_head *ext3_getblk(handle_t
95         dummy.b_state = 0;
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);
105  }
106  
107 +static int
108 +ext3_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf,
109 +               unsigned long blocknr, int blocksize)
110 +{
111 +       struct ext3_inode_info *ei = EXT3_I(inode);
112 +       handle_t *handle = NULL;
113 +       int ret;
114 +       int orphan = 0;
115 +       loff_t offset = blocknr << inode->i_blkbits;    /* ugh */
116 +       ssize_t count = iobuf->length;                  /* ditto */
117 +
118 +       if (rw == WRITE) {
119 +               loff_t final_size = offset + count;
120 +
121 +               lock_kernel();
122 +               handle = ext3_journal_start(inode, DIO_CREDITS);
123 +               unlock_kernel();
124 +               if (IS_ERR(handle)) {
125 +                       ret = PTR_ERR(handle);
126 +                       goto out;
127 +               }
128 +               if (final_size > inode->i_size) {
129 +                       lock_kernel();
130 +                       ret = ext3_orphan_add(handle, inode);
131 +                       unlock_kernel();
132 +                       if (ret)
133 +                               goto out_stop;
134 +                       orphan = 1;
135 +                       ei->i_disksize = inode->i_size;
136 +               }
137 +       }
138 +
139 +       ret = generic_direct_IO(rw, inode, iobuf, blocknr,
140 +                               blocksize, ext3_direct_io_get_block);
141 +
142 +out_stop:
143 +       if (handle) {
144 +               int err;
145 +
146 +               lock_kernel();
147 +               if (orphan) 
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);
155 +                               if (!ret) 
156 +                                       ret = err;
157 +                       }
158 +               }
159 +               err = ext3_journal_stop(handle, inode);
160 +               if (ret == 0)
161 +                       ret = err;
162 +               unlock_kernel();
163 +       }
164 +out:
165 +       return ret;
166 +
167 +}
168  
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 */
176  };
177  
178  /*
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],
183 -                                               &bh_tmp, 1);
184 +                                               &bh_tmp, 1, 1);
185                 if (ret)
186                         break;
187  
188 @@ -3047,7 +3143,7 @@ int ext3_map_inode_page(struct inode *in
189                  if (blocks[i] != 0)
190                          continue;
191  
192 -                rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1);
193 +                rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1, 1);
194                  if (rc) {
195                          printk(KERN_INFO "ext3_map_inode_page: error %d "
196                                 "allocating block %ld\n", rc, iblock);
197
198 _