Whamcloud - gitweb
fixed a refcount bug for types.
[fs/lustre-release.git] / lustre / obdclass / class_obd.c
index ceb72c3..68d586f 100644 (file)
@@ -74,7 +74,7 @@ static int obd_class_open(struct inode * inode, struct file * file)
        if (dev >= MAX_OBD_DEVICES)
                return -ENODEV;
        obd_dev[dev].obd_refcnt++;
-       CDEBUG(D_PSDEV, "Refcount now %d\n", obd_dev[dev].obd_refcnt++);
+       CDEBUG(D_PSDEV, "Refcount now %d\n", obd_dev[dev].obd_refcnt);
 
         MOD_INC_USE_COUNT;
         EXIT;
@@ -94,12 +94,11 @@ static int obd_class_release(struct inode * inode, struct file * file)
                return -ENODEV;
        fsync_dev(inode->i_rdev);
        if (obd_dev[dev].obd_refcnt <= 0)
-               printk(KERN_ALERT "presto_psdev_release: refcount(%d) <= 0\n",
+               printk(KERN_ALERT "obd_class_release: refcount(%d) <= 0\n",
                       obd_dev[dev].obd_refcnt);
        obd_dev[dev].obd_refcnt--;
 
-       CDEBUG(D_PSDEV, "Refcount now %d\n", obd_dev[dev].obd_refcnt++);
-
+       CDEBUG(D_PSDEV, "Refcount now %d\n", obd_dev[dev].obd_refcnt);
         MOD_DEC_USE_COUNT;
 
         EXIT;
@@ -168,9 +167,11 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
        conn.oc_dev = obddev;
 
        switch (cmd) {
+       case TCGETS:
+               return -EINVAL;
        case OBD_IOC_ATTACH: {
                struct obd_type *type;
-               struct oic_attach input;
+               struct oic_generic input;
 
                /* have we attached a type to this device */
                if ( obddev->obd_type || (obddev->obd_flags & OBD_ATTACHED) ){
@@ -409,7 +410,7 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
 
                conn.oc_id = mvdata.conn_id;
 
-               err = obddev->obd_type->typ_ops->o_migrate(&conn, srcoa, tgtoa);
+               err = obddev->obd_type->typ_ops->o_migrate(&conn, tgtoa, srcoa);
 
                obd_free_oa(srcoa);
                obd_free_oa(tgtoa);
@@ -450,6 +451,7 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                       obddev->obd_type->typ_name);
                if ( !obddev->obd_type->typ_ops || 
                     !obddev->obd_type->typ_ops->o_setup ) {
+                       obddev->obd_type->typ_refcnt++;
                        obddev->obd_flags |= OBD_SET_UP;
                        return 0;
                }
@@ -760,9 +762,57 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
                return rc;
                
        }
-       default:
-               printk("invalid ioctl: cmd = %x, arg = %lx\n", cmd, arg);
-               return -ENOTTY;
+       default: {
+               struct obd_type *type;
+               struct oic_generic input;
+               void *karg;
+
+               /* get data structures */
+               err = copy_from_user(&input, (void *) arg, sizeof(input));
+               if (err) {
+                       EXIT;
+                       return err;
+               }
+
+               if ( (err = getdata(input.att_typelen + 1, &input.att_type))){
+                       EXIT;
+                       return err;
+               }
+
+               /* find the type */
+               err = -EINVAL;
+               type = obd_nm_to_type(input.att_type);
+               OBD_FREE(input.att_type, input.att_typelen + 1);
+               if ( !type ) {
+                       printk("Unknown obd type dev %d\n", dev);
+                       EXIT;
+                       return err;
+               }
+               
+               if ( !type->typ_ops->o_iocontrol ) {
+                       EXIT;
+                       return -EINVAL;
+               }
+               conn.oc_id = input.att_connid;
+               
+               CDEBUG(D_IOCTL, "Calling ioctl %x for type %s, len %d\n",
+                      cmd, type->typ_name, input.att_datalen);
+
+               /* get the generic data */
+               karg = input.att_data;
+               if ( (err = getdata(input.att_datalen, &karg)) ) {
+                       EXIT;
+                       return err;
+               }
+
+               err = type->typ_ops->o_iocontrol
+                       (cmd, &conn, input.att_datalen, 
+                        karg, input.att_data);
+               OBD_FREE(karg, input.att_datalen);
+
+               EXIT;
+               return err;
+       }
        }
 }