#ifndef __LINUX_SNAPFS_H
#define __LINUX_SNAPFS_H
/* maximum number of snapshot tables we maintain in the kernel */
-#define SNAP_MAX_TABLES 32
+#define SNAP_MAX 32
+#define SNAP_MAX_TABLES 32
#define SNAP_MAX_NAMELEN 64
/* ioctls for manipulating snapshots 40 - 60 */
#define IOC_SNAP_MAX_NR 51
-
struct snap {
time_t time;
unsigned int index;
char name[SNAP_MAX_NAMELEN];
};
-/* snap ioctl data for table fiddling */
-struct snap_table_data {
- int tblcmd_no; /* which table */
- unsigned long dev;
- unsigned int tblcmd_count; /* how many snaps */
- struct snap tblcmd_snaps[0]; /* sorted times! */
-};
+
/*FIXME, use ioc_data temporary, will use obd_ioc_data later*/
struct ioc_data {
unsigned int ioc_inlen;
char *ioc_inbuf;
char ioc_bulk[0];
};
+
+/* snap ioctl data for table fiddling */
+struct ioc_snap_tbl_data {
+ int no; /* which table */
+ unsigned long dev;
+ unsigned int count; /* how many snaps */
+ struct snap snaps[0]; /* sorted times! */
+};
+
/* we have just a single snapshot control device
it contains a list of all the snap_current info's
*/
//#define OBD_OBDMDSZ 54
//#define SNAP_MAX ((OBD_OBDMDSZ - sizeof(uint32_t))/sizeof(snap_id))
-#define SNAP_MAX 50
/* if time is 0 this designates the "current" snapshot, i.e.
unsigned int snap_index;/* which snapshot is ours */
unsigned int snap_table;/* which table do we use */
};
-
-struct snap_table {
- struct semaphore tbl_sema;
- spinlock_t tbl_lock;
- unsigned int tbl_count; /* how many snapshots exist in this table*/
- unsigned int generation;
- struct snap snap_items[SNAP_MAX];
-};
#define DISK_SNAPTABLE_ATTR "Snaptable"
#define DISK_SNAP_TABLE_MAGIC 0x1976
struct snap_disk_table {
struct snap_disk snap_items[SNAP_MAX];
};
+/*Snap Table*/
+struct snap_table {
+ struct semaphore tbl_sema;
+ spinlock_t tbl_lock;
+ unsigned int tbl_count; /* how many snapshots exist in this table*/
+ unsigned int generation;
+ struct snap snap_items[SNAP_MAX];
+};
+
struct snap_iterdata {
kdev_t dev; /* snap current device number */
int index;
RETURN(index);
} /* snap_needs_cow */
-int snap_print_table(struct snap_table_data *data, char *buf, int *buflen)
+int snap_print_table(struct ioc_snap_tbl_data *data, char *buf, int *buflen)
{
struct snap_table *table;
- int tableno = data->tblcmd_no;
- int i, l, rc = 0, nleft = (*buflen);
+ struct ioc_snap_tbl_data *stbl_out;
+ int tableno = data->no;
+ int i, rc = 0, nleft = (*buflen);
+
char *buf_ptr;
- if ( tableno < 0 || tableno > SNAP_MAX_TABLES ) {
+ if (tableno < 0 || tableno > SNAP_MAX_TABLES) {
CERROR("invalid table number %d\n", tableno);
RETURN(-EINVAL);
}
-
+
table = &snap_tables[tableno];
-
- buf_ptr = buf;
- l = snprintf(buf_ptr, nleft, "snap table %d snap count %d \n",
- tableno, table->tbl_count);
- nleft -= l;
- if(nleft < 0) {
- CERROR("can not get enough space to print snaptable\n");
- rc = -ERANGE;
- goto exit;
- } else {
- buf_ptr += l;
- }
-
+ stbl_out = (struct ioc_snap_tbl_data *)buf;
+ stbl_out->count = table->tbl_count;
+ stbl_out->no = tableno;
+ buf_ptr = (char*)stbl_out->snaps;
+ nleft -= buf_ptr - buf;
for (i = 0; i < table->tbl_count; i++) {
- /*FIXME later, will convert time to time string later */
- l = snprintf(buf_ptr, nleft,
- "-- slot %d, idx %d, time %lu, name %s\n", i,
- table->snap_items[i+1].index, table->snap_items[i+1].time,
- &table->snap_items[i+1].name[0]);
+ memcpy(buf_ptr, &table->snap_items[i+1], sizeof(struct snap));
- nleft -= l;
+ nleft -= sizeof(struct snap);
if(nleft < 0) {
CERROR("can not get enough space to print snaptable\n");
rc = -ERANGE;
goto exit;
} else {
- buf_ptr += l;
+ buf_ptr += sizeof(struct snap);
}
}
exit:
if(nleft > 0)
(*buflen) = (*buflen) - nleft;
-
return 0;
}
-static int inline get_index_of_item(struct snap_table *table)
+static int inline get_index_of_item(struct snap_table *table, char *name)
{
int count = table->tbl_count;
int i, j;
-
- for (i = 0; i < SNAP_MAX; i ++) {
- for (j = 1; j < count; j++) {
- if (table->snap_items[j].index == i)
- break;
+
+ for (i = 0; i < SNAP_MAX; i++) {
+ if (!strcmp(name, table->snap_items[i].name))
+ return -EINVAL;
+ }
+ for (i = 0; i < SNAP_MAX; i++) {
+ int found = 0;
+ for (j = 0; j < (count + 1); j++) {
+ if (table->snap_items[j].index == i) {
+ found = 1;
+ break;
+ }
}
- if (j >= count)
+ if (!found)
return i;
}
return -EINVAL;
/* This function will write one item(a snapshot) to snaptable
* and will also write to disk.
*/
-int snaptable_add_item(struct snap_table_data *data)
+static int snaptable_add_item(struct ioc_snap_tbl_data *data)
{
struct snap_table *table;
struct snap_disk_table *disk_snap_table;
if (!snapops || !snapops->set_meta_attr)
RETURN(-EINVAL);
- tableno = data->tblcmd_no;
+ tableno = data->no;
if (tableno < 0 || tableno > SNAP_MAX_TABLES) {
CERROR("invalid table number %d\n", tableno);
RETURN(-EINVAL);
count = table->tbl_count;
/* XXX Is down this sema necessary*/
- //down_interruptible(&table->tbl_sema);
+ down_interruptible(&table->tbl_sema);
/*add item in snap_table*/
table->snap_items[count+1].gen = table->generation;
table->snap_items[count+1].time = CURRENT_TIME;
/* find table index */
- index = get_index_of_item(table);
+ index = get_index_of_item(table, data->snaps[0].name);
if (index < 0)
RETURN(-EINVAL);
-
+
table->snap_items[count+1].index = index;
table->snap_items[count+1].flags = 0;
memcpy(&table->snap_items[count + 1].name[0],
- &data->tblcmd_snaps[0].name[0], SNAP_MAX_NAMELEN);
+ data->snaps[0].name, SNAP_MAX_NAMELEN);
/* we will write the whole snap_table to disk */
SNAP_ALLOC(disk_snap_table, sizeof(struct snap_disk_table));
if (!disk_snap_table)
table->tbl_count++;
table->generation++;
- //up(&table->tbl_sema);
+ up(&table->tbl_sema);
return 0;
}
#define IOC_BUF_MAX_LEN 8192
static char rawbuf[IOC_BUF_MAX_LEN];
static char *buf = rawbuf;
-
/*FIXME add this temporary, will use obd_ioc_data later*/
-#define IOC_PACK(buffer, length) \
+#define IOC_INIT(ptr) \
+do{ \
+ struct ioc_data* pbuf; \
+ memset(buf, 0, sizeof(rawbuf)); \
+ pbuf = (struct ioc_data*)buf; \
+ pbuf->ioc_inbuf = pbuf->ioc_bulk; \
+ ptr = (struct ioc_snap_tbl_data *)pbuf->ioc_bulk; \
+} while(0)
+
+#define IOC_PACK(length) \
do{ \
struct ioc_data* pbuf; \
- memset(buf, 0, sizeof(rawbuf)); \
pbuf = (struct ioc_data*)buf; \
- pbuf->ioc_inbuf = pbuf->ioc_bulk; \
pbuf->ioc_inlen = length; \
- memcpy(pbuf->ioc_inbuf, buffer, length);\
} while (0)
static struct list_head snap_list;
release_snap_list();
return 0;
}
+static inline void print_snap_table(void * buf)
+{
+ struct ioc_snap_tbl_data *ptable;
+ int i;
+
+ ptable = (struct ioc_snap_tbl_data*)buf;
+
+ printf("There are %d snapshot in the system\n", ptable->count);
+ printf("index\t\tname\t\t\ttime\t\t\n");
+ for (i = 0; i < ptable->count; i++) {
+ struct tm* local_time;
+ char time[128];
+
+ memset (time, 0, sizeof(time));
+ local_time = localtime(&ptable->snaps[i].time);
+ if (local_time)
+ strftime(time, sizeof(time), "%a %b %d %Y %H:%M:%S", local_time);
+ printf("%-10d\t%-20s\t%s\n", ptable->snaps[i].index, ptable->snaps[i].name, time);
+ }
+}
int snap_snap_list(int argc, char **argv)
{
int i, rc = 0;
}
for (i = 0; i < open_device_table.count; i++) {
- struct snap_table_data snap_ioc_data;
-
+ struct ioc_snap_tbl_data *snap_ioc_data;
+
+ IOC_INIT(snap_ioc_data);
+
if (argc == 2) {
- snap_ioc_data.tblcmd_no = atoi(argv[1]);
+ snap_ioc_data->no = atoi(argv[1]);
} else {
- snap_ioc_data.tblcmd_no = 0;
+ snap_ioc_data->no = 0;
}
- IOC_PACK((char*)&snap_ioc_data, sizeof(struct snap_table_data));
+ IOC_PACK(sizeof(struct ioc_snap_tbl_data));
if ((rc = ioctl(open_device_table.device[i].fd,
IOC_SNAP_PRINTTABLE, buf))) {
&open_device_table.device[i].name[0], rc);
return (rc);
}
- printf("%s", ((struct ioc_data*)buf)->ioc_bulk);
+ if(((struct ioc_data*)buf)->ioc_bulk)
+ print_snap_table(((struct ioc_data*)buf)->ioc_bulk);
}
return rc;
}
return (-EINVAL);
}
for (i = 0; i < open_device_table.count; i++) {
- struct snap_table_data snap_ioc_data;
+ struct ioc_snap_tbl_data *snap_ioc_data;
+
+ IOC_INIT(snap_ioc_data);
- snap_ioc_data.tblcmd_count = 1;
- snap_ioc_data.dev = open_device_table.device[i].dev;
+ snap_ioc_data->count = 1;
+ snap_ioc_data->dev = open_device_table.device[i].dev;
if (argc == 3) {
- snap_ioc_data.tblcmd_no = atoi(argv[1]);
- memcpy(&snap_ioc_data.tblcmd_snaps[0].name[0],
+ snap_ioc_data->no = atoi(argv[1]);
+ memcpy(snap_ioc_data->snaps[0].name,
argv[2], strlen(argv[2]));
} else {
- snap_ioc_data.tblcmd_no = 0;
- memcpy(&snap_ioc_data.tblcmd_snaps[0].name[0],
+ snap_ioc_data->no = 0;
+ memcpy(snap_ioc_data->snaps[0].name,
argv[1], strlen(argv[1]));
}
- snap_ioc_data.tblcmd_snaps[0].time = time(NULL);
+ snap_ioc_data->snaps[0].time = time(NULL);
- IOC_PACK(&snap_ioc_data, sizeof(struct snap_table_data));
+ IOC_PACK(sizeof(struct ioc_snap_tbl_data) + sizeof(struct snap));
if ((rc = ioctl(open_device_table.device[i].fd,
- IOC_SNAP_ADD, buf))) {
- fprintf(stderr, "add snapshot %s failed %d \n",
- &open_device_table.device[i].name[0], rc);
+ IOC_SNAP_ADD, buf))) {
+ fprintf(stderr, "add %s failed \n", argv[1]);
} else {
- fprintf(stderr, "add snapshot %s success\n",
- &open_device_table.device[i].name[0]);
+ fprintf(stderr, "add %s success\n", argv[1]);
}
}
return rc;