Whamcloud - gitweb
minor fix for snap_inode_init
[fs/lustre-release.git] / lustre / smfs / file.c
index fce003a..af1e1f5 100644 (file)
@@ -1,5 +1,25 @@
-/*
- * file.c
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  lustre/smfs/inode.c
+ *  Lustre filesystem abstraction routines
+ *
+ *  Copyright (C) 2004 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define DEBUG_SUBSYSTEM S_SM
 #include <linux/stat.h>
 #include <linux/unistd.h>
 #include <linux/pagemap.h>
-#include "smfs_internal.h" 
-
-static int smfs_readpage(struct file *file, 
-                        struct page *page)
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/obd_class.h>
+#include <linux/obd_support.h>
+#include <linux/lustre_lib.h>
+#include <linux/lustre_idl.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/lustre_smfs.h>
+
+#include "smfs_internal.h"
+
+static ssize_t smfs_write(struct file *filp, const char *buf, size_t count,
+                          loff_t *ppos)
 {
-       struct  inode *inode = page->mapping->host;
-       struct  inode *cache_inode;
-       struct page *cache_page = NULL;
-       int rc = 0; 
-
-       ENTRY;
-       
-       cache_inode = I2CI(inode);
-        if (!cache_inode)
-                RETURN(-ENOENT);
-       
-       cache_page = grab_cache_page(cache_inode->i_mapping, page->index);
-
-       if (!cache_page) 
-               GOTO(exit_release, rc = -ENOMEM);
+        struct inode *cache_inode;
+        struct smfs_file_info *sfi;
+        loff_t tmp_ppos;
+        loff_t *cache_ppos;
+        int rc = 0;
+        ENTRY;
 
-       if ((rc = cache_inode->i_mapping->a_ops->readpage(file, cache_page)))
-               GOTO(exit_release, 0);
-       
-       wait_on_page(cache_page);
+        cache_inode = I2CI(filp->f_dentry->d_inode);
 
-       if (!Page_Uptodate(cache_page))
-               GOTO(exit_release, rc = -EIO);
+        if (!cache_inode)
+                RETURN(-ENOENT);
 
-       memcpy(kmap(page), kmap(cache_page), PAGE_CACHE_SIZE);
+        sfi = F2SMFI(filp);
 
-       flush_dcache_page(page);
+        if (sfi->magic != SMFS_FILE_MAGIC) 
+                LBUG();
 
-       kunmap(cache_page);
-       page_cache_release(cache_page);
+        if (ppos != &(filp->f_pos)) {
+                cache_ppos = &tmp_ppos;
+        } else {
+                cache_ppos = &sfi->c_file->f_pos;
+        }
+        *cache_ppos = *ppos;
 
-exit:  
-       kunmap(page);
-       SetPageUptodate(page);
-       UnlockPage(page);
+        pre_smfs_inode(filp->f_dentry->d_inode, cache_inode);
 
-       RETURN(rc);
+        if (cache_inode->i_fop->write) {
+                rc = cache_inode->i_fop->write(sfi->c_file, buf,
+                                               count, cache_ppos);
+        }
 
-exit_release:
-       if (cache_page) 
-               page_cache_release(cache_page);
-       UnlockPage(page);
-       RETURN(rc);
+        SMFS_KML_POST(filp->f_dentry->d_inode, filp->f_dentry,
+                      ppos, &count, REINT_WRITE, "write", rc, exit);
+exit:
+        post_smfs_inode(filp->f_dentry->d_inode, cache_inode);
+        *ppos = *cache_ppos;
+        duplicate_file(filp, sfi->c_file);
+        RETURN(rc);
 }
 
-static int smfs_writepage(struct page *page)
+int smfs_ioctl(struct inode * inode, struct file * filp,
+               unsigned int cmd, unsigned long arg)
 {
+        struct        inode *cache_inode;
+        struct  smfs_file_info *sfi;
+        ssize_t rc = 0;
 
-       struct  inode *inode = page->mapping->host;
-       struct  inode *cache_inode;
-       int     rc;
-       
-       ENTRY;
-       
-       cache_inode = I2CI(inode);
+        ENTRY;
+
+        cache_inode = I2CI(filp->f_dentry->d_inode);
         if (!cache_inode)
                 RETURN(-ENOENT);
 
-       if (cache_inode->i_mapping->a_ops->writepage)
-               rc = cache_inode->i_mapping->a_ops->writepage(page);
-               
-        RETURN(rc);
-}
+        sfi = F2SMFI(filp);
+        if (sfi->magic != SMFS_FILE_MAGIC) 
+                LBUG();
 
-static int smfs_sync_page(struct page *page)
-{
-       struct inode *inode = page->mapping->host;
-       struct inode *cache_inode;
-       int    rc = 0;
-               
-       cache_inode = I2CI(inode);
-        if (!cache_inode)
-                RETURN(-ENOENT);
+        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);
+        }
 
-       if (cache_inode->i_mapping->a_ops->sync_page)
-               rc = cache_inode->i_mapping->a_ops->sync_page(page);
+        post_smfs_inode(inode, cache_inode);
+        duplicate_file(filp, sfi->c_file);
 
         RETURN(rc);
 }
 
-static int smfs_prepare_write(struct file *file, struct page *page,
-                              unsigned from, unsigned to)
+static ssize_t smfs_read(struct file *filp, char *buf,
+                         size_t count, loff_t *ppos)
 {
-       struct inode *inode = page->mapping->host;
-       struct inode *cache_inode;
-       int    rc = 0;
-               
-       cache_inode = I2CI(inode);
+        struct        inode *cache_inode;
+        struct  smfs_file_info *sfi;
+        loff_t  tmp_ppos;
+        loff_t  *cache_ppos;
+        ssize_t rc = 0;
+
+        ENTRY;
+
+        cache_inode = I2CI(filp->f_dentry->d_inode);
         if (!cache_inode)
                 RETURN(-ENOENT);
 
-       if (cache_inode->i_mapping->a_ops->prepare_write)
-               rc = cache_inode->i_mapping->a_ops->prepare_write(file, page, from, to);
+        sfi = F2SMFI(filp);
+        if (sfi->magic != SMFS_FILE_MAGIC) 
+                LBUG();
+
+        if (ppos != &(filp->f_pos)) {
+                cache_ppos = &tmp_ppos;
+        } 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->read) {
+                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);
 
         RETURN(rc);
 }
 
-static int smfs_commit_write(struct file *file, struct page *page,
-                             unsigned from, unsigned to)
+static loff_t smfs_llseek(struct file *file,
+                          loff_t offset,
+                          int origin)
 {
-       struct inode *inode = page->mapping->host;
-       struct inode *cache_inode;
-       int    rc = 0;
-               
-       cache_inode = I2CI(inode);
+        struct        inode *cache_inode;
+        struct  smfs_file_info *sfi;
+        ssize_t rc = 0;
+
+        ENTRY;
+
+        cache_inode = I2CI(file->f_dentry->d_inode);
         if (!cache_inode)
                 RETURN(-ENOENT);
 
-       if (cache_inode->i_mapping->a_ops->commit_write)
-               rc = cache_inode->i_mapping->a_ops->commit_write(file, page, from, to);
+        sfi = F2SMFI(file);
+        if (sfi->magic != SMFS_FILE_MAGIC) 
+                LBUG();
+
+        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);
+        }
+
+        post_smfs_inode(file->f_dentry->d_inode, cache_inode);
+        duplicate_file(file, sfi->c_file);
 
         RETURN(rc);
 }
 
-static int smfs_bmap(struct address_space *mapping, long block)
+static int smfs_mmap(struct file *file, struct vm_area_struct *vma)
 {
-       struct inode *inode = mapping->host;
-       struct inode *cache_inode;
-       int    rc = 0;
-               
-       cache_inode = I2CI(inode);
+        struct inode *inode = file->f_dentry->d_inode;
+        struct smfs_file_info *sfi;
+        struct inode *cache_inode = NULL;
+        int rc = 0;
+        ENTRY;
+
+        cache_inode = I2CI(inode);
         if (!cache_inode)
                 RETURN(-ENOENT);
 
-       if (cache_inode->i_mapping->a_ops->bmap)
-               rc = cache_inode->i_mapping->a_ops->bmap(mapping, block);
+        sfi = F2SMFI(file);
+        if (sfi->magic != SMFS_FILE_MAGIC)
+                LBUG();
+
+        if (cache_inode->i_mapping == &cache_inode->i_data)
+                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);
+
+        post_smfs_inode(inode, cache_inode);
+        duplicate_file(file, sfi->c_file);
 
         RETURN(rc);
 }
 
-static int smfs_flushpage(struct page *page, unsigned long offset) 
+static int smfs_init_cache_file(struct inode *inode, struct file *filp)
 {
-       struct inode *inode = page->mapping->host;
-       struct inode *cache_inode;
-       int    rc = 0;
-               
-       cache_inode = I2CI(inode);
-        if (!cache_inode)
-                RETURN(-ENOENT);
+        struct smfs_file_info *sfi = NULL;
+        struct file *cache_filp = NULL;
+        struct dentry *cache_dentry = NULL;
+        int rc = 0;
+        ENTRY;
+
+        OBD_ALLOC(sfi, sizeof(struct smfs_file_info));
+        if (!sfi)
+                RETURN(-ENOMEM);
+
+        cache_filp = get_empty_filp();
+        if (!cache_filp)
+                GOTO(err_exit, rc = -ENOMEM);
+
+        sfi->magic = SMFS_FILE_MAGIC;
 
-       if (cache_inode->i_mapping->a_ops->flushpage)
-               rc = cache_inode->i_mapping->a_ops->flushpage(page, offset);
+        cache_dentry = pre_smfs_dentry(NULL, I2CI(inode), filp->f_dentry);
+        if (!cache_dentry)
+                GOTO(err_exit, rc = -ENOMEM);
 
+        cache_filp->f_vfsmnt = filp->f_vfsmnt;
+
+        cache_filp->f_dentry = cache_dentry;
+        duplicate_file(cache_filp, filp);
+
+        sfi->c_file = cache_filp;
+
+        if (filp->private_data != NULL)
+                LBUG();
+
+        filp->private_data = sfi;
+
+        RETURN(rc);
+err_exit:
+        if (sfi)
+                OBD_FREE(sfi, sizeof(struct smfs_file_info));
+        if (cache_filp)
+                put_filp(cache_filp);
         RETURN(rc);
 }
 
-static int smfs_releasepage(struct page *page, int wait) 
+static int smfs_cleanup_cache_file(struct file *filp)
 {
-       struct inode *inode = page->mapping->host;
-       struct inode *cache_inode;
-       int    rc = 0;
-               
-       cache_inode = I2CI(inode);
-        if (!cache_inode)
-                RETURN(-ENOENT);
+        struct smfs_file_info *sfi = NULL;
+        int rc = 0;
+        ENTRY;
+
+        if (!filp)
+                RETURN(rc);
+        sfi = F2SMFI(filp);
+
+        post_smfs_dentry(sfi->c_file->f_dentry);
+
+        put_filp(sfi->c_file);
 
-       if (cache_inode->i_mapping->a_ops->releasepage)
-               rc = cache_inode->i_mapping->a_ops->releasepage(page, wait);
+        OBD_FREE(sfi, sizeof(struct smfs_file_info));
+
+        filp->private_data = NULL;
 
         RETURN(rc);
 }
 
-static int smfs_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf,
-                unsigned long blocknr, int blocksize) 
+int smfs_open(struct inode *inode, struct file *filp)
 {
-       struct inode *cache_inode;
-       int    rc = 0;
-               
-       cache_inode = I2CI(inode);
+        struct inode *cache_inode = NULL;
+        int rc = 0;
+        ENTRY;
+
+        cache_inode = I2CI(inode);
         if (!cache_inode)
                 RETURN(-ENOENT);
 
-       if (cache_inode->i_mapping->a_ops->direct_IO)
-               rc = cache_inode->i_mapping->a_ops->direct_IO(rw, cache_inode, iobuf,
-                                                             blocknr, blocksize);
+        if ((rc = smfs_init_cache_file(inode, filp)))
+                RETURN(rc);
+
+        pre_smfs_inode(inode, cache_inode);
+        if (cache_inode->i_fop->open)
+                rc = cache_inode->i_fop->open(cache_inode, F2CF(filp));
+
+        post_smfs_inode(inode, cache_inode);
+        duplicate_file(filp, F2CF(filp));
         RETURN(rc);
 }
 
-struct address_space_operations smfs_file_aops = {
-       readpage:       smfs_readpage,
-       writepage:      smfs_writepage,
-       sync_page:      smfs_sync_page,
-       prepare_write:  smfs_prepare_write,
-       commit_write:   smfs_commit_write,
-       bmap:           smfs_bmap,
-       flushpage:      smfs_flushpage,
-       releasepage:    smfs_releasepage,
-       direct_IO:      smfs_direct_IO, 
-};
-        
-/* instantiate a file handle to the cache file */
-void smfs_prepare_cachefile(struct inode *inode,
-                           struct file *file, 
-                           struct inode *cache_inode,
-                           struct file *cache_file,
-                           struct dentry *cache_dentry)
+int smfs_release(struct inode *inode, struct file *filp)
 {
-       ENTRY;
-       cache_file->f_pos = file->f_pos;
-        cache_file->f_mode = file->f_mode;
-        cache_file->f_flags = file->f_flags;
-        cache_file->f_count  = file->f_count;
-        cache_file->f_owner  = file->f_owner;
-       cache_file->f_error = file->f_error;
-       cache_file->f_op = inode->i_fop;
-       cache_file->f_dentry = cache_dentry;
-        cache_file->f_dentry->d_inode = cache_inode;
-       cache_file->f_vfsmnt = file->f_vfsmnt;
-       cache_file->private_data = file->private_data;
-       cache_file->f_it = file->f_it;
-       cache_file->f_reada = file->f_reada;
-       cache_file->f_ramax = file->f_ramax;
-       cache_file->f_raend = file->f_raend;
-       cache_file->f_ralen = file->f_ralen;
-       cache_file->f_rawin = file->f_rawin;
-       EXIT;
-}
-/* update file structs*/
-void smfs_update_file(struct file *file, 
-                     struct file *cache_file)
-{
-       ENTRY;
-       file->f_pos = cache_file->f_pos;
-        file->f_mode = cache_file->f_mode;
-        file->f_flags = cache_file->f_flags;
-        file->f_count  = cache_file->f_count;
-        file->f_owner  = cache_file->f_owner;
-       file->f_reada = cache_file->f_reada;
-       file->f_ramax = cache_file->f_ramax;
-       file->f_raend = cache_file->f_raend;
-       file->f_ralen = cache_file->f_ralen;
-       file->f_rawin = cache_file->f_rawin;
-       EXIT;
-}
+        struct inode *cache_inode = NULL;
+        struct file *cache_file = NULL;
+        struct smfs_file_info *sfi = NULL;
+        int rc = 0;
+        ENTRY;
 
