From c79f7a9cdeeef1e421e47cc853482b247d8bd969 Mon Sep 17 00:00:00 2001 From: uid721 Date: Fri, 13 Aug 2004 09:21:19 +0000 Subject: [PATCH] 1)cleanup smfs for build in 2.6 2)some minor fix for building 2.6 --- lustre/cmobd/cmobd_mds_reint.c | 7 +- lustre/cmobd/cmobd_write.c | 12 +- lustre/include/linux/lustre_idl.h | 3 +- lustre/include/linux/lustre_lite.h | 1 - lustre/llite/llite_lib.c | 3 +- lustre/llite/namei.c | 4 - lustre/lvfs/fsfilt_snap_ext3.c | 426 ++++++++++++++++++++----------------- lustre/lvfs/fsfilt_snap_smfs.c | 3 +- lustre/mds/handler.c | 9 - lustre/mds/mds_lib.c | 6 - lustre/mds/mds_open.c | 12 +- lustre/mds/mds_reint.c | 10 +- lustre/smfs/Makefile.in | 2 +- lustre/smfs/cache.c | 82 +------ lustre/smfs/inode.c | 186 ++++++++++------ lustre/smfs/sm_fs.c | 85 -------- lustre/smfs/smfs_cow.c | 6 +- lustre/smfs/smfs_internal.h | 9 +- lustre/smfs/smfs_lib.c | 408 +++++++++++++++++++++++++++++++++++ lustre/smfs/super.c | 348 +++++------------------------- 20 files changed, 843 insertions(+), 779 deletions(-) delete mode 100644 lustre/smfs/sm_fs.c create mode 100644 lustre/smfs/smfs_lib.c diff --git a/lustre/cmobd/cmobd_mds_reint.c b/lustre/cmobd/cmobd_mds_reint.c index 0398ce3..c2edd3f 100644 --- a/lustre/cmobd/cmobd_mds_reint.c +++ b/lustre/cmobd/cmobd_mds_reint.c @@ -49,11 +49,10 @@ int cmobd_setattr_reint(struct obd_device *obd, struct ptlrpc_request *req) if (rec->sa_valid & ATTR_FROM_OPEN) req->rq_request_portal = MDS_SETATTR_PORTAL; //XXX FIXME bug 249 - if (rec->sa_valid & (ATTR_MTIME | ATTR_CTIME)) + if (rec->sa_valid & (ATTR_MTIME | ATTR_CTIME)) CDEBUG(D_INODE, "setting mtime %lu, ctime %lu\n", - LTIME_S(((time_t)rec->sa_mtime)), - LTIME_S(((time_t)rec->sa_ctime))); - + ((time_t)rec->sa_mtime), + ((time_t)rec->sa_ctime)); size[0] = sizeof(struct mds_body); req->rq_replen = lustre_msg_size(1, size); diff --git a/lustre/cmobd/cmobd_write.c b/lustre/cmobd/cmobd_write.c index 424ae98..815efc6 100644 --- a/lustre/cmobd/cmobd_write.c +++ b/lustre/cmobd/cmobd_write.c @@ -363,16 +363,8 @@ static int cmobd_write_main(void *arg) ENTRY; lock_kernel(); - /* vv ptlrpc_daemonize(); vv */ - exit_mm(current); - - current->session = 1; - current->pgrp = 1; - current->tty = NULL; - - exit_files(current); - reparent_to_init(); - /* ^^ ptlrpc_daemonize(); ^^ */ + + ptlrpc_daemonize(); SIGNAL_MASK_LOCK(current, flags); sigfillset(¤t->blocked); diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h index a2d9215..8f5bd37 100644 --- a/lustre/include/linux/lustre_idl.h +++ b/lustre/include/linux/lustre_idl.h @@ -515,8 +515,7 @@ struct ll_fid { __u32 generation; __u32 f_type; __u32 mds; - __u16 snap_index; - __u16 padding; + __u32 padding; }; struct mea_old { diff --git a/lustre/include/linux/lustre_lite.h b/lustre/include/linux/lustre_lite.h index 20547ce..26d38c87 100644 --- a/lustre/include/linux/lustre_lite.h +++ b/lustre/include/linux/lustre_lite.h @@ -156,7 +156,6 @@ static inline void ll_inode2fid(struct ll_fid *fid, struct inode *inode) mdc_pack_fid(fid, inode->i_ino, inode->i_generation, inode->i_mode & S_IFMT); LASSERT(ll_i2info(inode)); - fid->snap_index = ll_i2info(inode)->lli_snap_index, fid->mds = ll_i2info(inode)->lli_mds; } diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 00b305a..6891035 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1257,9 +1257,10 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md) if (body->valid & OBD_MD_FLSIZE) set_bit(LLI_F_HAVE_MDS_SIZE_LOCK, &lli->lli_flags); - lli->lli_snap_index = body->fid1.snap_index; lli->lli_mds = body->mds; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) inode->i_dev = (kdev_t) body->mds; +#endif LASSERT(body->mds < 1000); } diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index a16814b..4b1efe3 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -87,10 +87,6 @@ static int ll_test_inode(struct inode *inode, void *opaque) if (ll_i2info(inode)->lli_mds != md->body->mds) return 0; -#ifdef CONFIG_SNAPFS - if (ll_i2info(inode)->lli_snap_index != md->body->fid1.snap_index) - return 0; -#endif /* Apply the attributes in 'opaque' to this inode */ ll_update_inode(inode, md); return 1; diff --git a/lustre/lvfs/fsfilt_snap_ext3.c b/lustre/lvfs/fsfilt_snap_ext3.c index fdb3ec5..cbecc3d 100644 --- a/lustre/lvfs/fsfilt_snap_ext3.c +++ b/lustre/lvfs/fsfilt_snap_ext3.c @@ -33,10 +33,12 @@ #include #include #include -#include #include #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include #include +#include +#include #else #include #endif @@ -45,10 +47,6 @@ #include #include #include -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#include -#include -#endif #include #include @@ -80,6 +78,64 @@ #define SNAP_EA_INO_BLOCK_SIZE(size) (((size)-sizeof(ino_t)*2)/2) #define SNAP_EA_PARENT_OFFSET(size) (sizeof(ino_t)*2 + SNAP_EA_INO_BLOCK_SIZE((size))) +#define EXT3_JOURNAL_START(sb, handle, blocks, rc) \ +do { \ + journal_t *journal; \ + journal = EXT3_SB(sb)->s_journal; \ + lock_kernel(); \ + handle = journal_start(journal, 1); \ + unlock_kernel(); \ + if(IS_ERR(handle)) { \ + CERROR("can't start transaction\n"); \ + rc = PTR_ERR(handle); \ + } else \ + rc = 0; \ +} while(0) + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +static inline void double_lock_inode(struct inode *i1, struct inode *i2) +{ + if (i1 == i2) + down(&i1->i_sem); + else + double_down(&i1->i_sem, &i2->i_sem); +} +static inline void double_unlock_inode(struct inode *i1, struct inode *i2) +{ + if (i1 == i2) + up(&i1->i_sem); + else + double_up(&i1->i_sem, &i2->i_sem); +} +#else +static inline void double_lock_inode(struct inode *i1, struct inode *i2) +{ + struct semaphore *s1 = &i1->i_sem; + struct semaphore *s2 = &i2->i_sem; + + if (s1 != s2) { + if ((unsigned long) s1 < (unsigned long) s2) { + struct semaphore *tmp = s2; + s2 = s1; s1 = tmp; + } + down(s1); + } + down(s2); +} + +static inline void double_unlock_inode(struct inode *i1, struct inode *i2) +{ + struct semaphore *s1 = &i1->i_sem; + struct semaphore *s2 = &i2->i_sem; + + up(s1); + if (s1 != s2) + up(s2); +} + +#endif + /* helper functions to manipulate field 'parent' in snap_ea */ static inline int set_parent_ino(struct snap_ea *pea, int size, int index, ino_t val) @@ -173,7 +229,7 @@ static int fsfilt_ext3_set_indirect(struct inode *pri, int index, ino_t ind_ino, { char buf[EXT3_MAX_SNAP_DATA]; struct snap_ea *snaps; - int err = 0, inlist = 1; + int rc = 0, inlist = 1; int ea_size; handle_t *handle = NULL; ENTRY; @@ -185,9 +241,9 @@ static int fsfilt_ext3_set_indirect(struct inode *pri, int index, ino_t ind_ino, RETURN(-EINVAL); /* need lock the list before get_attr() to avoid race */ /* read ea at first */ - err = ext3_xattr_get(pri, EXT3_SNAP_INDEX ,EXT3_SNAP_ATTR, + rc = ext3_xattr_get(pri, EXT3_SNAP_INDEX ,EXT3_SNAP_ATTR, buf, EXT3_MAX_SNAP_DATA); - if (err == -ENODATA || err == -ENOATTR) { + if (rc == -ENODATA || rc == -ENODATA) { CDEBUG(D_INODE, "no extended attributes - zeroing\n"); memset(buf, 0, EXT3_MAX_SNAP_DATA); /* XXX @@ -195,27 +251,27 @@ static int fsfilt_ext3_set_indirect(struct inode *pri, int index, ino_t ind_ino, * So take care of snap ea of primary inodes very carefully. * Is it right in snapfs EXT3, check it later? */ - inlist = 0; - } else if (err < 0 || err > EXT3_MAX_SNAP_DATA) { - GOTO(out_unlock, err); + inlist = 0; + rc = 0; + } else if (rc < 0 || rc > EXT3_MAX_SNAP_DATA) { + GOTO(out_unlock, rc); } + EXT3_JOURNAL_START(pri->i_sb, handle, SNAP_SETIND_TRANS_BLOCKS, rc); + if(rc) + GOTO(out_unlock, rc = PTR_ERR(handle)); - handle = ext3_journal_start(pri, SNAP_SETIND_TRANS_BLOCKS); - if(!handle) - GOTO(out_unlock, err = PTR_ERR(handle)); - - snaps = (struct snap_ea *)buf; + snaps = (struct snap_ea *)buf; snaps->ino[index] = cpu_to_le32 (ind_ino); ea_size = EXT3_MAX_SNAP_DATA; set_parent_ino(snaps, ea_size, index, cpu_to_le32(parent_ino)); - err = ext3_xattr_set(handle, pri, EXT3_SNAP_INDEX, EXT3_SNAP_ATTR, - buf, EXT3_MAX_SNAP_DATA, 0); + rc = ext3_xattr_set_handle(handle, pri, EXT3_SNAP_INDEX,EXT3_SNAP_ATTR, + buf, EXT3_MAX_SNAP_DATA, 0); ext3_mark_inode_dirty(handle, pri); - ext3_journal_stop(handle, pri); + journal_stop(handle); out_unlock: - return err; + RETURN(rc); } static int ext3_set_generation(struct inode *inode, unsigned long gen) @@ -223,20 +279,20 @@ static int ext3_set_generation(struct inode *inode, unsigned long gen) handle_t *handle; int err = 0; ENTRY; - - handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS); - if( !handle ) - RETURN(-EINVAL); - - err = ext3_xattr_set(handle, inode, EXT3_SNAP_INDEX, - EXT3_SNAP_GENERATION, - (char*)&gen, sizeof(int), 0); + + EXT3_JOURNAL_START(inode->i_sb, handle, EXT3_XATTR_TRANS_BLOCKS, err); + if(err) + RETURN(err); + + err = ext3_xattr_set_handle(handle, inode, EXT3_SNAP_INDEX, + EXT3_SNAP_GENERATION, (char*)&gen, + sizeof(int), 0); if (err < 0) { CERROR("ino %lu, set_ext_attr err %d\n", inode->i_ino, err); RETURN(err); } - ext3_journal_stop(handle, inode); + journal_stop(handle); RETURN(0); } @@ -256,14 +312,17 @@ static void ext3_copy_meta(handle_t *handle, struct inode *dst, struct inode *sr dst->i_mtime = src->i_mtime; dst->i_ctime = src->i_ctime; // dst->i_version = src->i_version; - dst->i_attr_flags = src->i_attr_flags; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + dst->i_attr_flags = src->i_attr_flags; +#endif dst->i_generation = src->i_generation; - dst->u.ext3_i.i_dtime = src->u.ext3_i.i_dtime; - dst->u.ext3_i.i_flags = src->u.ext3_i.i_flags | EXT3_COW_FL; + EXT3_I(dst)->i_dtime = EXT3_I(src)->i_dtime; + EXT3_I(dst)->i_flags = EXT3_I(src)->i_flags | EXT3_COW_FL; #ifdef EXT3_FRAGMENTS - dst->u.ext3_i.i_faddr = src->u.ext3_i.i_faddr; - dst->u.ext3_i.i_frag_no = src->u.ext3_i.i_frag_no; - dst->u.ext3_i.i_frag_size = src->u.ext3_i.i_frag_size; + EXT3_I(dst)->i_faddr = EXT3_I(src)->i_faddr; + EXT3_I(dst)->i_frag_no = EXT3_I(src)->i_frag_no; + EXT3_I(dst)->i_frag_size = EXT3_I(src)->i_frag_size; #endif if ((size = ext3_xattr_list(src, NULL, 0)) > 0) { char names[size]; @@ -300,8 +359,9 @@ static void ext3_copy_meta(handle_t *handle, struct inode *dst, struct inode *sr if (ext3_xattr_get(src, EXT3_SNAP_INDEX, EXT3_SNAP_ATTR, buf, attrlen) < 0) continue; - if (ext3_xattr_set(handle, dst, EXT3_SNAP_INDEX, - EXT3_SNAP_ATTR, buf, attrlen, 0) < 0) + if (ext3_xattr_set_handle(handle, dst, EXT3_SNAP_INDEX, + EXT3_SNAP_ATTR, buf, attrlen, + 0) < 0) break; OBD_FREE(buf, attrlen); name += namelen + 1; /* skip name and trailing NUL */ @@ -350,7 +410,7 @@ static int ext3_copy_reg_block(struct inode *dst, struct inode *src, int blk) rc = 1; dst_page_unlock: kunmap(dst_page); - UnlockPage(dst_page); + unlock_page(dst_page); page_cache_release(dst_page); src_page_unlock: kunmap(src_page); @@ -362,10 +422,11 @@ static int ext3_copy_dir_block(struct inode *dst, struct inode *src, int blk) struct buffer_head *bh_dst = NULL, *bh_src = NULL; int rc = 0; handle_t *handle = NULL; - ENTRY; - handle = ext3_journal_start(dst, SNAP_COPYBLOCK_TRANS_BLOCKS); - if( !handle ) - RETURN(-EINVAL); + ENTRY; + + EXT3_JOURNAL_START(dst->i_sb, handle, SNAP_COPYBLOCK_TRANS_BLOCKS, rc); + if(rc) + RETURN(rc); bh_src = ext3_bread(handle, src, blk, 0, &rc); if (!bh_src) { @@ -389,7 +450,7 @@ exit_relese: if (bh_src) brelse(bh_src); if (bh_dst) brelse(bh_dst); if (handle) - ext3_journal_stop(handle, dst); + journal_stop(handle); RETURN(rc); } /* fsfilt_ext3_copy_block - copy one data block from inode @src to @dst. @@ -430,7 +491,9 @@ static inline int ext3_has_ea(struct inode *inode) static void fs_flushinval_pages(handle_t *handle, struct inode* inode) { if (inode->i_blocks > 0 && inode->i_mapping) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) fsync_inode_data_buffers(inode); +#endif truncate_inode_pages(inode->i_mapping, 0); } } @@ -500,6 +563,7 @@ static handle_t * ext3_copy_data(handle_t *handle, struct inode *dst, { unsigned long blocks, blk, cur_blks; int low_credits, save_ref; + int err = 0; ENTRY; blocks =(src->i_size + src->i_sb->s_blocksize-1) >> @@ -527,7 +591,7 @@ static handle_t * ext3_copy_data(handle_t *handle, struct inode *dst, ext3_orphan_add(handle, dst); *has_orphan = 1; } - dst->u.ext3_i.i_disksize = + EXT3_I(dst)->i_disksize = blk * dst->i_sb->s_blocksize; dst->i_blocks = cur_blks; dst->i_mtime = CURRENT_TIME; @@ -538,17 +602,14 @@ static handle_t * ext3_copy_data(handle_t *handle, struct inode *dst, */ save_ref = handle->h_ref; handle->h_ref = 1; - if( ext3_journal_stop(handle, dst) ){ + if(journal_stop(handle) ){ CERROR("fail to stop journal\n"); handle = NULL; break; } - handle = ext3_journal_start(dst, - low_credits + needed); - if( !handle ){ - CERROR("fail to restart handle\n"); - break; - } + EXT3_JOURNAL_START(dst->i_sb, handle, + low_credits + needed, err); + if(err) break; handle->h_ref = save_ref; } } @@ -557,7 +618,7 @@ static handle_t * ext3_copy_data(handle_t *handle, struct inode *dst, cur_blks += dst->i_sb->s_blocksize / 512; } - dst->i_size = dst->u.ext3_i.i_disksize = src->i_size; + dst->i_size = EXT3_I(dst)->i_disksize = src->i_size; RETURN(handle); } /*Here delete the data of that pri inode @@ -568,15 +629,14 @@ static int ext3_throw_inode_data(handle_t *handle, struct inode *inode) { struct inode *tmp = NULL; ENTRY; - tmp = ext3_new_inode(handle, inode, (int)inode->i_mode, 0); if(tmp) { CERROR("ext3_new_inode error\n"); RETURN(-EIO); } - double_down(&inode->i_sem, &tmp->i_sem); + double_lock_inode(inode, tmp); ext3_migrate_data(handle, tmp, inode); - double_up(&inode->i_sem, &tmp->i_sem); + double_unlock_inode(inode, tmp); tmp->i_nlink = 0; iput(tmp); RETURN(0); @@ -603,11 +663,11 @@ static struct inode* fsfilt_ext3_create_indirect(struct inode *pri, int index, { struct inode *ind = NULL; handle_t *handle = NULL; - int err = 0; + int err = 0; int has_orphan = 0; ENTRY; - if( pri == pri->i_sb->u.ext3_sb.s_journal_inode ){ + if( pri == EXT3_SB(pri->i_sb)->s_journal_inode ){ CERROR("TRY TO COW JOUNRAL\n"); RETURN(ERR_PTR(-EINVAL)); } @@ -615,12 +675,11 @@ static struct inode* fsfilt_ext3_create_indirect(struct inode *pri, int index, pri->i_ino, index, del ? "deleting" : "preserve"); ind = fsfilt_ext3_get_indirect(pri, NULL, index); - - handle = ext3_journal_start(pri, SNAP_CREATEIND_TRANS_BLOCKS); - if( !handle ) { - CERROR("handle not NULL\n"); - RETURN(ERR_PTR(-EINVAL)); - } + + EXT3_JOURNAL_START(pri->i_sb, handle, SNAP_CREATEIND_TRANS_BLOCKS, + err); + if(err) + RETURN(ERR_PTR(err)); /* XXX ? We should pass an err argument to get_indirect and precisely * detect the errors, for some errors, we should exit right away. */ @@ -639,7 +698,7 @@ static struct inode* fsfilt_ext3_create_indirect(struct inode *pri, int index, GOTO(exit, err); pri->i_nlink = 1; } - pri->u.ext3_i.i_dtime = CURRENT_TIME; + EXT3_I(pri)->i_dtime = LTIME_S(CURRENT_TIME); ext3_mark_inode_dirty(handle, pri); GOTO(exit, err=0); } @@ -653,6 +712,7 @@ static struct inode* fsfilt_ext3_create_indirect(struct inode *pri, int index, /* XXX: check this, ext3_new_inode, the first arg should be "dir" */ ind = ext3_new_inode(handle, pri, (int)pri->i_mode, 0); + if (IS_ERR(ind)) GOTO(exit, err); CDEBUG(D_INODE, "got new inode %lu\n", ind->i_ino); @@ -696,11 +756,11 @@ static struct inode* fsfilt_ext3_create_indirect(struct inode *pri, int index, GOTO(exit_unlock, err= -EINVAL); } - pri->u.ext3_i.i_flags |= EXT3_DEL_FL; - ind->u.ext3_i.i_flags |= EXT3_COW_FL; + EXT3_I(pri)->i_flags |= EXT3_DEL_FL; + EXT3_I(ind)->i_flags |= EXT3_COW_FL; if(S_ISREG(pri->i_mode)) pri->i_nlink = 1; - pri->u.ext3_i.i_dtime = CURRENT_TIME; - //pri->u.ext3_i.i_generation++; + EXT3_I(pri)->i_dtime = LTIME_S(CURRENT_TIME); + //EXT3_I(pri)->i_generation++; ext3_mark_inode_dirty(handle, pri); ext3_mark_inode_dirty(handle, ind); up(&ind->i_sem); @@ -743,8 +803,8 @@ static struct inode* fsfilt_ext3_create_indirect(struct inode *pri, int index, } } /* set cow flag for ind */ - ind->u.ext3_i.i_flags |= EXT3_COW_FL; - pri->u.ext3_i.i_flags &= ~EXT3_COW_FL; + EXT3_I(ind)->i_flags |= EXT3_COW_FL; + EXT3_I(pri)->i_flags &= ~EXT3_COW_FL; ext3_mark_inode_dirty(handle, pri); ext3_mark_inode_dirty(handle, ind); @@ -758,10 +818,10 @@ static struct inode* fsfilt_ext3_create_indirect(struct inode *pri, int index, if (!EXT3_HAS_COMPAT_FEATURE(pri->i_sb, EXT3_FEATURE_COMPAT_SNAPFS)) { lock_super(pri->i_sb); - ext3_journal_get_write_access(handle, pri->i_sb->u.ext3_sb.s_sbh); - pri->i_sb->u.ext3_sb.s_es->s_feature_compat |= + ext3_journal_get_write_access(handle, EXT3_SB(pri->i_sb)->s_sbh); + EXT3_SB(pri->i_sb)->s_es->s_feature_compat |= cpu_to_le32(EXT3_FEATURE_COMPAT_SNAPFS); - ext3_journal_dirty_metadata(handle, pri->i_sb->u.ext3_sb.s_sbh); + ext3_journal_dirty_metadata(handle, EXT3_SB(pri->i_sb)->s_sbh); pri->i_sb->s_dirt = 1; unlock_super(pri->i_sb); } @@ -770,7 +830,7 @@ static struct inode* fsfilt_ext3_create_indirect(struct inode *pri, int index, ind->i_ino, ind->i_nlink); ext3_orphan_del(handle, ind); } - ext3_journal_stop(handle, pri); + journal_stop(handle); RETURN(ind); @@ -784,7 +844,7 @@ exit: ext3_orphan_del(handle, ind); } iput(ind); - ext3_journal_stop(handle, pri); + journal_stop(handle); RETURN(ERR_PTR(err)); } @@ -797,24 +857,20 @@ static int fsfilt_ext3_snap_feature (struct super_block *sb, int feature, int op switch (op) { case SNAP_SET_FEATURE: - handle = ext3_journal_start(sb->s_root->d_inode, 1); - lock_super(sb); - ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); - SB_FEATURE_COMPAT(sb) |= cpu_to_le32(feature); - sb->s_dirt = 1; - ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); - unlock_super(sb); - ext3_journal_stop(handle, sb->s_root->d_inode); - break; case SNAP_CLEAR_FEATURE: - handle = ext3_journal_start(sb->s_root->d_inode, 1); + EXT3_JOURNAL_START(sb, handle, 1, rc); + if(rc) + RETURN(rc); lock_super(sb); ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); - SB_FEATURE_COMPAT(sb) &= ~cpu_to_le32(feature); - ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); + if (op == SNAP_SET_FEATURE) + SB_FEATURE_COMPAT(sb) |= cpu_to_le32(feature); + else + SB_FEATURE_COMPAT(sb) &= ~cpu_to_le32(feature); sb->s_dirt = 1; + ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); unlock_super(sb); - ext3_journal_stop(handle, sb->s_root->d_inode); + journal_stop(handle); break; case SNAP_HAS_FEATURE: /*FIXME should lock super or not*/ @@ -878,8 +934,8 @@ static ino_t fsfilt_ext3_get_indirect_ino(struct super_block *sb, } err = ext3_xattr_get(primary, EXT3_SNAP_INDEX, EXT3_SNAP_ATTR, buf, EXT3_MAX_SNAP_DATA); - if (err == -ENOATTR) { - GOTO(err_free, ino = -ENOATTR); + if (err == -ENODATA) { + GOTO(err_free, ino = -ENODATA); } else if (err < 0) { CERROR(" attribute read error err=%d\n", err); GOTO(err_free, ino = err); @@ -928,9 +984,6 @@ static int ext3_migrate_block(handle_t *handle, struct inode * dst, int i1_d=0, i1_s=0, i2_d=0, i2_s=0, i3_d=0, i3_s=0; int addr_per_block = EXT3_ADDR_PER_BLOCK(src->i_sb); int addr_per_block_bits = EXT3_ADDR_PER_BLOCK_BITS(src->i_sb); - unsigned long blksz = src->i_sb->s_blocksize; - kdev_t ddev = dst->i_dev; - kdev_t sdev = src->i_dev; int physical = 0; ENTRY; @@ -972,18 +1025,18 @@ static int ext3_migrate_block(handle_t *handle, struct inode * dst, else RETURN(0); } - if(block_bmap(bread(ddev, i1_d, blksz), block)) + if(block_bmap(sb_bread(dst->i_sb, i1_d), block)) RETURN(0); i1_s = inode_bmap (src, EXT3_IND_BLOCK); if( !i1_s) RETURN(0); - physical = block_bmap(bread(sdev, i1_s, blksz), block); + physical = block_bmap(sb_bread(src->i_sb, i1_s), block); if( physical) { - block_setbmap(handle, bread(ddev, i1_d, blksz),block, + block_setbmap(handle, sb_bread(dst->i_sb, i1_d),block, physical); - block_setbmap(handle, bread(sdev, i1_s, blksz),block,0); + block_setbmap(handle, sb_bread(src->i_sb, i1_s),block,0); RETURN(1); } else @@ -1003,41 +1056,41 @@ static int ext3_migrate_block(handle_t *handle, struct inode * dst, else RETURN(0); } - i2_d = block_bmap (bread (ddev, i1_d, blksz), + i2_d = block_bmap (sb_bread (dst->i_sb, i1_d), block >> addr_per_block_bits); if (!i2_d) { if(!i1_s) RETURN(0); - physical = block_bmap(bread (sdev, i1_s, blksz), + physical = block_bmap(sb_bread (src->i_sb, i1_s), block >> addr_per_block_bits); if(physical) { - block_setbmap(handle, bread (ddev, i1_d,blksz), + block_setbmap(handle, sb_bread(dst->i_sb, i1_d), block >> addr_per_block_bits, physical); - block_setbmap(handle, bread (sdev, i1_s,blksz), + block_setbmap(handle, sb_bread(src->i_sb, i1_s), block >> addr_per_block_bits, 0); RETURN(1); } else RETURN(0); } - physical = block_bmap(bread (ddev, i2_d, blksz), + physical = block_bmap(sb_bread(dst->i_sb, i2_d), block & (addr_per_block - 1)); if(physical) RETURN(0); else { - i2_s = block_bmap (bread (sdev, i1_s, blksz), + i2_s = block_bmap (sb_bread(src->i_sb, i1_s), block >> addr_per_block_bits); if(!i2_s) RETURN(0); - physical = block_bmap(bread (sdev, i2_s, blksz), + physical = block_bmap(sb_bread(src->i_sb, i2_s), block & (addr_per_block - 1)); if(physical) { - block_setbmap(handle, bread (ddev, i2_d, blksz), + block_setbmap(handle, sb_bread(dst->i_sb, i2_d), block & (addr_per_block - 1), physical); - block_setbmap(handle, bread (sdev, i2_s, blksz), + block_setbmap(handle, sb_bread(src->i_sb, i2_s), block & (addr_per_block - 1), 0); RETURN(1); } @@ -1056,41 +1109,41 @@ static int ext3_migrate_block(handle_t *handle, struct inode * dst, else RETURN(0); } - i2_d = block_bmap(bread (ddev, i1_d, blksz), + i2_d = block_bmap(sb_bread (dst->i_sb, i1_d), block >> (addr_per_block_bits * 2)); - if(i1_s) i2_s = block_bmap(bread(sdev, i1_s, blksz), + if(i1_s) i2_s = block_bmap(sb_bread(src->i_sb, i1_s), block >> (addr_per_block_bits * 2)); if (!i2_d) { if( !i1_s) RETURN(0); - physical = block_bmap(bread (sdev, i1_s, blksz), + physical = block_bmap(sb_bread (src->i_sb, i1_s), block >> (addr_per_block_bits * 2)); if(physical) { - block_setbmap(handle, bread (ddev, i1_d, blksz), + block_setbmap(handle, sb_bread (dst->i_sb, i1_d), block >> (addr_per_block_bits * 2), physical); - block_setbmap(handle, bread (sdev, i1_s, blksz), + block_setbmap(handle, sb_bread (src->i_sb, i1_s), block >> (addr_per_block_bits * 2), 0); RETURN(1); } else RETURN(0); } - i3_d = block_bmap (bread (ddev, i2_d, blksz), + i3_d = block_bmap (sb_bread (dst->i_sb, i2_d), (block >> addr_per_block_bits) & (addr_per_block - 1)); - if( i2_s) i3_s = block_bmap (bread (sdev, i2_s, blksz), + if( i2_s) i3_s = block_bmap (sb_bread (src->i_sb, i2_s), (block >> addr_per_block_bits) & (addr_per_block - 1)); if (!i3_d) { if (!i2_s) RETURN(0); - physical = block_bmap (bread (sdev, i2_s, blksz), + physical = block_bmap (sb_bread (src->i_sb, i2_s), (block >> addr_per_block_bits) & (addr_per_block - 1)); if( physical) { - block_setbmap (handle, bread (ddev, i2_d, blksz), + block_setbmap (handle, sb_bread (dst->i_sb, i2_d), (block >> addr_per_block_bits) & (addr_per_block - 1), physical); - block_setbmap (handle, bread (sdev, i2_s, blksz), + block_setbmap (handle, sb_bread (src->i_sb, i2_s), (block >> addr_per_block_bits) & (addr_per_block - 1),0); RETURN(1); @@ -1098,19 +1151,19 @@ static int ext3_migrate_block(handle_t *handle, struct inode * dst, else RETURN(0); } - physical = block_bmap (bread (ddev, i3_d, blksz), + physical = block_bmap (sb_bread (dst->i_sb, i3_d), block & (addr_per_block - 1)) ; if(physical) RETURN(0); else { if(!i3_s) RETURN(0); - physical = block_bmap(bread(sdev, i3_s, blksz), + physical = block_bmap(sb_bread(src->i_sb, i3_s), block & (addr_per_block - 1)); if(physical) { - block_setbmap (handle, bread (ddev, i3_d, blksz), + block_setbmap (handle, sb_bread (dst->i_sb, i3_d), block & (addr_per_block - 1), physical); - block_setbmap (handle, bread (sdev, i3_s, blksz), + block_setbmap (handle, sb_bread (src->i_sb, i3_s), block & (addr_per_block - 1), 0); RETURN(1); } @@ -1202,13 +1255,12 @@ static int fsfilt_ext3_destroy_indirect(struct inode *pri, int index, struct inode *ind; int save = 0, i=0, err = 0; handle_t *handle=NULL; - time_t ctime; ENTRY; if (index < 0 || index > EXT3_MAX_SNAPS) RETURN(0); - if( pri == pri->i_sb->u.ext3_sb.s_journal_inode ){ + if( pri == EXT3_SB(pri->i_sb)->s_journal_inode ){ CERROR("TRY TO DESTROY JOURNAL'S IND\n"); RETURN(-EINVAL); } @@ -1237,11 +1289,11 @@ static int fsfilt_ext3_destroy_indirect(struct inode *pri, int index, CDEBUG(D_INODE, "iget ind %lu, ref count = %d\n", ind->i_ino, atomic_read(&ind->i_count)); - - handle = ext3_journal_start(pri, SNAP_DESTROY_TRANS_BLOCKS); - if (!handle) { + + EXT3_JOURNAL_START(pri->i_sb, handle, SNAP_DESTROY_TRANS_BLOCKS, err); + if (err) { iput(ind); - RETURN(-EINVAL); + RETURN(err); } /* if it's block level cow, first copy the blocks back */ if (EXT3_HAS_COMPAT_FEATURE(pri->i_sb, EXT3_FEATURE_COMPAT_BLOCKCOW) && @@ -1252,7 +1304,7 @@ static int fsfilt_ext3_destroy_indirect(struct inode *pri, int index, next_ind = pri; down(&ind->i_sem); } else { - double_down(&next_ind->i_sem, &ind->i_sem); + double_lock_inode(next_ind, ind); } blocks = (next_ind->i_size + next_ind->i_sb->s_blocksize-1) >> next_ind->i_sb->s_blocksize_bits; @@ -1275,8 +1327,7 @@ static int fsfilt_ext3_destroy_indirect(struct inode *pri, int index, if (next_ind == pri) up(&ind->i_sem); else - double_up(&next_ind->i_sem, &ind->i_sem); - + double_unlock_inode(next_ind, ind); } CDEBUG(D_INODE, "delete indirect ino %lu\n", ind->i_ino); @@ -1298,7 +1349,7 @@ static int fsfilt_ext3_destroy_indirect(struct inode *pri, int index, * Otherwise, if we are deleting the last indirect inode remove the * snaptable from the inode. XXX */ - if (!save && pri->u.ext3_i.i_dtime) { + if (!save && EXT3_I(pri)->i_dtime) { CDEBUG(D_INODE, "deleting primary %lu\n", pri->i_ino); pri->i_nlink = 0; /* reset err to 0 now */ @@ -1306,15 +1357,12 @@ static int fsfilt_ext3_destroy_indirect(struct inode *pri, int index, } else { CDEBUG(D_INODE, "%s redirector table\n", save ? "saving" : "deleting"); - /* XXX: since set ea will modify i_ctime of pri, - so save/restore i_ctime. Need this necessary ? */ - ctime = pri->i_ctime; - err = ext3_xattr_set(handle, pri, EXT3_SNAP_INDEX, EXT3_SNAP_ATTR, - save ? buf : NULL, EXT3_MAX_SNAP_DATA, 0); - pri->i_ctime = ctime; + err = ext3_xattr_set_handle(handle, pri, EXT3_SNAP_INDEX, + EXT3_SNAP_ATTR, save ? buf : NULL, + EXT3_MAX_SNAP_DATA, 0); ext3_mark_inode_dirty(handle, pri); } - ext3_journal_stop(handle, pri); + journal_stop(handle); RETURN(err); } @@ -1330,7 +1378,7 @@ static int fsfilt_ext3_restore_indirect(struct inode *pri, int index) if (index < 0 || index > EXT3_MAX_SNAPS) RETURN(-EINVAL); - if( pri == pri->i_sb->u.ext3_sb.s_journal_inode ){ + if( pri == EXT3_SB(pri->i_sb)->s_journal_inode ){ CERROR("TRY TO RESTORE JOURNAL\n"); RETURN(-EINVAL); } @@ -1343,9 +1391,9 @@ static int fsfilt_ext3_restore_indirect(struct inode *pri, int index) CDEBUG(D_INODE, "restore ino %lu to %lu\n", pri->i_ino, ind->i_ino); - handle = ext3_journal_start(pri, SNAP_RESTORE_TRANS_BLOCKS); - if( !handle ) - RETURN(-EINVAL); + EXT3_JOURNAL_START(pri->i_sb, handle, SNAP_RESTORE_TRANS_BLOCKS, err); + if(err) + RETURN(err); /* first destroy all the data blocks in primary inode */ /* XXX: check this, ext3_new_inode, the first arg should be "dir" */ err = ext3_throw_inode_data(handle, pri); @@ -1353,15 +1401,15 @@ static int fsfilt_ext3_restore_indirect(struct inode *pri, int index) CERROR("restore_indirect, new_inode err\n"); RETURN(err); } - double_down(&pri->i_sem, &ind->i_sem); + double_lock_inode(pri, ind); ext3_migrate_data(handle, pri, ind); - pri->u.ext3_i.i_flags &= ~EXT3_COW_FL; + EXT3_I(pri)->i_flags &= ~EXT3_COW_FL; ext3_mark_inode_dirty(handle, pri); - double_up(&pri->i_sem, &ind->i_sem); + double_unlock_inode(pri, ind); iput(ind); //fsfilt_ext3_destroy_indirect(pri, index); - ext3_journal_stop(handle, pri); + journal_stop(handle); RETURN(err); } @@ -1432,51 +1480,47 @@ static int ext3_iterate_all(struct super_block *sb, ibase = gstart * EXT3_INODES_PER_GROUP(sb); for (gnum = gstart; gnum < EXT3_SB(sb)->s_groups_count; gnum++, ibase += EXT3_INODES_PER_GROUP(sb)) { + struct buffer_head *bitmap_bh = NULL; struct ext3_group_desc * gdp; - int bitmap_nr, ibyte; - char *bitmap; - + ino_t ino; + gdp = ext3_get_group_desc (sb, gnum, NULL); if (!gdp || le16_to_cpu(gdp->bg_free_inodes_count) == EXT3_INODES_PER_GROUP(sb)) continue; - - bitmap_nr = ext3_load_inode_bitmap(sb, gnum); - if (bitmap_nr < 0) - continue; - - bitmap = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr]->b_data; - for (ibyte = istart >> 3; ibyte < EXT3_INODES_PER_GROUP(sb) >> 3; - ibyte++) { - int i, bit; - - if (!bitmap[ibyte]) - continue; - - /* FIXME need to verify if bit endianness will - * work properly here for all architectures. - */ - for (i = 1, bit = 1; i <= 8; i++, bit <<= 1) { - ino_t ino = ibase + (ibyte << 3) + i; - - if ((bitmap[ibyte] & bit) == 0) + bitmap_bh = read_inode_bitmap(sb, gnum); + + if (!bitmap_bh) + continue; + ino = 0; +repeat: +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + ino = find_next_bit((unsigned long *)bitmap_bh->b_data, + EXT3_INODES_PER_GROUP(sb), ino); +#else + ino = find_next_bit((unsigned long *)bitmap_bh->b_data, + EXT3_INODES_PER_GROUP(sb), ino); +#warning"FIXME-WANGDI need to port find_next_bit to 2.4" +#endif + if (ino < EXT3_INODES_PER_GROUP(sb)) { + ino_t inum = ino + gnum * EXT3_INODES_PER_GROUP(sb) + 1; + if (*start) { + if (inum < (*start)->i_ino) continue; - if (*start) { - if (ino < (*start)->i_ino) - continue; - } else { - *start = iget(sb, ino); - if (!*start) - GOTO(exit, err = -ENOMEM); - if (is_bad_inode(*start)) - GOTO(exit, err = -EIO); - } - if ((err = (*repeat)(*start, priv)) != 0) - GOTO(exit, err); - iput(*start); - *start = NULL; + } else { + *start = iget(sb, inum); + if (!*start) + GOTO(exit, err = -ENOMEM); + if (is_bad_inode(*start)) + GOTO(exit, err = -EIO); } - } + if ((err = (*repeat)(*start, priv)) != 0) + GOTO(exit, err); + iput(*start); + *start = NULL; + if (++ino < EXT3_INODES_PER_GROUP(sb)) + goto repeat; + } istart = 0; } exit: @@ -1523,7 +1567,7 @@ static int fsfilt_ext3_get_snap_info(struct inode *inode, void *key, rc = ext3_xattr_get(inode, EXT3_SNAP_INDEX,EXT3_SNAP_GENERATION, (char *)val, *vallen); - if (rc == -ENOATTR) { + if (rc == -ENODATA) { *((__u32 *)val) = 0; *vallen = sizeof(int); rc = 0; @@ -1548,13 +1592,13 @@ static int fsfilt_ext3_set_snap_info(struct inode *inode, void *key, if (keylen >= strlen(SNAPTABLE_INFO) && strcmp(key, SNAPTABLE_INFO) == 0) { handle_t *handle; - - handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS); - if( !handle ) - RETURN(-EINVAL); - rc = ext3_xattr_set(handle, inode, EXT3_SNAP_INDEX, - EXT3_SNAPTABLE_EA, val, *vallen, 0); - ext3_journal_stop(handle, inode); + EXT3_JOURNAL_START(inode->i_sb, handle, + EXT3_XATTR_TRANS_BLOCKS, rc); + if(rc) + RETURN(rc); + rc = ext3_xattr_set_handle(handle, inode, EXT3_SNAP_INDEX, + EXT3_SNAPTABLE_EA, val, *vallen, 0); + journal_stop(handle); RETURN(rc); } else if (keylen >= strlen(SNAP_GENERATION) diff --git a/lustre/lvfs/fsfilt_snap_smfs.c b/lustre/lvfs/fsfilt_snap_smfs.c index 640d288..f59f55f 100644 --- a/lustre/lvfs/fsfilt_snap_smfs.c +++ b/lustre/lvfs/fsfilt_snap_smfs.c @@ -75,7 +75,8 @@ static struct inode* fsfilt_smfs_create_indirect(struct inode *inode, if (cache_ind_inode && !IS_ERR(cache_ind_inode)){ /*FIXME: get indirect inode set_cow flags*/ - ind_inode = iget4(inode->i_sb, cache_ind_inode->i_ino, NULL, 0); + ind_inode = smfs_get_inode(inode->i_sb, cache_ind_inode->i_ino, + inode, 0); } RETURN(ind_inode); } diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 5bd0496..9b55c52 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -299,16 +299,7 @@ struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid, if (ino == 0) RETURN(ERR_PTR(-ESTALE)); -#ifdef CONFIG_SNAPFS - if (is_smfs_sb(mds->mds_sb)) { - snprintf(fid_name, sizeof(fid_name), "0x%lx:%lx", ino, - fid->snap_index); - } else { - snprintf(fid_name, sizeof(fid_name), "0x%lx", ino); - } -#else snprintf(fid_name, sizeof(fid_name), "0x%lx", ino); -#endif CDEBUG(D_DENTRY, "--> mds_fid2dentry: ino/gen %lu/%u, sb %p\n", ino, generation, mds->mds_sb); diff --git a/lustre/mds/mds_lib.c b/lustre/mds/mds_lib.c index 81107a1..2fe77d2 100644 --- a/lustre/mds/mds_lib.c +++ b/lustre/mds/mds_lib.c @@ -70,12 +70,6 @@ void mds_pack_dentry2body(struct mds_body *b, struct dentry *dentry) void mds_pack_inode2fid(struct obd_device *obd, struct ll_fid *fid, struct inode *inode) { -#ifdef CONFIG_SNAPFS - if (is_smfs_sb(inode->i_sb)) { - struct smfs_inode_info *sm_info = I2SMI(inode); - fid->snap_index = sm_info->sm_sninfo.sn_index; - } -#endif fid->id = inode->i_ino; fid->generation = inode->i_generation; fid->f_type = (S_IFMT & inode->i_mode); diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c index 2d96fe9..07ea3d8 100644 --- a/lustre/mds/mds_open.c +++ b/lustre/mds/mds_open.c @@ -1039,9 +1039,9 @@ got_child: } created = 1; - LTIME_S(iattr.ia_atime) = LTIME_S(rec->ur_time); - LTIME_S(iattr.ia_ctime) = LTIME_S(rec->ur_time); - LTIME_S(iattr.ia_mtime) = LTIME_S(rec->ur_time); + LTIME_S(iattr.ia_atime) = rec->ur_time; + LTIME_S(iattr.ia_ctime) = rec->ur_time; + LTIME_S(iattr.ia_mtime) = rec->ur_time; iattr.ia_uid = rec->_ur_fsuid; if (dparent->d_inode->i_mode & S_ISGID) @@ -1314,11 +1314,11 @@ int mds_mfd_close(struct ptlrpc_request *req, struct obd_device *obd, * it is more out-of-date than the specified limit. If we * are already going to write out the atime then do it anyway. * */ - if ((LTIME_S(request_body->atime) > + if ((request_body->atime > LTIME_S(inode->i_atime) + MAX_ATIME_DIFF) || (iattr.ia_valid != 0 && - LTIME_S(request_body->atime) > LTIME_S(inode->i_atime))) { - LTIME_S(iattr.ia_atime) = LTIME_S(request_body->atime); + request_body->atime > LTIME_S(inode->i_atime))) { + LTIME_S(iattr.ia_atime) = request_body->atime; iattr.ia_valid |= ATTR_ATIME; } } diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c index a9e1f40..1b88793 100644 --- a/lustre/mds/mds_reint.c +++ b/lustre/mds/mds_reint.c @@ -829,9 +829,9 @@ static int mds_reint_create(struct mds_update_record *rec, int offset, struct mds_body *body; created = 1; - LTIME_S(iattr.ia_atime) = LTIME_S(rec->ur_time); - LTIME_S(iattr.ia_ctime) = LTIME_S(rec->ur_time); - LTIME_S(iattr.ia_mtime) = LTIME_S(rec->ur_time); + LTIME_S(iattr.ia_atime) = rec->ur_time; + LTIME_S(iattr.ia_ctime) = rec->ur_time; + LTIME_S(iattr.ia_mtime) = rec->ur_time; iattr.ia_uid = rec->_ur_fsuid; if (dir->i_mode & S_ISGID) iattr.ia_gid = dir->i_gid; @@ -1845,8 +1845,8 @@ static int mds_reint_unlink(struct mds_update_record *rec, int offset, int err; iattr.ia_valid = ATTR_MTIME | ATTR_CTIME; - LTIME_S(iattr.ia_mtime) = LTIME_S(rec->ur_time); - LTIME_S(iattr.ia_ctime) = LTIME_S(rec->ur_time); + LTIME_S(iattr.ia_mtime) = rec->ur_time; + LTIME_S(iattr.ia_ctime) = rec->ur_time; err = fsfilt_setattr(obd, dparent, handle, &iattr, 0); if (err) diff --git a/lustre/smfs/Makefile.in b/lustre/smfs/Makefile.in index 8586c58..d95b3a7 100644 --- a/lustre/smfs/Makefile.in +++ b/lustre/smfs/Makefile.in @@ -1,6 +1,6 @@ MODULES := smfs smfs-objs := super.o options.o inode.o cache.o cache_space.o dir.o ioctl.o -smfs-objs += sysctl.o file.o symlink.o sm_fs.o kml.o journal.o smfs_llog.o +smfs-objs += sysctl.o file.o symlink.o smfs_lib.o kml.o journal.o smfs_llog.o smfs-objs += mds_kml.o ost_kml.o @SNAPFS_TRUE@smfs-objs += smfs_cow.o @INCLUDE_RULES@ diff --git a/lustre/smfs/cache.c b/lustre/smfs/cache.c index 717e3af..2911adf 100644 --- a/lustre/smfs/cache.c +++ b/lustre/smfs/cache.c @@ -238,8 +238,6 @@ static void setup_sm_sb_ops(struct super_block *cache_sb, struct super_block *sb memset(sops, 0, sizeof (struct super_operations)); if (cache_sb->s_op) { - if (cache_sb->s_op->read_inode) - sops->read_inode = smfs_sops->read_inode; if (cache_sb->s_op->dirty_inode) sops->dirty_inode = smfs_sops->dirty_inode; if (cache_sb->s_op->write_inode) @@ -262,16 +260,18 @@ static void setup_sm_sb_ops(struct super_block *cache_sb, struct super_block *sb sops->remount_fs = smfs_sops->remount_fs; if (cache_sb->s_op->umount_begin) sops->umount_begin = smfs_sops->umount_begin; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) if (cache_sb->s_op->fh_to_dentry) sops->fh_to_dentry = smfs_sops->fh_to_dentry; if (cache_sb->s_op->dentry_to_fh) sops->dentry_to_fh = smfs_sops->dentry_to_fh; if (cache_sb->s_op->show_options) sops->show_options = smfs_sops->show_options; - + sops->read_inode2 = smfs_sops->read_inode2; +#endif /* FIXME-WANGDI we need this method to clear the cache inode. */ sops->clear_inode = smfs_sops->clear_inode; - sops->read_inode2 = smfs_sops->read_inode2; } lock_kernel(); @@ -322,78 +322,4 @@ void sm_set_sb_ops(struct super_block *cache_sb, struct super_block *sb) sb->s_op = cache_sops(smb); return; } -struct smfs_hook_ops *smfs_alloc_hook_ops(char *name, smfs_hook_func pre_hook, - smfs_hook_func post_hook) -{ - struct smfs_hook_ops *smfs_hops = NULL; - - ENTRY; - OBD_ALLOC(smfs_hops, sizeof(struct smfs_hook_ops)); - - if (!smfs_hops) - RETURN(NULL); - - OBD_ALLOC(smfs_hops->smh_name, strlen(name) + 1); - - if (!smfs_hops->smh_name) { - OBD_FREE(smfs_hops, sizeof(struct smfs_hook_ops)); - RETURN(NULL); - } - - memcpy(smfs_hops->smh_name, name, strlen(name)); - - smfs_hops->smh_post_op = post_hook; - smfs_hops->smh_pre_op = pre_hook; - - RETURN(smfs_hops); -} -void smfs_free_hook_ops(struct smfs_hook_ops *hops) -{ - if (hops) { - if (hops->smh_name){ - OBD_FREE(hops->smh_name, strlen(hops->smh_name) + 1); - } - OBD_FREE(hops, sizeof(struct smfs_hook_ops)); - } -} - -int smfs_register_hook_ops(struct super_block *sb, - struct smfs_hook_ops *smh_ops) -{ - struct smfs_super_info *smb = S2SMI(sb); - struct list_head *hlist = &smb->smsi_hook_list; - struct list_head *p; - ENTRY; - - list_for_each(p, hlist) { - struct smfs_hook_ops *found; - found = list_entry(p, struct smfs_hook_ops, smh_list); - if (!strcmp(found->smh_name, smh_ops->smh_name)) { - CWARN("hook ops %s list reregister\n", smh_ops->smh_name); - RETURN(0); - } - } - list_add(&smh_ops->smh_list, hlist); - RETURN(0); -} -struct smfs_hook_ops *smfs_unregister_hook_ops(struct super_block *sb, - char *name) -{ - struct smfs_super_info *smb = S2SMI(sb); - struct list_head *hlist = &smb->smsi_hook_list; - struct list_head *p; - ENTRY; - - list_for_each(p, hlist) { - struct smfs_hook_ops *found; - - found = list_entry(p, typeof(*found), smh_list); - if (!memcmp(found->smh_name, name, strlen(name))) { - list_del(p); - RETURN(found); - } - } - RETURN(NULL); -} - diff --git a/lustre/smfs/inode.c b/lustre/smfs/inode.c index 8360b18..bd45cfb 100644 --- a/lustre/smfs/inode.c +++ b/lustre/smfs/inode.c @@ -36,97 +36,117 @@ #include #include #include "smfs_internal.h" - -static void smfs_read_inode(struct inode *inode) +static void smfs_init_cache_inode (struct inode *inode, void *opaque) { - struct inode *cache_inode; - ENTRY; - - if (!inode) - return; - - CDEBUG(D_INODE, "read_inode ino %lu\n", inode->i_ino); - + struct smfs_inode_info *sm_info = (struct smfs_inode_info *)opaque; + struct inode *cache_inode = NULL; + cache_inode = iget(S2CSB(inode->i_sb), inode->i_ino); - - I2CI(inode) = cache_inode; + if (sm_info) + memcpy(I2SMI(inode), sm_info, sizeof(struct smfs_inode_info)); + + I2CI(inode) = cache_inode; post_smfs_inode(inode, cache_inode); sm_set_inode_ops(cache_inode, inode); - - CDEBUG(D_INODE, "read_inode ino %lu icount %d \n", - inode->i_ino, atomic_read(&inode->i_count)); - return; +#if CONFIG_SNAPFS + if (sm_info) { + smfs_init_snap_inode_info(inode, &sm_info->sm_sninfo); + } +#endif } static void smfs_read_inode2(struct inode *inode, void *opaque) { - struct inode *cache_inode; ENTRY; - if (!inode) return; CDEBUG(D_INODE, "read_inode ino %lu\n", inode->i_ino); - - cache_inode = iget(S2CSB(inode->i_sb), inode->i_ino); - - if (opaque) - I2SMI(inode)->smi_flags = *((int *)opaque); - - I2CI(inode) = cache_inode; - - post_smfs_inode(inode, cache_inode); - sm_set_inode_ops(cache_inode, inode); -#if CONFIG_SNAPFS - if (opaque) - smfs_init_snap_inode_info(inode, *((int *)opaque)); -#endif + smfs_init_cache_inode(inode, opaque); CDEBUG(D_INODE, "read_inode ino %lu icount %d \n", inode->i_ino, atomic_read(&inode->i_count)); + EXIT; return; } -/* Although some filesystem(such as ext3) do not have - * clear_inode method, but we need it to free the - * cache inode - */ -static void smfs_clear_inode(struct inode *inode) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +static int smfs_test_inode(struct inode *inode, unsigned long ino, + void *opaque) +#else +static int smfs_test_inode(struct inode *inode, void *opaque) +#endif { - struct inode *cache_inode; + struct snap_inode_info *sn_info = &I2SMI(inode)->sm_sninfo; + struct snap_inode_info *test_info = (struct snap_inode_info *)opaque; + + if (!sn_info || !test_info) + return 0; + if (sn_info->sn_index != test_info->sn_index) + return 0; + if (sn_info->sn_gen != test_info->sn_gen) + return 0; +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + smfs_init_cache_inode(inode, opaque); +#endif + return 1; +} - ENTRY; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) +int smfs_set_inode(struct inode *inode, void *opaque) +{ + smfs_read_inode2(inode, opaque); + return 0; +} - if (!inode) return; +struct inode *smfs_iget(struct super_block *sb, ino_t hash, + struct smfs_inode_info *si_info) +{ + struct inode *inode; - cache_inode = I2CI(inode); + LASSERT(hash != 0); + inode = iget5_locked(sb, hash, smfs_test_inode, smfs_set_inode, + si_info); - /* FIXME: because i_count of cache_inode may not - * be 0 or 1 in before smfs_delete inode, So we - * need to dec it to 1 before we call delete_inode - * of the bellow cache filesystem Check again latter. */ - if (cache_inode != cache_inode->i_sb->s_root->d_inode) { - struct list_head *lp; - struct dentry *tmp; - while (!list_empty(&cache_inode->i_dentry)) { - lp = cache_inode->i_dentry.next; - tmp = list_entry(lp, struct dentry, d_alias); - if (atomic_read(&tmp->d_count) >= 1) - post_smfs_dentry(tmp); - } - if (atomic_read(&cache_inode->i_count) < 1) - LBUG(); - - while (atomic_read(&cache_inode->i_count) != 1) { - atomic_dec(&cache_inode->i_count); - } - iput(cache_inode); - SMFS_CLEAN_INODE_REC(inode); - I2CI(inode) = NULL; + if (inode) { + if (inode->i_state & I_NEW) + unlock_new_inode(inode); + CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino, + inode->i_generation, inode); } - return; + return inode; } +#else +struct inode *smfs_iget(struct super_block *sb, ino_t hash, + struct smfs_inode_info *si_info) +{ + struct inode *inode; + LASSERT(hash != 0); + + inode = iget4(sb, hash, smfs_test_inode, si_info); + if (inode) + CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino, + inode->i_generation, inode); + return inode; +} +#endif +struct inode *smfs_get_inode (struct super_block *sb, ino_t hash, + struct inode *dir, int index) +{ + struct smfs_inode_info sm_info; + struct inode *inode = NULL; + ENTRY; + + sm_info.smi_flags = I2SMI(dir)->smi_flags; + sm_info.sm_sninfo.sn_flags = I2SMI(dir)->sm_sninfo.sn_flags; + sm_info.sm_sninfo.sn_index = index; + sm_info.sm_sninfo.sn_gen = I2SMI(dir)->sm_sninfo.sn_gen; + inode = smfs_iget(sb, hash, &sm_info); + + RETURN(inode); +} +EXPORT_SYMBOL(smfs_get_inode); static void smfs_delete_inode(struct inode *inode) { struct inode *cache_inode; @@ -228,9 +248,14 @@ static void smfs_put_inode(struct inode *inode) CWARN("cache inode null\n"); return; } + + if (atomic_read(&cache_inode->i_count) > 1 && + cache_inode != cache_inode->i_sb->s_root->d_inode) + iput(cache_inode); + if (S2CSB(inode->i_sb)->s_op->put_inode) S2CSB(inode->i_sb)->s_op->put_inode(cache_inode); - + EXIT; } @@ -245,6 +270,26 @@ static void smfs_write_super(struct super_block *sb) S2CSB(sb)->s_op->write_super(S2CSB(sb)); duplicate_sb(sb, S2CSB(sb)); EXIT; + return; +} + +static void smfs_clear_inode(struct inode *inode) +{ + struct inode *cache_inode; + + ENTRY; + + if (!inode) return; + + cache_inode = I2CI(inode); + + if (cache_inode != cache_inode->i_sb->s_root->d_inode) { + iput(cache_inode); + SMFS_CLEAN_INODE_REC(inode); + I2CI(inode) = NULL; + } + EXIT; + return; } static void smfs_write_super_lockfs(struct super_block *sb) @@ -300,7 +345,6 @@ static int smfs_statfs(struct super_block *sb, struct kstatfs *buf) RETURN(rc); } - static int smfs_remount(struct super_block *sb, int *flags, char *data) { struct super_block *cache_sb; @@ -318,10 +362,10 @@ static int smfs_remount(struct super_block *sb, int *flags, char *data) duplicate_sb(sb, cache_sb); RETURN(rc); } - struct super_operations smfs_super_ops = { - .read_inode = smfs_read_inode, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) .read_inode2 = smfs_read_inode2, +#endif .clear_inode = smfs_clear_inode, .put_super = smfs_put_super, .delete_inode = smfs_delete_inode, @@ -334,3 +378,9 @@ struct super_operations smfs_super_ops = { .statfs = smfs_statfs, /* BKL held */ .remount_fs = smfs_remount, /* BKL held */ }; + +int is_smfs_sb(struct super_block *sb) +{ + return (sb->s_op->put_super == smfs_super_ops.put_super); +} +EXPORT_SYMBOL(is_smfs_sb); diff --git a/lustre/smfs/sm_fs.c b/lustre/smfs/sm_fs.c deleted file mode 100644 index e8709f8..0000000 --- a/lustre/smfs/sm_fs.c +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * - * lustre/smfs/sm_fs.c - * Lustre filesystem abstraction routines - * - * Copyright (C) 2004 Cluster File Systems, Inc. - * - * This file is part of Lustre, http://www.lustre.org. - * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define DEBUG_SUBSYSTEM S_SM - -#ifndef EXPORT_SYMTAB -#define EXPORT_SYMTAB -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "smfs_internal.h" - -int sm_stack = 0; -long sm_kmemory = 0; - -MODULE_AUTHOR("Peter J. Braam "); -MODULE_DESCRIPTION("Smfs file system filters v0.01"); -MODULE_LICENSE("GPL"); - -extern int init_smfs(void); -extern int cleanup_smfs(void); - -static int __init smfs_init(void) -{ - int err; - - if ( (err = init_smfs_psdev()) ) { - printk("Error initializing smfs_psdev, %d\n", err); - return -EINVAL; - } - - if ( (err = init_smfs()) ) { - printk("Error initializing smfs, %d\n", err); - return -EINVAL; - } - - if ( (err = init_smfs_proc_sys()) ) { - printk("Error initializing smfs proc sys, %d\n", err); - return -EINVAL; - } - - return 0; -} - -static void __exit smfs_cleanup(void) -{ - cleanup_smfs(); - smfs_cleanup_psdev(); -} -module_init(smfs_init); -module_exit(smfs_cleanup); diff --git a/lustre/smfs/smfs_cow.c b/lustre/smfs/smfs_cow.c index 8282a82..159dda5 100644 --- a/lustre/smfs/smfs_cow.c +++ b/lustre/smfs/smfs_cow.c @@ -84,7 +84,7 @@ static int smfs_init_snaptabe(struct super_block *sb) strlen(SNAPTABLE_INFO), snap_table, &table_size); if (rc < 0) { - if (rc == -ENOATTR) { + if (rc == -ENODATA) { snap_table->sntbl_count = 0; CDEBUG(D_INFO, "No snaptable here\n"); RETURN(0); @@ -380,7 +380,7 @@ void snap_last(struct super_block *sb, struct snap *snap) { struct snap_info *snap_info = S2SNAPI(sb); struct snap_table *table = snap_info->sntbl; - time_t now = CURRENT_TIME; + time_t now = LTIME_S(CURRENT_TIME); int i ; ENTRY; @@ -442,7 +442,7 @@ int smfs_add_snap_item(struct super_block *sb, char *name) snap_item = &snap_table->sntbl_items[count]; /*add item in snap_table set generation*/ - snap_item->sn_time = CURRENT_TIME; + snap_item->sn_time = LTIME_S(CURRENT_TIME); /* find table index */ index = get_index_of_item(snap_table, name); if (index < 0) diff --git a/lustre/smfs/smfs_internal.h b/lustre/smfs/smfs_internal.h index 7efefbd..1fe7f9a 100644 --- a/lustre/smfs/smfs_internal.h +++ b/lustre/smfs/smfs_internal.h @@ -128,11 +128,10 @@ int smfs_register_hook_ops(struct super_block *sb, struct smfs_hook_ops *smfs_unregister_hook_ops(struct super_block *sb, char *name); -/*super.c*/ -extern int init_smfs(void); -extern int cleanup_smfs(void); -extern void smfs_put_super(struct super_block *sb); +/*smfs_lib.c*/ +void smfs_put_super(struct super_block *sb); extern struct super_block *smfs_get_sb_by_path(char *path, int len); +int smfs_fill_super(struct super_block *sb, void *data, int silent); /*sysctl.c*/ extern int sm_debug_level; extern int sm_inodes; @@ -159,7 +158,9 @@ extern int smfs_release(struct inode * inode, struct file * filp); /*inode.c*/ struct inode *smfs_get_inode(struct super_block *sb, ino_t hash, struct inode *dir, int index); + extern struct super_operations smfs_super_ops; + /*symlink.c*/ extern struct inode_operations smfs_sym_iops; extern struct file_operations smfs_sym_fops; diff --git a/lustre/smfs/smfs_lib.c b/lustre/smfs/smfs_lib.c new file mode 100644 index 0000000..f9045d1 --- /dev/null +++ b/lustre/smfs/smfs_lib.c @@ -0,0 +1,408 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * lustre/smfs/super.c + * Lustre filesystem abstraction routines + * + * Copyright (C) 2004 Cluster File Systems, Inc. + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define DEBUG_SUBSYSTEM S_SM + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "smfs_internal.h" +static char *smfs_options(char *data, char **devstr, char **namestr, + int *kml, int *cache, char **opts, int *iopen_nopriv, + int *cow) +{ + char *pos; + struct option *opt_value = NULL; + + while (!(get_opt(&opt_value, &pos))) { + if (!strcmp(opt_value->opt, "dev")) { + if (devstr != NULL) + *devstr = opt_value->value; + } else if (!strcmp(opt_value->opt, "type")) { + if (namestr != NULL) + *namestr = opt_value->value; + } else if (!strcmp(opt_value->opt, "kml")) { + if (kml) + *kml = 1; + } else if (!strcmp(opt_value->opt, "cache")) { + if (cache) + *cache = 1; + } else if (!strcmp(opt_value->opt, "options")) { + if (opts != NULL) + *opts = opt_value->value; + } else if (!strcmp(opt_value->opt, "iopen_nopriv")) { + if (iopen_nopriv != NULL) + *iopen_nopriv = 1; + } else if (!strcmp(opt_value->opt, "snap")) { + *cow = 1; + } else { + break; + } + } + return pos; +} + +struct super_block *smfs_get_sb_by_path(char *path, int len) +{ + struct super_block *sb; + struct nameidata nd; + int error = 0; + + ENTRY; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + if (path_init(path, LOOKUP_FOLLOW, &nd)) { +#else + if (path_lookup(path, LOOKUP_FOLLOW, &nd)) { +#endif + error = path_walk(path, &nd); + if (error) { + path_release(&nd); + RETURN(NULL); + } + } else { + RETURN(NULL); + } + + /* FIXME-WANGDI: add some check code here. */ + sb = nd.dentry->d_sb; + path_release(&nd); + RETURN(sb); +} + +static int smfs_init_fsfilt_ops(struct super_block *sb) +{ + ENTRY; + if (!S2SMI(sb)->sm_cache_fsfilt) { + S2SMI(sb)->sm_cache_fsfilt = + fsfilt_get_ops(S2SMI(sb)->smsi_cache_ftype); + if (!S2SMI(sb)->sm_cache_fsfilt) { + CERROR("Can not get %s fsfilt ops needed by kml\n", + S2SMI(sb)->smsi_cache_ftype); + RETURN(-EINVAL); + } + } + if (!S2SMI(sb)->sm_fsfilt) { + S2SMI(sb)->sm_fsfilt = + fsfilt_get_ops(S2SMI(sb)->smsi_ftype); + if (!S2SMI(sb)->sm_fsfilt) { + CERROR("Can not get %s fsfilt ops needed by kml\n", + S2SMI(sb)->smsi_ftype); + RETURN(-EINVAL); + } + } + RETURN(0); +} + +void smfs_cleanup_fsfilt_ops(struct super_block *sb) +{ + if (S2SMI(sb)->sm_cache_fsfilt) + fsfilt_put_ops(S2SMI(sb)->sm_cache_fsfilt); + if (S2SMI(sb)->sm_fsfilt) + fsfilt_put_ops(S2SMI(sb)->sm_fsfilt); +} + +static int sm_mount_cache(struct super_block *sb, char *devstr, + char *typestr, char *opts, int iopen_nopriv) +{ + struct smfs_super_info *smb = S2SMI(sb); + int err = 0, typelen; + struct vfsmount *mnt; + unsigned long page; + ENTRY; + + typelen = strlen(typestr); + + page = __get_free_page(GFP_KERNEL); + if (!page) + GOTO(err_out, err = -ENOMEM); + + memset((void *)page, 0, PAGE_SIZE); + + if (iopen_nopriv) + sprintf((char *)page, "iopen_nopriv"); + + if (opts && strlen(opts)) { + int n = strlen((char *)page); + sprintf((char *)page + n, ",%s", opts); + } + + printk("smfs: mounting %s at %s\n", typestr, devstr); + + mnt = do_kern_mount(typestr, 0, devstr, (void *)page); + free_page(page); + + if (IS_ERR(mnt)) { + CERROR("do_kern_mount failed: rc = %ld\n", PTR_ERR(mnt)); + GOTO(err_out, err = PTR_ERR(mnt)); + } + + smb->smsi_sb = mnt->mnt_sb; + smb->smsi_mnt = mnt; + + smfs_init_sm_ops(smb); + + OBD_ALLOC(smb->smsi_cache_ftype, strlen(typestr) + 1); + memcpy(smb->smsi_cache_ftype, typestr, strlen(typestr)); + + OBD_ALLOC(smb->smsi_ftype, strlen(SMFS_TYPE) + 1); + memcpy(smb->smsi_ftype, SMFS_TYPE, strlen(SMFS_TYPE)); + + duplicate_sb(sb, mnt->mnt_sb); + sm_set_sb_ops(mnt->mnt_sb, sb); + + err = smfs_init_fsfilt_ops(sb); +err_out: + return err; +} + +static int sm_umount_cache(struct super_block *sb) +{ + struct smfs_super_info *smb = S2SMI(sb); + + iput(S2CSB(sb)->s_root->d_inode); + dput(S2CSB(sb)->s_root); + mntput(smb->smsi_mnt); + smfs_cleanup_sm_ops(smb); + smfs_cleanup_fsfilt_ops(sb); + + if (smb->smsi_cache_ftype) + OBD_FREE(smb->smsi_cache_ftype, + strlen(smb->smsi_cache_ftype) + 1); + if (smb->smsi_ftype) + OBD_FREE(smb->smsi_ftype, strlen(smb->smsi_ftype) + 1); + + return 0; +} + +static int smfs_init_hook_ops(struct super_block *sb) +{ + struct smfs_super_info *smb = S2SMI(sb); + ENTRY; + + INIT_LIST_HEAD(&smb->smsi_hook_list); + + RETURN(0); +} +static void smfs_cleanup_hook_ops(struct super_block *sb) +{ + struct smfs_super_info *smb = S2SMI(sb); + struct list_head *hlist = &smb->smsi_hook_list; + ENTRY; + + while (!list_empty(hlist)) { + struct smfs_hook_ops *smfs_hops; + + smfs_hops = list_entry(hlist->next, struct smfs_hook_ops, + smh_list); + CERROR("Unregister %s hook ops\n", smfs_hops->smh_name); + + smfs_unregister_hook_ops(sb, smfs_hops->smh_name); + smfs_free_hook_ops(smfs_hops); + } + EXIT; + return; +} + +void smfs_put_super(struct super_block *sb) +{ + if (SMFS_CACHE_HOOK(S2SMI(sb))) + cache_space_hook_exit(sb); + if (SMFS_DO_REC(S2SMI(sb))) + smfs_rec_cleanup(sb); +#if CONFIG_SNAPFS + if (SMFS_DO_COW(S2SMI(sb))) + smfs_cow_cleanup(sb); +#endif + smfs_cleanup_hook_ops(sb); + + if (sb) + sm_umount_cache(sb); + return; +} +int smfs_fill_super(struct super_block *sb, void *data, int silent) +{ + ino_t root_ino; + char *cache_data; + + int iopen_nopriv = 0; + struct inode *root_inode = NULL; + int err = 0, do_rec = 0, cache_hook = 0, do_cow = 0; + char *devstr = NULL, *typestr = NULL, *opts = NULL; + + ENTRY; + + CDEBUG(D_SUPER, "mount opts: %s\n", data ? + (char *)data : "(none)"); + + init_option(data); + + /* read and validate passed options. */ + cache_data = smfs_options(data, &devstr, &typestr, + &do_rec, &cache_hook, &opts, + &iopen_nopriv, &do_cow); + + if (*cache_data) + CWARN("smfs_fill_super(): options parsing stoped at " + "option %s\n", cache_data); + + if (!typestr || !devstr) { + CERROR("mount options name and dev mandatory\n"); + GOTO(out_err, err = -EINVAL); + } + err = sm_mount_cache(sb, devstr, typestr, opts, iopen_nopriv); + if (err) { + CERROR("Can not mount %s as %s\n", devstr, typestr); + GOTO(out_err, 0); + } + + err = smfs_init_hook_ops(sb); + if (err) { + CERROR("Can not init super hook ops err %d\n", err); + GOTO(out_err, 0); + } + + if (do_rec) smfs_rec_init(sb); + if (cache_hook) cache_space_hook_init(sb); + + dget(S2CSB(sb)->s_root); + root_ino = S2CSB(sb)->s_root->d_inode->i_ino; + root_inode = iget(sb, root_ino); + + CDEBUG(D_SUPER, "readinode %p, root ino %ld, root inode at %p\n", + sb->s_op->read_inode, root_ino, root_inode); + + sb->s_root = d_alloc_root(root_inode); + + if (!sb->s_root) { + sm_umount_cache(sb); + GOTO(out_err, err=-EINVAL); + } +#if CONFIG_SNAPFS + if (do_cow) smfs_cow_init(sb); +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + CDEBUG(D_SUPER, "sb %lx, &sb->u.generic_sbp: %lx\n", + (ulong)sb, (ulong)&sb->u.generic_sbp); +#else + CDEBUG(D_SUPER, "sb %lx, &sb->s_fs_info: %lx\n", + (ulong)sb, (ulong)&sb->s_fs_info); +#endif + +out_err: + cleanup_option(); + return err; +} +struct smfs_hook_ops *smfs_alloc_hook_ops(char *name, smfs_hook_func pre_hook, + smfs_hook_func post_hook) +{ + struct smfs_hook_ops *smfs_hops = NULL; + + ENTRY; + OBD_ALLOC(smfs_hops, sizeof(struct smfs_hook_ops)); + + if (!smfs_hops) + RETURN(NULL); + + OBD_ALLOC(smfs_hops->smh_name, strlen(name) + 1); + + if (!smfs_hops->smh_name) { + OBD_FREE(smfs_hops, sizeof(struct smfs_hook_ops)); + RETURN(NULL); + } + + memcpy(smfs_hops->smh_name, name, strlen(name)); + + smfs_hops->smh_post_op = post_hook; + smfs_hops->smh_pre_op = pre_hook; + + RETURN(smfs_hops); +} + +void smfs_free_hook_ops(struct smfs_hook_ops *hops) +{ + if (hops) { + if (hops->smh_name){ + OBD_FREE(hops->smh_name, strlen(hops->smh_name) + 1); + } + OBD_FREE(hops, sizeof(struct smfs_hook_ops)); + } +} + +int smfs_register_hook_ops(struct super_block *sb, + struct smfs_hook_ops *smh_ops) +{ + struct smfs_super_info *smb = S2SMI(sb); + struct list_head *hlist = &smb->smsi_hook_list; + struct list_head *p; + ENTRY; + + list_for_each(p, hlist) { + struct smfs_hook_ops *found; + found = list_entry(p, struct smfs_hook_ops, smh_list); + if (!strcmp(found->smh_name, smh_ops->smh_name)) { + CWARN("hook ops %s list reregister\n", smh_ops->smh_name); + RETURN(0); + } + } + list_add(&smh_ops->smh_list, hlist); + RETURN(0); +} +struct smfs_hook_ops *smfs_unregister_hook_ops(struct super_block *sb, + char *name) +{ + struct smfs_super_info *smb = S2SMI(sb); + struct list_head *hlist = &smb->smsi_hook_list; + struct list_head *p; + ENTRY; + + list_for_each(p, hlist) { + struct smfs_hook_ops *found; + + found = list_entry(p, typeof(*found), smh_list); + if (!memcmp(found->smh_name, name, strlen(name))) { + list_del(p); + RETURN(found); + } + } + RETURN(NULL); +} + diff --git a/lustre/smfs/super.c b/lustre/smfs/super.c index 7f79438..dfbe801 100644 --- a/lustre/smfs/super.c +++ b/lustre/smfs/super.c @@ -45,298 +45,9 @@ #include #include "smfs_internal.h" -static char *smfs_options(char *data, char **devstr, char **namestr, - int *kml, int *cache, char **opts, int *iopen_nopriv, - int *cow) -{ - char *pos; - struct option *opt_value = NULL; - - while (!(get_opt(&opt_value, &pos))) { - if (!strcmp(opt_value->opt, "dev")) { - if (devstr != NULL) - *devstr = opt_value->value; - } else if (!strcmp(opt_value->opt, "type")) { - if (namestr != NULL) - *namestr = opt_value->value; - } else if (!strcmp(opt_value->opt, "kml")) { - if (kml) - *kml = 1; - } else if (!strcmp(opt_value->opt, "cache")) { - if (cache) - *cache = 1; - } else if (!strcmp(opt_value->opt, "options")) { - if (opts != NULL) - *opts = opt_value->value; - } else if (!strcmp(opt_value->opt, "iopen_nopriv")) { - if (iopen_nopriv != NULL) - *iopen_nopriv = 1; - } else if (!strcmp(opt_value->opt, "snap")) { - *cow = 1; - } else { - break; - } - } - return pos; -} - -struct super_block *smfs_get_sb_by_path(char *path, int len) -{ - struct super_block *sb; - struct nameidata nd; - int error = 0; - - ENTRY; - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - if (path_init(path, LOOKUP_FOLLOW, &nd)) { -#else - if (path_lookup(path, LOOKUP_FOLLOW, &nd)) { -#endif - error = path_walk(path, &nd); - if (error) { - path_release(&nd); - RETURN(NULL); - } - } else { - RETURN(NULL); - } - - /* FIXME-WANGDI: add some check code here. */ - sb = nd.dentry->d_sb; - path_release(&nd); - RETURN(sb); -} - -static int smfs_init_fsfilt_ops(struct super_block *sb) -{ - ENTRY; - if (!S2SMI(sb)->sm_cache_fsfilt) { - S2SMI(sb)->sm_cache_fsfilt = - fsfilt_get_ops(S2SMI(sb)->smsi_cache_ftype); - if (!S2SMI(sb)->sm_cache_fsfilt) { - CERROR("Can not get %s fsfilt ops needed by kml\n", - S2SMI(sb)->smsi_cache_ftype); - RETURN(-EINVAL); - } - } - if (!S2SMI(sb)->sm_fsfilt) { - S2SMI(sb)->sm_fsfilt = - fsfilt_get_ops(S2SMI(sb)->smsi_ftype); - if (!S2SMI(sb)->sm_fsfilt) { - CERROR("Can not get %s fsfilt ops needed by kml\n", - S2SMI(sb)->smsi_ftype); - RETURN(-EINVAL); - } - } - RETURN(0); -} - -void smfs_cleanup_fsfilt_ops(struct super_block *sb) -{ - if (S2SMI(sb)->sm_cache_fsfilt) - fsfilt_put_ops(S2SMI(sb)->sm_cache_fsfilt); - if (S2SMI(sb)->sm_fsfilt) - fsfilt_put_ops(S2SMI(sb)->sm_fsfilt); -} - -static int sm_mount_cache(struct super_block *sb, char *devstr, - char *typestr, char *opts, int iopen_nopriv) -{ - struct smfs_super_info *smb = S2SMI(sb); - int err = 0, typelen; - struct vfsmount *mnt; - unsigned long page; - ENTRY; - - typelen = strlen(typestr); - - page = __get_free_page(GFP_KERNEL); - if (!page) - GOTO(err_out, err = -ENOMEM); - - memset((void *)page, 0, PAGE_SIZE); - - if (iopen_nopriv) - sprintf((char *)page, "iopen_nopriv"); - - if (opts && strlen(opts)) { - int n = strlen((char *)page); - sprintf((char *)page + n, ",%s", opts); - } - - printk("smfs: mounting %s at %s\n", typestr, devstr); - - mnt = do_kern_mount(typestr, 0, devstr, (void *)page); - free_page(page); - - if (IS_ERR(mnt)) { - CERROR("do_kern_mount failed: rc = %ld\n", PTR_ERR(mnt)); - GOTO(err_out, err = PTR_ERR(mnt)); - } - - smb->smsi_sb = mnt->mnt_sb; - smb->smsi_mnt = mnt; - - smfs_init_sm_ops(smb); - - OBD_ALLOC(smb->smsi_cache_ftype, strlen(typestr) + 1); - memcpy(smb->smsi_cache_ftype, typestr, strlen(typestr)); - - OBD_ALLOC(smb->smsi_ftype, strlen(SMFS_TYPE) + 1); - memcpy(smb->smsi_ftype, SMFS_TYPE, strlen(SMFS_TYPE)); - - duplicate_sb(sb, mnt->mnt_sb); - sm_set_sb_ops(mnt->mnt_sb, sb); - - err = smfs_init_fsfilt_ops(sb); -err_out: - return err; -} - -static int sm_umount_cache(struct super_block *sb) -{ - struct smfs_super_info *smb = S2SMI(sb); - - iput(S2CSB(sb)->s_root->d_inode); - dput(S2CSB(sb)->s_root); - mntput(smb->smsi_mnt); - smfs_cleanup_sm_ops(smb); - smfs_cleanup_fsfilt_ops(sb); - - if (smb->smsi_cache_ftype) - OBD_FREE(smb->smsi_cache_ftype, - strlen(smb->smsi_cache_ftype) + 1); - if (smb->smsi_ftype) - OBD_FREE(smb->smsi_ftype, strlen(smb->smsi_ftype) + 1); - - return 0; -} - -static int smfs_init_hook_ops(struct super_block *sb) -{ - struct smfs_super_info *smb = S2SMI(sb); - ENTRY; - - INIT_LIST_HEAD(&smb->smsi_hook_list); - - RETURN(0); -} -static void smfs_cleanup_hook_ops(struct super_block *sb) -{ - struct smfs_super_info *smb = S2SMI(sb); - struct list_head *hlist = &smb->smsi_hook_list; - ENTRY; - - while (!list_empty(hlist)) { - struct smfs_hook_ops *smfs_hops; - - smfs_hops = list_entry(hlist->next, struct smfs_hook_ops, - smh_list); - CERROR("Unregister %s hook ops\n", smfs_hops->smh_name); - - smfs_unregister_hook_ops(sb, smfs_hops->smh_name); - smfs_free_hook_ops(smfs_hops); - } - EXIT; - return; -} - -void smfs_put_super(struct super_block *sb) -{ - if (SMFS_CACHE_HOOK(S2SMI(sb))) - cache_space_hook_exit(sb); - if (SMFS_DO_REC(S2SMI(sb))) - smfs_rec_cleanup(sb); -#if CONFIG_SNAPFS - if (SMFS_DO_COW(S2SMI(sb))) - smfs_cow_cleanup(sb); -#endif - smfs_cleanup_hook_ops(sb); - - if (sb) - sm_umount_cache(sb); - return; -} -static int smfs_fill_super(struct super_block *sb, - void *data, int silent) -{ - ino_t root_ino; - char *cache_data; - - int iopen_nopriv = 0; - struct inode *root_inode = NULL; - int err = 0, do_rec = 0, cache_hook = 0, do_cow = 0; - char *devstr = NULL, *typestr = NULL, *opts = NULL; - - ENTRY; - - CDEBUG(D_SUPER, "mount opts: %s\n", data ? - (char *)data : "(none)"); - - init_option(data); - - /* read and validate passed options. */ - cache_data = smfs_options(data, &devstr, &typestr, - &do_rec, &cache_hook, &opts, - &iopen_nopriv, &do_cow); - - if (*cache_data) - CWARN("smfs_fill_super(): options parsing stoped at " - "option %s\n", cache_data); - - if (!typestr || !devstr) { - CERROR("mount options name and dev mandatory\n"); - GOTO(out_err, err = -EINVAL); - } - err = sm_mount_cache(sb, devstr, typestr, opts, iopen_nopriv); - if (err) { - CERROR("Can not mount %s as %s\n", devstr, typestr); - GOTO(out_err, 0); - } - - err = smfs_init_hook_ops(sb); - if (err) { - CERROR("Can not init super hook ops err %d\n", err); - GOTO(out_err, 0); - } - - if (do_rec) smfs_rec_init(sb); - if (cache_hook) cache_space_hook_init(sb); - - dget(S2CSB(sb)->s_root); - root_ino = S2CSB(sb)->s_root->d_inode->i_ino; - root_inode = iget(sb, root_ino); - - CDEBUG(D_SUPER, "readinode %p, root ino %ld, root inode at %p\n", - sb->s_op->read_inode, root_ino, root_inode); - - sb->s_root = d_alloc_root(root_inode); - - if (!sb->s_root) { - sm_umount_cache(sb); - GOTO(out_err, err=-EINVAL); - } -#if CONFIG_SNAPFS - if (do_cow) smfs_cow_init(sb); -#endif - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - CDEBUG(D_SUPER, "sb %lx, &sb->u.generic_sbp: %lx\n", - (ulong)sb, (ulong)&sb->u.generic_sbp); -#else - CDEBUG(D_SUPER, "sb %lx, &sb->s_fs_info: %lx\n", - (ulong)sb, (ulong)&sb->s_fs_info); -#endif - -out_err: - cleanup_option(); - return err; -} - #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -static struct super_block *smfs_read_super(struct super_block *sb, - void *data, int silent) +static struct super_block *smfs_read_super(struct super_block *sb, void *data, + int silent) { int err; @@ -346,26 +57,28 @@ static struct super_block *smfs_read_super(struct super_block *sb, return sb; } + +static struct file_system_type smfs_type = { + .owner = THIS_MODULE, + .name = "smfs", + .read_super = smfs_read_super, +}; #else -struct super_block *smfs_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data) +struct super_block *smfs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data) { return get_sb_nodev(fs_type, flags, data, smfs_fill_super); } -#endif static struct file_system_type smfs_type = { .owner = THIS_MODULE, .name = "smfs", -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - .read_super = smfs_read_super, -#else .get_sb = smfs_get_sb, .kill_sb = kill_anon_super, -#endif }; +#endif -int init_smfs(void) +static int init_smfs(void) { int err; @@ -375,7 +88,7 @@ int init_smfs(void) return err; } -int cleanup_smfs(void) +static int cleanup_smfs(void) { int err = 0; @@ -384,3 +97,38 @@ int cleanup_smfs(void) CERROR("unregister_filesystem() failed, rc = %d\n", err); return 0; } + +static int __init smfs_init(void) +{ + int err; + + if ( (err = init_smfs_psdev()) ) { + printk("Error initializing smfs_psdev, %d\n", err); + return -EINVAL; + } + + if ( (err = init_smfs()) ) { + printk("Error initializing smfs, %d\n", err); + return -EINVAL; + } + + if ( (err = init_smfs_proc_sys()) ) { + printk("Error initializing smfs proc sys, %d\n", err); + return -EINVAL; + } + + return 0; +} + +static void __exit smfs_cleanup(void) +{ + cleanup_smfs(); + smfs_cleanup_psdev(); +} + +MODULE_AUTHOR("Cluster File Systems, Inc. "); +MODULE_DESCRIPTION("Smfs file system filters v0.01"); +MODULE_LICENSE("GPL"); + +module_init(smfs_init); +module_exit(smfs_cleanup); -- 1.8.3.1