Whamcloud - gitweb
Update smfs: 1)unlock cache inode after we call bottom fs methods 2)minor fix in...
[fs/lustre-release.git] / lustre / smfs / dir.c
index 3835509..d194bb8 100644 (file)
@@ -9,19 +9,15 @@
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/unistd.h>
+#include <linux/lustre_idl.h> 
+#include <linux/smp_lock.h>
 
 #include "smfs_internal.h" 
+#include "kml_idl.h" 
 
-static void d_unalloc(struct dentry *dentry)
-{
-        if (dentry) {                                                                                                                                                                                
-               list_del(&dentry->d_hash);
-               INIT_LIST_HEAD(&dentry->d_hash);
-               dput(dentry);   
-       }
-}
-                                                                                                                                                                                                     
-static void prepare_parent_dentry(struct dentry *dentry, struct inode *inode)
+#define NAME_ALLOC_LEN(len)     ((len+16) & ~15)
+                                                                                                                                                                                        
+void prepare_parent_dentry(struct dentry *dentry, struct inode *inode)
 {
         atomic_set(&dentry->d_count, 1);
         dentry->d_vfs_flags = 0;
@@ -36,14 +32,22 @@ 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)
 {
        struct  inode *cache_dir; 
-       struct  inode *cache_inode, *inode;
-       struct  dentry tmp
-       struct  dentry *cache_dentry;
+       struct  inode *cache_inode = NULL, *inode;
+       struct  dentry parent
+       struct  dentry *cache_dentry = NULL;
        int     rc;
        
        ENTRY;
@@ -52,18 +56,20 @@ static int smfs_create(struct inode *dir,
         if (!cache_dir)
                 RETURN(-ENOENT);
        
-       prepare_parent_dentry(&tmp, cache_dir);      
-       cache_dentry = d_alloc(&tmp, &dentry->d_name);
-        
-       if (!cache_dentry) 
-                RETURN(-ENOENT);
+       prepare_parent_dentry(&parent, cache_dir);      
+       cache_dentry = d_alloc(&parent, &dentry->d_name);
        
-       if(cache_dir && cache_dir->i_op->create)
+       if (!cache_dentry) {
+               RETURN(-ENOMEM);
+       }
+                
+       if (cache_dir && cache_dir->i_op->create)
                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);    
 
@@ -74,7 +80,7 @@ static int smfs_create(struct inode *dir,
        
        sm_set_inode_ops(cache_inode, inode);
 exit:
-       d_unalloc(cache_dentry);        
+       d_unalloc(cache_dentry);
        RETURN(rc);
 }
 
@@ -82,9 +88,9 @@ static struct dentry *smfs_lookup(struct inode *dir,
                                  struct dentry *dentry)
 {
        struct  inode *cache_dir; 
-       struct  inode *cache_inode, *inode;
-       struct  dentry tmp
-       struct  dentry *cache_dentry;
+       struct  inode *cache_inode = NULL, *inode;
+       struct  dentry parent
+       struct  dentry *cache_dentry = NULL;
        struct  dentry *rc = NULL;
        
        ENTRY;
@@ -92,12 +98,9 @@ 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);      
-       cache_dentry = d_alloc(&tmp, &dentry->d_name);
+       prepare_parent_dentry(&parent, cache_dir);      
+       cache_dentry = d_alloc(&parent, &dentry->d_name);
       
-       if (!cache_dentry)
-               RETURN(ERR_PTR(-ENOENT));
-
        if(cache_dir && cache_dir->i_op->lookup)
                rc = cache_dir->i_op->lookup(cache_dir, cache_dentry);
 
@@ -107,13 +110,13 @@ static struct dentry *smfs_lookup(struct inode *dir,
                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:
-       d_unalloc(cache_dentry);        
+       d_unalloc(cache_dentry);
        RETURN(rc);
 }                     
 
@@ -140,61 +143,77 @@ 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 = NULL;
-       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;
        
        cache_old_inode = I2CI(inode);
        
-       if (!cache_old_inode || !dir) 
+       if (!cache_old_inode || !cache_dir) 
                 RETURN(-ENOENT);
-
-       prepare_parent_dentry(&tmp_old, cache_old_inode);
-
-       prepare_parent_dentry(&tmp, cache_dir);
-       cache_dentry = d_alloc(&tmp, &dentry->d_name); 
-       
+       
+       prepare_parent_dentry(&parent, cache_dir);
+       cache_dentry = d_alloc(&parent, &dentry->d_name);
+       
+       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(&tmp, cache_dir, cache_dentry);              
+               rc = cache_dir->i_op->link(cache_old_dentry, cache_dir, cache_dentry);          
        
-       if (rc == 0) {
-               d_instantiate(dentry, inode);
-       }       
+       if (rc)
+               GOTO(exit, rc); 
        
-       d_unalloc(cache_dentry);
+       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);
        