-static ssize_t smfs_write (struct file *filp, const char *buf, 
-                          size_t count, loff_t *ppos)
-{
-       struct  inode *cache_inode;
-       struct  dentry *dentry = filp->f_dentry;
-       struct  inode *inode = dentry->d_inode;
-        struct  file open_file;
-       struct  dentry open_dentry;
-       loff_t  tmp_ppos;
-       loff_t  *cache_ppos;
-       int     rc = 0;
-       
-       ENTRY;
-       
-       cache_inode = I2CI(inode);
+        cache_inode = I2CI(inode);
         if (!cache_inode)
                 RETURN(-ENOENT);
-       
-       if (ppos != &(filp->f_pos)) {
-               cache_ppos = &tmp_ppos; 
-       } else {
-               cache_ppos = &open_file.f_pos; 
-       }
-       *cache_ppos = *ppos;
-       
-       smfs_prepare_cachefile(inode, filp, cache_inode, 
-                              &open_file, &open_dentry);
-       if (cache_inode->i_fop->write)
-               rc = cache_inode->i_fop->write(&open_file, buf, count, cache_ppos);
-       
-       *ppos = *cache_ppos;
-       duplicate_inode(cache_inode, inode);
-       smfs_update_file(filp, &open_file);
-
-       RETURN(rc);
+        if (filp) {
+                sfi = F2SMFI(filp);
+                if (sfi->magic != SMFS_FILE_MAGIC)
+                        LBUG();
+                cache_file = sfi->c_file;
+        }
+        pre_smfs_inode(inode, cache_inode);
+        if (cache_inode->i_fop->release)
+                rc = cache_inode->i_fop->release(cache_inode, cache_file);
+
+        post_smfs_inode(inode, cache_inode);
+        duplicate_file(filp, cache_file);
+
+        smfs_cleanup_cache_file(filp);
+        RETURN(rc);
 }
 
