Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / smfs / file.c
index 9ccb62b..88e3931 100644 (file)
 static ssize_t smfs_write(struct file *filp, const char *buf, size_t count,
                           loff_t *ppos)
 {
-        struct inode *cache_inode;
+        struct inode *cache_inode = I2CI(filp->f_dentry->d_inode);
         struct smfs_file_info *sfi;
-        loff_t tmp_ppos;
         loff_t *cache_ppos = NULL;
         int rc = 0;
+        struct hook_write_msg msg = {
+                .dentry = filp->f_dentry,
+                .count = count,
+                .pos = *ppos
+        };
+         
         ENTRY;
 
-        cache_inode = I2CI(filp->f_dentry->d_inode);
-
-        if (!cache_inode || !cache_inode->i_fop->write)
-                RETURN(-ENOENT);
+        LASSERT(cache_inode);
+        LASSERT(cache_inode->i_fop->write);
 
         sfi = F2SMFI(filp);
 
@@ -64,49 +67,43 @@ static ssize_t smfs_write(struct file *filp, const char *buf, size_t count,
                 LBUG();
 
         if (filp->f_flags & O_APPEND)
-                tmp_ppos = filp->f_dentry->d_inode->i_size;
-        else {
-                tmp_ppos = *ppos;
-        }
+                msg.pos = filp->f_dentry->d_inode->i_size;
         
-        SMFS_HOOK(filp->f_dentry->d_inode, filp->f_dentry, &count, &tmp_ppos,
-                  HOOK_WRITE, NULL, PRE_HOOK, rc, exit);
+        pre_smfs_inode(filp->f_dentry->d_inode, cache_inode);
+
+        SMFS_PRE_HOOK(filp->f_dentry->d_inode, HOOK_WRITE, &msg);
 
         if (ppos != &(filp->f_pos)) {
-                cache_ppos = &tmp_ppos;
+                cache_ppos = &msg.pos;
         } else {
                 cache_ppos = &sfi->c_file->f_pos;
         }
         
         *cache_ppos = *ppos;
 
-        pre_smfs_inode(filp->f_dentry->d_inode, cache_inode);
-
         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);
+        SMFS_POST_HOOK(filp->f_dentry->d_inode, HOOK_WRITE, &msg, rc);
         
-exit:
         post_smfs_inode(filp->f_dentry->d_inode, cache_inode);
         *ppos = *cache_ppos;
         duplicate_file(filp, sfi->c_file);
+        
         RETURN(rc);
 }
 
 int smfs_ioctl(struct inode * inode, struct file * filp,
                unsigned int cmd, unsigned long arg)
 {
-        struct        inode *cache_inode;
+        struct  inode *cache_inode = I2CI(filp->f_dentry->d_inode);
         struct  smfs_file_info *sfi;
         ssize_t rc = 0;
 
         ENTRY;
 
-        cache_inode = I2CI(filp->f_dentry->d_inode);
-        if (!cache_inode || !cache_inode->i_fop->ioctl)
-                RETURN(-ENOENT);
+        LASSERT(cache_inode);
+        LASSERT(cache_inode->i_fop->ioctl);
 
         sfi = F2SMFI(filp);
         if (sfi->magic != SMFS_FILE_MAGIC) 
@@ -125,7 +122,7 @@ int smfs_ioctl(struct inode * inode, struct file * filp,
 static ssize_t smfs_read(struct file *filp, char *buf,
                          size_t count, loff_t *ppos)
 {
-        struct        inode *cache_inode;
+        struct  inode *cache_inode = I2CI(filp->f_dentry->d_inode);
         struct  smfs_file_info *sfi;
         loff_t  tmp_ppos;
         loff_t  *cache_ppos = NULL;
@@ -133,9 +130,8 @@ static ssize_t smfs_read(struct file *filp, char *buf,
 
         ENTRY;
 
-        cache_inode = I2CI(filp->f_dentry->d_inode);
-        if (!cache_inode || !cache_inode->i_fop->read)
-                RETURN(-ENOENT);
+        LASSERT(cache_inode);
+        LASSERT(cache_inode->i_fop->read);
 
         sfi = F2SMFI(filp);
         if (sfi->magic != SMFS_FILE_MAGIC) 
@@ -159,19 +155,16 @@ static ssize_t smfs_read(struct file *filp, char *buf,
         RETURN(rc);
 }
 
-static loff_t smfs_llseek(struct file *file,
-                          loff_t offset,
-                          int origin)
+static loff_t smfs_llseek(struct file *file, loff_t offset, int origin)
 {
-        struct        inode *cache_inode;
+        struct  inode *cache_inode = I2CI(file->f_dentry->d_inode);
         struct  smfs_file_info *sfi;
         ssize_t rc = 0;
 
         ENTRY;
 
-        cache_inode = I2CI(file->f_dentry->d_inode);
-        if (!cache_inode || !cache_inode->i_fop->llseek)
-                RETURN(-ENOENT);
+        LASSERT(cache_inode);
+        LASSERT(cache_inode->i_fop->llseek);
 
         sfi = F2SMFI(file);
         if (sfi->magic != SMFS_FILE_MAGIC) 
@@ -191,14 +184,12 @@ static int smfs_mmap(struct file *file, struct vm_area_struct *vma)
 {
         struct inode *inode = file->f_dentry->d_inode;
         struct smfs_file_info *sfi;
-        struct inode *cache_inode = NULL;
+        struct inode *cache_inode = I2CI(inode);
         int rc = 0;
         ENTRY;
 
-        cache_inode = I2CI(inode);
-        if (!cache_inode)
-                RETURN(-ENOENT);
-
+        LASSERT(cache_inode);
+        
         sfi = F2SMFI(file);
         if (sfi->magic != SMFS_FILE_MAGIC)
                 LBUG();
@@ -229,20 +220,22 @@ static int smfs_init_cache_file(struct inode *inode, struct file *filp)
                 RETURN(-ENOMEM);
 
         cache_filp = get_empty_filp();
-        if (!cache_filp)
-                GOTO(err_exit, rc = -ENOMEM);
+        if (!cache_filp) {
+                rc = -ENOMEM;
+                goto err_exit;
+        }
 
         sfi->magic = SMFS_FILE_MAGIC;
 
         cache_dentry = pre_smfs_dentry(NULL, I2CI(inode), filp->f_dentry);
-        if (!cache_dentry)
-                GOTO(err_exit, rc = -ENOMEM);
+        if (!cache_dentry) {
+                rc = -ENOMEM;
+                goto err_exit;
+        }
 
         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)
@@ -250,7 +243,7 @@ static int smfs_init_cache_file(struct inode *inode, struct file *filp)
 
         filp->private_data = sfi;
 
-        RETURN(rc);
+        RETURN(0);
 err_exit:
         if (sfi)
                 OBD_FREE(sfi, sizeof(struct smfs_file_info));
@@ -262,11 +255,12 @@ err_exit:
 static int smfs_cleanup_cache_file(struct file *filp)
 {
         struct smfs_file_info *sfi = NULL;
-        int rc = 0;
+                
         ENTRY;
 
         if (!filp)
-                RETURN(rc);
+                RETURN(0);
+        
         sfi = F2SMFI(filp);
 
         post_smfs_dentry(sfi->c_file->f_dentry);
@@ -277,40 +271,40 @@ static int smfs_cleanup_cache_file(struct file *filp)
 
         filp->private_data = NULL;
 
-        RETURN(rc);
+        RETURN(0);
 }
 
 int smfs_open(struct inode *inode, struct file *filp)
 {
-        struct inode *cache_inode = NULL;
+        struct inode *cache_inode = I2CI(inode);
         int rc = 0;
+        
         ENTRY;
         
-        cache_inode = I2CI(inode);
-        if (!cache_inode)
-                RETURN(-ENOENT);
+        LASSERT(cache_inode);
         
         if ((rc = smfs_init_cache_file(inode, filp)))
                 RETURN(rc);
-
+        //it possible that backstore fs has no open(), 
+        //but we need it to init cache filp
         if (cache_inode->i_fop->open) {
                 rc = cache_inode->i_fop->open(cache_inode, F2CF(filp));
                 duplicate_file(filp, F2CF(filp));
         }
+
         RETURN(rc);
 }
 
 int smfs_release(struct inode *inode, struct file *filp)
 {
-        struct inode *cache_inode = NULL;
+        struct inode *cache_inode = I2CI(inode);
         struct file *cache_file = NULL;
         struct smfs_file_info *sfi = NULL;
         int rc = 0;
+        
         ENTRY;
 
-        cache_inode = I2CI(inode);
-        if (!cache_inode)
-               RETURN(-ENOENT);
+        LASSERT(cache_inode);
         
         if (filp) {
                 sfi = F2SMFI(filp);
@@ -334,12 +328,13 @@ int smfs_fsync(struct file *file, struct dentry *dentry, int datasync)
         struct smfs_file_info *sfi = NULL;
         struct dentry *cache_dentry = NULL;
         struct file *cache_file = NULL;
-        struct inode *cache_inode;
+        struct inode *cache_inode = I2CI(dentry->d_inode);
         int rc = 0;
 
-        cache_inode = I2CI(dentry->d_inode);
-        if (!cache_inode || !cache_inode->i_fop->fsync)
-                RETURN(-ENOENT);
+        ENTRY;
+        
+        LASSERT(cache_inode);
+        LASSERT(cache_inode->i_fop->fsync);
         
         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
@@ -393,14 +388,19 @@ static void smfs_truncate(struct inode *inode)
 
 int smfs_setattr(struct dentry *dentry, struct iattr *attr)
 {
-        struct inode *cache_inode;
+        struct inode *cache_inode = I2CI(dentry->d_inode);
         struct dentry *cache_dentry;
         void  *handle = NULL;
         int rc = 0;
+        struct hook_setattr_msg msg = {
+                .dentry = dentry,
+                .attr = attr
+        };
 
-        cache_inode = I2CI(dentry->d_inode);
-        if (!cache_inode || !cache_inode->i_op->setattr)
-                RETURN(-ENOENT);
+        ENTRY;
+        
+        LASSERT(cache_inode);
+        LASSERT(cache_inode->i_op->setattr);
 
         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
@@ -408,40 +408,37 @@ 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");
-                GOTO(exit, rc = -ENOSPC);
+                rc = -ENOSPC;
+                goto exit;
         }
 
         pre_smfs_inode(dentry->d_inode, cache_inode);
         
-        SMFS_HOOK(dentry->d_inode, dentry, attr, NULL, HOOK_SETATTR, NULL, 
-                  PRE_HOOK, rc, exit); 
+        SMFS_PRE_HOOK(dentry->d_inode, HOOK_SETATTR, &msg); 
                   
         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); 
-
+        SMFS_POST_HOOK(dentry->d_inode, HOOK_SETATTR, &msg, rc);
+        
         post_smfs_inode(dentry->d_inode, cache_inode);
-                  
-exit:
         smfs_trans_commit(dentry->d_inode, handle, 0);
+exit:
+        post_smfs_dentry(cache_dentry);
         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 *cache_dentry;
+        struct inode *cache_inode = I2CI(dentry->d_inode);
+        struct dentry *cache_dentry = NULL;
         int rc = 0;
 
-        cache_inode = I2CI(dentry->d_inode);
-        if (!cache_inode || !cache_inode->i_op->setxattr)
-                RETURN(-ENOENT);
-
+        ENTRY;
+        
+        LASSERT(cache_inode);
+        LASSERT(cache_inode->i_op->setxattr);
+        
         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
                 RETURN(-ENOMEM);
@@ -460,14 +457,15 @@ int smfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 int smfs_getxattr(struct dentry *dentry, const char *name, void *buffer,
                   size_t size)
 {
-        struct inode *cache_inode;
+        struct inode *cache_inode = I2CI(dentry->d_inode);
         struct dentry *cache_dentry;
         int rc = 0;
 
-        cache_inode = I2CI(dentry->d_inode);
-        if (!cache_inode || !cache_inode->i_op->getattr)
-                RETURN(-ENOENT);
-
+        ENTRY;
+        
+        LASSERT(cache_inode);
+        LASSERT(cache_inode->i_op->getxattr);
+        
         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
                 RETURN(-ENOMEM);
@@ -485,13 +483,14 @@ int smfs_getxattr(struct dentry *dentry, const char *name, void *buffer,
 
 ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
 {
-        struct inode *cache_inode;
+        struct inode *cache_inode = I2CI(dentry->d_inode);
         struct dentry *cache_dentry;
         int rc = 0;
 
-        cache_inode = I2CI(dentry->d_inode);
-        if (!cache_inode || !cache_inode->i_op->listxattr)
-                RETURN(-ENOENT);
+        ENTRY;
+        
+        LASSERT(cache_inode);
+        LASSERT(cache_inode->i_op->listxattr);
 
         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
@@ -509,13 +508,14 @@ ssize_t smfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
 
 int smfs_removexattr(struct dentry *dentry, const char *name)
 {
-        struct inode *cache_inode;
+        struct inode *cache_inode = I2CI(dentry->d_inode);
         struct dentry *cache_dentry;
         int rc = 0;
 
-        cache_inode = I2CI(dentry->d_inode);
-        if (!cache_inode || !cache_inode->i_op->removexattr)
-                RETURN(-ENOENT);
+        ENTRY;
+        
+        LASSERT(cache_inode);
+        LASSERT(cache_inode->i_op->removexattr);
 
         cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);
         if (!cache_dentry)
@@ -531,11 +531,41 @@ int smfs_removexattr(struct dentry *dentry, const char *name)
         RETURN(rc);
 }
 
+int smfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+        struct inode *cache_inode = I2CI(inode);
+        int rc = 0;
+
+        ENTRY;
+        
+        LASSERT(cache_inode);
+        LASSERT(cache_inode->i_op->permission);
+
+        pre_smfs_inode(inode, cache_inode);
+
+        rc = cache_inode->i_op->permission(cache_inode, mask, nd);
+
+        post_smfs_inode(inode, cache_inode);
+
+        RETURN(rc);
+}
+
 struct inode_operations smfs_file_iops = {
         .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 */
+        .setxattr       = smfs_setxattr,
+        .getxattr       = smfs_getxattr,
+        .listxattr      = smfs_listxattr,
+        .removexattr    = smfs_removexattr,
+        .permission     = smfs_permission,
 };
+
+struct inode_operations smfs_special_iops = {
+        .setattr        = smfs_setattr,           /* BKL held */
+        .setxattr       = smfs_setxattr,
+        .getxattr       = smfs_getxattr,
+        .listxattr      = smfs_listxattr,
+        .removexattr    = smfs_removexattr,
+        .permission     = smfs_permission,
+};
+