+       d_unalloc(cache_dentry);
+       d_unalloc(cache_old_dentry);
+
        RETURN(rc);
 }
+
 static int smfs_unlink(struct inode * dir, 
                       struct dentry *dentry)
 {
        struct inode *cache_dir = I2CI(dir);
        struct inode *cache_inode = I2CI(dentry->d_inode);
-       struct dentry *cache_dentry = NULL;
-       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);
-       cache_dentry = d_alloc(&tmp, &dentry->d_name); 
+       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->unlink)
                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);
+       
+       igrab(cache_dentry->d_inode);
+
        d_unalloc(cache_dentry);        
        RETURN(rc);     
 }
+
 static int smfs_symlink (struct inode * dir,
                         struct dentry *dentry, 
                         const char * symname)
@@ -202,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 = NULL
-       struct dentry tmp
+       struct dentry *cache_dentry; 
+       struct dentry parent
        int    rc = 0;
 
        if (!cache_dir) 
                RETURN(-ENOENT);
        
-       prepare_parent_dentry(&tmp, NULL);
-       cache_dentry = d_alloc(&tmp, &dentry->d_name); 
+       prepare_parent_dentry(&parent, cache_dir);
+       cache_dentry = d_alloc(&parent, &dentry->d_name);
 
-       if (cache_inode->i_op->symlink)
+       if (cache_dir->i_op->symlink)
                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);
 
@@ -224,9 +243,11 @@ static int smfs_symlink (struct inode * dir,
        else
                rc = -ENOENT;
        
-       d_unalloc(cache_dentry);
+       d_unalloc(cache_dentry);        
+       
        RETURN(rc);                     
 }
+
 static int smfs_mkdir(struct inode * dir, 
                      struct dentry * dentry, 
                      int mode)
@@ -234,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 = NULL;
-       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, NULL);
-       cache_dentry = d_alloc(&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);
 
-       cache_inode = cache_dentry->d_inode;
+       cache_inode = igrab(cache_dentry->d_inode);
 
        inode = iget(dir->i_sb, cache_inode->i_ino);
 
@@ -255,31 +284,42 @@ 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:
+       unlock_kernel();        
+       smfs_trans_commit(handle);
        d_unalloc(cache_dentry);
        RETURN(rc);             
 }
+
 static int  smfs_rmdir(struct inode * dir, 
                       struct dentry *dentry) 
 {
        struct inode *cache_dir = I2CI(dir);
-       struct dentry *cache_dentry = NULL;
-       struct dentry tmp;
+       struct inode *cache_inode = I2CI(dentry->d_inode);
+       struct dentry *cache_dentry;
+       struct dentry parent;
        int    rc = 0;
 
        if (!cache_dir) 
                RETURN(-ENOENT);
        
-       prepare_parent_dentry(&tmp, NULL);
-       cache_dentry = d_alloc(&tmp, &dentry->d_name); 
+       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);
 
-       duplicate_inode(cache_dir, dir);
-       duplicate_inode(cache_dentry->d_inode, dentry->d_inode);
-
+       post_smfs_inode(dir, cache_dir);
+       post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
        d_unalloc(cache_dentry);
        RETURN(rc);             
 }
@@ -288,22 +328,31 @@ static int smfs_mknod(struct inode * dir, struct dentry *dentry,
                       int mode, int rdev)
 {
        struct inode *cache_dir = I2CI(dir);
-       struct dentry *cache_dentry = NULL;
-       struct dentry tmp;
+       struct inode *inode = NULL;
+       struct inode *cache_inode = NULL;
+       struct dentry *cache_dentry;
+       struct dentry parent;
        int    rc = 0;
 
        if (!cache_dir) 
                RETURN(-ENOENT);
 
-       prepare_parent_dentry(&tmp, NULL);
-       cache_dentry = d_alloc(&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, dentry, mode, rdev);
-
-       duplicate_inode(cache_dir, dir);
-       duplicate_inode(cache_dentry->d_inode, dentry->d_inode);
-
+               rc = cache_dir->i_op->mknod(cache_dir, cache_dentry, mode, rdev);
+       
+       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);             
 }
@@ -313,39 +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 = NULL;
-       struct dentry *cache_new_dentry = NULL;
-       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, old_dir);
-       cache_old_dentry = d_alloc(&tmp_old, &old_dentry->d_name); 
+       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, NULL);
-       cache_new_dentry = d_alloc(&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);
-       
-       cache_new_inode = cache_new_dentry->d_inode; 
-       new_inode = iget(new_dir->i_sb, cache_new_inode->i_ino);
-       
-       d_instantiate(new_dentry, new_inode);
-               
-       duplicate_inode(cache_old_dir, old_dir);
-       duplicate_inode(cache_new_dir, new_dir);
 
+       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);             
 }