-int smfs_ioctl(struct inode * inode, struct file * filp, 
-              unsigned int cmd, unsigned long arg)
+int smfs_fsync(struct file *file, struct dentry *dentry, int datasync)
 {
-       struct  inode *cache_inode;
-       struct  dentry *dentry = filp->f_dentry;
-        struct  file open_file;
-       struct  dentry open_dentry;
-       ssize_t rc = 0;
-       
-       ENTRY;
-       
-       cache_inode = I2CI(dentry->d_inode);
+        struct smfs_file_info *sfi = NULL;
+        struct dentry *cache_dentry = NULL;
+        struct file *cache_file = NULL;
+        struct inode *cache_inode;
+        int rc = 0;
+
+        cache_inode = I2CI(dentry->d_inode);
         if (!cache_inode)
                 RETURN(-ENOENT);
+        
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
+        if (!cache_dentry)
+                RETURN(-ENOMEM);
+
+        if (file) {
+                sfi = F2SMFI(file);
+                if (sfi->magic != SMFS_FILE_MAGIC)
+                        LBUG();
+                cache_file = sfi->c_file;
+        } 
+
+        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);
+        
+        }
+        post_smfs_inode(dentry->d_inode, cache_inode);
+        duplicate_file(file, cache_file);
+        post_smfs_dentry(cache_dentry);
 
-       smfs_prepare_cachefile(inode, filp, cache_inode, 
-                              &open_file, &open_dentry);
-       
-       if (cache_inode->i_fop->ioctl)
-               rc = cache_inode->i_fop->ioctl(cache_inode, &open_file, cmd, arg);
-               
-       duplicate_inode(cache_inode, inode);
-       smfs_update_file(filp, &open_file);
         RETURN(rc);
 }
 
-static ssize_t smfs_read (struct file *filp, char *buf, 
-                         size_t count, loff_t *ppos)
+struct file_operations smfs_file_fops = {
+        llseek:         smfs_llseek,
+        read:           smfs_read,
+        write:          smfs_write,
+        ioctl:          smfs_ioctl,
+        mmap:           smfs_mmap,
+        open:           smfs_open,
+        release:        smfs_release,
+        fsync:          smfs_fsync,
+};
+
+static void smfs_truncate(struct inode *inode)
 {
-       struct  inode *cache_inode;
-       struct  dentry *dentry = filp->f_dentry;
-       struct  inode *inode = dentry->d_inode;
-        struct  file open_file;
-       struct  dentry open_dentry;
-       loff_t  tmp_ppos;
-       loff_t  *cache_ppos;
-       ssize_t rc = 0;
-       
-       ENTRY;
-       
-       cache_inode = I2CI(dentry->d_inode);
-        if (!cache_inode)
-                RETURN(-ENOENT);
+        struct inode *cache_inode;
 
-       if (ppos != &(filp->f_pos)) {
-               cache_ppos = &tmp_ppos; 
-       } else {
-               cache_ppos = &open_file.f_pos; 
-       }
-       *cache_ppos = *ppos;
-       
-       
-       smfs_prepare_cachefile(inode, filp, cache_inode, 
-                              &open_file, &open_dentry);
-
-       
-       if (cache_inode->i_fop->read)
-               rc = cache_inode->i_fop->read(&open_file, buf, count, cache_ppos);
-    
-       *ppos = *cache_ppos;
-       duplicate_inode(cache_inode, inode);
-       smfs_update_file(filp, &open_file);
-       RETURN(rc);
-}
+        cache_inode = I2CI(inode);
 
