X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fsmfs%2Finode.c;h=2f2f4d22aa85af3b13be97073fb19917a00d07b7;hb=ac013f696b87e01072e6b1925e6f7fdd1fa22e5f;hp=73b9a88f4a8fb92b6da945d4d8c46f85fb530d03;hpb=7088f04601ade93b6bba2c44cc9c98af485c8e86;p=fs%2Flustre-release.git diff --git a/lustre/smfs/inode.c b/lustre/smfs/inode.c index 73b9a88..2f2f4d2 100644 --- a/lustre/smfs/inode.c +++ b/lustre/smfs/inode.c @@ -37,146 +37,167 @@ #include #include "smfs_internal.h" -static void smfs_read_inode(struct inode *inode) +static void smfs_init_inode_info (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); - - I2CI(inode) = cache_inode; + struct smfs_iget_args *sargs = (struct smfs_iget_args*)opaque; + struct inode *cache_inode = NULL; + if (sargs) + cache_inode = iget(S2CSB(inode->i_sb), sargs->s_ino); + else + cache_inode = iget(S2CSB(inode->i_sb), inode->i_ino); + + OBD_ALLOC(I2SMI(inode), sizeof(struct smfs_inode_info)); + LASSERT(I2SMI(inode)); + I2CI(inode) = cache_inode; + CDEBUG(D_INODE, "cache_inode i_count ino %lu i_count %d\n", + cache_inode->i_ino, atomic_read(&cache_inode->i_count)); post_smfs_inode(inode, cache_inode); sm_set_inode_ops(cache_inode, inode); + if (sargs) { + struct inode *dir = sargs->s_inode; + if (dir) + I2SMI(inode)->smi_flags = I2SMI(dir)->smi_flags; + } +} - CDEBUG(D_INODE, "read_inode ino %lu icount %d \n", - inode->i_ino, atomic_read(&inode->i_count)); - return; +static void smfs_clear_inode_info(struct inode *inode) +{ + if (I2SMI(inode)) { + struct inode *cache_inode = I2CI(inode); + LASSERTF(((atomic_read(&cache_inode->i_count) == 1) || + cache_inode == cache_inode->i_sb->s_root->d_inode), + "inode %p cache inode %p %lu i_count %d != 0 \n", + inode, cache_inode, cache_inode->i_ino, + atomic_read(&cache_inode->i_count)); + if (cache_inode != cache_inode->i_sb->s_root->d_inode) + iput(cache_inode); + OBD_FREE(I2SMI(inode), sizeof(struct smfs_inode_info)); + I2SMI(inode) = NULL; + } } 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_inode_info(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 smfs_iget_args *sargs = (struct smfs_iget_args*)opaque; + + LASSERT(sargs); + if (!sargs) + return 1; + + if (inode->i_ino != sargs->s_ino) + return 0; +#ifdef CONFIG_SNAPFS + if (SMFS_DO_COW(S2SMI(inode->i_sb)) && + !smfs_snap_test_inode(inode, opaque)) + return 0; +#endif + if (I2SMI(inode)) { + struct inode *cache_inode = I2CI(inode); + + LASSERTF(cache_inode->i_ino == inode->i_ino, + "inode ino %lu != cache ino %lu", + cache_inode->i_ino, inode->i_ino); + } + if (!I2SMI(inode)) + smfs_init_inode_info(inode, opaque); + 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_iget_args *sargs) +{ + struct inode *inode; + + LASSERT(hash != 0); + + inode = iget5_locked(sb, hash, smfs_test_inode, smfs_set_inode, sargs); + if (inode) { + if (inode->i_state & I_NEW) + unlock_new_inode(inode); + CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p) index %d ino %lu \n", + inode->i_ino, inode->i_generation, inode, sargs->s_index, + sargs->s_ino); + inode->i_ino = hash; + } + return inode; +} +#else +struct inode *smfs_iget(struct super_block *sb, ino_t hash, + struct smfs_iget_args *sargs) +{ + struct inode *inode; + LASSERT(hash != 0); - cache_inode = I2CI(inode); + inode = iget4(sb, hash, smfs_test_inode, sargs); - /* 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) { + struct inode *cache_inode = I2CI(inode); + + LASSERTF((inode->i_ino == cache_inode->i_ino), + "inode %p ino %lu != cache inode %p ino %lu", + inode, inode->i_ino, cache_inode, cache_inode->i_ino); + CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino, + inode->i_generation, inode); } - return; + return inode; } - +#endif +struct inode *smfs_get_inode (struct super_block *sb, ino_t hash, + struct inode *dir, int index) +{ + struct inode *inode; + struct smfs_iget_args sargs; + ENTRY; + + sargs.s_index = index; + sargs.s_inode = dir; + sargs.s_ino = hash; + inode = smfs_iget(sb, hash, &sargs); + + RETURN(inode); +} + static void smfs_delete_inode(struct inode *inode) { struct inode *cache_inode; ENTRY; - cache_inode = I2CI(inode); - - if (!cache_inode || !S2CSB(inode->i_sb)) - return; - - /* FIXME-WANGDI: 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 (atomic_read(&cache_inode->i_count) < 1) - BUG(); - - while (atomic_read(&cache_inode->i_count) != 1) - atomic_dec(&cache_inode->i_count); - - pre_smfs_inode(inode, cache_inode); - - if (atomic_read(&cache_inode->i_count) < 1) - LBUG(); - - while (atomic_read(&cache_inode->i_count) != 1) { - atomic_dec(&cache_inode->i_count); + if (I2SMI(inode)) { + cache_inode = I2CI(inode); + if (!cache_inode || !S2CSB(inode->i_sb)) + return; + post_smfs_inode(inode, cache_inode); + smfs_clear_inode_info(inode); } - - pre_smfs_inode(inode, cache_inode); - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - list_del(&cache_inode->i_hash); - INIT_LIST_HEAD(&cache_inode->i_hash); -#else - hlist_del_init(&cache_inode->i_hash); -#endif - - list_del(&cache_inode->i_list); - INIT_LIST_HEAD(&cache_inode->i_list); - - if (cache_inode->i_data.nrpages) - truncate_inode_pages(&cache_inode->i_data, 0); - - if (S2CSB(inode->i_sb)->s_op->delete_inode) - S2CSB(inode->i_sb)->s_op->delete_inode(cache_inode); - - post_smfs_inode(inode, cache_inode); - - I2CI(inode) = NULL; + inode->i_state = I_CLEAR; return; } @@ -192,10 +213,10 @@ static void smfs_write_inode(struct inode *inode, int wait) return; } pre_smfs_inode(inode, cache_inode); - if (S2CSB(inode->i_sb)->s_op->write_inode) S2CSB(inode->i_sb)->s_op->write_inode(cache_inode, wait); - + + post_smfs_inode(inode, cache_inode); EXIT; } @@ -228,9 +249,18 @@ static void smfs_put_inode(struct inode *inode) CWARN("cache inode null\n"); return; } + + if (atomic_read(&cache_inode->i_count) > 1) { + iput(cache_inode); + } + if (S2CSB(inode->i_sb)->s_op->put_inode) S2CSB(inode->i_sb)->s_op->put_inode(cache_inode); - + + if (atomic_read(&inode->i_count) == 0 && + cache_inode->i_sb->s_root->d_inode != cache_inode) + smfs_clear_inode_info(inode); + EXIT; } @@ -245,6 +275,23 @@ 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); + + smfs_clear_inode_info(inode); + + EXIT; + return; } static void smfs_write_super_lockfs(struct super_block *sb) @@ -300,7 +347,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 +364,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 +380,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);