Whamcloud - gitweb
b=5881
authortappro <tappro>
Wed, 16 Mar 2005 10:55:48 +0000 (10:55 +0000)
committertappro <tappro>
Wed, 16 Mar 2005 10:55:48 +0000 (10:55 +0000)
r=wangdi

smfs fixes to make it works in 2.6.7 kernel and in conformity with smfs hld/dld documents.

lustre/smfs/dir.c
lustre/smfs/doc/dld.lyx
lustre/smfs/doc/hld.lyx
lustre/smfs/file.c
lustre/smfs/inode.c
lustre/smfs/options.c
lustre/smfs/smfs_api.h [new file with mode: 0644]
lustre/smfs/smfs_internal.h
lustre/smfs/smfs_lib.c
lustre/smfs/symlink.c
lustre/smfs/sysctl.c

index 685d6ff..774bde8 100644 (file)
@@ -54,22 +54,15 @@ static int smfs_create(struct inode *dir, struct dentry *dentry,
         struct dentry *cache_dentry = NULL;
         struct dentry *cache_parent = NULL;
         void *handle = NULL;
+        struct inode *cache_inode = NULL;
         int rc = 0;
 
         ENTRY;
 
         cache_dir = I2CI(dir);
-        if (!cache_dir)
-                RETURN(-ENOENT);
+        LASSERT(cache_dir && cache_dir->i_op->create);
 
-        handle = smfs_trans_start(dir, FSFILT_OP_CREATE, NULL);
-        if (IS_ERR(handle))
-                       RETURN(-ENOSPC);
-        
-        lock_kernel();
-        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_CREATE, handle,
-                  PRE_HOOK, rc, exit);
-        
+        //lock_kernel();
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
 
@@ -78,28 +71,34 @@ static int smfs_create(struct inode *dir, struct dentry *dentry,
        
         pre_smfs_inode(dir, cache_dir);
         
+        handle = smfs_trans_start(dir, FSFILT_OP_CREATE, NULL);
+        if (IS_ERR(handle))
+                       GOTO(exit, rc = -ENOSPC);
+        
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_CREATE, handle,
+                  PRE_HOOK, rc, exit);
+        
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        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);
 #else
-        if (cache_dir && cache_dir->i_op->create)
-                rc = cache_dir->i_op->create(cache_dir, cache_dentry,
-                                             mode, nd);
+        rc = cache_dir->i_op->create(cache_dir, cache_dentry, mode, nd);
 #endif
+        cache_inode = cache_dentry->d_inode;
+        
         if (rc)
                 GOTO(exit, rc);
         
-        SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode,
-                       rc, exit); 
+        SMFS_IGET(dir, cache_inode->i_ino, inode, rc, exit); 
 
         d_instantiate(dentry, inode);
-        post_smfs_inode(dir, cache_dir);
-        
+
         SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_CREATE, handle,
                   POST_HOOK, rc,  exit); 
+
+        post_smfs_inode(dir, cache_dir);
+
 exit:
-        unlock_kernel();
+        //unlock_kernel();
         post_smfs_dentry(cache_dentry);
         post_smfs_dentry(cache_parent);
         smfs_trans_commit(dir, handle, 0);
@@ -118,13 +117,13 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry,
         struct inode *inode = NULL;
         struct dentry *cache_dentry = NULL;
         struct dentry *cache_parent = NULL;
-        struct dentry *rc = NULL;
-        void *handle = NULL;
-        int rc2 = 0;
+        struct dentry *rdentry = NULL;
+        int rc = 0;
 
         ENTRY;
 
-        if (!(cache_dir = I2CI(dir)))
+        cache_dir = I2CI(dir);
+        if (!cache_dir || !cache_dir->i_op->lookup)
                 RETURN(ERR_PTR(-ENOENT));
 
         /* preparing artificial backing fs dentries. */
@@ -132,71 +131,69 @@ static struct dentry *smfs_lookup(struct inode *dir, struct dentry *dentry,
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
 
         if (!cache_dentry || !cache_parent)
-                GOTO(exit, rc = ERR_PTR(-ENOMEM));
+                RETURN (ERR_PTR(-ENOMEM));
 
-        if (!cache_dir && cache_dir->i_op->lookup)
-                GOTO(exit, rc = ERR_PTR(-ENOENT));
-
-        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_LOOKUP, handle, 
-                  PRE_HOOK, rc2, exit); 
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_LOOKUP, NULL, 
+                  PRE_HOOK, rc, exit); 
 
         /* perform lookup in backing fs. */
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        rc = cache_dir->i_op->lookup(cache_dir, cache_dentry);
+        rdentry = cache_dir->i_op->lookup(cache_dir, cache_dentry);
 #else
-        rc = cache_dir->i_op->lookup(cache_dir, cache_dentry, nd);
+        rdentry = cache_dir->i_op->lookup(cache_dir, cache_dentry, nd);
 #endif
-        if (rc && IS_ERR(rc))
-                GOTO(exit, rc);
+        cache_inode = cache_dentry->d_inode;
         
-        if ((cache_inode = rc ? rc->d_inode : cache_dentry->d_inode)) {
-                if (IS_ERR(cache_inode)) {
-                        dentry->d_inode = cache_inode;
-                        GOTO(exit, rc = NULL);
-                }
-                SMFS_GET_INODE(dir->i_sb, cache_inode, dir, inode, rc2, exit);
+        if (rdentry) {
+                if (IS_ERR(rdentry))
+                        GOTO(exit, rdentry);
+        
+                cache_inode = rdentry->d_inode;
+                dput(rdentry);
+                rdentry = NULL;
         }
-
+        
+        if (cache_inode) 
+                SMFS_IGET(dir, cache_inode->i_ino, inode, rc, exit);
+     
+        
+        //rdentry = d_splice_alias(inode, dentry);
         d_add(dentry, inode);
-        rc = NULL;
+        //CDEBUG(D_INODE, "dir %p (inode %p)\n", dir, cache_dir);
 
-        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_LOOKUP, handle, POST_HOOK, rc2
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_LOOKUP, NULL, POST_HOOK, rc
                   exit); 
 exit:
-        if (rc2 < 0)
-                rc = ERR_PTR(rc2);
         post_smfs_dentry(cache_dentry);
         post_smfs_dentry(cache_parent);
-        smfs_trans_commit(dir, handle, 0);
-        RETURN(rc);
+        return rdentry;
 }
 
 static int smfs_link(struct dentry *old_dentry,
                      struct inode *dir, struct dentry *dentry)
 {
         struct inode *cache_old_inode = NULL;
-        struct inode *cache_dir = I2CI(dir);
-        struct inode *inode = NULL;
+        struct inode *cache_dir = NULL;
+        struct inode *old_inode = NULL;
         struct dentry *cache_dentry = NULL;
         struct dentry *cache_old_dentry = NULL;
         struct dentry *cache_parent = NULL;
         void *handle = NULL;
         int rc = 0;
 
-        inode = old_dentry->d_inode;
-        cache_old_inode = I2CI(inode);
+        ENTRY;
 
-        handle = smfs_trans_start(dir, FSFILT_OP_LINK, NULL);
-        if (IS_ERR(handle))
-                 RETURN(-ENOSPC);
+        cache_dir = I2CI(dir);
+        if (!cache_dir || !cache_dir->i_op->link)
+                GOTO(exit, rc = -ENOENT);
         
-        lock_kernel();
-        SMFS_HOOK(dir, old_dentry, NULL, NULL, HOOK_LINK, handle,
-                  PRE_HOOK, rc, exit); 
+        old_inode = old_dentry->d_inode;        
+        cache_old_inode = I2CI(old_inode);
+        if (!cache_old_inode)
+                GOTO(exit, rc = -ENOENT);
         
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
-
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
@@ -204,25 +201,33 @@ static int smfs_link(struct dentry *old_dentry,
                                            old_dentry);
         if (!cache_old_dentry)
                 GOTO(exit, rc = -ENOMEM);
-
+        
         pre_smfs_inode(dir, cache_dir);
-        pre_smfs_inode(inode, cache_old_dentry->d_inode);
+        pre_smfs_inode(old_inode, cache_old_inode);
 
-        if (cache_dir->i_op->link)
-                rc = cache_dir->i_op->link(cache_old_dentry, cache_dir,
+        handle = smfs_trans_start(dir, FSFILT_OP_LINK, NULL);
+        if (IS_ERR(handle))
+                 GOTO(exit, rc = -ENOSPC);
+        
+        //lock_kernel();
+        SMFS_HOOK(dir, old_dentry, NULL, NULL, HOOK_LINK, handle,
+                  PRE_HOOK, rc, exit); 
+
+        rc = cache_dir->i_op->link(cache_old_dentry, cache_dir,
                                            cache_dentry);
         if (rc)
                 GOTO(exit, rc);
 
-        atomic_inc(&inode->i_count);
-        post_smfs_inode(inode, cache_old_dentry->d_inode);
-        d_instantiate(dentry, inode);
+        atomic_inc(&old_inode->i_count);
+        d_instantiate(dentry, old_inode);
+
+        post_smfs_inode(old_inode, cache_old_inode);
         post_smfs_inode(dir, cache_dir);
 
         SMFS_HOOK(dir, old_dentry, dentry, NULL, HOOK_LINK, handle,
                   POST_HOOK, rc, exit); 
 exit:
-        unlock_kernel();
+        //unlock_kernel();
         post_smfs_dentry(cache_dentry);
         post_smfs_dentry(cache_parent);
         post_smfs_dentry(cache_old_dentry);
@@ -241,37 +246,42 @@ static int smfs_unlink(struct inode * dir,
         int    rc = 0;
         int    mode = 0;
 
-        if (!cache_dir || !cache_inode)
+        ENTRY;
+        
+        if (!cache_dir || !cache_inode || !cache_dir->i_op->unlink)
                 RETURN(-ENOENT);
 
-        handle = smfs_trans_start(dir, FSFILT_OP_UNLINK, NULL);
-        if (IS_ERR(handle))
-                RETURN(-ENOSPC);
-
-        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_UNLINK, handle, PRE_HOOK, rc, 
-                  exit); 
-        
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
 
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
                 
-        lock_kernel();
+        //lock_kernel();
         pre_smfs_inode(dir, cache_dir);
         pre_smfs_inode(dentry->d_inode, cache_inode);
-        if (cache_dir->i_op->unlink)
-                rc = cache_dir->i_op->unlink(cache_dir, cache_dentry);
+
+        handle = smfs_trans_start(dir, FSFILT_OP_UNLINK, NULL);
+        if (IS_ERR(handle))
+                GOTO(exit, rc = -ENOSPC);
+
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_UNLINK, handle, PRE_HOOK, rc, 
+                  exit); 
+        
+        rc = cache_dir->i_op->unlink(cache_dir, cache_dentry);
+        if (rc)
+                GOTO(exit, rc);
+        
         post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
         post_smfs_inode(dir, cache_dir);
-        unlock_kernel();
+        //unlock_kernel();
         
         SMFS_HOOK(dir, dentry, &mode, NULL, HOOK_UNLINK, handle, POST_HOOK, 
                   rc, exit); 
 exit:
+        smfs_trans_commit(dir, handle, 0);
         post_smfs_dentry(cache_dentry);
         post_smfs_dentry(cache_parent);
-        smfs_trans_commit(dir, handle, 0);
         RETURN(rc);
 }
 
