Whamcloud - gitweb
* Added a file handling snapshot tables
authorbraam <braam>
Mon, 6 Dec 1999 16:35:50 +0000 (16:35 +0000)
committerbraam <braam>
Mon, 6 Dec 1999 16:35:50 +0000 (16:35 +0000)
        * Added an ioctl system that allows ioctls to be made without
          specific devices being attached (pass method down).
        * Numerous small routines for snapshot handling.

lustre/include/linux/obd_class.h
lustre/include/linux/obd_snap.h
lustre/obdclass/class_obd.c
lustre/obdclass/obdcontrol

index 640f691..73acad6 100644 (file)
@@ -95,6 +95,7 @@ struct obd_ops {
        int  (*o_set_info)(struct obd_conn *, int keylen, void *key, int vallen, void *val);
        int (*o_migrate)(struct obd_conn *, obdattr *src, obdattr *dst);
        int (*o_copy)(struct obd_conn *dev, obdattr *source, obdattr *target);
+       int (*o_iocontrol)(int cmd, int len, void *karg, void *uarg);
 
 };
 
@@ -133,7 +134,7 @@ int gen_copy_data(struct obd_conn *, obdattr *source, obdattr *target);
 /*
  * ioctl commands
  */
-struct oic_attach {
+struct oic_generic {
        int  att_typelen;
        void *att_type;
        int  att_datalen;
index 4289bac..95ea117 100644 (file)
@@ -3,33 +3,61 @@
 
 #define OBD_SNAP_MAGIC 0x47224722
 
-#define SNAP_MAX  8 /* must fit in "u" area of struct inode */
+
+/* maximum number of snapshot tables we maintain in the kernel */
+#define SNAP_MAX_TABLES 8
+
+
+/* maximum number of snapshots per device 
+   must fit in "u" area of struct inode */
+#define SNAP_MAX  8 
+
+
+/* ioctls for manipulating snapshots 40 - 50 */
+#define OBD_SNAP_SETTABLE           _IOWR('f', 40, long)
+#define OBD_SNAP_PRINTTABLE           _IOWR('f', 41, long)
+
+
 
 /* if time is 0 this designates the "current" snapshot, i.e.
    the head of the tree 
 */
-
 struct snap {
        time_t time;
        int index;
 };
 
-/* snap ioctl data for attach */
+/* snap ioctl data for attach: current always in first slot of this array */
 struct snap_obd_data {
-       int snap_dev;             /* which device contains the data */
-       unsigned int snap_no;     /* which snapshot are we accessing */
-       unsigned int snap_count;  /* how many snapshots exist */
-       struct snap snap_snaps[SNAP_MAX]; /* times must be incr or attach will fail */
+       int          snap_dev;  /* which device contains the data */
+       unsigned int snap_index;/* which snapshot is ours */
+       unsigned int snap_table;/* which table do we use */
+};
+
+
+/* snap ioctl data for table fiddling */
+struct snap_table_data {
+       int             tblcmd_no;      /* which table */
+       unsigned int    tblcmd_count;   /* how many snaps */
+       struct snap     tblcmd_snaps[SNAP_MAX]; /* sorted times! */
+};
+
+
+struct snap_table {
+       spinlock_t          tbl_lock;
+       unsigned int tbl_count; /* how many snapshots exist in this table*/
+       int tbl_used;  /* bitmap of snaps in use by a device */
+       time_t tbl_times[SNAP_MAX];
+       int tbl_index[SNAP_MAX];
 };
 
 
-/* this is the obd device descriptor */
+/* this is the obd device descriptor: 
+   - current snapshot ends up in first slot of this array
+ */
 struct snap_obd {
-       unsigned int snap_no;    /* which snapshot index are we accessing */
-       unsigned int snap_current;
-       unsigned int snap_count; /* how many snapshots exist */
-       time_t snap_times[SNAP_MAX];
-       int snap_index[SNAP_MAX];
+       unsigned int snap_index;  /* which snapshot index are we accessing */
+       int snap_tableno;
 };
 
 
@@ -40,6 +68,12 @@ struct snap_object_data {
        unsigned long od_ids[SNAP_MAX + 1]; 
 };
 
+#define        this_snapidx(obd) (obd->u.snap.snap_index)
 
+extern int snap_iocontrol(int cmd, int len, void *karg, void *uarg);
+void snap_use(int table_no, int snap_index) ;
+void snap_unuse(int table_no, int snap_index) ;
+int snap_is_used(int table_no, int snap_index) ;
+int snap_table_attach(int tableno, int snap_index);
 
 #endif
index aab4274..eab54c9 100644 (file)
@@ -170,7 +170,7 @@ static int obd_class_ioctl (struct inode * inode, struct file * filp,
        switch (cmd) {
        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) ){
@@ -760,9 +760,55 @@ 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;
+               }
+
+               
+               CDEBUG(D_IOCTL, "Calling ioctl %x for type %s, len %d\n",
+                      cmd, type->typ_name, input.att_datalen);
+
+               /* get the generic data */
+               if ( (err = getdata(input.att_datalen, &karg)) ) {
+                       EXIT;
+                       return err;
+               }
+
+               err = type->typ_ops->o_iocontrol(cmd, input.att_datalen, 
+                                                karg, input.att_data);
+               OBD_FREE(karg, input.att_datalen);
+
+               EXIT;
+               return err;
+       }
        }
 }
 
