X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fsmfs%2Fdir.c;h=d194bb8f21168674d300c62cc25e15cf61111b80;hb=15536fec0812786260f59f64085fd08217347736;hp=6996a0cbfdb47893d74e93cb1cf143bf52143303;hpb=29a9b5d7e11386493d356e8b2436894b7b6c9f91;p=fs%2Flustre-release.git diff --git a/lustre/smfs/dir.c b/lustre/smfs/dir.c index 6996a0c..d194bb8 100644 --- a/lustre/smfs/dir.c +++ b/lustre/smfs/dir.c @@ -9,76 +9,15 @@ #include #include #include +#include +#include #include "smfs_internal.h" +#include "kml_idl.h" #define NAME_ALLOC_LEN(len) ((len+16) & ~15) - -void smfs_clear_dentry(struct dentry *dentry) -{ - struct qstr *name = NULL; - - if (dentry) { - if (!atomic_dec_and_lock(&dentry->d_count, &dcache_lock)) - return; - list_del(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_hash); - list_del(&dentry->d_child); - if (dentry->d_inode) { - dentry->d_inode = NULL; - list_del_init(&dentry->d_alias); - } - - name = &(dentry->d_name); - if (name->len > DNAME_INLINE_LEN-1) { - SM_FREE((char *)name->name, NAME_ALLOC_LEN(name->len)); - } - } -} - -int smfs_prepare_dentry(struct dentry *dentry, - struct dentry *parent, - struct qstr *name) -{ - char *str = NULL; - - if (name->len > DNAME_INLINE_LEN-1) { - SM_ALLOC(str, NAME_ALLOC_LEN(name->len)); - if (!str) - return (-ENOMEM); - } else - str = dentry->d_iname; - - memcpy(str, name->name, name->len); - str[name->len] = 0; - - atomic_set(&dentry->d_count, 1); - dentry->d_vfs_flags = 0; - dentry->d_flags = 0; - dentry->d_inode = NULL; - dentry->d_parent = NULL; - dentry->d_sb = NULL; - dentry->d_name.name = str; - dentry->d_name.len = name->len; - dentry->d_name.hash = name->hash; - dentry->d_op = NULL; - dentry->d_fsdata = NULL; - dentry->d_mounted = 0; - INIT_LIST_HEAD(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_lru); - INIT_LIST_HEAD(&dentry->d_subdirs); - INIT_LIST_HEAD(&dentry->d_alias); - - if (parent) { - dentry->d_parent = dget(parent); - dentry->d_sb = parent->d_sb; - list_add(&dentry->d_child, &parent->d_subdirs); - } else - INIT_LIST_HEAD(&dentry->d_child); - - return 0; -} -static void prepare_parent_dentry(struct dentry *dentry, struct inode *inode) + +void prepare_parent_dentry(struct dentry *dentry, struct inode *inode) { atomic_set(&dentry->d_count, 1); dentry->d_vfs_flags = 0; @@ -93,6 +32,14 @@ static void prepare_parent_dentry(struct dentry *dentry, struct inode *inode) INIT_LIST_HEAD(&dentry->d_alias); } +void d_unalloc(struct dentry *dentry) +{ + + list_del(&dentry->d_hash); + INIT_LIST_HEAD(&dentry->d_hash); + dput(dentry); /* this will free the dentry memory */ +} + static int smfs_create(struct inode *dir, struct dentry *dentry, int mode) @@ -100,7 +47,7 @@ static int smfs_create(struct inode *dir, struct inode *cache_dir; struct inode *cache_inode = NULL, *inode; struct dentry parent; - struct dentry cache_dentry; + struct dentry *cache_dentry = NULL; int rc; ENTRY; @@ -110,14 +57,19 @@ static int smfs_create(struct inode *dir, RETURN(-ENOENT); prepare_parent_dentry(&parent, cache_dir); - smfs_prepare_dentry(&cache_dentry, &parent, &dentry->d_name); - + cache_dentry = d_alloc(&parent, &dentry->d_name); + + if (!cache_dentry) { + RETURN(-ENOMEM); + } + if (cache_dir && cache_dir->i_op->create) - rc = cache_dir->i_op->create(cache_dir, &cache_dentry, mode); + rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode); + if (rc) GOTO(exit, rc); - - cache_inode = cache_dentry.d_inode; + + cache_inode = igrab(cache_dentry->d_inode); inode = iget(dir->i_sb, cache_inode->i_ino); @@ -128,7 +80,7 @@ static int smfs_create(struct inode *dir, sm_set_inode_ops(cache_inode, inode); exit: - smfs_clear_dentry(&cache_dentry); + d_unalloc(cache_dentry); RETURN(rc); } @@ -137,8 +89,8 @@ static struct dentry *smfs_lookup(struct inode *dir, { struct inode *cache_dir; struct inode *cache_inode = NULL, *inode; - struct dentry tmp; - struct dentry cache_dentry; + struct dentry parent; + struct dentry *cache_dentry = NULL; struct dentry *rc = NULL; ENTRY; @@ -146,25 +98,25 @@ static struct dentry *smfs_lookup(struct inode *dir, cache_dir = I2CI(dir); if (!cache_dir) RETURN(ERR_PTR(-ENOENT)); - prepare_parent_dentry(&tmp, cache_dir); - smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name); + prepare_parent_dentry(&parent, cache_dir); + cache_dentry = d_alloc(&parent, &dentry->d_name); if(cache_dir && cache_dir->i_op->lookup) - rc = cache_dir->i_op->lookup(cache_dir, &cache_dentry); + rc = cache_dir->i_op->lookup(cache_dir, cache_dentry); - if (rc || !cache_dentry.d_inode || - is_bad_inode(cache_dentry.d_inode) || - IS_ERR(cache_dentry.d_inode)) { + if (rc || !cache_dentry->d_inode || + is_bad_inode(cache_dentry->d_inode) || + IS_ERR(cache_dentry->d_inode)) { GOTO(exit, rc); } - cache_inode = cache_dentry.d_inode; + cache_inode = igrab(cache_dentry->d_inode); inode = iget(dir->i_sb, cache_inode->i_ino); d_add(dentry, inode); exit: - smfs_clear_dentry(&cache_dentry); + d_unalloc(cache_dentry); RETURN(rc); } @@ -191,10 +143,10 @@ static int smfs_link(struct dentry * old_dentry, struct inode *cache_old_inode = NULL; struct inode *cache_dir = I2CI(dir); struct inode *inode = NULL; - struct dentry cache_dentry; - struct dentry cache_old_dentry; - struct dentry tmp; - struct dentry tmp_old; + struct dentry *cache_dentry; + struct dentry *cache_old_dentry; + struct dentry parent; + struct dentry parent_old; int rc = 0; inode = old_dentry->d_inode; @@ -204,24 +156,32 @@ static int smfs_link(struct dentry * old_dentry, if (!cache_old_inode || !cache_dir) RETURN(-ENOENT); - prepare_parent_dentry(&tmp, cache_dir); - smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name); + prepare_parent_dentry(&parent, cache_dir); + cache_dentry = d_alloc(&parent, &dentry->d_name); - prepare_parent_dentry(&tmp_old, cache_dir); - smfs_prepare_dentry(&cache_old_dentry, &tmp_old, &dentry->d_name); - d_add(&cache_old_dentry, cache_old_inode); + prepare_parent_dentry(&parent_old, cache_dir); + cache_old_dentry = d_alloc(&parent_old, &dentry->d_name); + d_add(cache_old_dentry, cache_old_inode); if (cache_dir->i_op->link) - rc = cache_dir->i_op->link(&cache_old_dentry, cache_dir, &cache_dentry); + rc = cache_dir->i_op->link(cache_old_dentry, cache_dir, cache_dentry); - if (rc == 0) { - atomic_inc(&inode->i_count); - duplicate_inode(cache_old_dentry.d_inode, inode); - d_instantiate(dentry, inode); - } + if (rc) + GOTO(exit, rc); + + atomic_inc(&inode->i_count); + post_smfs_inode(inode, cache_old_dentry->d_inode); + d_instantiate(dentry, inode); + +exit: + if (cache_dentry->d_inode) + igrab(cache_dentry->d_inode); + if (cache_old_dentry->d_inode) + igrab(cache_old_dentry->d_inode); - smfs_clear_dentry(&cache_dentry); - smfs_clear_dentry(&cache_old_dentry); + d_unalloc(cache_dentry); + d_unalloc(cache_old_dentry); + RETURN(rc); } @@ -230,24 +190,27 @@ static int smfs_unlink(struct inode * dir, { struct inode *cache_dir = I2CI(dir); struct inode *cache_inode = I2CI(dentry->d_inode); - struct dentry cache_dentry; - struct dentry tmp; + struct dentry *cache_dentry; + struct dentry parent; int rc = 0; if (!cache_dir || !cache_inode) RETURN(-ENOENT); - prepare_parent_dentry(&tmp, cache_dir); - smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name); - d_add(&cache_dentry, cache_inode); + prepare_parent_dentry(&parent, cache_dir); + cache_dentry = d_alloc(&parent, &dentry->d_name); + d_add(cache_dentry, cache_inode); if (cache_dir->i_op->unlink) - rc = cache_dir->i_op->unlink(cache_dir, &cache_dentry); + rc = cache_dir->i_op->unlink(cache_dir, cache_dentry); + - duplicate_inode(cache_dentry.d_inode, dentry->d_inode); - duplicate_inode(cache_dir, dir); + post_smfs_inode(dentry->d_inode, cache_dentry->d_inode); + post_smfs_inode(dir, cache_dir); - smfs_clear_dentry(&cache_dentry); + igrab(cache_dentry->d_inode); + + d_unalloc(cache_dentry); RETURN(rc); } @@ -258,20 +221,20 @@ static int smfs_symlink (struct inode * dir, struct inode *cache_dir = I2CI(dir); struct inode *cache_inode = NULL; struct inode *inode = NULL; - struct dentry cache_dentry; - struct dentry tmp; + struct dentry *cache_dentry; + struct dentry parent; int rc = 0; if (!cache_dir) RETURN(-ENOENT); - prepare_parent_dentry(&tmp, cache_dir); - smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name); + prepare_parent_dentry(&parent, cache_dir); + cache_dentry = d_alloc(&parent, &dentry->d_name); if (cache_dir->i_op->symlink) - rc = cache_dir->i_op->symlink(cache_dir, &cache_dentry, symname); + rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname); - cache_inode = cache_dentry.d_inode; + cache_inode = igrab(cache_dentry->d_inode); inode = iget(dir->i_sb, cache_inode->i_ino); @@ -280,7 +243,8 @@ static int smfs_symlink (struct inode * dir, else rc = -ENOENT; - smfs_clear_dentry(&cache_dentry); + d_unalloc(cache_dentry); + RETURN(rc); } @@ -291,20 +255,28 @@ static int smfs_mkdir(struct inode * dir, struct inode *cache_dir = I2CI(dir); struct inode *cache_inode = NULL; struct inode *inode = NULL; - struct dentry cache_dentry; - struct dentry tmp; + struct dentry *cache_dentry; + struct dentry parent; + void *handle; int rc = 0; if (!cache_dir) RETURN(-ENOENT); + + handle = smfs_trans_start(cache_dir, KML_OPCODE_MKDIR); + if (IS_ERR(handle) ) { + CERROR("smfs_do_mkdir: no space for transaction\n"); + RETURN(-ENOSPC); + } - prepare_parent_dentry(&tmp, cache_dir); - smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name); - + prepare_parent_dentry(&parent, cache_dir); + cache_dentry = d_alloc(&parent, &dentry->d_name); + + lock_kernel(); if (cache_dir->i_op->mkdir) - rc = cache_dir->i_op->mkdir(cache_dir, &cache_dentry, mode); + rc = cache_dir->i_op->mkdir(cache_dir, cache_dentry, mode); - cache_inode = cache_dentry.d_inode; + cache_inode = igrab(cache_dentry->d_inode); inode = iget(dir->i_sb, cache_inode->i_ino); @@ -312,9 +284,16 @@ static int smfs_mkdir(struct inode * dir, GOTO(exit, rc = -ENOENT); d_instantiate(dentry, inode); - duplicate_inode(cache_dir, dir); + /*Do KML post hook*/ + if (smfs_do_kml(dir)) { + rc = post_kml_mkdir(dir, dentry); + GOTO(exit, rc); + } + post_smfs_inode(dir, cache_dir); exit: - smfs_clear_dentry(&cache_dentry); + unlock_kernel(); + smfs_trans_commit(handle); + d_unalloc(cache_dentry); RETURN(rc); } @@ -323,24 +302,25 @@ static int smfs_rmdir(struct inode * dir, { struct inode *cache_dir = I2CI(dir); struct inode *cache_inode = I2CI(dentry->d_inode); - struct dentry cache_dentry; - struct dentry tmp; + struct dentry *cache_dentry; + struct dentry parent; int rc = 0; if (!cache_dir) RETURN(-ENOENT); - prepare_parent_dentry(&tmp, cache_dir); - smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name); - d_add(&cache_dentry, cache_inode); + prepare_parent_dentry(&parent, cache_dir); + cache_dentry = d_alloc(&parent, &dentry->d_name); + d_add(cache_dentry, cache_inode); + + igrab(cache_inode); if (cache_dir->i_op->rmdir) - rc = cache_dir->i_op->rmdir(cache_dir, &cache_dentry); + rc = cache_dir->i_op->rmdir(cache_dir, cache_dentry); - duplicate_inode(cache_dir, dir); - duplicate_inode(cache_dentry.d_inode, dentry->d_inode); - - smfs_clear_dentry(&cache_dentry); + post_smfs_inode(dir, cache_dir); + post_smfs_inode(dentry->d_inode, cache_dentry->d_inode); + d_unalloc(cache_dentry); RETURN(rc); } @@ -350,27 +330,30 @@ static int smfs_mknod(struct inode * dir, struct dentry *dentry, struct inode *cache_dir = I2CI(dir); struct inode *inode = NULL; struct inode *cache_inode = NULL; - struct dentry cache_dentry; - struct dentry tmp; + struct dentry *cache_dentry; + struct dentry parent; int rc = 0; if (!cache_dir) RETURN(-ENOENT); - prepare_parent_dentry(&tmp, cache_dir); - smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name); - + prepare_parent_dentry(&parent, cache_dir); + cache_dentry = d_alloc(&parent, &dentry->d_name); + if (cache_dir->i_op->mknod) - rc = cache_dir->i_op->mknod(cache_dir, &cache_dentry, mode, rdev); + rc = cache_dir->i_op->mknod(cache_dir, cache_dentry, mode, rdev); - if (!rc) { - cache_inode = cache_dentry.d_inode; - inode = iget(dir->i_sb, cache_inode->i_ino); - d_instantiate(dentry, inode); - duplicate_inode(cache_dir, dir); - duplicate_inode(cache_dentry.d_inode, dentry->d_inode); - } - smfs_clear_dentry(&cache_dentry); + if (cache_dentry->d_inode) + cache_inode = igrab(cache_dentry->d_inode); + if (rc) + GOTO(exit, rc); + + inode = iget(dir->i_sb, cache_inode->i_ino); + d_instantiate(dentry, inode); + post_smfs_inode(dir, cache_dir); + post_smfs_inode(dentry->d_inode, cache_dentry->d_inode); +exit: + d_unalloc(cache_dentry); RETURN(rc); } static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry, @@ -379,33 +362,34 @@ 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 *cache_old_inode = I2CI(old_dentry->d_inode); - struct inode *cache_new_inode = NULL; - struct inode *new_inode = NULL; - struct dentry cache_old_dentry; - struct dentry cache_new_dentry; - struct dentry tmp_new; - struct dentry tmp_old; + struct dentry *cache_old_dentry; + struct dentry *cache_new_dentry; + struct dentry parent_new; + struct dentry parent_old; int rc = 0; if (!cache_old_dir || !cache_new_dir || !cache_old_inode) RETURN(-ENOENT); - prepare_parent_dentry(&tmp_old, cache_old_dir); - smfs_prepare_dentry(&cache_old_dentry, &tmp_old, &old_dentry->d_name); - d_add(&cache_old_dentry, cache_old_inode); + prepare_parent_dentry(&parent_old, cache_old_dir); + cache_old_dentry = d_alloc(&parent_old, &old_dentry->d_name); + d_add(cache_old_dentry, cache_old_inode); + igrab(cache_old_inode); - prepare_parent_dentry(&tmp_new, cache_new_dir); - smfs_prepare_dentry(&cache_new_dentry, &tmp_new, &new_dentry->d_name); + prepare_parent_dentry(&parent_new, cache_new_dir); + cache_new_dentry = d_alloc(&parent_new, &new_dentry->d_name); if (cache_old_dir->i_op->rename) - rc = cache_old_dir->i_op->rename(cache_old_dir, &cache_old_dentry, - cache_new_dir, &cache_new_dentry); - - duplicate_inode(cache_old_dir, old_dir); - duplicate_inode(cache_new_dir, new_dir); - smfs_clear_dentry(&cache_old_dentry); - smfs_clear_dentry(&cache_new_dentry); + rc = cache_old_dir->i_op->rename(cache_old_dir, cache_old_dentry, + cache_new_dir, cache_new_dentry); + post_smfs_inode(old_dir, cache_old_dir) ; + post_smfs_inode(new_dir, cache_new_dir); + if (cache_new_dentry->d_inode) { + igrab(cache_new_dentry->d_inode); + } + d_unalloc(cache_old_dentry); + d_unalloc(cache_new_dentry); RETURN(rc); }