@@ -285,16 +295,10 @@ static int smfs_symlink(struct inode *dir, struct dentry *dentry,
         void   *handle = NULL;
         int    rc = 0, tgt_len;
 
-        if (!cache_dir)
-                RETURN(-ENOENT);
-
-        handle = smfs_trans_start(dir, FSFILT_OP_SYMLINK, NULL);
-        if (IS_ERR(handle))
-                RETURN(-ENOSPC);
+        ENTRY;
         
-        lock_kernel();
-        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_SYMLINK, handle, PRE_HOOK, rc, 
-                  exit); 
+        if (!cache_dir || !cache_dir->i_op->symlink)
+                RETURN(-ENOENT);
 
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
@@ -303,26 +307,33 @@ static int smfs_symlink(struct inode *dir, struct dentry *dentry,
                 GOTO(exit, rc = -ENOMEM);
        
         pre_smfs_inode(dir, cache_dir);
-        if (cache_dir->i_op->symlink)
-                rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname);
-
+        
+        handle = smfs_trans_start(dir, FSFILT_OP_SYMLINK, NULL);
+        if (IS_ERR(handle))
+                GOTO(exit, rc = -ENOSPC);
+        
+        //lock_kernel();
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_SYMLINK, handle, PRE_HOOK, rc, 
+                  exit); 
+        
+        rc = cache_dir->i_op->symlink(cache_dir, cache_dentry, symname);
+        if (rc)
+                GOTO(exit, rc);
+        
+        SMFS_IGET(dir, cache_dentry->d_inode->i_ino, inode, rc, exit); 
+        
+        d_instantiate(dentry, inode);
         post_smfs_inode(dir, cache_dir);
         
-        SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode, rc, exit); 
-        if (inode)
-                d_instantiate(dentry, inode);
-        else
-                rc = -ENOENT;
-
         tgt_len = strlen(symname) + 1;
-        
         SMFS_HOOK(dir, dentry, (char *)symname, &tgt_len, HOOK_SYMLINK, handle, 
                   POST_HOOK, rc, exit); 
+        
 exit:
-        unlock_kernel();
+        //unlock_kernel();
+        smfs_trans_commit(dir, handle, 0);
         post_smfs_dentry(cache_dentry);
         post_smfs_dentry(cache_parent);
-        smfs_trans_commit(dir, handle, 0);
         RETURN(rc);
 }
 
@@ -336,18 +347,11 @@ static int smfs_mkdir(struct inode *dir, struct dentry *dentry,
         void   *handle = NULL;
         int    rc = 0;
 
-        if (!cache_dir)
+        ENTRY;
+        
+        if (!cache_dir || !cache_dir->i_op->mkdir)
                 RETURN(-ENOENT);
 
-        handle = smfs_trans_start(dir, FSFILT_OP_MKDIR, NULL);
-        if (IS_ERR(handle))
-                RETURN(-ENOSPC);
-
-        lock_kernel();
-        
-        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKDIR, handle, PRE_HOOK, rc, 
-                  exit); 
-        
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
 
@@ -356,23 +360,32 @@ static int smfs_mkdir(struct inode *dir, struct dentry *dentry,
 
         pre_smfs_inode(dir, cache_dir);
 
-        if (cache_dir->i_op->mkdir)
-                rc = cache_dir->i_op->mkdir(cache_dir, cache_dentry, mode);
+        handle = smfs_trans_start(dir, FSFILT_OP_MKDIR, NULL);
+        if (IS_ERR(handle))
+                GOTO(exit, rc = -ENOSPC);
+
+        //lock_kernel();
+        
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKDIR, handle, PRE_HOOK, rc, 
+                  exit); 
+        
+        rc = cache_dir->i_op->mkdir(cache_dir, cache_dentry, mode);
 
         if (rc)
                 GOTO(exit, rc);
   
-        SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode, rc, exit); 
+        SMFS_IGET(dir, cache_dentry->d_inode->i_ino, inode, rc, exit);
+        
         d_instantiate(dentry, inode);
         post_smfs_inode(dir, cache_dir);
 
         SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKDIR, handle, POST_HOOK, rc,
                   exit); 
 exit:
-        unlock_kernel();
+        //unlock_kernel();
+        smfs_trans_commit(dir, handle, 0);
         post_smfs_dentry(cache_dentry);
         post_smfs_dentry(cache_parent);
-        smfs_trans_commit(dir, handle, 0);
         RETURN(rc);
 }
 
@@ -385,20 +398,11 @@ static int smfs_rmdir(struct inode *dir, struct dentry *dentry)
         void *handle = NULL;
         int    rc = 0, mode = S_IFDIR;
 
-        if (!cache_dir)
+        ENTRY;
+        
+        if (!cache_dir || !cache_dir->i_op->rmdir)
                 RETURN(-ENOENT);
 
-        handle = smfs_trans_start(dir, FSFILT_OP_RMDIR, NULL);
-        if (IS_ERR(handle) ) {
-                CERROR("smfs_do_mkdir: no space for transaction\n");
-                RETURN(-ENOSPC);
-        }
-
-        lock_kernel();
-
-        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_RMDIR, handle, PRE_HOOK, rc, 
-                  exit); 
-
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry);
         cache_dentry = pre_smfs_dentry(cache_parent, cache_inode, dentry);
 
@@ -407,19 +411,32 @@ static int smfs_rmdir(struct inode *dir, struct dentry *dentry)
 
         pre_smfs_inode(dir, cache_dir);
         pre_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
-        if (cache_dir->i_op->rmdir)
-                rc = cache_dir->i_op->rmdir(cache_dir, cache_dentry);
+        
+        handle = smfs_trans_start(dir, FSFILT_OP_RMDIR, NULL);
+        if (IS_ERR(handle) ) {
+                CERROR("smfs_do_mkdir: no space for transaction\n");
+                GOTO(exit, rc = -ENOSPC);
+        }
 
+        //lock_kernel();
+
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_RMDIR, handle, PRE_HOOK, rc, 
+                  exit); 
+
+        rc = cache_dir->i_op->rmdir(cache_dir, cache_dentry);
+        if (rc)
+                GOTO(exit, rc);
+        
         post_smfs_inode(dir, cache_dir);
         post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
-        unlock_kernel();
+        //unlock_kernel();
         
         SMFS_HOOK(dir, dentry, &mode, NULL, HOOK_RMDIR, handle, POST_HOOK, 
                   rc, exit); 
 exit:
+        smfs_trans_commit(dir, handle, 0);
         post_smfs_dentry(cache_dentry);
         post_smfs_dentry(cache_parent);
-        smfs_trans_commit(dir, handle, 0);
         RETURN(rc);
 }
 
