]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: fix file refs vs special files
authorSage Weil <sage@newdream.net>
Tue, 17 Mar 2009 19:54:03 +0000 (12:54 -0700)
committerSage Weil <sage@newdream.net>
Tue, 17 Mar 2009 20:11:43 +0000 (13:11 -0700)
Special inodes get their own fops, so we don't get a ceph_release
call.  Therefore, we need to drop any fmode refs we took in
ceph_init_file for those files (that is, any file where we don't
have i_fop->release set to ceph_release).

Add some BUG_ON's to ensure as much.

src/kernel/file.c

index 0c379bd18871dbb7531f4770e9393c46612d45a4..35abc32ca39b80d94159f60f0a2e3fde466db51c 100644 (file)
@@ -56,15 +56,35 @@ out:
 static int ceph_init_file(struct inode *inode, struct file *file, int fmode)
 {
        struct ceph_file_info *cf;
+       int ret = 0;
+
+       switch (inode->i_mode & S_IFMT) {
+       case S_IFREG:
+       case S_IFDIR:
+               dout(20, "init_file %p 0%o (regular)\n", inode, inode->i_mode);
+               cf = kzalloc(sizeof(*cf), GFP_NOFS);
+               if (cf == NULL) {
+                       ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
+                       return -ENOMEM;
+               }
+               cf->fmode = fmode;
+               file->private_data = cf;
+               BUG_ON(inode->i_fop->release != ceph_release);
+               break;
 
-       cf = kzalloc(sizeof(*cf), GFP_NOFS);
-       if (cf == NULL) {
+       default:
+               dout(20, "init_file %p 0%o (special)\n", inode, inode->i_mode);
+               /*
+                * we need to drop the open ref now, since we don't
+                * have .release set to ceph_release.
+                */
                ceph_put_fmode(ceph_inode(inode), fmode); /* clean up */
-               return -ENOMEM;
+               BUG_ON(inode->i_fop->release == ceph_release);
+
+               /* call the proper open fop */
+               ret = inode->i_fop->open(inode, file);          
        }
-       cf->fmode = fmode;
-       file->private_data = cf;
-       return 0;
+       return ret;
 }
 
 /*
@@ -766,4 +786,3 @@ const struct file_operations ceph_file_fops = {
        .unlocked_ioctl = ceph_ioctl,
 };
 
-