Whamcloud - gitweb
b=6285
[fs/lustre-release.git] / lustre / smfs / dir.c
index fe17f3a..296973b 100644 (file)
@@ -61,7 +61,11 @@ static int smfs_create(struct inode *dir, struct dentry *dentry,
         int rc = 0;
         
         ENTRY;
-
+        
+        CDEBUG(D_INODE, "VFS Op:name=%.*s (%p),dir=%lu/%u\n",
+               dentry->d_name.len, dentry->d_name.name, dentry,
+               dir->i_ino, dir->i_generation);
+        
         LASSERT(cache_dir);
         LASSERT(cache_dir->i_op->create);
         
@@ -180,6 +184,10 @@ static int smfs_do_lookup (struct inode * dir,
 
         ENTRY;
         
+        CDEBUG(D_INODE, "VFS Op:name=%.*s (%p),dir=%lu/%u\n",
+               dentry->d_name.len, dentry->d_name.name, dentry,
+               dir->i_ino, dir->i_generation);
+
         if (!cache_dir)
                 RETURN(-ENOENT);
 
@@ -215,14 +223,25 @@ static int smfs_do_lookup (struct inode * dir,
                 smfs_update_dentry(dentry, tmp);         
                 
                 if (tmp->d_inode) {
-                        if (!tmp->d_inode->i_nlink)
-                                CWARN("inode #%lu (%p) nlink is 0\n",
-                                      tmp->d_inode->i_ino, tmp->d_inode);
-                        
                         *inode = smfs_get_inode(dir->i_sb, tmp->d_inode, 
                                                 I2SMI(dir), 0); 
                         if (!(*inode))
                                 rc = -ENOENT;
+                        else {
+                                if (!tmp->d_inode->i_nlink) {
+                                        struct inode * ind = tmp->d_inode;
+                                
+                                        CWARN("inode #%lu (%*s) nlink is %i/%i\n",
+                                              ind->i_ino, tmp->d_name.len,
+                                              tmp->d_name.name, ind->i_nlink,
+                                              (*inode)->i_nlink);
+                                        CWARN("parent #%lu (%*s) nlink is %i\n",
+                                              dir->i_ino, tmp->d_parent->d_name.len,
+                                              tmp->d_parent->d_name.name,
+                                              cache_dir->i_nlink);
+                                        LBUG();
+                                }
+                        }
                 }
         }
         
@@ -375,6 +394,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));
         }
 
@@ -416,6 +436,10 @@ static int smfs_unlink(struct inode * dir, struct dentry *dentry)
         LASSERT(cache_dir->i_op->unlink);
         LASSERT(parent);
         
+        CDEBUG(D_INODE, "VFS Op:name=%.*s (%p),dir=%lu/%u\n",
+               dentry->d_name.len, dentry->d_name.name, dentry,
+               dir->i_ino, dir->i_generation);
+
         cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
         cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
         if (!cache_dentry || !cache_parent) {
@@ -437,9 +461,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:
@@ -527,6 +553,11 @@ static int smfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
         LASSERT(cache_dir);
         LASSERT(parent);
         
+        CDEBUG(D_INODE, "VFS Op:name=%.*s (%p),dir=%lu/%u\n",
+               dentry->d_name.len, dentry->d_name.name, dentry,
+               dir->i_ino, dir->i_generation);
+
+        
         cache_parent = pre_smfs_dentry(NULL, parent, dentry->d_parent);
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
         if (!cache_parent || !cache_dentry) {
@@ -548,7 +579,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 +603,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 = {
@@ -581,6 +613,10 @@ static int smfs_rmdir(struct inode *dir, struct dentry *dentry)
 
         ENTRY;
         
+        CDEBUG(D_INODE, "VFS Op:name=%.*s (%p),dir=%lu/%u\n",
+               dentry->d_name.len, dentry->d_name.name, dentry,
+               dir->i_ino, dir->i_generation);
+
         LASSERT(cache_dir);
         LASSERT(cache_dir->i_op->rmdir);
         LASSERT(parent);
@@ -591,30 +627,36 @@ static int smfs_rmdir(struct inode *dir, struct dentry *dentry)
                 rc = -ENOMEM;
                 goto exit;
         }
-
+        
         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:
         post_smfs_dentry(cache_dentry);
         post_smfs_dentry(cache_parent);
@@ -692,6 +734,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);
@@ -713,8 +756,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);
         }
@@ -743,8 +786,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); 
         
@@ -752,12 +796,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:
@@ -774,13 +830,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,