@@ -438,49 +455,49 @@ static int smfs_mknod(struct inode *dir, struct dentry *dentry,
         void *handle = NULL;
         int rc = 0;
 
-        if (!cache_dir)
+        ENTRY;
+        
+        if (!cache_dir || !cache_dir->i_op->mknod)
                 RETURN(-ENOENT);
 
-        handle = smfs_trans_start(dir, FSFILT_OP_MKNOD, NULL);
-        if (IS_ERR(handle)) {
-                CERROR("smfs_do_mkdir: no space for transaction\n");
-                RETURN(-ENOSPC);
-        }
-
-        lock_kernel();
-        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKNOD, handle, PRE_HOOK, rc, 
-                  exit); 
-        
         cache_parent = pre_smfs_dentry(NULL, cache_dir, dentry->d_parent);
         cache_dentry = pre_smfs_dentry(cache_parent, NULL, dentry);
+        
         if (!cache_parent || !cache_dentry)
                 GOTO(exit, rc = -ENOMEM);
 
         pre_smfs_inode(dir, cache_dir);
         pre_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
 
-        if (!cache_dir->i_op->mknod)
-                RETURN(-ENOENT);
+        handle = smfs_trans_start(dir, FSFILT_OP_MKNOD, NULL);
+        if (IS_ERR(handle)) {
+                CERROR("smfs_do_mkdir: no space for transaction\n");
+                GOTO(exit, rc = -ENOSPC);
+        }
 
-        if ((rc = cache_dir->i_op->mknod(cache_dir, cache_dentry,
-                                         mode, rdev)))
+        //lock_kernel();
+        SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKNOD, handle, PRE_HOOK, rc, 
+                  exit); 
+        
+        rc = cache_dir->i_op->mknod(cache_dir, cache_dentry, mode, rdev);
+        if (rc)
                 GOTO(exit, rc);
 
-        SMFS_GET_INODE(dir->i_sb, cache_dentry->d_inode, dir, inode, rc, exit); 
+        SMFS_IGET(dir, cache_dentry->d_inode->i_ino, inode, rc, exit); 
 
         d_instantiate(dentry, inode);
 
-        pre_smfs_inode(dir, cache_dir);
-        pre_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
+        post_smfs_inode(dir, cache_dir);
+        post_smfs_inode(dentry->d_inode, cache_dentry->d_inode);
 
         SMFS_HOOK(dir, dentry, NULL, NULL, HOOK_MKNOD, handle, POST_HOOK, rc, 
                   exit); 
         
 exit:
-        unlock_kernel();
+        //unlock_kernel();
+        smfs_trans_commit(dir, handle, 0);
         post_smfs_dentry(cache_dentry);
         post_smfs_dentry(cache_parent);
-        smfs_trans_commit(dir, handle, 0);
         RETURN(rc);
 }
 
@@ -501,20 +518,12 @@ static int smfs_rename(struct inode *old_dir, struct dentry *old_dentry,
         void *handle = NULL;
         int    rc = 0;
 
-        if (!cache_old_dir || !cache_new_dir || !cache_old_inode)
+        ENTRY;
+        
+        if (!cache_old_dir || !cache_new_dir || !cache_old_inode
+            || !cache_old_dir->i_op->rename)
                 RETURN(-ENOENT);
 
-        handle = smfs_trans_start(old_dir, FSFILT_OP_RENAME, NULL);
-        if (IS_ERR(handle)) {
-                CERROR("smfs_do_mkdir: no space for transaction\n");
-                RETURN(-ENOSPC);
-        }
-        lock_kernel();
-
-        
-        SMFS_HOOK(old_dir, old_dentry, new_dir, new_dentry, HOOK_RENAME,
-                  handle, PRE_HOOK, rc, exit); 
-        
         cache_old_parent = pre_smfs_dentry(NULL, cache_old_dir, old_dentry);
 
         cache_old_dentry = pre_smfs_dentry(cache_old_parent, cache_old_inode,
@@ -524,7 +533,6 @@ static int smfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                 GOTO(exit, rc = -ENOMEM);
 
         cache_new_parent = pre_smfs_dentry(NULL, cache_new_dir, new_dentry);
-        
         cache_new_dentry = pre_smfs_dentry(cache_new_parent, cache_new_inode,
                                            new_dentry);
 
@@ -534,25 +542,36 @@ 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 (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);
+        handle = smfs_trans_start(old_dir, FSFILT_OP_RENAME, NULL);
+        if (IS_ERR(handle)) {
+                CERROR("smfs_do_mkdir: no space for transaction\n");
+                GOTO(exit, rc = -ENOSPC);
+        }
+        //lock_kernel();
+        
+        SMFS_HOOK(old_dir, old_dentry, new_dir, new_dentry, HOOK_RENAME,
+                  handle, PRE_HOOK, rc, exit); 
+        
+        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 (new_dentry->d_inode)
+                post_smfs_inode(new_dentry->d_inode, cache_new_dentry->d_inode);
+        
         SMFS_HOOK(old_dir, old_dentry, new_dir, new_dentry, HOOK_RENAME, handle, 
                   POST_HOOK, rc, exit); 
         
-        if (new_dentry->d_inode)
-                post_smfs_inode(new_dentry->d_inode, cache_new_dentry->d_inode);
+
 exit:
-        unlock_kernel();
+        //unlock_kernel();
+        smfs_trans_commit(old_dir, handle, 0);
         post_smfs_dentry(cache_old_dentry);
         post_smfs_dentry(cache_old_parent);
         post_smfs_dentry(cache_new_dentry);
         post_smfs_dentry(cache_new_parent);
-        smfs_trans_commit(old_dir, handle, 0);
         RETURN(rc);
 }
 
@@ -579,28 +598,35 @@ static ssize_t smfs_read_dir(struct file *filp, char *buf,
         struct inode *cache_inode = NULL;
         struct smfs_file_info *sfi = NULL;
         loff_t tmp_ppos;
-        loff_t *cache_ppos;
+        loff_t *cache_ppos = NULL;
         int    rc = 0;
 
+        ENTRY;
+        
         cache_inode = I2CI(dentry->d_inode);
 
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_fop->read)
                 RETURN(-EINVAL);
 
         sfi = F2SMFI(filp);
-        if (sfi->magic != SMFS_FILE_MAGIC) BUG();
+        if (sfi->magic != SMFS_FILE_MAGIC)
+                BUG();
 
         if (ppos != &(filp->f_pos))
                 cache_ppos = &tmp_ppos;
         else
                 cache_ppos = &sfi->c_file->f_pos;
+        
         *cache_ppos = *ppos;
 
-        if (cache_inode->i_fop->read)
-                rc = cache_inode->i_fop->read(sfi->c_file, buf, size,
-                                              cache_ppos);
+        rc = cache_inode->i_fop->read(sfi->c_file, buf, size, cache_ppos);
+        if (rc)
+                RETURN(rc);
+
         *ppos = *cache_ppos;
+        
         duplicate_file(filp, sfi->c_file);
+        
         RETURN(rc);
 }
 
@@ -611,8 +637,10 @@ static int smfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
         struct smfs_file_info *sfi = NULL;
         int    rc = 0;
 
+        ENTRY;
+        
         cache_inode = I2CI(dentry->d_inode);
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_fop->readdir)
                 RETURN(-EINVAL);
 
         sfi = F2SMFI(filp);
@@ -621,13 +649,16 @@ static int smfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
         SMFS_HOOK(dentry->d_inode, filp, dirent, filldir, HOOK_READDIR, NULL, 
                   PRE_HOOK, rc, exit); 
         
-        if (cache_inode->i_fop->readdir)
-                rc = cache_inode->i_fop->readdir(sfi->c_file, dirent, filldir);
+        rc = cache_inode->i_fop->readdir(sfi->c_file, dirent, filldir);
+        CDEBUG(D_INODE,"readdir rc=%u\n",rc);
+        if (rc < 0)
+                RETURN(rc);
+
+        duplicate_file(filp, sfi->c_file);
 
         SMFS_HOOK(dentry->d_inode, filp, dirent, filldir, HOOK_READDIR, NULL, 
                   POST_HOOK, rc, exit);
         
-        duplicate_file(filp, sfi->c_file);
 exit:
         if (rc > 0)
                 rc = 0;
index 77e3651..0fd7997 100644 (file)
@@ -662,12 +662,9 @@ Fsfilt operations
 \layout Standard
 
 LVFS has fsfilt operations for SMFS.
- SMFS store copy of fsfilt operations from backstore filesystem, gets fsfilt
operations for itself and pass each call to backstore filesysem.
+ SMFS store copy of fsfilt operations from backstore filesystem.
If it gets fsfilt operations then it is passed to backstore filesysem.
  
-\layout Comment
-
-should I give more info?
 \layout Subsubsection
 
 Transactions handling
@@ -680,10 +677,7 @@ All hooks should be in the same transaction with backstore fs operation.
  stuff to it.
  To solve this SMFS pass transaction handler to plugin, so it can do transaction
  in right way.
-\layout Comment
-
-details?
+ Also plugin should provide method to calculate extra size for transaction.
 \layout Subsection
 
 Backstore filesystem
@@ -693,8 +687,7 @@ Initialization
 \layout Enumerate
 
 Backstore FS is mounted by SMFS while initialization, if mount is failed
