···3636struct nilfs_dat_info {3737 struct nilfs_mdt_info mi;3838 struct nilfs_palloc_cache palloc_cache;3939+ struct nilfs_shadow_map shadow;3940};40414142static inline struct nilfs_dat_info *NILFS_DAT_I(struct inode *dat)···328327 ret = nilfs_palloc_get_entry_block(dat, vblocknr, 0, &entry_bh);329328 if (ret < 0)330329 return ret;330330+331331+ /*332332+ * The given disk block number (blocknr) is not yet written to333333+ * the device at this point.334334+ *335335+ * To prevent nilfs_dat_translate() from returning the336336+ * uncommited block number, this makes a copy of the entry337337+ * buffer and redirects nilfs_dat_translate() to the copy.338338+ */339339+ if (!buffer_nilfs_redirected(entry_bh)) {340340+ ret = nilfs_mdt_freeze_buffer(dat, entry_bh);341341+ if (ret) {342342+ brelse(entry_bh);343343+ return ret;344344+ }345345+ }346346+331347 kaddr = kmap_atomic(entry_bh->b_page, KM_USER0);332348 entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr);333349 if (unlikely(entry->de_blocknr == cpu_to_le64(0))) {···389371 */390372int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp)391373{392392- struct buffer_head *entry_bh;374374+ struct buffer_head *entry_bh, *bh;393375 struct nilfs_dat_entry *entry;394376 sector_t blocknr;395377 void *kaddr;···398380 ret = nilfs_palloc_get_entry_block(dat, vblocknr, 0, &entry_bh);399381 if (ret < 0)400382 return ret;383383+384384+ if (!nilfs_doing_gc() && buffer_nilfs_redirected(entry_bh)) {385385+ bh = nilfs_mdt_get_frozen_buffer(dat, entry_bh);386386+ if (bh) {387387+ WARN_ON(!buffer_uptodate(bh));388388+ brelse(entry_bh);389389+ entry_bh = bh;390390+ }391391+ }401392402393 kaddr = kmap_atomic(entry_bh->b_page, KM_USER0);403394 entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr);···495468 di = NILFS_DAT_I(dat);496469 lockdep_set_class(&di->mi.mi_sem, &dat_lock_key);497470 nilfs_palloc_setup_cache(dat, &di->palloc_cache);471471+ nilfs_mdt_setup_shadow_map(dat, &di->shadow);498472 }499473 return dat;500474}
-87
fs/nilfs2/gcdat.c
···11-/*22- * gcdat.c - NILFS shadow DAT inode for GC33- *44- * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.55- *66- * This program is free software; you can redistribute it and/or modify77- * it under the terms of the GNU General Public License as published by88- * the Free Software Foundation; either version 2 of the License, or99- * (at your option) any later version.1010- *1111- * This program is distributed in the hope that it will be useful,1212- * but WITHOUT ANY WARRANTY; without even the implied warranty of1313- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414- * GNU General Public License for more details.1515- *1616- * You should have received a copy of the GNU General Public License1717- * along with this program; if not, write to the Free Software1818- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA1919- *2020- * Written by Seiji Kihara <kihara@osrg.net>, Amagai Yoshiji <amagai@osrg.net>,2121- * and Ryusuke Konishi <ryusuke@osrg.net>.2222- *2323- */2424-2525-#include <linux/buffer_head.h>2626-#include "nilfs.h"2727-#include "page.h"2828-#include "mdt.h"2929-3030-int nilfs_init_gcdat_inode(struct the_nilfs *nilfs)3131-{3232- struct inode *dat = nilfs->ns_dat, *gcdat = nilfs->ns_gc_dat;3333- struct nilfs_inode_info *dii = NILFS_I(dat), *gii = NILFS_I(gcdat);3434- int err;3535-3636- gcdat->i_state = 0;3737- gcdat->i_blocks = dat->i_blocks;3838- gii->i_flags = dii->i_flags;3939- gii->i_state = dii->i_state | (1 << NILFS_I_GCDAT);4040- gii->i_cno = 0;4141- nilfs_bmap_init_gcdat(gii->i_bmap, dii->i_bmap);4242- err = nilfs_copy_dirty_pages(gcdat->i_mapping, dat->i_mapping);4343- if (unlikely(err))4444- return err;4545-4646- return nilfs_copy_dirty_pages(&gii->i_btnode_cache,4747- &dii->i_btnode_cache);4848-}4949-5050-void nilfs_commit_gcdat_inode(struct the_nilfs *nilfs)5151-{5252- struct inode *dat = nilfs->ns_dat, *gcdat = nilfs->ns_gc_dat;5353- struct nilfs_inode_info *dii = NILFS_I(dat), *gii = NILFS_I(gcdat);5454- struct address_space *mapping = dat->i_mapping;5555- struct address_space *gmapping = gcdat->i_mapping;5656-5757- down_write(&NILFS_MDT(dat)->mi_sem);5858- dat->i_blocks = gcdat->i_blocks;5959- dii->i_flags = gii->i_flags;6060- dii->i_state = gii->i_state & ~(1 << NILFS_I_GCDAT);6161-6262- nilfs_bmap_commit_gcdat(gii->i_bmap, dii->i_bmap);6363-6464- nilfs_palloc_clear_cache(dat);6565- nilfs_palloc_clear_cache(gcdat);6666- nilfs_clear_dirty_pages(mapping);6767- nilfs_copy_back_pages(mapping, gmapping);6868- /* note: mdt dirty flags should be cleared by segctor. */6969-7070- nilfs_clear_dirty_pages(&dii->i_btnode_cache);7171- nilfs_copy_back_pages(&dii->i_btnode_cache, &gii->i_btnode_cache);7272-7373- up_write(&NILFS_MDT(dat)->mi_sem);7474-}7575-7676-void nilfs_clear_gcdat_inode(struct the_nilfs *nilfs)7777-{7878- struct inode *gcdat = nilfs->ns_gc_dat;7979- struct nilfs_inode_info *gii = NILFS_I(gcdat);8080-8181- gcdat->i_state = I_FREEING | I_CLEAR;8282- gii->i_flags = 0;8383-8484- nilfs_palloc_clear_cache(gcdat);8585- truncate_inode_pages(gcdat->i_mapping, 0);8686- truncate_inode_pages(&gii->i_btnode_cache, 0);8787-}