aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2/alloc.c')
-rw-r--r--fs/nilfs2/alloc.c111
1 files changed, 87 insertions, 24 deletions
diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c
index d69e6ae59251..7cfb87e692da 100644
--- a/fs/nilfs2/alloc.c
+++ b/fs/nilfs2/alloc.c
@@ -26,6 +26,7 @@
26#include <linux/buffer_head.h> 26#include <linux/buffer_head.h>
27#include <linux/fs.h> 27#include <linux/fs.h>
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/slab.h>
29#include "mdt.h" 30#include "mdt.h"
30#include "alloc.h" 31#include "alloc.h"
31 32
@@ -142,29 +143,75 @@ static void nilfs_palloc_desc_block_init(struct inode *inode,
142 } 143 }
143} 144}
144 145
146static int nilfs_palloc_get_block(struct inode *inode, unsigned long blkoff,
147 int create,
148 void (*init_block)(struct inode *,
149 struct buffer_head *,
150 void *),
151 struct buffer_head **bhp,
152 struct nilfs_bh_assoc *prev,
153 spinlock_t *lock)
154{
155 int ret;
156
157 spin_lock(lock);
158 if (prev->bh && blkoff == prev->blkoff) {
159 get_bh(prev->bh);
160 *bhp = prev->bh;
161 spin_unlock(lock);
162 return 0;
163 }
164 spin_unlock(lock);
165
166 ret = nilfs_mdt_get_block(inode, blkoff, create, init_block, bhp);
167 if (!ret) {
168 spin_lock(lock);
169 /*
170 * The following code must be safe for change of the
171 * cache contents during the get block call.
172 */
173 brelse(prev->bh);
174 get_bh(*bhp);
175 prev->bh = *bhp;
176 prev->blkoff = blkoff;
177 spin_unlock(lock);
178 }
179 return ret;
180}
181
145static int nilfs_palloc_get_desc_block(struct inode *inode, 182static int nilfs_palloc_get_desc_block(struct inode *inode,
146 unsigned long group, 183 unsigned long group,
147 int create, struct buffer_head **bhp) 184 int create, struct buffer_head **bhp)
148{ 185{
149 return nilfs_mdt_get_block(inode, 186 struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
150 nilfs_palloc_desc_blkoff(inode, group), 187
151 create, nilfs_palloc_desc_block_init, bhp); 188 return nilfs_palloc_get_block(inode,
189 nilfs_palloc_desc_blkoff(inode, group),
190 create, nilfs_palloc_desc_block_init,
191 bhp, &cache->prev_desc, &cache->lock);
152} 192}
153 193
154static int nilfs_palloc_get_bitmap_block(struct inode *inode, 194static int nilfs_palloc_get_bitmap_block(struct inode *inode,
155 unsigned long group, 195 unsigned long group,
156 int create, struct buffer_head **bhp) 196 int create, struct buffer_head **bhp)
157{ 197{
158 return nilfs_mdt_get_block(inode, 198 struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
159 nilfs_palloc_bitmap_blkoff(inode, group), 199
160 create, NULL, bhp); 200 return nilfs_palloc_get_block(inode,
201 nilfs_palloc_bitmap_blkoff(inode, group),
202 create, NULL, bhp,
203 &cache->prev_bitmap, &cache->lock);
161} 204}
162 205
163int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr, 206int nilfs_palloc_get_entry_block(struct inode *inode, __u64 nr,
164 int create, struct buffer_head **bhp) 207 int create, struct buffer_head **bhp)
165{ 208{
166 return nilfs_mdt_get_block(inode, nilfs_palloc_entry_blkoff(inode, nr), 209 struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
167 create, NULL, bhp); 210
211 return nilfs_palloc_get_block(inode,
212 nilfs_palloc_entry_blkoff(inode, nr),
213 create, NULL, bhp,
214 &cache->prev_entry, &cache->lock);
168} 215}
169 216
170static struct nilfs_palloc_group_desc * 217static struct nilfs_palloc_group_desc *
@@ -176,13 +223,6 @@ nilfs_palloc_block_get_group_desc(const struct inode *inode,
176 group % nilfs_palloc_groups_per_desc_block(inode); 223 group % nilfs_palloc_groups_per_desc_block(inode);
177} 224}
178 225
179static unsigned char *
180nilfs_palloc_block_get_bitmap(const struct inode *inode,
181 const struct buffer_head *bh, void *kaddr)
182{
183 return (unsigned char *)(kaddr + bh_offset(bh));
184}
185
186void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr, 226void *nilfs_palloc_block_get_entry(const struct inode *inode, __u64 nr,
187 const struct buffer_head *bh, void *kaddr) 227 const struct buffer_head *bh, void *kaddr)
188{ 228{
@@ -289,8 +329,7 @@ int nilfs_palloc_prepare_alloc_entry(struct inode *inode,
289 if (ret < 0) 329 if (ret < 0)
290 goto out_desc; 330 goto out_desc;
291 bitmap_kaddr = kmap(bitmap_bh->b_page); 331 bitmap_kaddr = kmap(bitmap_bh->b_page);
292 bitmap = nilfs_palloc_block_get_bitmap( 332 bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
293 inode, bitmap_bh, bitmap_kaddr);
294 pos = nilfs_palloc_find_available_slot( 333 pos = nilfs_palloc_find_available_slot(
295 inode, group, group_offset, bitmap, 334 inode, group, group_offset, bitmap,
296 entries_per_group); 335 entries_per_group);
@@ -351,8 +390,7 @@ void nilfs_palloc_commit_free_entry(struct inode *inode,
351 desc = nilfs_palloc_block_get_group_desc(inode, group, 390 desc = nilfs_palloc_block_get_group_desc(inode, group,
352 req->pr_desc_bh, desc_kaddr); 391 req->pr_desc_bh, desc_kaddr);
353 bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page); 392 bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page);
354 bitmap = nilfs_palloc_block_get_bitmap(inode, req->pr_bitmap_bh, 393 bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
355 bitmap_kaddr);
356 394
357 if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group), 395 if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group),
358 group_offset, bitmap)) 396 group_offset, bitmap))
@@ -385,11 +423,10 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode,
385 desc = nilfs_palloc_block_get_group_desc(inode, group, 423 desc = nilfs_palloc_block_get_group_desc(inode, group,
386 req->pr_desc_bh, desc_kaddr); 424 req->pr_desc_bh, desc_kaddr);
387 bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page); 425 bitmap_kaddr = kmap(req->pr_bitmap_bh->b_page);
388 bitmap = nilfs_palloc_block_get_bitmap(inode, req->pr_bitmap_bh, 426 bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
389 bitmap_kaddr);
390 if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group), 427 if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group),
391 group_offset, bitmap)) 428 group_offset, bitmap))
392 printk(KERN_WARNING "%s: entry numer %llu already freed\n", 429 printk(KERN_WARNING "%s: entry number %llu already freed\n",
393 __func__, (unsigned long long)req->pr_entry_nr); 430 __func__, (unsigned long long)req->pr_entry_nr);
394 431
395 nilfs_palloc_group_desc_add_entries(inode, group, desc, 1); 432 nilfs_palloc_group_desc_add_entries(inode, group, desc, 1);
@@ -472,8 +509,7 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
472 desc = nilfs_palloc_block_get_group_desc( 509 desc = nilfs_palloc_block_get_group_desc(
473 inode, group, desc_bh, desc_kaddr); 510 inode, group, desc_bh, desc_kaddr);
474 bitmap_kaddr = kmap(bitmap_bh->b_page); 511 bitmap_kaddr = kmap(bitmap_bh->b_page);
475 bitmap = nilfs_palloc_block_get_bitmap( 512 bitmap = bitmap_kaddr + bh_offset(bitmap_bh);
476 inode, bitmap_bh, bitmap_kaddr);
477 for (j = i, n = 0; 513 for (j = i, n = 0;
478 (j < nitems) && nilfs_palloc_group_is_in(inode, group, 514 (j < nitems) && nilfs_palloc_group_is_in(inode, group,
479 entry_nrs[j]); 515 entry_nrs[j]);
@@ -502,3 +538,30 @@ int nilfs_palloc_freev(struct inode *inode, __u64 *entry_nrs, size_t nitems)
502 } 538 }
503 return 0; 539 return 0;
504} 540}
541
542void nilfs_palloc_setup_cache(struct inode *inode,
543 struct nilfs_palloc_cache *cache)
544{
545 NILFS_MDT(inode)->mi_palloc_cache = cache;
546 spin_lock_init(&cache->lock);
547}
548
549void nilfs_palloc_clear_cache(struct inode *inode)
550{
551 struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
552
553 spin_lock(&cache->lock);
554 brelse(cache->prev_desc.bh);
555 brelse(cache->prev_bitmap.bh);
556 brelse(cache->prev_entry.bh);
557 cache->prev_desc.bh = NULL;
558 cache->prev_bitmap.bh = NULL;
559 cache->prev_entry.bh = NULL;
560 spin_unlock(&cache->lock);
561}
562
563void nilfs_palloc_destroy_cache(struct inode *inode)
564{
565 nilfs_palloc_clear_cache(inode);
566 NILFS_MDT(inode)->mi_palloc_cache = NULL;
567}