- SMFS initialization is also failed (maybe in that case we need to mount
- backstore FS directly instead of SMFS?)
+ SMFS initialization is also failed.
 \layout Enumerate
 
 SMFS creates own superblock using backstore one and fsfilter operations
@@ -717,7 +710,13 @@ Inode operations
 SMFS creates own inode operations for each inode.
  When some operations in invoked SMFS calls real filesystem method to complete
  it.
- There are additional actions for making SMFS inode and real inode consistent.
+\layout Standard
+
+There are additional actions for making SMFS inode and real inode consistent.
+ These actions are needed before real operation to create artificial objects
+ and after - to copy changes from backfs inode.
 \layout Subsubsection
 
 File operations
@@ -725,7 +724,8 @@ File operations
 
 SMFS creates own filp, duplicate backstore FS filp and dentry.
  They are used in file operations following by backstore operation call.
+ To do file operations we create artificial file object before calling of
+ real operation.
 \layout Section
 
 
@@ -739,7 +739,7 @@ Backstore filesystem
 Next options is passed to smfs and descript backstore FS completely:
 \layout Standard
 
-smfs dev=/mnt type=ext3
+smfs dev=/mnt type=ldiskfs
 \layout Subsection
 
 SMFS plugins/upcalls
@@ -1387,6 +1387,127 @@ duplicate-sb(sb, backfs_sb);
 Inode operations
 \layout Standard
 
+Each inode operaion uses backfs inode structure, this structure is created
+ while several fs operations are invoked.
+ Logic of all operations is next:
+\layout Itemize
+
+There is smfs dentry for each operation passed as parameter
+\layout Itemize
+
+SMFS creates artificial dentries for using they in backstore fs operation
+\layout Itemize
+
+after operation there is backstore fs inode in backfs_dentry->d_inode
+\layout Itemize
+
+if SMFS inode not exits it is created here and connected to backfs inode
+\layout Itemize
+
+several fields are copied from backstore fs inode to smfs one
+\layout Itemize
+
+all artificial dentries are cleared.
+\layout Standard
+
+
+\emph on 
+Artificial dentry handling
+\layout LyX-Code
+
+struct dentry *pre_smfs_dentry(struct dentry *parent_dentry, struct inode
+ *cache_inode,
+\layout LyX-Code
+
+                               struct dentry *dentry) {
+\layout LyX-Code
+
+        struct dentry *cache_dentry = NULL;
+\layout LyX-Code
+
+        cache_dentry = d_alloc(parent_dentry, &dentry->d_name);
+\layout LyX-Code
+
+        if (!cache_dentry)
+\layout LyX-Code
+
+                RETURN(NULL);
+\layout LyX-Code
+
+        if (!parent_dentry)
+\layout LyX-Code
+
+                cache_dentry->d_parent = cache_dentry;
+\layout LyX-Code
+
+        if (cache_inode)
+\layout LyX-Code
+
+                d_add(cache_dentry, cache_inode);
+\layout LyX-Code
+
+        RETURN(cache_dentry);
+\layout LyX-Code
+
+}
+\layout LyX-Code
+
+\layout LyX-Code
+
+void post_smfs_dentry(struct dentry *cache_dentry) {
+\layout LyX-Code
+
+        if (!cache_dentry)
+\layout LyX-Code
+
+                return;
+\layout LyX-Code
+
+        d_unalloc(cache_dentry);
+\layout LyX-Code
+
+} 
+\layout Standard
+
+For inode operation we have parent inode and dentry for operation.
+ So SMFS has to create artificial parent dentry with backfs_inode connected
+ to it and artificial dentry for ext3 operation.
+ This is done with pre_smfs_dentry() method.
+\layout Standard
+
+After successfull creation SMFS will do backfs operation and gets filled
+ artificial dentry.
+ Next step is getting SMFS inode from cache using ext3 inode number.
+ If inode is found it is connected to smfs dentry and operation can be counted
+ as completed.
+ SMFS clean all artificial dentries and exits.
+\layout Standard
+
+
+\emph on 
+duplicate_inode details
+\layout Standard
+
+
+\begin_inset ERT
+status Open
+
+\layout Standard
+
+\backslash 
+lst{../../include/linux/lustre_smfs.h}{Duplicate
+\backslash 
+_inode()}{firstline=297,lastline=316}
+\end_inset 
+
+
+\layout Standard
+
+
+\emph on 
+Inode operations
+\layout Standard
+
 
 \begin_inset ERT
 status Open
@@ -1570,6 +1691,36 @@ lst{../../smfs/file.c}{Truncate()}{firstline=385,lastline=404}
 \layout Subsubsection
 
 File operations
+\layout Standard
+
+SMFS creates artificial struct file object for each SMFS file struct and
+ use it for backstore fs operations.
+ Backstore struct file is created in open() method and connected to private
+ field in smfs struct file.
+ This struct will be released in smfs_release().
+\layout Standard
+
+When created and modified this struct file is duplicated to smfs one:
+\layout Standard
+
+
+\emph on 
+duplicate_file
+\layout Standard
+
+
+\begin_inset ERT
+status Open
+
+\layout Standard
+
+\backslash 
+lst{../../include/linux/lustre_smfs.h}{duplicate
+\backslash 
+_file()}{firstline=343,lastline=362}
+\end_inset 
+
+
 \layout Paragraph
 
 Common case (write/read/llseek/mmap/ioctl/readdir)
@@ -1827,18 +1978,6 @@ Plugin commit transaction.
 
 Transaction MUST be commited where it was started.
  It is not allowed to start it in pre_hook and commit in post_hook.
-\layout Subsubsection
-
-Special case: write operation
-\layout Standard
-
-Write operation cannot be encapsulated in SMFS transaction because really
- this operation starts transactions for each prepare_write/commit_write
- so current transaction can be easily overflowed.
- At the moment SMFS do nothing with write, but plugin like KML do log for
- write operation.
- Therefore in case of crush we will not be able to restore KML log synced
- with FS operations.
 \layout Subsection
 
 Locking
index 75a5215..254d051 100644 (file)
@@ -753,6 +753,20 @@ int smfs_register_plugin (struct smfs_plugin *);
 
 SMFS will return 0 in case of successfull registration or error code otherwise.
  
+\layout Subsubsection*
+
+Plugin deregistration
+\layout Standard
+
+SMFS provide following method for deregistration:
+\layout LyX-Code
+
+void * smfs_deregister_plugin (int type);
+\layout Standard
+
+SMFS will return private plugin data from struct smfs_plugin in case of
+ successfull registration or NULL pointer otherwise.
 \layout Paragraph*
 
 Plugins operation
@@ -761,7 +775,7 @@ Plugins operation
 Plugin's hook function must have the same type:
 \layout LyX-Code
 
-typedef int smfs_hook_func (int opcode, void * parameter);
+typedef int (*smfs_plg_hook) (int opcode, void * parameter, void * plg_private);
 \layout Standard
 
 Parameter can contains:
@@ -785,6 +799,13 @@ opcode - hook code
 handle - fsfilt transaction if exists
 \layout Standard
 
+
+\emph on 
+Plg_private 
+\emph default 
+is private plugin data.
+\layout Standard
+
 There are opcodes for now:
 \layout LyX-Code
 
@@ -895,7 +916,7 @@ calculate size for transaction - if plugin will participate into transaction
 etc.
 \layout LyX-Code
 
-smfs_helper(int code, void * parameter);
+smfs_helper(int code, void * parameter, void * plg_private);
 \layout Standard
 
 Where 
index f427884..9ccb62b 100644 (file)
@@ -49,13 +49,13 @@ static ssize_t smfs_write(struct file *filp, const char *buf, size_t count,
         struct inode *cache_inode;
         struct smfs_file_info *sfi;
         loff_t tmp_ppos;
-        loff_t *cache_ppos;
+        loff_t *cache_ppos = NULL;
         int rc = 0;
         ENTRY;
 
         cache_inode = I2CI(filp->f_dentry->d_inode);
 
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_fop->write)
                 RETURN(-ENOENT);
 
         sfi = F2SMFI(filp);