-static loff_t smfs_llseek(struct file *file, 
-                         loff_t offset, 
-                         int origin)
-{
-       struct  inode *cache_inode;
-       struct  dentry *dentry = file->f_dentry;
-        struct  file open_file;
-       struct  dentry open_dentry;
-       ssize_t rc = 0;
-       
-       ENTRY;
-       
-       cache_inode = I2CI(dentry->d_inode);
         if (!cache_inode)
-                RETURN(-ENOENT);
+                return;
 
-       smfs_prepare_cachefile(dentry->d_inode, file, cache_inode, 
-                              &open_file, &open_dentry);
-       
-       if (cache_inode->i_fop->llseek)
-               rc = cache_inode->i_fop->llseek(&open_file, offset, origin);
+        if (!cache_inode)
+                return;
 
-       duplicate_inode(cache_inode, dentry->d_inode);
-       smfs_update_file(file, &open_file);
-               
-        RETURN(rc);
+        pre_smfs_inode(inode, cache_inode);
+        if (cache_inode->i_op->truncate)
+                cache_inode->i_op->truncate(cache_inode);
+
+        post_smfs_inode(inode, cache_inode);
+
+        return;
 }
 
-static int smfs_mmap(struct file * file, struct vm_area_struct * vma)
+int smfs_setattr(struct dentry *dentry, struct iattr *attr)
 {
-       struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
-        struct inode *inode = mapping->host;
-        struct inode *cache_inode = NULL;
-        struct  file open_file;
-       struct  dentry open_dentry;
-       int    rc = 0;
+        struct inode *cache_inode;
+        struct dentry *cache_dentry;
+        void  *handle = NULL;
+        int rc = 0;
 
-       cache_inode = I2CI(inode);
+        cache_inode = I2CI(dentry->d_inode);
         if (!cache_inode)
                 RETURN(-ENOENT);
 
-       smfs_prepare_cachefile(inode, file, cache_inode, 
-                              &open_file, &open_dentry);
-       
-       if (cache_inode->i_fop->mmap)
-               rc = cache_inode->i_fop->mmap(&open_file, vma);
-       
-       duplicate_inode(cache_inode, inode);
-       smfs_update_file(file, &open_file);
-       
-       RETURN(rc);
-}
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
+        if (!cache_dentry)
+                RETURN(-ENOMEM);
 
-static int smfs_open(struct inode * inode, struct file * filp)
-{
-       struct inode *cache_inode = NULL;
-        struct  file open_file;
-       struct  dentry open_dentry;
-       int    rc = 0;
+        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);
+        }
 
-       cache_inode = I2CI(inode);
-        if (!cache_inode)
-                RETURN(-ENOENT);
+        pre_smfs_inode(dentry->d_inode, cache_inode);
 
-       smfs_prepare_cachefile(inode, filp, cache_inode, 
-                              &open_file, &open_dentry);
-       
-       if (cache_inode->i_fop->open)
-               rc = cache_inode->i_fop->open(cache_inode, &open_file);
-        
-       duplicate_inode(cache_inode, inode);
-       smfs_update_file(filp, &open_file);
-       
-       RETURN(rc);
+        if (cache_inode->i_op->setattr)
+                rc = cache_inode->i_op->setattr(cache_dentry, attr);
 
+        SMFS_KML_POST(dentry->d_inode, dentry, attr, NULL,
+                      REINT_SETATTR, "setattr", rc, exit);
+exit:
+        post_smfs_inode(dentry->d_inode, cache_inode);
+        post_smfs_dentry(cache_dentry);
+        smfs_trans_commit(dentry->d_inode, handle, 0);
+        RETURN(rc);
 }
-static int smfs_release(struct inode * inode, struct file * filp)
+
+int smfs_setxattr(struct dentry *dentry, const char *name, const void *value,
+                  size_t size, int flags)
 {
-       struct inode *cache_inode = NULL;
-        struct  file open_file;
-       struct  dentry open_dentry;
-       int    rc = 0;
+        struct inode *cache_inode;
+        struct dentry *cache_dentry;
+        int rc = 0;
 
-       cache_inode = I2CI(inode);
+        cache_inode = I2CI(dentry->d_inode);
         if (!cache_inode)
                 RETURN(-ENOENT);
-       
-       smfs_prepare_cachefile(inode, filp, cache_inode, 
-                              &open_file, &open_dentry);
 
-       if (cache_inode->i_fop->release)
-               rc = cache_inode->i_fop->release(cache_inode, &open_file);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
+        if (!cache_dentry)
+                RETURN(-ENOMEM);
 
-       duplicate_inode(cache_inode, inode);
-       smfs_update_file(filp, &open_file);
-        
-       RETURN(rc);
-}
-int smfs_fsync(struct file * file, 
-                     struct dentry *dentry, 
-                     int datasync)
-{
-       struct inode *inode = dentry->d_inode;
-       struct inode *cache_inode;
-        struct  file open_file;
-       struct  dentry open_dentry;
-       int    rc = 0;
+        pre_smfs_inode(dentry->d_inode, cache_inode);
 
-       cache_inode = I2CI(inode);
-        if (!cache_inode)
-                RETURN(-ENOENT);
-       
-       smfs_prepare_cachefile(inode, file, cache_inode, 
-                              &open_file, &open_dentry);
-
-       if (cache_inode->i_fop->fsync)
-               rc = cache_inode->i_fop->fsync(&open_file, &open_dentry, datasync);
-       
-       duplicate_inode(cache_inode, inode);
-       smfs_update_file(file, &open_file);
-       
-       RETURN(rc);
-}
+        if (cache_inode->i_op->setxattr)
+                rc = cache_inode->i_op->setxattr(cache_dentry, name, value,
+                                                 size, flags);
 
