Commit e912a5b6 authored by Ryusuke Konishi's avatar Ryusuke Konishi

nilfs2: use root object to get ifile

This rewrites functions using ifile so that they get ifile from
nilfs_root object, and will remove sbi->s_ifile.  Some functions that
don't know the root object are extended to receive it from caller.
Signed-off-by: default avatarRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
parent 8e656fd5
...@@ -301,7 +301,7 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) ...@@ -301,7 +301,7 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode)
ii->i_state = 1 << NILFS_I_NEW; ii->i_state = 1 << NILFS_I_NEW;
ii->i_root = root; ii->i_root = root;
err = nilfs_ifile_create_inode(sbi->s_ifile, &ino, &ii->i_bh); err = nilfs_ifile_create_inode(root->ifile, &ino, &ii->i_bh);
if (unlikely(err)) if (unlikely(err))
goto failed_ifile_create_inode; goto failed_ifile_create_inode;
/* reference count of i_bh inherits from nilfs_mdt_read_block() */ /* reference count of i_bh inherits from nilfs_mdt_read_block() */
...@@ -358,16 +358,6 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) ...@@ -358,16 +358,6 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode)
return ERR_PTR(err); return ERR_PTR(err);
} }
void nilfs_free_inode(struct inode *inode)
{
struct super_block *sb = inode->i_sb;
struct nilfs_sb_info *sbi = NILFS_SB(sb);
/* XXX: check error code? Is there any thing I can do? */
(void) nilfs_ifile_delete_inode(sbi->s_ifile, inode->i_ino);
atomic_dec(&sbi->s_inodes_count);
}
void nilfs_set_inode_flags(struct inode *inode) void nilfs_set_inode_flags(struct inode *inode)
{ {
unsigned int flags = NILFS_I(inode)->i_flags; unsigned int flags = NILFS_I(inode)->i_flags;
...@@ -431,7 +421,8 @@ int nilfs_read_inode_common(struct inode *inode, ...@@ -431,7 +421,8 @@ int nilfs_read_inode_common(struct inode *inode,
return 0; return 0;
} }
static int __nilfs_read_inode(struct super_block *sb, unsigned long ino, static int __nilfs_read_inode(struct super_block *sb,
struct nilfs_root *root, unsigned long ino,
struct inode *inode) struct inode *inode)
{ {
struct nilfs_sb_info *sbi = NILFS_SB(sb); struct nilfs_sb_info *sbi = NILFS_SB(sb);
...@@ -441,11 +432,11 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino, ...@@ -441,11 +432,11 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino,
int err; int err;
down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ down_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
err = nilfs_ifile_get_inode_block(sbi->s_ifile, ino, &bh); err = nilfs_ifile_get_inode_block(root->ifile, ino, &bh);
if (unlikely(err)) if (unlikely(err))
goto bad_inode; goto bad_inode;
raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, bh); raw_inode = nilfs_ifile_map_inode(root->ifile, ino, bh);
err = nilfs_read_inode_common(inode, raw_inode); err = nilfs_read_inode_common(inode, raw_inode);
if (err) if (err)
...@@ -468,14 +459,14 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino, ...@@ -468,14 +459,14 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino,
inode, inode->i_mode, inode, inode->i_mode,
huge_decode_dev(le64_to_cpu(raw_inode->i_device_code))); huge_decode_dev(le64_to_cpu(raw_inode->i_device_code)));
} }
nilfs_ifile_unmap_inode(sbi->s_ifile, ino, bh); nilfs_ifile_unmap_inode(root->ifile, ino, bh);
brelse(bh); brelse(bh);
up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */ up_read(&NILFS_MDT(dat)->mi_sem); /* XXX */
nilfs_set_inode_flags(inode); nilfs_set_inode_flags(inode);
return 0; return 0;
failed_unmap: failed_unmap:
nilfs_ifile_unmap_inode(sbi->s_ifile, ino, bh); nilfs_ifile_unmap_inode(root->ifile, ino, bh);
brelse(bh); brelse(bh);
bad_inode: bad_inode:
...@@ -530,7 +521,7 @@ struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, ...@@ -530,7 +521,7 @@ struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root,
if (!(inode->i_state & I_NEW)) if (!(inode->i_state & I_NEW))
return inode; return inode;
err = __nilfs_read_inode(sb, ino, inode); err = __nilfs_read_inode(sb, root, ino, inode);
if (unlikely(err)) { if (unlikely(err)) {
iget_failed(inode); iget_failed(inode);
return ERR_PTR(err); return ERR_PTR(err);
...@@ -595,21 +586,20 @@ void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh) ...@@ -595,21 +586,20 @@ void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh)
{ {
ino_t ino = inode->i_ino; ino_t ino = inode->i_ino;
struct nilfs_inode_info *ii = NILFS_I(inode); struct nilfs_inode_info *ii = NILFS_I(inode);
struct super_block *sb = inode->i_sb; struct inode *ifile = ii->i_root->ifile;
struct nilfs_sb_info *sbi = NILFS_SB(sb);
struct nilfs_inode *raw_inode; struct nilfs_inode *raw_inode;
raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, ibh); raw_inode = nilfs_ifile_map_inode(ifile, ino, ibh);
if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state)) if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state))
memset(raw_inode, 0, NILFS_MDT(sbi->s_ifile)->mi_entry_size); memset(raw_inode, 0, NILFS_MDT(ifile)->mi_entry_size);
set_bit(NILFS_I_INODE_DIRTY, &ii->i_state); set_bit(NILFS_I_INODE_DIRTY, &ii->i_state);
nilfs_write_inode_common(inode, raw_inode, 0); nilfs_write_inode_common(inode, raw_inode, 0);
/* XXX: call with has_bmap = 0 is a workaround to avoid /* XXX: call with has_bmap = 0 is a workaround to avoid
deadlock of bmap. This delays update of i_bmap to just deadlock of bmap. This delays update of i_bmap to just
before writing */ before writing */
nilfs_ifile_unmap_inode(sbi->s_ifile, ino, ibh); nilfs_ifile_unmap_inode(ifile, ino, ibh);
} }
#define NILFS_MAX_TRUNCATE_BLOCKS 16384 /* 64MB for 4KB block */ #define NILFS_MAX_TRUNCATE_BLOCKS 16384 /* 64MB for 4KB block */
...@@ -719,12 +709,16 @@ void nilfs_evict_inode(struct inode *inode) ...@@ -719,12 +709,16 @@ void nilfs_evict_inode(struct inode *inode)
if (inode->i_data.nrpages) if (inode->i_data.nrpages)
truncate_inode_pages(&inode->i_data, 0); truncate_inode_pages(&inode->i_data, 0);
/* TODO: some of the following operations may fail. */
nilfs_truncate_bmap(ii, 0); nilfs_truncate_bmap(ii, 0);
nilfs_mark_inode_dirty(inode); nilfs_mark_inode_dirty(inode);
end_writeback(inode); end_writeback(inode);
nilfs_ifile_delete_inode(ii->i_root->ifile, inode->i_ino);
atomic_dec(&NILFS_SB(sb)->s_inodes_count);
nilfs_clear_inode(inode); nilfs_clear_inode(inode);
nilfs_free_inode(inode);
/* nilfs_free_inode() marks inode buffer dirty */
if (IS_SYNC(inode)) if (IS_SYNC(inode))
nilfs_set_transaction_flag(NILFS_TI_SYNC); nilfs_set_transaction_flag(NILFS_TI_SYNC);
nilfs_transaction_commit(sb); nilfs_transaction_commit(sb);
...@@ -779,8 +773,8 @@ int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode, ...@@ -779,8 +773,8 @@ int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode,
spin_lock(&sbi->s_inode_lock); spin_lock(&sbi->s_inode_lock);
if (ii->i_bh == NULL) { if (ii->i_bh == NULL) {
spin_unlock(&sbi->s_inode_lock); spin_unlock(&sbi->s_inode_lock);
err = nilfs_ifile_get_inode_block(sbi->s_ifile, inode->i_ino, err = nilfs_ifile_get_inode_block(ii->i_root->ifile,
pbh); inode->i_ino, pbh);
if (unlikely(err)) if (unlikely(err))
return err; return err;
spin_lock(&sbi->s_inode_lock); spin_lock(&sbi->s_inode_lock);
...@@ -860,7 +854,7 @@ int nilfs_mark_inode_dirty(struct inode *inode) ...@@ -860,7 +854,7 @@ int nilfs_mark_inode_dirty(struct inode *inode)
} }
nilfs_update_inode(inode, ibh); nilfs_update_inode(inode, ibh);
nilfs_mdt_mark_buffer_dirty(ibh); nilfs_mdt_mark_buffer_dirty(ibh);
nilfs_mdt_mark_dirty(sbi->s_ifile); nilfs_mdt_mark_dirty(NILFS_I(inode)->i_root->ifile);
brelse(ibh); brelse(ibh);
return 0; return 0;
} }
......
...@@ -286,7 +286,6 @@ extern int nilfs_commit_super(struct nilfs_sb_info *, int); ...@@ -286,7 +286,6 @@ extern int nilfs_commit_super(struct nilfs_sb_info *, int);
extern int nilfs_cleanup_super(struct nilfs_sb_info *); extern int nilfs_cleanup_super(struct nilfs_sb_info *);
int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt,
struct nilfs_root **root); struct nilfs_root **root);
extern void nilfs_detach_checkpoint(struct nilfs_sb_info *);
/* gcinode.c */ /* gcinode.c */
int nilfs_gccache_submit_read_data(struct inode *, sector_t, sector_t, __u64, int nilfs_gccache_submit_read_data(struct inode *, sector_t, sector_t, __u64,
......
...@@ -773,7 +773,7 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs, ...@@ -773,7 +773,7 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs,
goto failed; goto failed;
} }
err = nilfs_attach_segment_constructor(sbi); err = nilfs_attach_segment_constructor(sbi, root);
if (unlikely(err)) if (unlikely(err))
goto failed; goto failed;
...@@ -791,7 +791,6 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs, ...@@ -791,7 +791,6 @@ int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs,
} }
failed: failed:
nilfs_detach_checkpoint(sbi);
nilfs_put_root(root); nilfs_put_root(root);
return err; return err;
} }
......
...@@ -68,9 +68,6 @@ struct nilfs_sb_info { ...@@ -68,9 +68,6 @@ struct nilfs_sb_info {
spinlock_t s_inode_lock; /* Lock for the nilfs inode. spinlock_t s_inode_lock; /* Lock for the nilfs inode.
It covers s_dirty_files list */ It covers s_dirty_files list */
/* Metadata files */
struct inode *s_ifile; /* index file inode */
/* Inode allocator */ /* Inode allocator */
spinlock_t s_next_gen_lock; spinlock_t s_next_gen_lock;
u32 s_next_generation; u32 s_next_generation;
......
...@@ -763,12 +763,12 @@ static void nilfs_dispose_list(struct nilfs_sb_info *sbi, ...@@ -763,12 +763,12 @@ static void nilfs_dispose_list(struct nilfs_sb_info *sbi,
} }
} }
static int nilfs_test_metadata_dirty(struct nilfs_sb_info *sbi) static int nilfs_test_metadata_dirty(struct the_nilfs *nilfs,
struct nilfs_root *root)
{ {
struct the_nilfs *nilfs = sbi->s_nilfs;
int ret = 0; int ret = 0;
if (nilfs_mdt_fetch_dirty(sbi->s_ifile)) if (nilfs_mdt_fetch_dirty(root->ifile))
ret++; ret++;
if (nilfs_mdt_fetch_dirty(nilfs->ns_cpfile)) if (nilfs_mdt_fetch_dirty(nilfs->ns_cpfile))
ret++; ret++;
...@@ -793,7 +793,7 @@ static int nilfs_segctor_confirm(struct nilfs_sc_info *sci) ...@@ -793,7 +793,7 @@ static int nilfs_segctor_confirm(struct nilfs_sc_info *sci)
struct nilfs_sb_info *sbi = sci->sc_sbi; struct nilfs_sb_info *sbi = sci->sc_sbi;
int ret = 0; int ret = 0;
if (nilfs_test_metadata_dirty(sbi)) if (nilfs_test_metadata_dirty(sbi->s_nilfs, sci->sc_root))
set_bit(NILFS_SC_DIRTY, &sci->sc_flags); set_bit(NILFS_SC_DIRTY, &sci->sc_flags);
spin_lock(&sbi->s_inode_lock); spin_lock(&sbi->s_inode_lock);
...@@ -809,7 +809,7 @@ static void nilfs_segctor_clear_metadata_dirty(struct nilfs_sc_info *sci) ...@@ -809,7 +809,7 @@ static void nilfs_segctor_clear_metadata_dirty(struct nilfs_sc_info *sci)
struct nilfs_sb_info *sbi = sci->sc_sbi; struct nilfs_sb_info *sbi = sci->sc_sbi;
struct the_nilfs *nilfs = sbi->s_nilfs; struct the_nilfs *nilfs = sbi->s_nilfs;
nilfs_mdt_clear_dirty(sbi->s_ifile); nilfs_mdt_clear_dirty(sci->sc_root->ifile);
nilfs_mdt_clear_dirty(nilfs->ns_cpfile); nilfs_mdt_clear_dirty(nilfs->ns_cpfile);
nilfs_mdt_clear_dirty(nilfs->ns_sufile); nilfs_mdt_clear_dirty(nilfs->ns_sufile);
nilfs_mdt_clear_dirty(nilfs_dat_inode(nilfs)); nilfs_mdt_clear_dirty(nilfs_dat_inode(nilfs));
...@@ -869,7 +869,8 @@ static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci) ...@@ -869,7 +869,8 @@ static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci)
else else
nilfs_checkpoint_set_minor(raw_cp); nilfs_checkpoint_set_minor(raw_cp);
nilfs_write_inode_common(sbi->s_ifile, &raw_cp->cp_ifile_inode, 1); nilfs_write_inode_common(sci->sc_root->ifile,
&raw_cp->cp_ifile_inode, 1);
nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, bh_cp); nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, bh_cp);
return 0; return 0;
...@@ -894,13 +895,12 @@ static void nilfs_fill_in_file_bmap(struct inode *ifile, ...@@ -894,13 +895,12 @@ static void nilfs_fill_in_file_bmap(struct inode *ifile,
} }
} }
static void nilfs_segctor_fill_in_file_bmap(struct nilfs_sc_info *sci, static void nilfs_segctor_fill_in_file_bmap(struct nilfs_sc_info *sci)
struct inode *ifile)
{ {
struct nilfs_inode_info *ii; struct nilfs_inode_info *ii;
list_for_each_entry(ii, &sci->sc_dirty_files, i_dirty) { list_for_each_entry(ii, &sci->sc_dirty_files, i_dirty) {
nilfs_fill_in_file_bmap(ifile, ii); nilfs_fill_in_file_bmap(sci->sc_root->ifile, ii);
set_bit(NILFS_I_COLLECTED, &ii->i_state); set_bit(NILFS_I_COLLECTED, &ii->i_state);
} }
} }
...@@ -1143,7 +1143,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode) ...@@ -1143,7 +1143,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
sci->sc_stage.flags |= NILFS_CF_IFILE_STARTED; sci->sc_stage.flags |= NILFS_CF_IFILE_STARTED;
/* Fall through */ /* Fall through */
case NILFS_ST_IFILE: case NILFS_ST_IFILE:
err = nilfs_segctor_scan_file(sci, sbi->s_ifile, err = nilfs_segctor_scan_file(sci, sci->sc_root->ifile,
&nilfs_sc_file_ops); &nilfs_sc_file_ops);
if (unlikely(err)) if (unlikely(err))
break; break;
...@@ -1984,6 +1984,7 @@ static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci, ...@@ -1984,6 +1984,7 @@ static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci,
struct nilfs_sb_info *sbi) struct nilfs_sb_info *sbi)
{ {
struct nilfs_inode_info *ii, *n; struct nilfs_inode_info *ii, *n;
struct inode *ifile = sci->sc_root->ifile;
spin_lock(&sbi->s_inode_lock); spin_lock(&sbi->s_inode_lock);
retry: retry:
...@@ -1994,14 +1995,14 @@ static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci, ...@@ -1994,14 +1995,14 @@ static int nilfs_segctor_check_in_files(struct nilfs_sc_info *sci,
spin_unlock(&sbi->s_inode_lock); spin_unlock(&sbi->s_inode_lock);
err = nilfs_ifile_get_inode_block( err = nilfs_ifile_get_inode_block(
sbi->s_ifile, ii->vfs_inode.i_ino, &ibh); ifile, ii->vfs_inode.i_ino, &ibh);
if (unlikely(err)) { if (unlikely(err)) {
nilfs_warning(sbi->s_super, __func__, nilfs_warning(sbi->s_super, __func__,
"failed to get inode block.\n"); "failed to get inode block.\n");
return err; return err;
} }
nilfs_mdt_mark_buffer_dirty(ibh); nilfs_mdt_mark_buffer_dirty(ibh);
nilfs_mdt_mark_dirty(sbi->s_ifile); nilfs_mdt_mark_dirty(ifile);
spin_lock(&sbi->s_inode_lock); spin_lock(&sbi->s_inode_lock);
if (likely(!ii->i_bh)) if (likely(!ii->i_bh))
ii->i_bh = ibh; ii->i_bh = ibh;
...@@ -2058,7 +2059,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) ...@@ -2058,7 +2059,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
if (unlikely(err)) if (unlikely(err))
goto out; goto out;
if (nilfs_test_metadata_dirty(sbi)) if (nilfs_test_metadata_dirty(nilfs, sci->sc_root))
set_bit(NILFS_SC_DIRTY, &sci->sc_flags); set_bit(NILFS_SC_DIRTY, &sci->sc_flags);
if (nilfs_segctor_clean(sci)) if (nilfs_segctor_clean(sci))
...@@ -2090,7 +2091,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode) ...@@ -2090,7 +2091,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
goto failed; goto failed;
if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED) if (sci->sc_stage.flags & NILFS_CF_IFILE_STARTED)
nilfs_segctor_fill_in_file_bmap(sci, sbi->s_ifile); nilfs_segctor_fill_in_file_bmap(sci);
if (mode == SC_LSEG_SR && if (mode == SC_LSEG_SR &&
sci->sc_stage.scnt >= NILFS_ST_CPFILE) { sci->sc_stage.scnt >= NILFS_ST_CPFILE) {
...@@ -2684,7 +2685,8 @@ static void nilfs_segctor_kill_thread(struct nilfs_sc_info *sci) ...@@ -2684,7 +2685,8 @@ static void nilfs_segctor_kill_thread(struct nilfs_sc_info *sci)
/* /*
* Setup & clean-up functions * Setup & clean-up functions
*/ */
static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi) static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi,
struct nilfs_root *root)
{ {
struct nilfs_sc_info *sci; struct nilfs_sc_info *sci;
...@@ -2695,6 +2697,9 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi) ...@@ -2695,6 +2697,9 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi)
sci->sc_sbi = sbi; sci->sc_sbi = sbi;
sci->sc_super = sbi->s_super; sci->sc_super = sbi->s_super;
nilfs_get_root(root);
sci->sc_root = root;
init_waitqueue_head(&sci->sc_wait_request); init_waitqueue_head(&sci->sc_wait_request);
init_waitqueue_head(&sci->sc_wait_daemon); init_waitqueue_head(&sci->sc_wait_daemon);
init_waitqueue_head(&sci->sc_wait_task); init_waitqueue_head(&sci->sc_wait_task);
...@@ -2769,6 +2774,8 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) ...@@ -2769,6 +2774,8 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
WARN_ON(!list_empty(&sci->sc_segbufs)); WARN_ON(!list_empty(&sci->sc_segbufs));
WARN_ON(!list_empty(&sci->sc_write_logs)); WARN_ON(!list_empty(&sci->sc_write_logs));
nilfs_put_root(sci->sc_root);
down_write(&sbi->s_nilfs->ns_segctor_sem); down_write(&sbi->s_nilfs->ns_segctor_sem);
del_timer_sync(&sci->sc_timer); del_timer_sync(&sci->sc_timer);
...@@ -2778,6 +2785,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) ...@@ -2778,6 +2785,7 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
/** /**
* nilfs_attach_segment_constructor - attach a segment constructor * nilfs_attach_segment_constructor - attach a segment constructor
* @sbi: nilfs_sb_info * @sbi: nilfs_sb_info
* @root: root object of the current filesystem tree
* *
* nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info, * nilfs_attach_segment_constructor() allocates a struct nilfs_sc_info,
* initializes it, and starts the segment constructor. * initializes it, and starts the segment constructor.
...@@ -2787,7 +2795,8 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) ...@@ -2787,7 +2795,8 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
* *
* %-ENOMEM - Insufficient memory available. * %-ENOMEM - Insufficient memory available.
*/ */
int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi) int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi,
struct nilfs_root *root)
{ {
struct the_nilfs *nilfs = sbi->s_nilfs; struct the_nilfs *nilfs = sbi->s_nilfs;
int err; int err;
...@@ -2801,7 +2810,7 @@ int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi) ...@@ -2801,7 +2810,7 @@ int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi)
nilfs_detach_segment_constructor(sbi); nilfs_detach_segment_constructor(sbi);
} }
sbi->s_sc_info = nilfs_segctor_new(sbi); sbi->s_sc_info = nilfs_segctor_new(sbi, root);
if (!sbi->s_sc_info) if (!sbi->s_sc_info)
return -ENOMEM; return -ENOMEM;
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include <linux/nilfs2_fs.h> #include <linux/nilfs2_fs.h>
#include "sb.h" #include "sb.h"
struct nilfs_root;
/** /**
* struct nilfs_recovery_info - Recovery information * struct nilfs_recovery_info - Recovery information
* @ri_need_recovery: Recovery status * @ri_need_recovery: Recovery status
...@@ -87,6 +89,7 @@ struct nilfs_segsum_pointer { ...@@ -87,6 +89,7 @@ struct nilfs_segsum_pointer {
* struct nilfs_sc_info - Segment constructor information * struct nilfs_sc_info - Segment constructor information
* @sc_super: Back pointer to super_block struct * @sc_super: Back pointer to super_block struct
* @sc_sbi: Back pointer to nilfs_sb_info struct * @sc_sbi: Back pointer to nilfs_sb_info struct
* @sc_root: root object of the current filesystem tree
* @sc_nblk_inc: Block count of current generation * @sc_nblk_inc: Block count of current generation
* @sc_dirty_files: List of files to be written * @sc_dirty_files: List of files to be written
* @sc_gc_inodes: List of GC inodes having blocks to be written * @sc_gc_inodes: List of GC inodes having blocks to be written
...@@ -129,6 +132,7 @@ struct nilfs_segsum_pointer { ...@@ -129,6 +132,7 @@ struct nilfs_segsum_pointer {
struct nilfs_sc_info { struct nilfs_sc_info {
struct super_block *sc_super; struct super_block *sc_super;
struct nilfs_sb_info *sc_sbi; struct nilfs_sb_info *sc_sbi;
struct nilfs_root *sc_root;
unsigned long sc_nblk_inc; unsigned long sc_nblk_inc;
...@@ -231,7 +235,8 @@ extern void nilfs_flush_segment(struct super_block *, ino_t); ...@@ -231,7 +235,8 @@ extern void nilfs_flush_segment(struct super_block *, ino_t);
extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *, extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *,
void **); void **);
extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *); int nilfs_attach_segment_constructor(struct nilfs_sb_info *sbi,
struct nilfs_root *root);
extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *); extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *);
/* recovery.c */ /* recovery.c */
......
...@@ -358,9 +358,9 @@ static void nilfs_put_super(struct super_block *sb) ...@@ -358,9 +358,9 @@ static void nilfs_put_super(struct super_block *sb)
down_write(&nilfs->ns_super_sem); down_write(&nilfs->ns_super_sem);
if (nilfs->ns_current == sbi) if (nilfs->ns_current == sbi)
nilfs->ns_current = NULL; nilfs->ns_current = NULL;
list_del_init(&sbi->s_list);
up_write(&nilfs->ns_super_sem); up_write(&nilfs->ns_super_sem);
nilfs_detach_checkpoint(sbi);
put_nilfs(sbi->s_nilfs); put_nilfs(sbi->s_nilfs);
sbi->s_super = NULL; sbi->s_super = NULL;
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
...@@ -405,13 +405,12 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, ...@@ -405,13 +405,12 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt,
if (!root) if (!root)
return err; return err;
down_write(&nilfs->ns_super_sem); if (root->ifile)
list_add(&sbi->s_list, &nilfs->ns_supers); goto reuse; /* already attached checkpoint */
up_write(&nilfs->ns_super_sem);
sbi->s_ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size); root->ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size);
if (!sbi->s_ifile) if (!root->ifile)
goto delist; goto failed;
down_read(&nilfs->ns_segctor_sem); down_read(&nilfs->ns_segctor_sem);
err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp, err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp,
...@@ -427,7 +426,7 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, ...@@ -427,7 +426,7 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt,
} }
goto failed; goto failed;
} }
err = nilfs_read_inode_common(sbi->s_ifile, &raw_cp->cp_ifile_inode); err = nilfs_read_inode_common(root->ifile, &raw_cp->cp_ifile_inode);
if (unlikely(err)) if (unlikely(err))
goto failed_bh; goto failed_bh;
atomic_set(&sbi->s_inodes_count, le64_to_cpu(raw_cp->cp_inodes_count)); atomic_set(&sbi->s_inodes_count, le64_to_cpu(raw_cp->cp_inodes_count));
...@@ -435,35 +434,18 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, ...@@ -435,35 +434,18 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt,
nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp); nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp);
reuse:
*rootp = root; *rootp = root;
return 0; return 0;
failed_bh: failed_bh:
nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp); nilfs_cpfile_put_checkpoint(nilfs->ns_cpfile, cno, bh_cp);
failed: failed:
nilfs_mdt_destroy(sbi->s_ifile);
sbi->s_ifile = NULL;
delist:
down_write(&nilfs->ns_super_sem);
list_del_init(&sbi->s_list);
up_write(&nilfs->ns_super_sem);
nilfs_put_root(root); nilfs_put_root(root);
return err; return err;
} }
void nilfs_detach_checkpoint(struct nilfs_sb_info *sbi)
{
struct the_nilfs *nilfs = sbi->s_nilfs;
nilfs_mdt_destroy(sbi->s_ifile);
sbi->s_ifile = NULL;
down_write(&nilfs->ns_super_sem);
list_del_init(&sbi->s_list);
up_write(&nilfs->ns_super_sem);
}
static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf) static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{ {
struct super_block *sb = dentry->d_sb; struct super_block *sb = dentry->d_sb;
...@@ -862,7 +844,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, ...@@ -862,7 +844,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
} }
if (!(sb->s_flags & MS_RDONLY)) { if (!(sb->s_flags & MS_RDONLY)) {
err = nilfs_attach_segment_constructor(sbi); err = nilfs_attach_segment_constructor(sbi, fsroot);
if (err) if (err)
goto failed_checkpoint; goto failed_checkpoint;
} }
...@@ -896,6 +878,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, ...@@ -896,6 +878,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
} }
down_write(&nilfs->ns_super_sem); down_write(&nilfs->ns_super_sem);
list_add(&sbi->s_list, &nilfs->ns_supers);
if (!nilfs_test_opt(sbi, SNAPSHOT)) if (!nilfs_test_opt(sbi, SNAPSHOT))
nilfs->ns_current = sbi; nilfs->ns_current = sbi;
up_write(&nilfs->ns_super_sem); up_write(&nilfs->ns_super_sem);
...@@ -906,7 +889,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent, ...@@ -906,7 +889,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
nilfs_detach_segment_constructor(sbi); nilfs_detach_segment_constructor(sbi);
failed_checkpoint: failed_checkpoint:
nilfs_detach_checkpoint(sbi);
nilfs_put_root(fsroot); nilfs_put_root(fsroot);
failed_sbi: failed_sbi:
...@@ -966,6 +948,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) ...@@ -966,6 +948,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
up_write(&nilfs->ns_sem); up_write(&nilfs->ns_sem);
} else { } else {
__u64 features; __u64 features;
struct nilfs_root *root;
/* /*
* Mounting a RDONLY partition read-write, so reread and * Mounting a RDONLY partition read-write, so reread and
...@@ -987,7 +970,8 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data) ...@@ -987,7 +970,8 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
sb->s_flags &= ~MS_RDONLY; sb->s_flags &= ~MS_RDONLY;
err = nilfs_attach_segment_constructor(sbi); root = NILFS_I(sb->s_root->d_inode)->i_root;
err = nilfs_attach_segment_constructor(sbi, root);
if (err) if (err)
goto restore_opts; goto restore_opts;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment