Whamcloud - gitweb
file export-do_kern_mount.patch was initially added on branch b1_5.
[fs/lustre-release.git] / lustre / llite / special.c
index e209697..46f2ab9 100644 (file)
@@ -77,9 +77,9 @@ static void save_fops(struct file *filp, struct inode *inode,
                 else if (S_ISFIFO(inode->i_mode))
                         filp->f_op = &ll_special_fifo_file_fops;
 
-                CWARN("saved %p, replaced with %p\n", *pfop, filp->f_op);
+                CDEBUG(D_INFO,"saved %p, replaced with %p\n", *pfop,filp->f_op);
                 if ((*pfop)->owner)
-                        CWARN("%p has owner %p\n", *pfop,(*pfop)->owner);
+                        CDEBUG(D_INFO,"%p has owner %p\n",*pfop,(*pfop)->owner);
         }
 }
 
@@ -155,8 +155,15 @@ static int ll_special_file_open(struct inode *inode, struct file *filp)
         struct file_operations **pfop = get_save_fops(filp, FILE_OPS);
         int rc = -EINVAL;
 
-        if (pfop && *pfop && (*pfop)->open)
-                rc = (*pfop)->open(inode, filp);
+        if (pfop && *pfop) {
+                fops_get(*pfop);
+
+                if ((*pfop)->open)
+                        rc = (*pfop)->open(inode, filp);
+
+                if (rc)
+                        fops_put(*pfop);
+        }
 
         RETURN(rc);
 }
@@ -195,6 +202,7 @@ static int ll_special_ioctl(struct inode *inode, struct file *filp,
                 struct file_operations *sfops = filp->f_op;
                        
                 rc = (*pfop)->ioctl(inode, filp, cmd, arg);
+
                 /* sometimes, file_operations will be changed in ioctl */
                 save_fops(filp, inode, sfops);
         }
@@ -259,12 +267,12 @@ static int ll_special_release_internal(struct inode *inode, struct file *filp,
         if (pfop && *pfop) {
                 if ((*pfop)->release)
                         rc = (*pfop)->release(inode, filp);
-                /* FIXME fops_put */
+                fops_put(*pfop);
         }
 
         lprocfs_counter_incr(sbi->ll_stats, LPROC_LL_RELEASE);
+        err = ll_md_close(sbi->ll_md_exp, inode, filp);
 
-        err = ll_mdc_close(sbi->ll_mdc_exp, inode, filp);
         if (err && rc == 0)
                 rc = err;
 
@@ -275,37 +283,98 @@ static int ll_special_open(struct inode *inode, struct file *filp)
 {
         struct file_operations **pfop = get_save_fops(filp, INODE_OPS);
         struct file_operations *sfops = filp->f_op;
+        struct ll_inode_info *lli = ll_i2info(inode);
         struct ptlrpc_request *req;
         struct lookup_intent *it;
         int rc = -EINVAL, err;
+        struct obd_client_handle **och_p;
+        __u64 *och_usecount;
         ENTRY;
 
+        it = filp->f_it;
+
+        if (LUSTRE_IT(it)->it_disposition) {
+                err = it_open_error(DISP_OPEN_OPEN, it);
+                if (err)
+                        RETURN(err);
+        }
+
         if (pfop && *pfop) {
-                /* FIXME fops_get */
+                /* mostly we will have @def_blk_fops here and it is not in a
+                 * module but we do this just to be sure. */
+                fops_get(*pfop);
+
                 if ((*pfop)->open) {
                         rc = (*pfop)->open(inode, filp);
 
-                        /* sometimes file_operations will be changed in open */
-                        save_fops(filp, inode, sfops);
+                        if (rc)
+                                fops_put(*pfop);
+                        else    /* sometimes ops will be changed in open */
+                                save_fops(filp, inode, sfops);
                 }
         }
 
+        /* Let's see if we have file open on MDS already. */
+        if (it->it_flags & FMODE_WRITE) {
+                och_p = &lli->lli_mds_write_och;
+                och_usecount = &lli->lli_open_fd_write_count;
+        } else if (it->it_flags & FMODE_EXEC) {
+                och_p = &lli->lli_mds_exec_och;
+                och_usecount = &lli->lli_open_fd_exec_count;
+         } else {
+                och_p = &lli->lli_mds_read_och;
+                och_usecount = &lli->lli_open_fd_read_count;
+        }
+
         lprocfs_counter_incr(ll_i2sbi(inode)->ll_stats, LPROC_LL_OPEN);
 
-        it = filp->f_it;
+        down(&lli->lli_och_sem);
+        if (*och_p) { /* Open handle is present */
+                if (LUSTRE_IT(it)->it_disposition) {
+                        struct obd_client_handle *och;
+                        /* Well, there's extra open request that we do not need,
+                           let's close it somehow*/
+                        OBD_ALLOC(och, sizeof (struct obd_client_handle));
+                        if (!och) {
+                                /* XXX We leak open fd and open OPEN connectioni
+                                   to server here */
+                                up(&lli->lli_och_sem);
+                                RETURN(-ENOMEM);
+                        }
+                        ll_och_fill(inode, it, och);
+                        /* ll_md_och_close() will free och */
+                        ll_md_och_close(ll_i2mdexp(inode), inode, och, 0, 0);
+                }       
+                (*och_usecount)++;        
+
+                err = ll_local_open(filp, it, NULL);
+        } else {
+                LASSERT(*och_usecount == 0);
+                OBD_ALLOC(*och_p, sizeof (struct obd_client_handle));
+                if (!*och_p) {
+                        // XXX Same as above
+                        up(&lli->lli_och_sem);
+                        RETURN(-ENOMEM);
+                }
+                (*och_usecount)++;
+
+                err = ll_local_open(filp, it, *och_p);
+        }
+        up(&lli->lli_och_sem);
 
-        err = ll_local_open(filp, it);
         if (rc != 0) {
-                CERROR("error opening special file: rc %d", rc);
-                ll_mdc_close(ll_i2sbi(inode)->ll_mdc_exp, inode, filp);
+                CERROR("error opening special file: rc %d\n", rc);
+                ll_md_close(ll_i2sbi(inode)->ll_md_exp, inode, filp);
         } else if (err) {
-                if (pfop && *pfop && (*pfop)->release)
-                        (*pfop)->release(inode, filp);
-                /* FIXME fops_put */
+                if (pfop && *pfop) {
+                        if ((*pfop)->release)
+                                (*pfop)->release(inode, filp);
+                        fops_put(*pfop);
+                }
                 rc = err;
         }
 
-        req = it->d.lustre.it_data;
+        req = LUSTRE_IT(it)->it_data;
         if (req)
                 ptlrpc_req_finished(req);
 
@@ -323,61 +392,67 @@ static int ll_special_file_release(struct inode *inode, struct file *filp)
 }
 
 struct inode_operations ll_special_inode_operations = {
-        setattr_raw:    ll_setattr_raw,
-        setattr:        ll_setattr,
+        .setattr        = ll_setattr,
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-        getattr_it:     ll_getattr,
+        .getattr        = ll_getattr,
 #else
-        revalidate_it:  ll_inode_revalidate_it,
+        .revalidate_it  = ll_inode_revalidate_it,
 #endif
+        .setxattr       = ll_setxattr,
+        .getxattr       = ll_getxattr,
+        .listxattr      = ll_listxattr,
+        .removexattr    = ll_removexattr,
+        .permission     = ll_inode_permission,
+        
 };
 
 struct file_operations ll_special_chr_inode_fops = {
-        owner:          THIS_MODULE,
-        open:           ll_special_open,
+        //FIXME .owner          = THIS_MODULE,
+        .open           = ll_special_open,
 };
 
 struct file_operations ll_special_blk_inode_fops = {
-        owner:          THIS_MODULE,
-        read:           ll_special_read,
-        write:          ll_special_write,
-        ioctl:          ll_special_ioctl,
-        open:           ll_special_open,
-        release:        ll_special_release,
-        mmap:           ll_special_mmap,
-        llseek:         ll_special_seek,
-        fsync:          ll_special_fsync,
+        //FIXME .owner          = THIS_MODULE,
+        .read           = ll_special_read,
+        .write          = ll_special_write,
+        .ioctl          = ll_special_ioctl,
+        .open           = ll_special_open,
+        .release        = ll_special_release,
+        .mmap           = ll_special_mmap,
+        .llseek         = ll_special_seek,
+        .fsync          = ll_special_fsync,
 };
 
 struct file_operations ll_special_fifo_inode_fops = {
-        owner:          THIS_MODULE,
-        open:           ll_special_open,
+        //FIXME .owner          = THIS_MODULE,
+        .open           = ll_special_open,
 };
 
 struct file_operations ll_special_sock_inode_fops = {
-        owner:          THIS_MODULE,
-        open:           ll_special_open
+        //FIXME .owner          = THIS_MODULE,
+        .open           = ll_special_open
 };
 
 struct file_operations ll_special_chr_file_fops = {
-        owner:          THIS_MODULE,
-       llseek:         ll_special_file_seek,
-       read:           ll_special_file_read,
-       write:          ll_special_file_write,
-       poll:           ll_special_file_poll,
-       ioctl:          ll_special_file_ioctl,
-       open:           ll_special_file_open,
-       release:        ll_special_file_release,
-       fasync:         ll_special_file_fasync,
+        //FIXME .owner          = THIS_MODULE,
+        .llseek         = ll_special_file_seek,
+        .read           = ll_special_file_read,
+        .write          = ll_special_file_write,
+        .poll           = ll_special_file_poll,
+        .ioctl          = ll_special_file_ioctl,
+        .open           = ll_special_file_open,
+        .release        = ll_special_file_release,
+        .fasync         = ll_special_file_fasync,
 };
 
 struct file_operations ll_special_fifo_file_fops = {
-        owner:          THIS_MODULE,
-       llseek:         ll_special_file_seek,
-       read:           ll_special_file_read,
-       write:          ll_special_file_write,
-       poll:           ll_special_file_poll,
-       ioctl:          ll_special_file_ioctl,
-       open:           ll_special_file_open,
-       release:        ll_special_file_release,
+        //FIXME .owner          = THIS_MODULE,
+        .llseek         = ll_special_file_seek,
+        .read           = ll_special_file_read,
+        .write          = ll_special_file_write,
+        .poll           = ll_special_file_poll,
+        .ioctl          = ll_special_file_ioctl,
+        .open           = ll_special_file_open,
+        .release        = ll_special_file_release,
 };
+