@@ -68,6 +68,7 @@ static ssize_t smfs_write(struct file *filp, const char *buf, size_t count,
         else {
                 tmp_ppos = *ppos;
         }
+        
         SMFS_HOOK(filp->f_dentry->d_inode, filp->f_dentry, &count, &tmp_ppos,
                   HOOK_WRITE, NULL, PRE_HOOK, rc, exit);
 
@@ -76,17 +77,17 @@ static ssize_t smfs_write(struct file *filp, const char *buf, size_t count,
         } else {
                 cache_ppos = &sfi->c_file->f_pos;
         }
+        
         *cache_ppos = *ppos;
 
         pre_smfs_inode(filp->f_dentry->d_inode, cache_inode);
 
-        if (cache_inode->i_fop->write) {
-                rc = cache_inode->i_fop->write(sfi->c_file, buf,
-                                               count, cache_ppos);
-        }
-
+        rc = cache_inode->i_fop->write(sfi->c_file, buf, count,
+                                       cache_ppos);
+        
         SMFS_HOOK(filp->f_dentry->d_inode, filp->f_dentry, ppos, &count,
                   HOOK_WRITE, NULL, POST_HOOK, rc, exit);
+        
 exit:
         post_smfs_inode(filp->f_dentry->d_inode, cache_inode);
         *ppos = *cache_ppos;
@@ -104,7 +105,7 @@ int smfs_ioctl(struct inode * inode, struct file * filp,
         ENTRY;
 
         cache_inode = I2CI(filp->f_dentry->d_inode);
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_fop->ioctl)
                 RETURN(-ENOENT);
 
         sfi = F2SMFI(filp);
@@ -113,11 +114,8 @@ int smfs_ioctl(struct inode * inode, struct file * filp,
 
         pre_smfs_inode(inode, cache_inode);
 
-        if (cache_inode->i_fop->ioctl) {
-                rc = cache_inode->i_fop->ioctl(cache_inode,
-                                               sfi->c_file, cmd, arg);
-        }
-
+        rc = cache_inode->i_fop->ioctl(cache_inode, sfi->c_file, cmd, arg);
+        
         post_smfs_inode(inode, cache_inode);
         duplicate_file(filp, sfi->c_file);
 
@@ -130,13 +128,13 @@ static ssize_t smfs_read(struct file *filp, char *buf,
         struct        inode *cache_inode;
         struct  smfs_file_info *sfi;
         loff_t  tmp_ppos;
-        loff_t  *cache_ppos;
+        loff_t  *cache_ppos = NULL;
         ssize_t rc = 0;
 
         ENTRY;
 
         cache_inode = I2CI(filp->f_dentry->d_inode);
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_fop->read)
                 RETURN(-ENOENT);
 
         sfi = F2SMFI(filp);
@@ -152,11 +150,8 @@ static ssize_t smfs_read(struct file *filp, char *buf,
 
         pre_smfs_inode(filp->f_dentry->d_inode, cache_inode);
 
-        if (cache_inode->i_fop->read) {
-                rc = cache_inode->i_fop->read(sfi->c_file, buf,
-                                              count, cache_ppos);
-        }
-
+        rc = cache_inode->i_fop->read(sfi->c_file, buf, count, cache_ppos);
+        
         *ppos = *cache_ppos;
         post_smfs_inode(filp->f_dentry->d_inode, cache_inode);
         duplicate_file(filp, sfi->c_file);
@@ -175,7 +170,7 @@ static loff_t smfs_llseek(struct file *file,
         ENTRY;
 
         cache_inode = I2CI(file->f_dentry->d_inode);
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_fop->llseek)
                 RETURN(-ENOENT);
 
         sfi = F2SMFI(file);
@@ -184,11 +179,8 @@ static loff_t smfs_llseek(struct file *file,
 
         pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
 
-        if (cache_inode->i_fop->llseek) {
-                rc = cache_inode->i_fop->llseek(sfi->c_file,
-                                                offset, origin);
-        }
-
+        rc = cache_inode->i_fop->llseek(sfi->c_file, offset, origin);
+        
         post_smfs_inode(file->f_dentry->d_inode, cache_inode);
         duplicate_file(file, sfi->c_file);
 
@@ -215,8 +207,8 @@ static int smfs_mmap(struct file *file, struct vm_area_struct *vma)
                 inode->i_mapping = cache_inode->i_mapping;
 
         pre_smfs_inode(inode, cache_inode);
-        if (cache_inode->i_fop->mmap)
-                rc = cache_inode->i_fop->mmap(sfi->c_file, vma);
+        
+        rc = cache_inode->i_fop->mmap(sfi->c_file, vma);
 
         post_smfs_inode(inode, cache_inode);
         duplicate_file(file, sfi->c_file);
@@ -293,18 +285,18 @@ int smfs_open(struct inode *inode, struct file *filp)
         struct inode *cache_inode = NULL;
         int rc = 0;
         ENTRY;
-
+        
         cache_inode = I2CI(inode);
         if (!cache_inode)
                 RETURN(-ENOENT);
-
+        
         if ((rc = smfs_init_cache_file(inode, filp)))
                 RETURN(rc);
 
-        if (cache_inode->i_fop->open)
+        if (cache_inode->i_fop->open) {
                 rc = cache_inode->i_fop->open(cache_inode, F2CF(filp));
-
-        duplicate_file(filp, F2CF(filp));
+                duplicate_file(filp, F2CF(filp));
+        }
         RETURN(rc);
 }
 
@@ -318,19 +310,22 @@ int smfs_release(struct inode *inode, struct file *filp)
 
         cache_inode = I2CI(inode);
         if (!cache_inode)
-                RETURN(-ENOENT);
+               RETURN(-ENOENT);
+        
         if (filp) {
                 sfi = F2SMFI(filp);
                 if (sfi->magic != SMFS_FILE_MAGIC)
                         LBUG();
                 cache_file = sfi->c_file;
         }
+        
         if (cache_inode->i_fop->release)
                 rc = cache_inode->i_fop->release(cache_inode, cache_file);
 
         post_smfs_inode(inode, cache_inode);
 
         smfs_cleanup_cache_file(filp);
+        
         RETURN(rc);
 }
 
@@ -343,7 +338,7 @@ int smfs_fsync(struct file *file, struct dentry *dentry, int datasync)
         int rc = 0;
 
         cache_inode = I2CI(dentry->d_inode);
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_fop->fsync)
                 RETURN(-ENOENT);
         
         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
@@ -359,11 +354,9 @@ int smfs_fsync(struct file *file, struct dentry *dentry, int datasync)
 
         pre_smfs_inode(dentry->d_inode, cache_inode);
 
-        if (cache_inode->i_fop->fsync) {
-                rc = cache_inode->i_fop->fsync(cache_file,
-                                               cache_dentry, datasync);
+        rc = cache_inode->i_fop->fsync(cache_file,
+                                       cache_dentry, datasync);
         
-        }
         post_smfs_inode(dentry->d_inode, cache_inode);
         duplicate_file(file, cache_file);
         post_smfs_dentry(cache_dentry);
@@ -384,19 +377,14 @@ struct file_operations smfs_file_fops = {
 
 static void smfs_truncate(struct inode *inode)
 {
-        struct inode *cache_inode;
-
-        cache_inode = I2CI(inode);
+        struct inode *cache_inode = I2CI(inode);
 
-        if (!cache_inode)
-                return;
-
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_op->truncate)
                 return;
 
         pre_smfs_inode(inode, cache_inode);
-        if (cache_inode->i_op->truncate)
-                cache_inode->i_op->truncate(cache_inode);
+        
+        cache_inode->i_op->truncate(cache_inode);
 
         post_smfs_inode(inode, cache_inode);
 
@@ -411,7 +399,7 @@ int smfs_setattr(struct dentry *dentry, struct iattr *attr)
         int rc = 0;
 
         cache_inode = I2CI(dentry->d_inode);
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_op->setattr)
                 RETURN(-ENOENT);
 
         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
@@ -421,20 +409,24 @@ int smfs_setattr(struct dentry *dentry, struct iattr *attr)
         handle = smfs_trans_start(dentry->d_inode, FSFILT_OP_SETATTR, NULL);
         if (IS_ERR(handle) ) {
                 CERROR("smfs_do_mkdir: no space for transaction\n");
-                RETURN(-ENOSPC);
+                GOTO(exit, rc = -ENOSPC);
         }
 
         pre_smfs_inode(dentry->d_inode, cache_inode);
-
-        if (cache_inode->i_op->setattr)
-                rc = cache_inode->i_op->setattr(cache_dentry, attr);
+        
+        SMFS_HOOK(dentry->d_inode, dentry, attr, NULL, HOOK_SETATTR, NULL, 
+                  PRE_HOOK, rc, exit); 
+                  
+        rc = cache_inode->i_op->setattr(cache_dentry, attr);
+        
+        post_smfs_dentry(cache_dentry);
 
         SMFS_HOOK(dentry->d_inode, dentry, attr, NULL, HOOK_SETATTR, NULL, 
                   POST_HOOK, rc, exit); 
+
+        post_smfs_inode(dentry->d_inode, cache_inode);
                   
 exit:
-        post_smfs_inode(dentry->d_inode, cache_inode);
-        post_smfs_dentry(cache_dentry);
         smfs_trans_commit(dentry->d_inode, handle, 0);
         RETURN(rc);
 }
@@ -447,7 +439,7 @@ int smfs_setxattr(struct dentry *dentry, const char *name, const void *value,
         int rc = 0;
 
         cache_inode = I2CI(dentry->d_inode);
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_op->setxattr)
                 RETURN(-ENOENT);
 
         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
@@ -456,9 +448,8 @@ int smfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 
         pre_smfs_inode(dentry->d_inode, cache_inode);
 
-        if (cache_inode->i_op->setxattr)
-                rc = cache_inode->i_op->setxattr(cache_dentry, name, value,
-                                                 size, flags);
+        rc = cache_inode->i_op->setxattr(cache_dentry, name, value,
+                                         size, flags);
 
         post_smfs_inode(dentry->d_inode, cache_inode);
         post_smfs_dentry(cache_dentry);
@@ -474,7 +465,7 @@ int smfs_getxattr(struct dentry *dentry, const char *name, void *buffer,
         int rc = 0;
 
         cache_inode = I2CI(dentry->d_inode);
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_op->getattr)
                 RETURN(-ENOENT);
 
         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
@@ -483,9 +474,8 @@ int smfs_getxattr(struct dentry *dentry, const char *name, void *buffer,
 
         pre_smfs_inode(dentry->d_inode, cache_inode);
 
-        if (cache_inode->i_op->getattr)
-                rc = cache_inode->i_op->getxattr(cache_dentry, name, buffer,
-                                                 size);
+        rc = cache_inode->i_op->getxattr(cache_dentry, name, buffer,
+                                         size);
 
         post_smfs_inode(dentry->d_inode, cache_inode);
         post_smfs_dentry(cache_dentry);
@@ -500,7 +490,7 @@ ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
         int rc = 0;
 
         cache_inode = I2CI(dentry->d_inode);
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_op->listxattr)
                 RETURN(-ENOENT);
 
         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
@@ -509,8 +499,7 @@ ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
 
         pre_smfs_inode(dentry->d_inode, cache_inode);
 
-        if (cache_inode->i_op->listxattr)
-                rc = cache_inode->i_op->listxattr(cache_dentry, buffer, size);
+        rc = cache_inode->i_op->listxattr(cache_dentry, buffer, size);
 
         post_smfs_inode(dentry->d_inode, cache_inode);
         post_smfs_dentry(cache_dentry);
@@ -525,7 +514,7 @@ int smfs_removexattr(struct dentry *dentry, const char *name)
         int rc = 0;
 
         cache_inode = I2CI(dentry->d_inode);
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_op->removexattr)
                 RETURN(-ENOENT);
 
         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
@@ -534,8 +523,7 @@ int smfs_removexattr(struct dentry *dentry, const char *name)
 
         pre_smfs_inode(dentry->d_inode, cache_inode);
 
-        if (cache_inode->i_op->removexattr)
-                rc = cache_inode->i_op->removexattr(cache_dentry, name);
+        rc = cache_inode->i_op->removexattr(cache_dentry, name);
 
         post_smfs_inode(dentry->d_inode, cache_inode);
         post_smfs_dentry(cache_dentry);
index 8d89199..71474dd 100644 (file)
@@ -48,15 +48,16 @@ static void smfs_init_inode_info(struct inode *inode, void *opaque)
                 
                 /* getting backing fs inode. */
                 ino = sargs ? sargs->s_ino : inode->i_ino;
+                //ino = sargs->s_ino;
                 cache_inode = iget(S2CSB(inode->i_sb), ino); 
-
+                
                 OBD_ALLOC(inode->u.generic_ip,
                           sizeof(struct smfs_inode_info));
         
                 LASSERT(inode->u.generic_ip);
                 I2CI(inode) = cache_inode;
         
-                CDEBUG(D_INODE, "cache_inode i_count ino %lu i_count %d\n",
+                CDEBUG(D_INODE, "cache_inode %lu i_count %d\n",
                        cache_inode->i_ino, atomic_read(&cache_inode->i_count));
         
                 post_smfs_inode(inode, cache_inode);
@@ -75,14 +76,16 @@ static void smfs_clear_inode_info(struct inode *inode)
         if (I2SMI(inode)) {
                 struct inode *cache_inode = I2CI(inode);
 
+                CDEBUG(D_INODE, "Clear_info: cache_inode %lu\n", cache_inode->i_ino);
+
                 LASSERTF(((atomic_read(&cache_inode->i_count) == 1) || 
                           cache_inode == cache_inode->i_sb->s_root->d_inode),
-                         "inode %p cache inode %p %lu i_count %d != 0 \n", 
+                         "inode %p cache inode %p #%lu i_count %d != 1 \n", 
                          inode, cache_inode, cache_inode->i_ino, 
                          atomic_read(&cache_inode->i_count));
-
-                if (cache_inode != cache_inode->i_sb->s_root->d_inode)
-                        iput(cache_inode);
+                
+                //if (cache_inode != cache_inode->i_sb->s_root->d_inode)
+                iput(cache_inode);
                 
                 OBD_FREE(inode->u.generic_ip,
                          sizeof(struct smfs_inode_info));
@@ -90,6 +93,7 @@ static void smfs_clear_inode_info(struct inode *inode)
         }
 }
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
 static void smfs_read_inode2(struct inode *inode, void *opaque)
 {
         ENTRY;
@@ -106,7 +110,6 @@ static void smfs_read_inode2(struct inode *inode, void *opaque)
         EXIT;
 }
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
 static int smfs_test_inode(struct inode *inode, unsigned long ino, 
                            void *opaque)
 #else
@@ -115,12 +118,7 @@ static int smfs_test_inode(struct inode *inode, void *opaque)
 {
         struct smfs_iget_args *sargs = (struct smfs_iget_args*)opaque;
 
-        LASSERT(sargs);
-
-        if (!sargs)
-                return 1;
-
-        if (inode->i_ino != sargs->s_ino)
+        if (!sargs || (inode->i_ino != sargs->s_ino))
                 return 0;
         
 #ifdef CONFIG_SNAPFS
@@ -128,19 +126,6 @@ static int smfs_test_inode(struct inode *inode, void *opaque)
             !smfs_snap_test_inode(inode, opaque))
                 return 0;  
 #endif
-        if (I2SMI(inode)) {
-                struct inode *cache_inode = I2CI(inode);
-
-                /* this is needed to make symatry between smfs_put_inode(). */
-                LASSERT(cache_inode != NULL);
-                igrab(cache_inode);
-                
-                LASSERTF(cache_inode->i_ino == inode->i_ino, 
-                         "inode ino %lu != cache ino %lu",
-                         cache_inode->i_ino, inode->i_ino); 
-        } else {
-                smfs_init_inode_info(inode, opaque);
-        }
         
         return 1;
 }
@@ -148,7 +133,7 @@ static int smfs_test_inode(struct inode *inode, void *opaque)
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
 int smfs_set_inode(struct inode *inode, void *opaque)
 {
-        smfs_read_inode2(inode, opaque);
+        //smfs_read_inode2(inode, opaque);
         return 0;
 }
 
@@ -161,13 +146,16 @@ struct inode *smfs_iget(struct super_block *sb, ino_t hash,
         inode = iget5_locked(sb, hash, smfs_test_inode,
                              smfs_set_inode, sargs);
         if (inode) {
-                if (inode->i_state & I_NEW)
+                if (inode->i_state & I_NEW) {
+                        smfs_init_inode_info(inode, (void*)sargs);
                         unlock_new_inode(inode);
+                }
+                inode->i_ino = hash;
                 CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p) index %d "
                        "ino %d\n", inode->i_ino, inode->i_generation,
                        inode, sargs->s_index, sargs->s_ino);
-                inode->i_ino = hash;
         }
+        
         return inode;
 }
 #else
@@ -180,10 +168,8 @@ struct inode *smfs_iget(struct super_block *sb, ino_t hash,
         inode = iget4(sb, hash, smfs_test_inode, sargs);
         if (inode) {
                 struct inode *cache_inode = I2CI(inode);
-                LASSERTF((inode->i_ino == cache_inode->i_ino), 
-                         "inode %p ino %lu != cache inode %p ino %lu",
-                          inode, inode->i_ino, cache_inode, cache_inode->i_ino); 
-                CDEBUG(D_VFSTRACE, "inode: %lu/%u(%p)\n", inode->i_ino,
+                
+                CDEBUG(D_VFSTRACE, "new inode: %lu/%u(%p)\n", inode->i_ino,
                        inode->i_generation, inode);
         }
         return inode;
@@ -200,6 +186,8 @@ struct inode *smfs_get_inode(struct super_block *sb, ino_t hash,
         sargs.s_ino = hash; 
         sargs.s_inode = dir; 
         sargs.s_index = index;
+        CDEBUG(D_VFSTRACE, "get_inode: %lu\n", hash);
+
         inode = smfs_iget(sb, hash, &sargs);
 
         RETURN(inode);
@@ -219,10 +207,13 @@ static void smfs_write_inode(struct inode *inode, int wait)
 
         cache_inode = I2CI(inode);
         LASSERT(cache_inode != NULL);
+        
+        CDEBUG(D_INODE,"Write inode %lu\n",inode->i_ino);
 
         pre_smfs_inode(inode, cache_inode);
-        if (S2CSB(inode->i_sb)->s_op->write_inode)
-                S2CSB(inode->i_sb)->s_op->write_inode(cache_inode, wait);
+        
+        if (cache_inode->i_sb->s_op->write_inode)
+                cache_inode->i_sb->s_op->write_inode(cache_inode, wait);
         
         post_smfs_inode(inode, cache_inode);
         EXIT;
@@ -246,9 +237,9 @@ static void smfs_dirty_inode(struct inode *inode)
         post_smfs_inode(inode, cache_inode);
         EXIT;
 }
-
 static void smfs_put_inode(struct inode *inode)
 {
+#if 0
         struct inode *cache_inode;
         ENTRY;
 
@@ -272,6 +263,7 @@ static void smfs_put_inode(struct inode *inode)
                 smfs_clear_inode_info(inode);
         
         EXIT;
+#endif
 }
 
 static void smfs_clear_inode(struct inode *inode)
index c707388..19a32bb 100644 (file)
@@ -81,6 +81,7 @@ int get_opt(struct option **option, char **pos)
 
         if (!*opt_left)
                 return -ENODATA;
+        
         left = strchr(opt_left, ',');
         if (left == opt_left)
                 return -EINVAL;
@@ -122,5 +123,49 @@ int get_opt(struct option **option, char **pos)
         list_add(&tmp_opt->list, &option_list);
         if (*opt_left == ',') opt_left ++; /*after ','*/
         *option = tmp_opt;
+        printk("Option: %s=%s\n", tmp_opt->opt, tmp_opt->value);
         return 0;
 }
+
+char *smfs_options(char *data, char **devstr, char **namestr,
+                   char *opts, int *flags)  
+{
+        struct option *opt_value = NULL;
+        char   *pos;
+        
+        LASSERT(opts && flags);
+        init_option(data);
+        
+        while (!(get_opt(&opt_value, &pos))) {
+                if (!strcmp(opt_value->opt, "dev")) {
+                        if (devstr != NULL)
+                                *devstr = opt_value->value;
+                } else if (!strcmp(opt_value->opt, "type")) {
+                        if (namestr != NULL)
+                                *namestr = opt_value->value;
+                } else if (!strcmp(opt_value->opt, "kml")) {
+                        *flags |= SM_DO_REC;
+                } else if (!strcmp(opt_value->opt, "cache")) {
+                        *flags |= SM_CACHE_HOOK;
+                } else if (!strcmp(opt_value->opt, "snap")) {
+                        *flags |= SM_DO_COW;
+                } else if (!strcmp(opt_value->opt, "options")) {
+                        if (strlen(opts) == 0)
+                                sprintf((char *)opts + strlen(opts), "%s",
+                                        opt_value->value);
+                        else  
+                                sprintf((char *)opts + strlen(opts), ",%s",
+                                        opt_value->value);
+                } else {
+                        /* FIXME-WANGDI: how about the opt_value->value */
+                        if (strlen(opts) == 0)
+                                sprintf((char *)opts + strlen(opts), "%s",
+                                        opt_value->opt);
+                        else  
+                                sprintf((char *)opts + strlen(opts), ",%s",
+                                        opt_value->opt);
+                }
+        }
+        return pos;
+}
+
diff --git a/lustre/smfs/smfs_api.h b/lustre/smfs/smfs_api.h
new file mode 100644 (file)
index 0000000..ec73811
--- /dev/null
@@ -0,0 +1,110 @@
+/* SMFS plugin stuff */
+#define SMFS_PLG_DUMMY  0
+#define SMFS_PLG_KML    1
+#define SMFS_PLG_LRU    2
+#define SMFS_PLG_COW    3
+#define SMFS_PLG_MAX    4
+
+typedef int (*smfs_plg_hook)(int hook_code, void *arg, void * priv);
+typedef int (*smfs_plg_func) (int help_code, void *arg, void * priv);
+
+struct smfs_plugin {
+        struct list_head plg_list;
+        int              plg_type;
+
+        smfs_plg_hook    plg_pre_op;
+        smfs_plg_hook    plg_post_op;
+        smfs_plg_func    plg_helper;
+        void *           plg_private;
+};
+
+#define HOOK_CREATE       1
+#define HOOK_LOOKUP       2
+#define HOOK_LINK         3
+#define HOOK_UNLINK       4
+#define HOOK_SYMLINK      5
+#define HOOK_MKDIR        6
+#define HOOK_RMDIR        7
+#define HOOK_MKNOD        8
+#define HOOK_RENAME       9
+#define HOOK_SETATTR      10
+#define HOOK_WRITE        11
+#define HOOK_READDIR      12
+#define HOOK_MAX          13
+
+struct hook_data {
+        struct inode * dir;
+        struct dentry * dentry;
+        int ret_code;
+};
+
+struct hook_data_rename {
+        struct hook_data data;
+        struct inode * new_dir;
+        struct inode * new_dentry;
+};
+
+struct hook_data_readdir {
+        struct hook_data data;
+        struct file * filp;
+        void * dirent;
+        filldir_t filldir;
+};
+
+struct hook_data_setattr {
+        struct hook_data data;
+        struct iattr *attr;
+};
+
+
+#define SMFS_PRE_HOOK (op, data)                               \
+do {                                                           \
+        struct list_head *hlist = &smfs_plg_list;              \
+        struct smfs_plugin *plugin;                            \
+                                                               \
+        list_for_each_entry(plugin, hlist, plg_list) {         \
+                if (plugin->plg_pre_op)                        \
+                        plugin->plg_pre_op(op, data,           \
+                                           plg->plg_private);  \
+        }                                                      \
+} while(0)
+
+#define SMFS_POST_HOOK (op, data, rc)                          \
+do {                                                           \
+        struct list_head *hlist = &smfs_plg_list;              \
+        struct smfs_plugin *plugin;                            \
+                                                               \
+        list_for_each_entry(plugin, hlist, plg_list) {         \
+                if (plugin->plg_post_op)                       \
+                        plugin->plg_post_op(op, data,          \
+                                            plg->plg_private); \
+        }                                                      \
+} while(0)
+
+#define PLG_EXIT        0
+#define PLG_TRANS_SIZE  1
+#define PLG_TEST_INODE  2
+#define PLG_SET_INODE   3
+#define PLG_HELPER_MAX  4
+
+#define SMFS_PLG_HELP (op, data)                              \
+do {                                                          \
+        struct list_head *hlist = &smfs_plg_list;             \
+        struct smfs_plugin *plugin;                           \
+                                                              \
+        list_for_each_entry(plugin, hlist, plg_list) {        \
+                if (plugin->plg_helper)                       \
+                        plugin->plg_helper(op, data,          \
+                                           plg->plg_private); \
+        }                                                     \
+} while(0)
+
+int smfs_register_plugin(struct smfs_plugin *);
+void * smfs_deregister_plugin(int);
+
+
+
+
+
+
+
index 5b73d03..4eb565c 100644 (file)
@@ -24,7 +24,7 @@
 #ifndef __LINUX_SMFS_H
 #define __LINUX_SMFS_H
 
-//#include <linux/lustre_fsfilt.h>
+#include "smfs_api.h"
 #define SMFSDEV_NAME "/dev/smfsconf"
 #define SMFS_PSDEV_MINOR 250
 #define SMFS_PSDEV_MAJOR 10
@@ -278,19 +278,6 @@ static inline int get_active_entry(struct inode *dir, __u64 *active_entry)
                 rc = 0;
         RETURN(rc);
 }
-#define HOOK_CREATE       1
-#define HOOK_LOOKUP       2
-#define HOOK_LINK         3
-#define HOOK_UNLINK       4
-#define HOOK_SYMLINK      5
-#define HOOK_MKDIR        6
-#define HOOK_RMDIR        7
-#define HOOK_MKNOD        8
-#define HOOK_RENAME       9
-#define HOOK_SETATTR      10
-#define HOOK_WRITE        11 
-#define HOOK_READDIR      12
-#define HOOK_MAX          12 
 
 #define PRE_HOOK          0
 #define POST_HOOK         1
@@ -321,15 +308,12 @@ do {                                                                           \
                 GOTO(label, rc);                                               \
 } while(0)                                                                     \
 
-#define SMFS_GET_INODE(sb, cache_inode, dir, inode, rc, label)          \
+#define SMFS_IGET(dir, hash, inode, rc, label)          \
 do {                                                                    \
-        LASSERT(cache_inode);                                           \
-        inode = smfs_get_inode(sb, cache_inode->i_ino, dir, 0);         \
-        iput(cache_inode);                                              \
+        inode = smfs_get_inode(dir->i_sb, hash, dir, 0);         \
         if (!inode)                                                     \
                 GOTO(label, rc = -ENOENT);                              \
-} while(0)        
-
+} while(0)      
 
 #if CONFIG_SNAPFS
 int smfs_cow_init(struct super_block *sb);
index 55662ae..7c824fc 100644 (file)
 #include <linux/lustre_smfs.h>
 #include "smfs_internal.h"
 
