From d0d9cf25e48b14377f2de2d99d18c17cf113a3c2 Mon Sep 17 00:00:00 2001 From: tappro Date: Sat, 25 Jun 2005 22:05:52 +0000 Subject: [PATCH] b=6285 r=alex smfs should care about nlinks handling instead of just copying it from/to bottom fs. --- lustre/include/linux/lustre_smfs.h | 78 ++++++++++++++++++++------------- lustre/mds/mds_reint.c | 9 ++-- lustre/smfs/dir.c | 89 +++++++++++++++++++++++--------------- lustre/smfs/fsfilt.c | 18 +++++--- lustre/smfs/inode.c | 1 + 5 files changed, 121 insertions(+), 74 deletions(-) diff --git a/lustre/include/linux/lustre_smfs.h b/lustre/include/linux/lustre_smfs.h index ba6667f..166d417 100644 --- a/lustre/include/linux/lustre_smfs.h +++ b/lustre/include/linux/lustre_smfs.h @@ -34,19 +34,19 @@ struct snap_inode_info { }; struct smfs_inode_info { /* this first part of struct should be the same as in mds_info_info */ - struct lustre_id smi_id; + //struct lustre_id smi_id; /* smfs part. */ struct inode *smi_inode; __u32 smi_flags; struct snap_inode_info sm_sninfo; }; - +#if 0 struct journal_operations { void *(*tr_start)(struct inode *, int op); void (*tr_commit)(void *handle); }; - +#endif struct sm_operations { /* operations on the file store */ struct super_operations sm_sb_ops; @@ -57,20 +57,22 @@ struct sm_operations { struct file_operations sm_dir_fops; struct file_operations sm_file_fops; struct file_operations sm_sym_fops; - struct dentry_operations sm_dentry_ops; - struct journal_operations sm_journal_ops; + //struct dentry_operations sm_dentry_ops; + //struct journal_operations sm_journal_ops; }; /*smfs rec*/ -typedef int (*smfs_pack_rec_func)(char *buffer, struct dentry *dentry, +/*typedef int (*smfs_pack_rec_func)(char *buffer, struct dentry *dentry, struct inode *dir, void *data1, void *data2, int op); + typedef enum { PACK_NORMAL = 0, PACK_OST = 1, PACK_MDS = 2, PACK_MAX = 3, } pack_func_t; +*/ struct mds_kml_pack_info { int mpi_bufcount; @@ -92,12 +94,13 @@ struct smfs_super_info { char *smsi_ftype; /* file system type */ struct obd_export *smsi_exp; /* file system obd exp */ struct snap_super_info *smsi_snap_info; /* snap table cow */ - smfs_pack_rec_func smsi_pack_rec[PACK_MAX]; /* sm_pack_rec type ops */ + //smfs_pack_rec_func smsi_pack_rec[PACK_MAX]; /* sm_pack_rec type ops */ + struct rw_semaphore plg_sem; /*rw semaphore to protect plg operations */ __u32 plg_flags; /* flags */ __u32 smsi_flags; __u32 smsi_ops_check; struct list_head smsi_plg_list; - kmem_cache_t * smsi_inode_cachep; /*inode_cachep*/ + //kmem_cache_t * smsi_inode_cachep; /*inode_cachep*/ }; @@ -122,7 +125,7 @@ struct fs_extent{ }; #define I2SMI(inode) ((struct smfs_inode_info *) ((inode->u.generic_ip))) -#define I2FSI(inode) (((inode->u.generic_ip))) +//#define I2FSI(inode) (((inode->u.generic_ip))) #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) #define S2FSI(sb) (((sb->u.generic_sbp))) @@ -163,14 +166,17 @@ struct fs_extent{ /* SMFS external flags and methods */ #define SM_ALL_PLG 0x80L -#define SM_DO_REC 0x1 -#define SM_INIT_REC 0x2 -#define SM_CACHE_HOOK 0x4 -#define SM_OVER_WRITE 0x8 -#define SM_DIRTY_WRITE 0x10 +#define SM_KML_PLG 0x1L +#define SM_DO_REC SM_KML_PLG + +//#define SM_INIT_REC 0x2 +//#define SM_CACHE_HOOK 0x4 +//#define SM_OVER_WRITE 0x8 +//#define SM_DIRTY_WRITE 0x10 #define SM_DO_COW 0x20 #define SM_DO_COWED 0x40 +/* #define SMFS_DO_REC(smfs_info) (smfs_info->smsi_flags & SM_DO_REC) #define SMFS_SET_REC(smfs_info) (smfs_info->smsi_flags |= SM_DO_REC) #define SMFS_CLEAN_REC(smfs_info) (smfs_info->smsi_flags &= ~SM_DO_REC) @@ -198,7 +204,7 @@ struct fs_extent{ #define SMFS_INODE_DIRTY_WRITE(inode) (I2SMI(inode)->smi_flags & SM_DIRTY_WRITE) #define SMFS_SET_INODE_DIRTY_WRITE(inode) (I2SMI(inode)->smi_flags |= SM_DIRTY_WRITE) #define SMFS_CLEAN_INODE_DIRTY_WRITE(inode) (I2SMI(inode)->smi_flags &= ~SM_DIRTY_WRITE) - +*/ #define SMFS_DO_COW(smfs_info) (smfs_info->smsi_flags & SM_DO_COW) #define SMFS_SET_COW(smfs_info) (smfs_info->smsi_flags |= SM_DO_COW) #define SMFS_CLEAN_COW(smfs_info) (smfs_info->smsi_flags &= ~SM_DO_COW) @@ -212,9 +218,9 @@ struct fs_extent{ #define SMFS_CLEAN_INODE_COWED(inode) (I2SMI(inode)->smi_flags &= ~SM_DO_COWED) -#define LVFS_SMFS_BACK_ATTR "lvfs_back_attr" - +//#define LVFS_SMFS_BACK_ATTR "lvfs_back_attr" +#if 0 #define REC_COUNT_BIT 0 #define REC_COUNT_MASK 0x01 /*0001*/ #define REC_OP_BIT 1 @@ -226,8 +232,8 @@ struct fs_extent{ #define REC_GET_OID_BIT 5 #define REC_GET_OID_MASK 0x20 /*100000*/ -#define REC_PACK_TYPE_BIT 6 -#define REC_PACK_TYPE_MASK 0x1C0 /*111000000*/ +//#define REC_PACK_TYPE_BIT 6 +//#define REC_PACK_TYPE_MASK 0x1C0 /*111000000*/ #define SET_REC_COUNT_FLAGS(flag, count_flag) \ (flag |= count_flag << REC_COUNT_BIT) @@ -259,11 +265,11 @@ struct fs_extent{ #define GET_REC_PACK_TYPE_INDEX(flag) \ ((flag & REC_PACK_TYPE_MASK) >> REC_PACK_TYPE_BIT) -#define SMFS_REC_ALL 0x1 -#define SMFS_REC_BY_COUNT 0x0 +//#define SMFS_REC_ALL 0x1 +//#define SMFS_REC_BY_COUNT 0x0 -#define SMFS_REINT_REC 0x1 -#define SMFS_UNDO_REC 0x2 +//#define SMFS_REINT_REC 0x1 +//#define SMFS_UNDO_REC 0x2 #define SMFS_WRITE_KML 0x1 #define SMFS_DEC_LINK 0x1 @@ -277,27 +283,28 @@ struct fs_extent{ (GET_REC_COUNT_FLAGS(flag) == SMFS_REC_ALL) #define SMFS_DO_REC_BY_COUNT(flag) \ (GET_REC_COUNT_FLAGS(flag) == SMFS_REC_BY_COUNT) + #define SMFS_DO_WRITE_KML(flag) \ (GET_REC_WRITE_KML_FLAGS(flag) == SMFS_WRITE_KML) + #define SMFS_DO_DEC_LINK(flag) \ (GET_REC_DEC_LINK_FLAGS(flag) == SMFS_DEC_LINK) #define SMFS_DO_GET_OID(flag) \ (GET_REC_GET_OID_FLAGS(flag) == SMFS_GET_OID) - +#endif /*DIRTY flags of write ops*/ #define REINT_EXTENTS_FLAGS "replay_flags" #define SMFS_DIRTY_WRITE 0x01 #define SMFS_OVER_WRITE 0x02 - static inline void duplicate_inode(struct inode *dst_inode, struct inode *src_inode) { dst_inode->i_mode = src_inode->i_mode; dst_inode->i_uid = src_inode->i_uid; dst_inode->i_gid = src_inode->i_gid; - dst_inode->i_nlink = src_inode->i_nlink; + //dst_inode->i_nlink = src_inode->i_nlink; dst_inode->i_size = src_inode->i_size; dst_inode->i_atime = src_inode->i_atime; dst_inode->i_ctime = src_inode->i_ctime; @@ -317,7 +324,6 @@ static inline void post_smfs_inode(struct inode *inode, { if (inode && cache_inode) { duplicate_inode(inode, cache_inode); - /* * here we must release the cache_inode, otherwise we will have * no chance to do it later. @@ -327,15 +333,25 @@ static inline void post_smfs_inode(struct inode *inode, } } +static inline void i_nlink_inc(struct inode * inode) +{ + inode->i_nlink++; + if (I2SMI(inode)) + I2CI(inode)->i_nlink++; +} + +static inline void i_nlink_dec(struct inode * inode) +{ + inode->i_nlink--; + if (I2SMI(inode)) + I2CI(inode)->i_nlink--; +} + static inline void pre_smfs_inode(struct inode *inode, struct inode *cache_inode) { if (inode && cache_inode) { cache_inode->i_flags = inode->i_flags; - //cache_inode->i_state = inode->i_state; - if (S_ISDIR(inode->i_mode)) { - cache_inode->i_nlink = inode->i_nlink; - } cache_inode->i_generation = inode->i_generation; } } diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c index 4b76927..e571b9b 100644 --- a/lustre/mds/mds_reint.c +++ b/lustre/mds/mds_reint.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "mds_internal.h" struct mds_logcancel_data { @@ -1761,8 +1762,8 @@ static int mds_orphan_add_link(struct mds_update_record *rec, S_ISDIR(mode) ? "dir" : S_ISREG(mode) ? "file" : "other", inode->i_nlink); if (S_ISDIR(mode)) { - inode->i_nlink++; - pending_dir->i_nlink++; + i_nlink_inc(inode); + i_nlink_inc(pending_dir); mark_inode_dirty(inode); mark_inode_dirty(pending_dir); } @@ -1862,7 +1863,7 @@ int mds_create_local_dentry(struct mds_update_record *rec, (unsigned long)child->d_inode->i_generation, rc); else { if (S_ISDIR(child->d_inode->i_mode)) { - id_dir->i_nlink++; + i_nlink_inc(id_dir); mark_inode_dirty(id_dir); } mark_inode_dirty(child->d_inode); @@ -2372,7 +2373,7 @@ static int mds_reint_link_acquire(struct mds_update_record *rec, rc = PTR_ERR(handle); GOTO(cleanup, rc); } - de_src->d_inode->i_nlink++; + i_nlink_inc(de_src->d_inode); mark_inode_dirty(de_src->d_inode); EXIT; diff --git a/lustre/smfs/dir.c b/lustre/smfs/dir.c index a73f7b2..75b0431 100644 --- a/lustre/smfs/dir.c +++ b/lustre/smfs/dir.c @@ -375,6 +375,7 @@ static int smfs_link(struct dentry *old_dentry, rc = cache_dir->i_op->link(cache_old_dentry, cache_dir, cache_dentry); if (!rc) { atomic_inc(&old_inode->i_count); + old_inode->i_nlink++; dput(iopen_connect_dentry(dentry, old_inode, 0)); } @@ -437,9 +438,11 @@ static int smfs_unlink(struct inode * dir, struct dentry *dentry) rc = cache_dir->i_op->unlink(cache_dir, cache_dentry); SMFS_POST_HOOK(dir, HOOK_UNLINK, &msg, rc); - - post_smfs_inode(dentry->d_inode, cache_dentry->d_inode); - post_smfs_inode(dir, cache_dir); + if (!rc) { + post_smfs_inode(dentry->d_inode, cache_inode); + dentry->d_inode->i_nlink--; + post_smfs_inode(dir, cache_dir); + } smfs_trans_commit(dir, handle, 0); exit: @@ -548,7 +551,7 @@ static int smfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) inode = smfs_get_inode(dir->i_sb, cache_dentry->d_inode, I2SMI(dir), 0); if (inode) { - //smsf_update_dentry(dentry, cache_dentry); + dir->i_nlink++; d_instantiate(dentry, inode); } else @@ -572,6 +575,7 @@ static int smfs_rmdir(struct inode *dir, struct dentry *dentry) struct inode *parent = I2CI(dentry->d_parent->d_inode); struct dentry *cache_dentry = NULL; struct dentry *cache_parent = NULL; + struct inode * inode = dentry->d_inode; void *handle = NULL; int rc = 0; struct hook_unlink_msg msg = { @@ -592,33 +596,36 @@ static int smfs_rmdir(struct inode *dir, struct dentry *dentry) goto exit; } - dentry_unhash(cache_dentry); - handle = smfs_trans_start(dir, FSFILT_OP_RMDIR, NULL); if (IS_ERR(handle) ) { rc = -ENOSPC; goto exit; } - + + dentry_unhash(cache_dentry); + pre_smfs_inode(dir, cache_dir); - pre_smfs_inode(dentry->d_inode, cache_dentry->d_inode); + pre_smfs_inode(inode, cache_inode); SMFS_PRE_HOOK(dir, HOOK_RMDIR, &msg); rc = cache_dir->i_op->rmdir(cache_dir, cache_dentry); SMFS_POST_HOOK(dir, HOOK_RMDIR, &msg, rc); - - post_smfs_inode(dir, cache_dir); - post_smfs_inode(dentry->d_inode, cache_dentry->d_inode); - //like vfs_rmdir is doing with inode - if (!rc) - cache_dentry->d_inode->i_flags |= S_DEAD; - + if (!rc) { + if (inode->i_nlink != 2) + CWARN("Directory #%lu under rmdir has %i nlinks\n", + inode->i_ino, inode->i_nlink); + inode->i_nlink = 0; + dir->i_nlink--; + post_smfs_inode(dir, cache_dir); + post_smfs_inode(inode, cache_inode); + //like vfs_rmdir is doing with inode + cache_inode->i_flags |= S_DEAD; + } smfs_trans_commit(dir, handle, 0); - + dput(cache_dentry); exit: - dput(cache_dentry); post_smfs_dentry(cache_dentry); post_smfs_dentry(cache_parent); RETURN(rc); @@ -695,6 +702,7 @@ static int smfs_rename(struct inode *old_dir, struct dentry *old_dentry, { struct inode *cache_old_dir = I2CI(old_dir); struct inode *cache_new_dir = I2CI(new_dir); + struct inode *new_inode = new_dentry->d_inode; struct inode *cache_old_inode = I2CI(old_dentry->d_inode); struct inode *old_parent = I2CI(old_dentry->d_parent->d_inode); struct inode *new_parent = I2CI(new_dentry->d_parent->d_inode); @@ -716,8 +724,8 @@ static int smfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (!cache_old_dir || !cache_new_dir || !cache_old_inode) RETURN(-ENOENT); - if (new_dentry->d_inode) { - cache_new_inode = I2CI(new_dentry->d_inode); + if (new_inode) { + cache_new_inode = I2CI(new_inode); if (!cache_new_inode) RETURN(-ENOENT); } @@ -746,8 +754,9 @@ static int smfs_rename(struct inode *old_dir, struct dentry *old_dentry, pre_smfs_inode(old_dir, cache_old_dir); pre_smfs_inode(new_dir, cache_new_dir); - if (new_dentry->d_inode) - pre_smfs_inode(new_dentry->d_inode, cache_new_dentry->d_inode); + pre_smfs_inode(old_dentry->d_inode, cache_old_inode); + if (new_inode) + pre_smfs_inode(new_inode, cache_new_inode); SMFS_PRE_HOOK(old_dir, HOOK_RENAME, &msg); @@ -755,12 +764,24 @@ static int smfs_rename(struct inode *old_dir, struct dentry *old_dentry, cache_new_dir, cache_new_dentry); SMFS_POST_HOOK(old_dir, HOOK_RENAME, &msg, rc); - - post_smfs_inode(old_dir, cache_old_dir); - post_smfs_inode(new_dir, cache_new_dir); - if (new_dentry->d_inode) - post_smfs_inode(new_dentry->d_inode, cache_new_dentry->d_inode); - + if (!rc) { + post_smfs_inode(old_dir, cache_old_dir); + post_smfs_inode(new_dir, cache_new_dir); + post_smfs_inode(old_dentry->d_inode, cache_old_inode); + if (new_inode) { + post_smfs_inode(new_inode, cache_new_inode); + new_inode->i_nlink--; + } + //directory is renamed + if (S_ISDIR(old_dentry->d_inode->i_mode)) { + old_dir->i_nlink--; + if (new_inode) { + new_inode->i_nlink--; + } else { + new_dir->i_nlink++; + } + } + } smfs_trans_commit(old_dir, handle, 0); exit: @@ -777,13 +798,13 @@ struct inode_operations smfs_dir_iops = { #if HAVE_LOOKUP_RAW .lookup_raw = smfs_lookup_raw, #endif - .link = smfs_link, /* BKL held */ - .unlink = smfs_unlink, /* BKL held */ - .symlink = smfs_symlink, /* BKL held */ - .mkdir = smfs_mkdir, /* BKL held */ - .rmdir = smfs_rmdir, /* BKL held */ - .mknod = smfs_mknod, /* BKL held */ - .rename = smfs_rename, /* BKL held */ + .link = smfs_link, + .unlink = smfs_unlink, + .symlink = smfs_symlink, + .mkdir = smfs_mkdir, + .rmdir = smfs_rmdir, + .mknod = smfs_mknod, + .rename = smfs_rename, .setxattr = smfs_setxattr, .getxattr = smfs_getxattr, .listxattr = smfs_listxattr, diff --git a/lustre/smfs/fsfilt.c b/lustre/smfs/fsfilt.c index be036c8..ceb6a63 100644 --- a/lustre/smfs/fsfilt.c +++ b/lustre/smfs/fsfilt.c @@ -919,16 +919,19 @@ static int fsfilt_smfs_precreate_rec(struct dentry *dentry, int *count, return rc; } +// should be rewrote when needed static int fsfilt_smfs_get_ino_write_extents(struct super_block *sb, ino_t ino, char **pbuf, int *size) { + int rc = 0; +#if 0 struct fs_extent *fs_extents; struct ldlm_extent *extents = NULL; struct inode *inode; struct inode *cache_inode; struct fsfilt_operations *cache_fsfilt = NULL; struct lvfs_run_ctxt saved; - int rc = 0, fs_ex_size, ex_num, flags; + int fs_ex_size, ex_num, flags; char *buf = NULL, *ex_buf = NULL; ENTRY; @@ -995,6 +998,7 @@ out: if (rc && extents) OBD_FREE(ex_buf, (*size) * (sizeof(struct ldlm_extent))); pop_ctxt(&saved, S2SMI(sb)->smsi_ctxt, NULL); +#endif return rc; } @@ -1124,11 +1128,15 @@ static int fsfilt_smfs_del_dir_entry(struct obd_device * obd, rc = cache_fsfilt->fs_del_dir_entry(obd, cache_dentry); - if (!rc) + if (!rc) { d_drop(dentry); - - post_smfs_inode(dentry->d_inode, cache_inode); - post_smfs_inode(dentry->d_parent->d_inode, cache_dir); + if (cache_inode) { + post_smfs_inode(dentry->d_inode, cache_inode); + if (S_ISDIR(dentry->d_inode->i_mode)) + dentry->d_parent->d_inode->i_nlink--; + } + post_smfs_inode(dentry->d_parent->d_inode, cache_dir); + } exit: post_smfs_dentry(cache_dentry); post_smfs_dentry(cache_parent); diff --git a/lustre/smfs/inode.c b/lustre/smfs/inode.c index d7c638d..c6afa5d 100644 --- a/lustre/smfs/inode.c +++ b/lustre/smfs/inode.c @@ -61,6 +61,7 @@ static void smfs_init_inode_info(struct inode *inode, void *opaque) atomic_read(&cache_inode->i_count)); post_smfs_inode(inode, cache_inode); + inode->i_nlink = cache_inode->i_nlink; sm_set_inode_ops(inode); //inherit parent inode flags -- 1.8.3.1