-struct file_operations smfs_file_fops = {
-       llseek:         smfs_llseek,
-       read:           smfs_read,
-       write:          smfs_write,
-       ioctl:          smfs_ioctl,
-       mmap:           smfs_mmap,
-       open:           smfs_open,
-       release:        smfs_release,
-       fsync:          smfs_fsync,
-};
+        post_smfs_inode(dentry->d_inode, cache_inode);
+        post_smfs_dentry(cache_dentry);
 
-static void smfs_prepare_cache_dentry(struct dentry *dentry, struct inode *inode)
-{
-       atomic_set(&dentry->d_count, 1);
-       dentry->d_vfs_flags = 0;
-       dentry->d_flags = 0;
-       dentry->d_inode = inode;
-       dentry->d_op = NULL;
-       dentry->d_fsdata = NULL;
-       dentry->d_mounted = 0;
-       INIT_LIST_HEAD(&dentry->d_hash);
-       INIT_LIST_HEAD(&dentry->d_lru);
-       INIT_LIST_HEAD(&dentry->d_subdirs);
-       INIT_LIST_HEAD(&dentry->d_alias);
+        RETURN(rc);
 }
 
-static void smfs_truncate(struct inode * inode)      
+int smfs_getxattr(struct dentry *dentry, const char *name, void *buffer,
+                  size_t size)
 {
-       struct  inode *cache_inode;
-
-       cache_inode = I2CI(inode);
+        struct inode *cache_inode;
+        struct dentry *cache_dentry;
+        int rc = 0;
 
-       if (!cache_inode)
-               return;
-       
-       if (cache_inode->i_op->truncate)
-               cache_inode->i_op->truncate(cache_inode);
+        cache_inode = I2CI(dentry->d_inode);
+        if (!cache_inode)
+                RETURN(-ENOENT);
 
-       duplicate_inode(inode, cache_inode);            
-        
-       return; 
-} 
-int smfs_setattr(struct dentry *dentry, struct iattr *attr)      
-{
-       struct  inode *cache_inode;
-       struct  dentry open_dentry;
-
-       int     rc = 0;
-
-       cache_inode = I2CI(dentry->d_inode);
-
-       if (!cache_inode) 
-               RETURN(-ENOENT);
-       smfs_prepare_cache_dentry(&open_dentry, cache_inode);
-       
-       if (cache_inode->i_op->setattr)
-               rc = cache_inode->i_op->setattr(&open_dentry, attr);
-
-       duplicate_inode(cache_inode, dentry->d_inode);          
-       
-       RETURN(rc);
-} 
-  
-int smfs_setxattr(struct dentry *dentry, const char *name,
-                 const void *value, size_t size, int flags)
-{
-       struct  inode *cache_inode;
-       struct  dentry open_dentry;
-       int     rc = 0;
-
-       cache_inode = I2CI(dentry->d_inode);
-
-       if (!cache_inode) 
-               RETURN(-ENOENT);
-
-       smfs_prepare_cache_dentry(&open_dentry, cache_inode);
-       
-       if (cache_inode->i_op->setattr)
-               rc = cache_inode->i_op->setxattr(&open_dentry, name, value, size, flags);
-
-       duplicate_inode(cache_inode, dentry->d_inode);          
-       RETURN(rc);
-} 
-                        
-int smfs_getxattr(struct dentry *dentry, const char *name,
-                 void *buffer, size_t size)
-{
-       struct  inode *cache_inode;
-       struct  dentry open_dentry;
-       int     rc = 0;
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
+        if (!cache_dentry)
+                RETURN(-ENOMEM);
 
-       cache_inode = I2CI(dentry->d_inode);
+        pre_smfs_inode(dentry->d_inode, cache_inode);
 
-       if (!cache_inode) 
-               RETURN(-ENOENT);
+        if (cache_inode->i_op->getattr)
+                rc = cache_inode->i_op->getxattr(cache_dentry, name, buffer,
+                                                 size);
 
-       smfs_prepare_cache_dentry(&open_dentry, cache_inode);
-       
-       if (cache_inode->i_op->setattr)
-               rc = cache_inode->i_op->getxattr(&open_dentry, name, buffer, size);
+        post_smfs_inode(dentry->d_inode, cache_inode);
+        post_smfs_dentry(cache_dentry);
 
-       duplicate_inode(cache_inode, dentry->d_inode);          
-       RETURN(rc);
+        RETURN(rc);
 }
 
 ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
 {
-       struct  inode *cache_inode;
-       struct  dentry open_dentry;
-       int     rc = 0;
+        struct inode *cache_inode;
+        struct dentry *cache_dentry;
+        int rc = 0;
 
-       cache_inode = I2CI(dentry->d_inode);
+        cache_inode = I2CI(dentry->d_inode);
+        if (!cache_inode)
+                RETURN(-ENOENT);
 
-       if (!cache_inode) 
-               RETURN(-ENOENT);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
+        if (!cache_dentry)
+                RETURN(-ENOMEM);
 
-       smfs_prepare_cache_dentry(&open_dentry, cache_inode);
-       
-       if (cache_inode->i_op->listxattr)
-               rc = cache_inode->i_op->listxattr(&open_dentry, buffer, size);
+        pre_smfs_inode(dentry->d_inode, cache_inode);
 
-       duplicate_inode(cache_inode, dentry->d_inode);          
-       RETURN(rc);
-}                                                                                                                                                           
+        if (cache_inode->i_op->listxattr)
+                rc = cache_inode->i_op->listxattr(cache_dentry, buffer, size);
+
+        post_smfs_inode(dentry->d_inode, cache_inode);
+        post_smfs_dentry(cache_dentry);
+
+        RETURN(rc);
+}
 
 int smfs_removexattr(struct dentry *dentry, const char *name)
 {
-       struct  inode *cache_inode;
-       struct  dentry open_dentry;
-       int     rc = 0;
+        struct inode *cache_inode;
+        struct dentry *cache_dentry;
+        int rc = 0;
+
+        cache_inode = I2CI(dentry->d_inode);
+        if (!cache_inode)
+                RETURN(-ENOENT);
 
-       cache_inode = I2CI(dentry->d_inode);
+        cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
+        if (!cache_dentry)
+                RETURN(-ENOMEM);
 
-       if (!cache_inode) 
-               RETURN(-ENOENT);
+        pre_smfs_inode(dentry->d_inode, cache_inode);
 
-       smfs_prepare_cache_dentry(&open_dentry, cache_inode);
-       
-       if (cache_inode->i_op->removexattr)
-               rc = cache_inode->i_op->removexattr(&open_dentry, name);
+        if (cache_inode->i_op->removexattr)
+                rc = cache_inode->i_op->removexattr(cache_dentry, name);
 
-       duplicate_inode(cache_inode, dentry->d_inode);          
-       RETURN(rc);
+        post_smfs_inode(dentry->d_inode, cache_inode);
+        post_smfs_dentry(cache_dentry);
+
+        RETURN(rc);
 }
 
 struct inode_operations smfs_file_iops = {
-       truncate:       smfs_truncate,          /* BKL held */
+        truncate:       smfs_truncate,          /* BKL held */
         setattr:        smfs_setattr,           /* BKL held */
         setxattr:       smfs_setxattr,          /* BKL held */
         getxattr:       smfs_getxattr,          /* BKL held */
         listxattr:      smfs_listxattr,         /* BKL held */
         removexattr:    smfs_removexattr,       /* BKL held */
 };
-