More commit description fixups
[ext4-patch-queue.git] / JC3-journal_credit_fix_for_dio_fallocate.patch
blobc5fd56384b25cca0fbbbbbf162a082d1590bcc50
1 ext4: journal credits reservation fixes for DIO, fallocate
3 From: Mingming Cao <cmm@us.ibm.com>
5 DIO and fallocate credit calculation is different than writepage, as
6 they do start a new journal right for each call to ext4_get_blocks_wrap().
7 This patch uses the helper function in DIO and fallocate case, passing
8 a flag indicating that the modified data are contigous thus could account
9 less indirect/index blocks.
11 This patch also fixed the journal credit reservation for direct I/O
12 (DIO). Previously the estimated credits for DIO only was calculated for
13 non-extent files, which was not enough if the file is extent-based.
15 Also fixed was fallocate double-counting credits for modifying the the
16 superblock.
18 Signed-off-by: Mingming Cao <cmm@us.ibm.com>
19 Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
20 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
21 ---
22 fs/ext4/ext4.h | 1 +
23 fs/ext4/extents.c | 14 +++++++-------
24 fs/ext4/inode.c | 45 ++++++++++++++++++++++++---------------------
25 3 files changed, 32 insertions(+), 28 deletions(-)
27 ===================================================================
28 Index: linux-2.6.27-rc3/fs/ext4/extents.c
29 ===================================================================
30 --- linux-2.6.27-rc3.orig/fs/ext4/extents.c 2008-08-18 12:17:27.000000000 -0700
31 +++ linux-2.6.27-rc3/fs/ext4/extents.c 2008-08-18 12:20:11.000000000 -0700
32 @@ -1758,7 +1758,7 @@ int ext4_ext_calc_credits_for_single_ext
34 if (path) {
35 int depth = ext_depth(inode);
36 - int ret;
37 + int ret = 0;
39 /* probably there is space in leaf? */
40 if (le16_to_cpu(path[depth].p_hdr->eh_entries)
41 @@ -1777,7 +1777,7 @@ int ext4_ext_calc_credits_for_single_ext
45 - return ext4_meta_trans_blocks(inode, num, 1);
46 + return ext4_chunk_trans_blocks(inode, num);
50 @@ -2810,7 +2810,7 @@ void ext4_ext_truncate(struct inode *ino
52 * probably first extent we're gonna free will be last in block
54 - err = ext4_writepage_trans_blocks(inode) + 3;
55 + err = ext4_writepage_trans_blocks(inode);
56 handle = ext4_journal_start(inode, err);
57 if (IS_ERR(handle))
58 return;
59 @@ -2923,10 +2923,9 @@ long ext4_fallocate(struct inode *inode,
60 max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits)
61 - block;
63 - * credits to insert 1 extent into extent tree + buffers to be able to
64 - * modify 1 super block, 1 block bitmap and 1 group descriptor.
65 + * credits to insert 1 extent into extent tree
67 - credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3;
68 + credits = ext4_chunk_trans_blocks(inode, max_blocks);
69 mutex_lock(&inode->i_mutex);
70 retry:
71 while (ret >= 0 && ret < max_blocks) {
72 Index: linux-2.6.27-rc3/fs/ext4/inode.c
73 ===================================================================
74 --- linux-2.6.27-rc3.orig/fs/ext4/inode.c 2008-08-18 12:14:42.000000000 -0700
75 +++ linux-2.6.27-rc3/fs/ext4/inode.c 2008-08-18 12:28:49.000000000 -0700
76 @@ -1044,18 +1044,6 @@ static void ext4_da_update_reserve_space
77 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
80 -/* Maximum number of blocks we map for direct IO at once. */
81 -#define DIO_MAX_BLOCKS 4096
82 -/*
83 - * Number of credits we need for writing DIO_MAX_BLOCKS:
84 - * We need sb + group descriptor + bitmap + inode -> 4
85 - * For B blocks with A block pointers per block we need:
86 - * 1 (triple ind.) + (B/A/A + 2) (doubly ind.) + (B/A + 2) (indirect).
87 - * If we plug in 4096 for B and 256 for A (for 1KB block size), we get 25.
88 - */
89 -#define DIO_CREDITS 25
93 * The ext4_get_blocks_wrap() function try to look up the requested blocks,
94 * and returns if the blocks are already mapped.
95 @@ -1167,19 +1155,23 @@ int ext4_get_blocks_wrap(handle_t *handl
96 return retval;
99 +/* Maximum number of blocks we map for direct IO at once. */
100 +#define DIO_MAX_BLOCKS 4096
102 static int ext4_get_block(struct inode *inode, sector_t iblock,
103 struct buffer_head *bh_result, int create)
105 handle_t *handle = ext4_journal_current_handle();
106 int ret = 0, started = 0;
107 unsigned max_blocks = bh_result->b_size >> inode->i_blkbits;
108 + int dio_credits;
110 if (create && !handle) {
111 /* Direct IO write... */
112 if (max_blocks > DIO_MAX_BLOCKS)
113 max_blocks = DIO_MAX_BLOCKS;
114 - handle = ext4_journal_start(inode, DIO_CREDITS +
115 - 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb));
116 + dio_credits = ext4_chunk_trans_blocks(inode, max_blocks);
117 + handle = ext4_journal_start(inode, dio_credits);
118 if (IS_ERR(handle)) {
119 ret = PTR_ERR(handle);
120 goto out;
121 @@ -2243,7 +2235,7 @@ static int ext4_da_writepage(struct page
122 * for DIO, writepages, and truncate
124 #define EXT4_MAX_WRITEBACK_PAGES DIO_MAX_BLOCKS
125 -#define EXT4_MAX_WRITEBACK_CREDITS DIO_CREDITS
126 +#define EXT4_MAX_WRITEBACK_CREDITS 25
128 static int ext4_da_writepages(struct address_space *mapping,
129 struct writeback_control *wbc)
130 @@ -4441,7 +4433,8 @@ int ext4_meta_trans_blocks(struct inode
133 * Calulate the total number of credits to reserve to fit
134 - * the modification of a single pages into a single transaction
135 + * the modification of a single pages into a single transaction,
136 + * which may include multiple chunks of block allocations.
138 * This could be called via ext4_write_begin() or later
139 * ext4_da_writepages() in delalyed allocation case.
140 @@ -4449,11 +4442,6 @@ int ext4_meta_trans_blocks(struct inode
141 * In both case it's possible that we could allocating multiple
142 * chunks of blocks. We need to consider the worse case, when
143 * one new block per extent.
145 - * For Direct IO and fallocate, the journal credits reservation
146 - * is based on one single extent allocation, so they could use
147 - * EXT4_DATA_TRANS_BLOCKS to get the needed credit to log a single
148 - * chunk of allocation needs.
150 int ext4_writepage_trans_blocks(struct inode *inode)
152 @@ -4467,6 +4455,21 @@ int ext4_writepage_trans_blocks(struct i
153 ret += bpp;
154 return ret;
158 + * Calculate the journal credits for a chunk of data modification.
160 + * This is called from DIO, fallocate or whoever calling
161 + * ext4_get_blocks_wrap() to map/allocate a chunk of contigous disk blocks.
163 + * journal buffers for data blocks are not included here, as DIO
164 + * and fallocate do no need to journal data buffers.
165 + */
166 +int ext4_chunk_trans_blocks(struct inode *inode, int nrblocks)
168 + return ext4_meta_trans_blocks(inode, nrblocks, 1);
172 * The caller must have previously called ext4_reserve_inode_write().
173 * Give this, we know that the caller already has write access to iloc->bh.
174 Index: linux-2.6.27-rc3/fs/ext4/ext4.h
175 ===================================================================
176 --- linux-2.6.27-rc3.orig/fs/ext4/ext4.h 2008-08-18 12:10:11.000000000 -0700
177 +++ linux-2.6.27-rc3/fs/ext4/ext4.h 2008-08-18 12:18:44.000000000 -0700
178 @@ -1073,6 +1073,7 @@ extern void ext4_get_inode_flags(struct
179 extern void ext4_set_aops(struct inode *inode);
180 extern int ext4_writepage_trans_blocks(struct inode *);
181 extern int ext4_meta_trans_blocks(struct inode *, int nrblocks, int idxblocks);
182 +extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks);
183 extern int ext4_block_truncate_page(handle_t *handle,
184 struct address_space *mapping, loff_t from);
185 extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page);