diff options
Diffstat (limited to 'fs/nilfs2')
-rw-r--r-- | fs/nilfs2/alloc.c | 62 |
1 files changed, 54 insertions, 8 deletions
diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c index c56300d8d177..3f959f1879d8 100644 --- a/fs/nilfs2/alloc.c +++ b/fs/nilfs2/alloc.c | |||
@@ -142,29 +142,75 @@ static void nilfs_palloc_desc_block_init(struct inode *inode, | |||
142 | } | 142 | } |
143 | } | 143 | } |
144 | 144 | ||
145 | static int nilfs_palloc_get_block(struct inode *inode, unsigned long blkoff, | ||
146 | int create, | ||
147 | void (*init_block)(struct inode *, | ||
148 | struct buffer_head *, | ||
149 | void *), | ||
150 | struct buffer_head **bhp, | ||
151 | struct nilfs_bh_assoc *prev, | ||
152 | spinlock_t *lock) | ||
153 | { | ||
154 | int ret; | ||
155 | |||
156 | spin_lock(lock); | ||
157 | if (prev->bh && blkoff == prev->blkoff) { | ||
158 | get_bh(prev->bh); | ||
159 | *bhp = prev->bh; | ||
160 | spin_unlock(lock); | ||
161 | return 0; | ||
162 | } | ||
163 | spin_unlock(lock); | ||
164 | |||
165 | ret = nilfs_mdt_get_block(inode, blkoff, create, init_block, bhp); | ||
166 | if (!ret) { | ||
167 | spin_lock(lock); | ||
168 | /* | ||
169 | * The following code must be safe for change of the | ||
170 | * cache contents during the get block call. | ||
171 | */ | ||
172 | brelse(prev->bh); | ||
173 | get_bh(*bhp); | ||
174 | prev->bh = *bhp; | ||
175 | prev->blkoff = blkoff; | ||
176 | spin_unlock(lock); | ||
177 | } | ||
178 | return ret; | ||
179 | } | ||
180 | |||
145 | static int nilfs_palloc_get_desc_block(struct inode *inode, | 181 | static int nilfs_palloc_get_desc_block(struct inode *inode, |
146 | unsigned long group, | 182 | unsigned long group, |
147 | int create, struct buffer_head **bhp) | 183 | int create, struct buffer_head **bhp) |
148 | { | 184 | { |
149 | return nilfs_mdt_get_block(inode, | 185 | struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache; |
150 | nilfs_palloc_desc_blkoff(inode, group), | 186 | |
151 | create, nilfs_palloc_desc_block_init, bhp); | 187 | return nilfs_palloc_get_block(inode, |
188 | nilfs_palloc_desc_blkoff(inode, group), | ||
189 | create, nilfs_palloc_desc_block_init, | ||
190 | bhp, &cache->prev_desc, &cache->lock); | ||
152 | } | 191 | } |
153 | 192 | ||
154 | static int nilfs_palloc_get_bitmap_block(struct inode *inode, | 193 | static int nilfs_palloc_get_bitmap_block(struct inode *inode, |
155 | unsigned long group, | 194 | unsigned long group, |
156 | int create, struct buffer_head **bhp) | 195 | int create, struct buffer_head **bhp) |
157 | { | 196 | { |
158 | return nilfs_mdt_get_block(inode, | 197 | struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache; |
159 | nilfs_palloc_bitmap_blkoff(inode, group), | 198 | |
160 | create, NULL, bhp); | 199 | return nilfs_palloc_get_block(inode, |
200 | nilfs_palloc_bitmap_blkoff(inode, group), | ||
201 | create, NULL, bhp, | ||
202 | &cache->prev_bitmap, &cache->lock); | ||
161 | } | 203 | } |
162 | 204 | ||
163 | int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr, | 205 | int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr, |
164 | int create, struct buffer_head **bhp) | 206 | int create, struct buffer_head **bhp) |
165 | { | 207 | { |
166 | return nilfs_mdt_get_block(inode, nilfs_palloc_entry_blkoff(inode, nr), | 208 | struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache; |
167 | create, NULL, bhp); | 209 | |
210 | return nilfs_palloc_get_block(inode, | ||
211 | nilfs_palloc_entry_blkoff(inode, nr), | ||
212 | create, NULL, bhp, | ||
213 | &cache->prev_entry, &cache->lock); | ||
168 | } | 214 | } |
169 | 215 | ||
170 | static struct nilfs_palloc_group_desc * | 216 | static struct nilfs_palloc_group_desc * |