-static char *smfs_options(char *data, char **devstr, 
-                          char **namestr, char *opts, 
-                          int *flags)  
-{
-        struct option *opt_value = NULL;
-        char   *pos;
-        
-        LASSERT(opts && flags);
-
-        while (!(get_opt(&opt_value, &pos))) {
-                if (!strcmp(opt_value->opt, "dev")) {
-                        if (devstr != NULL)
-                                *devstr = opt_value->value;
-                } else if (!strcmp(opt_value->opt, "type")) {
-                        if (namestr != NULL)
-                                *namestr = opt_value->value;
-                } else if (!strcmp(opt_value->opt, "kml")) {
-                        *flags |= SM_DO_REC;
-                } else if (!strcmp(opt_value->opt, "cache")) {
-                        *flags |= SM_CACHE_HOOK;
-                } else if (!strcmp(opt_value->opt, "snap")) {
-                        *flags |= SM_DO_COW;
-                } else if (!strcmp(opt_value->opt, "options")) {
-                        if (strlen(opts) == 0)
-                                sprintf((char *)opts + strlen(opts), "%s",
-                                        opt_value->value);
-                        else  
-                                sprintf((char *)opts + strlen(opts), ",%s",
-                                        opt_value->value);
-                } else {
-                        /* FIXME-WANGDI: how about the opt_value->value */
-                        if (strlen(opts) == 0)
-                                sprintf((char *)opts + strlen(opts), "%s",
-                                        opt_value->opt);
-                        else  
-                                sprintf((char *)opts + strlen(opts), ",%s",
-                                        opt_value->opt);
-                }
-        }
-        return pos;
-}
-
-struct super_block *smfs_get_sb_by_path(char *path, int len)
-{
-        struct super_block *sb;
-        struct nameidata nd;
-        int error = 0;
-
-        ENTRY;
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-        if (path_init(path, LOOKUP_FOLLOW, &nd)) {
-#else
-        if (path_lookup(path, LOOKUP_FOLLOW, &nd)) {
-#endif
-                error = path_walk(path, &nd);
-                if (error) {
-                        path_release(&nd);
-                        RETURN(NULL);
-                }
-        } else {
-                RETURN(NULL);
-        }
 
-        /* FIXME-WANGDI: add some check code here. */
-        sb = nd.dentry->d_sb;
-        path_release(&nd);
-        RETURN(sb);
-}
+struct list_head smfs_plg_list;
 
 static struct smfs_super_info *smfs_init_smb(struct super_block *sb)
 {
@@ -195,11 +128,11 @@ err_out:
 
 static int smfs_umount_cache(struct smfs_super_info *smb)
 {
-        struct dentry *root = smb->smsi_sb->s_root;
+        //struct dentry *root = smb->smsi_sb->s_root;
         
-        dput(root);
-        if (atomic_read(&root->d_inode->i_count) == 0)
-                igrab(root->d_inode); 
+        //dput(root);
+        //if (atomic_read(&root->d_inode->i_count) == 0)
+        //        igrab(root->d_inode); 
         
         mntput(smb->smsi_mnt);
         smfs_cleanup_sm_ops(smb);
@@ -218,6 +151,7 @@ static int smfs_init_hook_ops(struct smfs_super_info *smb)
 {
         ENTRY;
         INIT_LIST_HEAD(&smb->smsi_hook_list);
+        INIT_LIST_HEAD(&smfs_plg_list);
         RETURN(0); 
 }
 
@@ -238,7 +172,6 @@ static void smfs_cleanup_hook_ops(struct smfs_super_info *smb)
         } 
         EXIT;
 }
-
 static void smfs_cleanup_smb(struct super_block *sb)
 {
         struct smfs_super_info *smb;
@@ -290,6 +223,8 @@ static int smfs_init_hooks(struct super_block *sb)
         RETURN(0);
 }
 
+extern char* smfs_options(char*, char**, char**, char*, int *);
+
 int smfs_fill_super(struct super_block *sb, void *data, int silent)
 {
         struct inode *root_inode = NULL;
@@ -316,7 +251,6 @@ int smfs_fill_super(struct super_block *sb, void *data, int silent)
         memset((void *)page, 0, PAGE_SIZE);
         opts = (char *)page;
 
-        init_option(data);
         cache_data = smfs_options(data, &devstr, &typestr, opts, 
                                   &smb->smsi_flags); 
         if (*cache_data) {
@@ -339,6 +273,7 @@ int smfs_fill_super(struct super_block *sb, void *data, int silent)
         }
 
         duplicate_sb(sb, smb->smsi_sb);
+        sb->s_bdev = smb->smsi_sb->s_bdev;
         sm_set_sb_ops(smb->smsi_sb, sb);
 
         err = smfs_init_hook_ops(smb);
@@ -349,7 +284,7 @@ int smfs_fill_super(struct super_block *sb, void *data, int silent)
         }
         
         /* init the root_inode of smfs. */ 
-        dget(S2CSB(sb)->s_root);
+        //dget(S2CSB(sb)->s_root);
         root_ino = S2CSB(sb)->s_root->d_inode->i_ino;
         root_inode = smfs_get_inode(sb, root_ino, NULL, 0);
 
@@ -372,9 +307,10 @@ int smfs_fill_super(struct super_block *sb, void *data, int silent)
         CDEBUG(D_SUPER, "sb %lx, &sb->u.generic_sbp: %lx\n",
                (ulong)sb, (ulong)&sb->u.generic_sbp);
 #else
-        CDEBUG(D_SUPER, "sb %lx, &sb->s_fs_info: %lx\n",
-               (ulong)sb, (ulong)&sb->s_fs_info);
+        CDEBUG(D_SUPER, "sb %lx(%p), &sb->s_fs_info: %lx\n",
+               (ulong)sb, smb->smsi_sb, (ulong)&sb->s_fs_info);
 #endif
+        
 out_err:
         cleanup_option();
         if (err)
@@ -452,7 +388,8 @@ struct smfs_hook_ops *smfs_unregister_hook_ops(struct smfs_super_info *smb,
                         list_del(p);
                         RETURN(found);
                 }
-        } 
+        }
+
         RETURN(NULL);
 }
 
@@ -484,3 +421,50 @@ void smfs_trans_commit(struct inode *inode, void *handle, int force_sync)
                 fsfilt->fs_commit(inode->i_sb, inode, handle, force_sync);
 }
 
+
+int smfs_register_plugin(struct smfs_plugin * new_plugin) 
+{
+        struct smfs_plugin * plg = NULL;
+        struct list_head * plist = &smfs_plg_list;
+        
+        ENTRY;
+        
+        list_for_each_entry(plg, plist, plg_list) {
+                if (plg->plg_type == new_plugin->plg_type) {
+                        CWARN("Plugin is already registered\n");
+                        RETURN(-EEXIST);
+                }
+        }
+        
+        OBD_ALLOC(plg, sizeof(*plg));
+        if (!plg) {
+                CWARN("Cannot allocate memory for plugin\n");
+                RETURN(-ENOMEM);
+        }
+        
+        memcpy(plg, new_plugin, sizeof(*plg));
+        list_add_tail(&plg->plg_list, plist);
+                
+        RETURN(0);
+}
+
+void * smfs_deregister_plugin(int type)
+{
+        struct smfs_plugin * plg = NULL;
+        struct list_head * plist = &smfs_plg_list;
+        void * priv = NULL;
+        
+        ENTRY;
+        list_for_each_entry(plg, plist, plg_list) {
+                if (plg->plg_type == type) {
+                        list_del(&plg->plg_list);
+                        priv = plg->plg_private;
+                        OBD_FREE(plg, sizeof(*plg));
+                        break;
+                }
+        }
+                
+        RETURN(priv);
+}
+
+
index 69496e5..619b7b7 100644 (file)
@@ -42,19 +42,17 @@ static int smfs_readlink(struct dentry *dentry, char *buffer, int buflen)
 {
         struct inode *cache_inode = I2CI(dentry->d_inode);
         struct dentry *cache_dentry;
-        int rc = 0;
+        int rc = -ENOMEM;
         ENTRY;
 
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_op->readlink)
                 RETURN(-ENOENT);
 
         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
-        if (!cache_dentry)
-                GOTO(exit, rc = -ENOMEM);
-        if (cache_inode->i_op && cache_inode->i_op->readlink)
-                rc = cache_inode->i_op->readlink(cache_dentry, buffer, buflen);
-        GOTO(exit, rc);
-exit:
+        if (cache_dentry)
+                rc = cache_inode->i_op->readlink(cache_dentry, buffer, 
+                                                 buflen);
+        
         post_smfs_dentry(cache_dentry);
         return rc;
 }
@@ -63,21 +61,18 @@ static int smfs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
         struct inode *cache_inode = I2CI(dentry->d_inode);
         struct dentry *cache_dentry;
-        int rc = 0;
+        int rc = -ENOMEM;
         ENTRY;
 
-        if (!cache_inode)
+        if (!cache_inode || !cache_inode->i_op->follow_link)
                 RETURN(-ENOENT);
 
         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
-        if (!cache_dentry)
-                GOTO(exit, rc = -ENOMEM);
-
-        if (cache_inode->i_op && cache_inode->i_op->follow_link)
+        if (cache_dentry)
                 rc = cache_inode->i_op->follow_link(cache_dentry, nd);
-exit:
+
         post_smfs_dentry(cache_dentry);
-        return rc;
+        RETURN(rc);
 }
 
 struct inode_operations smfs_sym_iops = {
index 7a36c65..c9c6866 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
- *  lustre/smfs/inode.c
+ *  lustre/smfs/sysctl.c
  *  Lustre filesystem abstraction routines
  *
  *  Copyright (C) 2002, 2003 Cluster File Systems, Inc.