From: braam Date: Mon, 6 Dec 1999 16:35:50 +0000 (+0000) Subject: * Added a file handling snapshot tables X-Git-Tag: v1_7_100~6172 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=8690bd7639c7878861b04d8606609ac239c2cb76;ds=sidebyside * Added a file handling snapshot tables * Added an ioctl system that allows ioctls to be made without specific devices being attached (pass method down). * Numerous small routines for snapshot handling. --- diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index 640f691..73acad6 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -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; diff --git a/lustre/include/linux/obd_snap.h b/lustre/include/linux/obd_snap.h index 4289bac..95ea117 100644 --- a/lustre/include/linux/obd_snap.h +++ b/lustre/include/linux/obd_snap.h @@ -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 diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c index aab4274..eab54c9 100644 --- a/lustre/obdclass/class_obd.c +++ b/lustre/obdclass/class_obd.c @@ -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; + } } } diff --git a/lustre/obdclass/obdcontrol b/lustre/obdclass/obdcontrol index e866cc6..e4eebbe 100755 --- a/lustre/obdclass/obdcontrol +++ b/lustre/obdclass/obdcontrol @@ -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) {