aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/dat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2/dat.c')
-rw-r--r--fs/nilfs2/dat.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c
index 013146755683..7091c4e0f042 100644
--- a/fs/nilfs2/dat.c
+++ b/fs/nilfs2/dat.c
@@ -36,6 +36,7 @@
36struct nilfs_dat_info { 36struct nilfs_dat_info {
37 struct nilfs_mdt_info mi; 37 struct nilfs_mdt_info mi;
38 struct nilfs_palloc_cache palloc_cache; 38 struct nilfs_palloc_cache palloc_cache;
39 struct nilfs_shadow_map shadow;
39}; 40};
40 41
41static inline struct nilfs_dat_info *NILFS_DAT_I(struct inode *dat) 42static inline struct nilfs_dat_info *NILFS_DAT_I(struct inode *dat)
@@ -327,6 +328,23 @@ int nilfs_dat_move(struct inode *dat, __u64 vblocknr, sector_t blocknr)
327 ret = nilfs_palloc_get_entry_block(dat, vblocknr, 0, &entry_bh); 328 ret = nilfs_palloc_get_entry_block(dat, vblocknr, 0, &entry_bh);
328 if (ret < 0) 329 if (ret < 0)
329 return ret; 330 return ret;
331
332 /*
333 * The given disk block number (blocknr) is not yet written to
334 * the device at this point.
335 *
336 * To prevent nilfs_dat_translate() from returning the
337 * uncommited block number, this makes a copy of the entry
338 * buffer and redirects nilfs_dat_translate() to the copy.
339 */
340 if (!buffer_nilfs_redirected(entry_bh)) {
341 ret = nilfs_mdt_freeze_buffer(dat, entry_bh);
342 if (ret) {
343 brelse(entry_bh);
344 return ret;
345 }
346 }
347
330 kaddr = kmap_atomic(entry_bh->b_page, KM_USER0); 348 kaddr = kmap_atomic(entry_bh->b_page, KM_USER0);
331 entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr); 349 entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr);
332 if (unlikely(entry->de_blocknr == cpu_to_le64(0))) { 350 if (unlikely(entry->de_blocknr == cpu_to_le64(0))) {
@@ -371,7 +389,7 @@ int nilfs_dat_move(struct inode *dat, __u64 vblocknr, sector_t blocknr)
371 */ 389 */
372int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp) 390int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp)
373{ 391{
374 struct buffer_head *entry_bh; 392 struct buffer_head *entry_bh, *bh;
375 struct nilfs_dat_entry *entry; 393 struct nilfs_dat_entry *entry;
376 sector_t blocknr; 394 sector_t blocknr;
377 void *kaddr; 395 void *kaddr;
@@ -381,6 +399,15 @@ int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp)
381 if (ret < 0) 399 if (ret < 0)
382 return ret; 400 return ret;
383 401
402 if (!nilfs_doing_gc() && buffer_nilfs_redirected(entry_bh)) {
403 bh = nilfs_mdt_get_frozen_buffer(dat, entry_bh);
404 if (bh) {
405 WARN_ON(!buffer_uptodate(bh));
406 brelse(entry_bh);
407 entry_bh = bh;
408 }
409 }
410
384 kaddr = kmap_atomic(entry_bh->b_page, KM_USER0); 411 kaddr = kmap_atomic(entry_bh->b_page, KM_USER0);
385 entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr); 412 entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr);
386 blocknr = le64_to_cpu(entry->de_blocknr); 413 blocknr = le64_to_cpu(entry->de_blocknr);
@@ -468,6 +495,7 @@ struct inode *nilfs_dat_new(struct the_nilfs *nilfs, size_t entry_size)
468 di = NILFS_DAT_I(dat); 495 di = NILFS_DAT_I(dat);
469 lockdep_set_class(&di->mi.mi_sem, &dat_lock_key); 496 lockdep_set_class(&di->mi.mi_sem, &dat_lock_key);
470 nilfs_palloc_setup_cache(dat, &di->palloc_cache); 497 nilfs_palloc_setup_cache(dat, &di->palloc_cache);
498 nilfs_mdt_setup_shadow_map(dat, &di->shadow);
471 } 499 }
472 return dat; 500 return dat;
473} 501}