Whamcloud - gitweb
Update smfs: fix bugs of smfs_create
[fs/lustre-release.git] / lustre / smfs / dir.c
index 0252608..c5f0554 100644 (file)
 
 #define NAME_ALLOC_LEN(len)     ((len+16) & ~15)
 
-struct  dentry parent; 
-struct  dentry cache_dentry;
-
-static void smfs_clear_dentry(struct dentry *dentry)
+void smfs_clear_dentry(struct dentry *dentry)
 {
        struct qstr *name = NULL; 
 
@@ -95,12 +92,15 @@ static void prepare_parent_dentry(struct dentry *dentry, struct inode *inode)
         INIT_LIST_HEAD(&dentry->d_subdirs);
         INIT_LIST_HEAD(&dentry->d_alias);
 }
+
 static int smfs_create(struct inode *dir, 
                       struct dentry *dentry, 
                       int mode)
 {
        struct  inode *cache_dir; 
-       struct  inode *cache_inode, *inode;
+       struct  inode *cache_inode = NULL, *inode;
+       struct  dentry parent; 
+       struct  dentry cache_dentry;
        int     rc;
        
        ENTRY;
@@ -129,7 +129,6 @@ static int smfs_create(struct inode *dir,
        sm_set_inode_ops(cache_inode, inode);
 exit:
        smfs_clear_dentry(&cache_dentry);       
-       iput(cache_inode);
        RETURN(rc);
 }
 
@@ -137,7 +136,7 @@ static struct dentry *smfs_lookup(struct inode *dir,
                                  struct dentry *dentry)
 {
        struct  inode *cache_dir; 
-       struct  inode *cache_inode, *inode;
+       struct  inode *cache_inode = NULL, *inode;
        struct  dentry tmp; 
        struct  dentry cache_dentry;
        struct  dentry *rc = NULL;
@@ -166,8 +165,6 @@ static struct dentry *smfs_lookup(struct inode *dir,
        d_add(dentry, inode);   
 exit:
        smfs_clear_dentry(&cache_dentry);       
-       iput(cache_inode);
-
        RETURN(rc);
 }                     
 
@@ -195,6 +192,7 @@ static int smfs_link(struct dentry * old_dentry,
        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; 
        int     rc = 0;
@@ -203,23 +201,28 @@ static int smfs_link(struct dentry * old_dentry,
        
        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);
-       smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
+       
        prepare_parent_dentry(&tmp, cache_dir);
-       
+       smfs_prepare_dentry(&cache_dentry, &tmp, &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); 
+       
        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);
        }       
        
        smfs_clear_dentry(&cache_dentry);
+       smfs_clear_dentry(&cache_old_dentry);
        RETURN(rc);
 }
+
 static int smfs_unlink(struct inode * dir, 
                       struct dentry *dentry)
 {
@@ -236,20 +239,16 @@ static int smfs_unlink(struct inode * dir,
        smfs_prepare_dentry(&cache_dentry, &tmp, &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);
        
-       iput(cache_dentry.d_inode);
        smfs_clear_dentry(&cache_dentry);
-       
        RETURN(rc);     
 }
+
 static int smfs_symlink (struct inode * dir,
                         struct dentry *dentry, 
                         const char * symname)
@@ -264,10 +263,10 @@ static int smfs_symlink (struct inode * dir,
        if (!cache_dir) 
                RETURN(-ENOENT);
        
-       prepare_parent_dentry(&tmp, NULL);
+       prepare_parent_dentry(&tmp, cache_dir);
        smfs_prepare_dentry(&cache_dentry, &tmp, &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;
@@ -282,6 +281,7 @@ static int smfs_symlink (struct inode * dir,
        smfs_clear_dentry(&cache_dentry);
        RETURN(rc);                     
 }
+
 static int smfs_mkdir(struct inode * dir, 
                      struct dentry * dentry, 
                      int mode)
@@ -296,7 +296,7 @@ static int smfs_mkdir(struct inode * dir,
        if (!cache_dir) 
                RETURN(-ENOENT);
        
-       prepare_parent_dentry(&tmp, NULL);
+       prepare_parent_dentry(&tmp, cache_dir);
        smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
        
        if (cache_dir->i_op->mkdir)
@@ -315,10 +315,12 @@ exit:
        smfs_clear_dentry(&cache_dentry);
        RETURN(rc);             
 }
+
 static int  smfs_rmdir(struct inode * dir, 
                       struct dentry *dentry) 
 {
        struct inode *cache_dir = I2CI(dir);
+       struct inode *cache_inode = I2CI(dentry->d_inode);
        struct dentry cache_dentry;
        struct dentry tmp;
        int    rc = 0;
@@ -326,8 +328,9 @@ static int  smfs_rmdir(struct inode * dir,
        if (!cache_dir) 
                RETURN(-ENOENT);
        
-       prepare_parent_dentry(&tmp, NULL);
+       prepare_parent_dentry(&tmp, cache_dir);
        smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
+       d_add(&cache_dentry, cache_inode);
        
        if (cache_dir->i_op->rmdir)
                rc = cache_dir->i_op->rmdir(cache_dir, &cache_dentry);
@@ -343,6 +346,8 @@ static int smfs_mknod(struct inode * dir, struct dentry *dentry,
                       int mode, int rdev)
 {
        struct inode *cache_dir = I2CI(dir);
+       struct inode *inode = NULL;
+       struct inode *cache_inode = NULL;
        struct dentry cache_dentry;
        struct dentry tmp;
        int    rc = 0;
@@ -350,15 +355,19 @@ static int smfs_mknod(struct inode * dir, struct dentry *dentry,
        if (!cache_dir) 
                RETURN(-ENOENT);
 
-       prepare_parent_dentry(&tmp, NULL);
+       prepare_parent_dentry(&tmp, cache_dir);
        smfs_prepare_dentry(&cache_dentry, &tmp, &dentry->d_name);
                
        if (cache_dir->i_op->mknod)
                rc = cache_dir->i_op->mknod(cache_dir, &cache_dentry, mode, rdev);
-
-       duplicate_inode(cache_dir, dir);
-       duplicate_inode(cache_dentry.d_inode, dentry->d_inode);
-
+       
+       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);
        RETURN(rc);             
 }
@@ -379,25 +388,19 @@ static int smfs_rename(struct inode * old_dir, struct dentry *old_dentry,
        if (!cache_old_dir || !cache_new_dir || !cache_old_inode) 
                RETURN(-ENOENT);
        
-       prepare_parent_dentry(&tmp_old, old_dir);
+       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(&tmp_new, NULL);
+       prepare_parent_dentry(&tmp_new, cache_new_dir);
        smfs_prepare_dentry(&cache_new_dentry, &tmp_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);
-
        smfs_clear_dentry(&cache_old_dentry);
        smfs_clear_dentry(&cache_new_dentry);