index e866cc6..e4eebbe 100755 (executable)
@@ -61,6 +61,10 @@ eval 'sub OBD_IOC_COPY () { &_IOC(3, ord(\'f\'), 22, 4);}' unless
   defined(&OBD_IOC_COPY);
 eval 'sub OBD_IOC_MIGR () { &_IOC(3, ord(\'f\'), 23, 4);}' unless
   defined(&OBD_IOC_MIGR);
+eval 'sub OBD_SNAP_SETTABLE () { &_IOC(3, ord(\'f\'), 40, 4);}' unless
+  defined(&OBD_SNAP_SETTABLE);
+eval 'sub OBD_SNAP_PRINTTABLE () { &_IOC(3, ord(\'f\'), 41, 4);}' unless
+  defined(&OBD_SNAP_PRINTTABLE);
 
 eval 'sub ATTR_MODE () {1;}' unless defined(&ATTR_MODE);
 eval 'sub ATTR_UID () {2;}' unless defined(&ATTR_UID);
@@ -95,7 +99,10 @@ my %commands =
      'create' => {func => "Create", doc => "create: creates a new inode"},
      'attach' => {func => "Attach", doc => "attach type [adapter bus tid lun]"},
      'detach' => {func => "Detach", doc => "detach this device"},
-     'snapattach' => {func => "SnapAttach", doc => "snapattach snapno snapcount time1 index1 .... timek indexk"},
+     'snapattach' => {func => "SnapAttach", doc => "snapattach snapno table"},
+     'snapset' => {func => "SnapSetTable", doc => "snapset tableno file" },
+     'snapprint' => {func => "SnapPrint", doc => "snapprint tableno"},
+
      'snaptable' => {func => "SnapShotTable", doc => "snaptable: build a snapshot table (interactive)"},
      'copy' => {func => "Copy", doc => "copy srcid tgtid"},
      'migrate' => {func => "Migrate", doc => "migrate srcid tgtid"},
@@ -288,11 +295,35 @@ sub Detach {
 }
 
 
-sub SnapAttach {
+sub SnapPrint { 
     my $err = 0;
     my $type = "snap_obd";
-    my $snapdev = shift;
-    my $snapno = shift;
+    my $snaptableno = shift;
+
+    $data = pack("i", $snaptableno);
+    $datalen = 4;
+
+    my $len = length($type);
+    my $cl = length($data);
+    my $add = pack("p", $data);
+    print "type $type (len $len), datalen $datalen ($cl)\n";
+    my $packed = pack("ipip", length($type), $type, $datalen, $data);
+
+    my $rc = ioctl(DEV_OBD, &OBD_SNAP_PRINTTABLE, $packed);
+
+    if (!defined $rc) {
+       print STDERR "ioctl failed: $!\n";
+    } elsif ($rc eq "0 but true") {
+       print "Finished (success)\n";
+    } else {
+       print "ioctl returned error code $rc.\n";
+    }
+}
+
+sub SnapSetTable {
+    my $err = 0;
+    my $type = "snap_obd";
+    my $snaptableno = shift;
     my $file = shift;
     my $snapcount;
     my $table = {};
@@ -312,8 +343,8 @@ sub SnapAttach {
        print "No current snapshot in table! First make one\n";
        return ;
     }
-    $data = pack("iii", $snapdev, $snapno, $snapcount);
-    $datalen = 3 * 4;
+    $data = pack("ii", $snaptableno, $snapcount);
+    $datalen = 2 * 4;
     foreach my $time (sort keys %{$table}) {
        $data .= pack("Ii", $time, $table->{$time});
        $datalen += 8;
@@ -325,6 +356,42 @@ sub SnapAttach {
     print "type $type (len $len), datalen $datalen ($cl)\n";
     my $packed = pack("ipip", length($type), $type, $datalen, $data);
 
+    my $rc = ioctl(DEV_OBD, &OBD_SNAP_SETTABLE, $packed);
+
+    if (!defined $rc) {
+       print STDERR "ioctl failed: $!\n";
+    } elsif ($rc eq "0 but true") {
+       print "Finished (success)\n";
+    } else {
+       print "ioctl returned error code $rc.\n";
+    }
+}
+
+
+sub SnapAttach {
+    my $err = 0;
+    my $type = "snap_obd";
+    my $snapdev = shift;
+    my $snapno = shift;
+    my $tableno = shift;
+    my $snapcount;
+    my $data;
+    my $datalen = 0;
+
+    if ( ! -f $file ) {
+       print "No such file $file\n";
+    }
+
+    $table = ReadSnapShotTable($file);
+    $data = pack("iii", $snapdev, $snapno, $tableno);
+    $datalen = 3 * 4;
+
+    my $len = length($type);
+    my $cl = length($data);
+    my $add = pack("p", $data);
+    print "type $type (len $len), datalen $datalen ($cl)\n";
+    my $packed = pack("ipip", length($type), $type, $datalen, $data);
+
     my $rc = ioctl(DEV_OBD, &OBD_IOC_ATTACH, $packed);
 
     if (!defined $rc) {