Whamcloud - gitweb
remove unecessary debugging
[fs/lustre-release.git] / lustre / snapfs / snaptable.c
index 84c414b..5759058 100644 (file)
 
 struct snap_table snap_tables[SNAP_MAX_TABLES];
 
-#if 0
-static void snap_lock_table(int table_no)
-{
-
-       spin_lock(snap_tables[table_no].tbl_lock);
-
-}
-
-static void snap_unlock_table(int table_no)
-{
-
-       spin_unlock(snap_tables[table_no].tbl_lock);
-
-}
-#endif
-
 int snap_index2slot(struct snap_table *snap_table, int snap_index)
 {
        int slot;
 
-       for ( slot=0 ; slot<snap_table->tbl_count ; slot++ )
+       for ( slot=0 ; slot < snap_table->tbl_count ; slot++ )
                if ( snap_table->snap_items[slot].index == snap_index )
                        return slot;
        return -1;
@@ -133,12 +117,12 @@ int snap_print_table(struct ioc_snap_tbl_data *data, char *buf, int *buflen)
        
        table = &snap_tables[tableno];
        stbl_out = (struct ioc_snap_tbl_data *)buf;
-       stbl_out->count = table->tbl_count;
+       stbl_out->count = table->tbl_count - 1;
        stbl_out->no = tableno; 
        buf_ptr = (char*)stbl_out->snaps; 
        nleft -= buf_ptr - buf; 
-       for (i = 0; i < table->tbl_count; i++) {
-               memcpy(buf_ptr, &table->snap_items[i+1], sizeof(struct snap));
+       for (i = 1; i < table->tbl_count; i++) {
+               memcpy(buf_ptr, &table->snap_items[i], sizeof(struct snap));
                
                nleft -= sizeof(struct snap);
                if(nleft < 0) { 
@@ -205,35 +189,37 @@ static int snaptable_add_item(struct ioc_snap_tbl_data *data)
        /* XXX Is down this sema necessary*/
        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;
+       /*add item in snap_table set generation*/
+       table->snap_items[count].gen = table->generation + 1;
+       table->snap_items[count].time = CURRENT_TIME;
        /* find table index */
        index = get_index_of_item(table, data->snaps[0].name);
-       if (index < 0)
-               RETURN(-EINVAL);
+       if (index < 0) {
+               CERROR("snaptable full Or Duplicate name in snaptable\n");
+               GOTO(exit, rc = -EINVAL);
+       }
        
-       table->snap_items[count+1].index = index;
-       table->snap_items[count+1].flags = 0;
-       memcpy(&table->snap_items[count + 1].name[0], 
+       table->snap_items[count].index = index;
+       table->snap_items[count].flags = 0;
+       memcpy(&table->snap_items[count].name[0], 
               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)
-               RETURN(-ENOMEM);
+               GOTO(exit, rc = -ENOMEM);
        disk_snap_table->magic = cpu_to_le32((__u32)DISK_SNAP_TABLE_MAGIC);
        disk_snap_table->count = cpu_to_le32((__u32)table->tbl_count);
-       disk_snap_table->generation = cpu_to_le32((__u32)table->generation);
+       disk_snap_table->generation = cpu_to_le32((__u32)table->generation + 1);
        memset(&disk_snap_table->snap_items[0], 0, 
               SNAP_MAX * sizeof(struct snap_disk));
        
-       for (i = 1; i <= count + 1; i++) {
+       for (i = 1; i <= count; i++) {
                struct snap *item = &table->snap_items[i];
-               disk_snap_table->snap_items[i].time = cpu_to_le64((__u64)item->time);
-               disk_snap_table->snap_items[i].gen = cpu_to_le32((__u32)item->gen);
-               disk_snap_table->snap_items[i].flags = cpu_to_le32((__u32)item->flags);
-               disk_snap_table->snap_items[i].index = cpu_to_le32((__u32)item->index);
-               memcpy(&disk_snap_table->snap_items[i].name , item->name, SNAP_MAX_NAMELEN);
+               disk_snap_table->snap_items[i-1].time = cpu_to_le64((__u64)item->time);
+               disk_snap_table->snap_items[i-1].gen = cpu_to_le32((__u32)item->gen);
+               disk_snap_table->snap_items[i-1].flags = cpu_to_le32((__u32)item->flags);
+               disk_snap_table->snap_items[i-1].index = cpu_to_le32((__u32)item->index);
+               memcpy(&disk_snap_table->snap_items[i-1].name , item->name, SNAP_MAX_NAMELEN);
        }
        rc = snapops->set_meta_attr(cache->cache_sb, DISK_SNAPTABLE_ATTR,
                                    (char*)disk_snap_table, sizeof(struct snap_disk_table));
@@ -241,10 +227,9 @@ static int snaptable_add_item(struct ioc_snap_tbl_data *data)
        SNAP_FREE(disk_snap_table, sizeof(struct snap_disk_table));
        table->tbl_count++;
        table->generation++;
-       
+exit:
        up(&table->tbl_sema);
-       
-       return 0;
+       RETURN(rc);
 }
 
 static int delete_inode(struct inode *primary, void *param)
@@ -263,67 +248,68 @@ static int delete_inode(struct inode *primary, void *param)
        struct inode *next_ind = NULL;
        int my_table[SNAP_MAX];
 
-       if(!primary) return 0;
+       ENTRY;
+
+       if(!primary) RETURN(0);
 
        data = (struct snap_iterdata*) param;
 
-       if(data) {
+       if (data) {
                index = data->index;
                tableno = data->tableno;
        }
 
-       CDEBUG(D_INODE, "delete_inode ino %lu, index %d\n", primary->i_ino, index);
+       CDEBUG(D_SNAP, "delete_inode ino %lu, index %d\n", primary->i_ino, index);
 
        table = &snap_tables[tableno];
 
        redirect = snap_get_indirect(primary, NULL, index);
 
-       if(!redirect)   
-               return 0;
-
+       if (!redirect) {
+               CDEBUG(D_SNAP, "redirect inode index %d not exist \n", index);
+               RETURN(0); 
+       }
        old_ind = redirect->i_ino;
        iput(redirect);
+
+       /* In destroy indirect inode, we lock the primary inode here */
+       down(&primary->i_sem);  
        slot = snap_index2slot(table, index) - 1;
-       if( slot > 0 ) {
+       if (slot > 0) {
                this_index = table->snap_items[slot].index;
                redirect = snap_get_indirect(primary, NULL, this_index);
-               if(redirect)    
+               if (redirect) { 
                        iput(redirect);
-               else  {
+               } else {
                        snap_set_indirect(primary, old_ind, this_index, 0);
                        snap_set_indirect(primary, 0, index, 0);
-                       return 0;
+                       up(&primary->i_sem);            
+                       RETURN(0);
                }
        }
-
-       /* get the FIRST index after this and before NOW */
-       /* used for destroy_indirect and block level cow */
-       /* XXX fix this later, now use tbl_count, not NOW */
+       
        delete_slot = snap_index2slot(table, index);
-       for(slot = table->tbl_count; slot > delete_slot; slot --)
-       {
+       for (slot = table->tbl_count - 1; slot > delete_slot; slot --) {
                my_table[slot - delete_slot] = table->snap_items[slot].index;
        }
-       next_ind = snap_get_indirect 
-               (primary, my_table, table->tbl_count - delete_slot );
-       if( next_ind && (next_ind->i_ino == primary->i_ino) ) {
-               iput(next_ind);
-               next_ind = NULL;
-       }
+       
+       this_index = table->tbl_count - delete_slot - 1;
+       next_ind = snap_get_indirect(primary, my_table, this_index);
 
-       if( next_ind && (next_ind->i_ino == old_ind) ) {
+       if (next_ind && (next_ind->i_ino == primary->i_ino)) {
                iput(next_ind);
                next_ind = NULL;
        }
-
        rc = snap_destroy_indirect(primary, index, next_ind);
 
-       if(next_ind)    iput(next_ind);
-
-       if(rc != 0)     
+       up(&primary->i_sem);
+       
+       if (next_ind)   iput(next_ind);
+       
+       if (rc != 0)    
                CERROR("snap_destroy_indirect(ino %lu,index %d),ret %d\n",
                        primary->i_ino, index, rc);
-       return 0;
+       RETURN(0);
 }
 
 static int snap_delete(struct super_block *sb, struct snap_iterdata *data)
@@ -338,6 +324,7 @@ static int snap_delete(struct super_block *sb, struct snap_iterdata *data)
 
 /* This function will delete one item(a snapshot) in the snaptable  
  * and will also delete the item in the disk.
+ * FIXME later, this should be in a transaction.
  */
 int snaptable_delete_item(struct super_block *sb, struct snap_iterdata *data)
 {
@@ -345,19 +332,26 @@ int snaptable_delete_item(struct super_block *sb, struct snap_iterdata *data)
        struct snap_disk_table          *disk_snap_table;
        struct snapshot_operations      *snapops;
        struct snap_cache               *cache;
-       int                             tableno = data->tableno, index, i, slot, rc, count;
+       int                             tableno = data->tableno; 
+       int                             index, i, del_slot, rc;
        
        if (!(cache = snap_find_cache((kdev_t)data->dev)))
                RETURN(-ENODEV);
 
-       snapops = filter_c2csnapops(cache->cache_filter);
-       if (!snapops || !snapops->set_meta_attr)
-               RETURN(-EINVAL);
-
        if (tableno < 0 || tableno > SNAP_MAX_TABLES) {
                CERROR("invalid table number %d\n", tableno);
                RETURN(-EINVAL);
        }
+
+       snapops = filter_c2csnapops(cache->cache_filter);
+       if (!snapops || !snapops->set_meta_attr)
+               RETURN(-EINVAL);
+       
+       index = data->index;
+       if (clonefs_mounted(cache, index)) {
+               CERROR("Please first umount this clonefs \n");
+               RETURN(-EBUSY);         
+       }       
        /*first delete the snapshot
         * FIXME if snap delete error, how to handle this error*/
        rc = snap_delete(sb, data);
@@ -365,55 +359,63 @@ int snaptable_delete_item(struct super_block *sb, struct snap_iterdata *data)
                RETURN(-EINVAL);
        /*delete item in snaptable */
        table = &snap_tables[tableno];
-       index = data->index;
 
-       slot = snap_index2slot(table, index);
-       if (slot < 0)
+       del_slot = snap_index2slot(table, index);
+       if (del_slot < 0)
                RETURN(-EINVAL);
 
        down_interruptible(&table->tbl_sema);
-       while(slot < table->tbl_count) {
-               struct snap *item = &table->snap_items[slot];
-               item->time = table->snap_items[slot + 1].time;
-               item->flags = table->snap_items[slot + 1].flags;
-               item->gen = table->snap_items[slot + 1].gen;
-               item->index = table->snap_items[slot + 1].index;
-               memcpy(&item->name[0], &table->snap_items[slot + 1].name[0],
-                       SNAP_MAX_NAMELEN);
-       }
-
-       table->tbl_count --;
        
        SNAP_ALLOC(disk_snap_table, sizeof(struct snap_disk_table));
 
-       if (!disk_snap_table)
+       if (!disk_snap_table) {
+               up(&table->tbl_sema);
                RETURN(-ENOMEM);
+       }
+
        /* we will delete the item  snap_table to disk */
-       
+
+       index = del_slot;
+       /*Move the items after the delete slot forward one step*/
+       memset(&table->snap_items[index], 0, sizeof(struct snap));
+       while(index < table->tbl_count - 1) {
+               struct snap *item = &table->snap_items[index];
+                       
+               item->time = table->snap_items[index + 1].time;
+               item->flags = table->snap_items[index + 1].flags;
+               item->gen = table->snap_items[index + 1].gen;
+               item->index = table->snap_items[index + 1].index;
+               memcpy(&item->name[0], &table->snap_items[index + 1].name[0],
+                      SNAP_MAX_NAMELEN);
+               index ++;
+       }
+
+       table->tbl_count --;
+               
        disk_snap_table->magic = cpu_to_le32((__u32)DISK_SNAP_TABLE_MAGIC);
-       disk_snap_table->count = cpu_to_le32((__u32)table->tbl_count);
-       disk_snap_table->generation = cpu_to_le32((__u32)table->generation);
+       disk_snap_table->count = cpu_to_le32((__u32)table->tbl_count - 1);
+       disk_snap_table->generation = cpu_to_le32((__u32)table->generation + 1);
        memset(&disk_snap_table->snap_items[0], 0, 
               SNAP_MAX * sizeof(struct snap_disk));
 
-       count = table->tbl_count;
-
-       for (i = 1; i <= count; i++) {
-               struct snap *item = &table->snap_items[i];
-               disk_snap_table->snap_items[i].time = cpu_to_le64((__u64)item->time);
-               disk_snap_table->snap_items[i].gen = cpu_to_le32((__u32)item->gen);
-               disk_snap_table->snap_items[i].flags = cpu_to_le32((__u32)item->flags);
-               disk_snap_table->snap_items[i].index = cpu_to_le32((__u32)item->index);
-               memcpy(&disk_snap_table->snap_items[i].name , item->name, SNAP_MAX_NAMELEN);
+       for (i = 0; i < table->tbl_count - 1; i++) {
+               struct snap_disk *disk_item = &disk_snap_table->snap_items[i];
+               struct snap *item = &table->snap_items[i+1];
+               
+               disk_item[i].time = cpu_to_le64((__u64)item->time);
+               disk_item[i].gen = cpu_to_le32((__u32)item->gen);
+               disk_item[i].flags = cpu_to_le32((__u32)item->flags);
+               disk_item[i].index = cpu_to_le32((__u32)item->index);
+               memcpy(&disk_item[i].name , item->name, SNAP_MAX_NAMELEN);
        }
+
        rc = snapops->set_meta_attr(cache->cache_sb, DISK_SNAPTABLE_ATTR,
                                    (char*)disk_snap_table, sizeof(struct snap_disk_table));
 
        SNAP_FREE(disk_snap_table, sizeof(struct snap_disk_table));
        
        up(&table->tbl_sema);
-       
-       RETURN(0);
+       RETURN(rc);
 }
 
 int snapfs_read_snaptable(struct snap_cache *cache, int tableno)
@@ -438,7 +440,9 @@ int snapfs_read_snaptable(struct snap_cache *cache, int tableno)
 
        memset(table, 0, sizeof(struct snap_table));
         init_MUTEX(&table->tbl_sema); 
-       
+
+       /*Initialized table */
+       table->tbl_count = 1;
        rc = snapops->get_meta_attr(cache->cache_sb, DISK_SNAPTABLE_ATTR,
                               (char*)disk_snap_table, &size);
        if (rc < 0) {
@@ -451,7 +455,7 @@ int snapfs_read_snaptable(struct snap_cache *cache, int tableno)
                RETURN(rc);
        }
        table->generation = le32_to_cpu(disk_snap_table->generation);
-       table->tbl_count = le32_to_cpu(disk_snap_table->count);
+       table->tbl_count += le32_to_cpu(disk_snap_table->count);
        for ( i = 0; i < disk_snap_table->count; i++) {
                struct snap *item = &table->snap_items[i + 1];
                item->time = le64_to_cpu(disk_snap_table->snap_items[i].time);
@@ -589,13 +593,12 @@ static int delete_new_inode(struct inode *pri, void *param)
 
        ENTRY; 
 
-       if(!pri) return 0;
-
-       if(snap_is_redirector(pri)){
-               EXIT;
-               return 0;
-       }
+       if(!pri) 
+               RETURN(0);
 
+       if(snap_is_redirector(pri))
+               RETURN(0);
+       
        data = (struct snap_iterdata*) param;
 
        if(data) {
@@ -616,14 +619,12 @@ static int delete_new_inode(struct inode *pri, void *param)
                }
                pri->i_nlink = 0;
        }
-       return 0;
-
+       RETURN(0);
 }
 
 static int restore_inode(struct inode *pri, void *param)
 {
        struct snap_iterdata * data;
-//     struct snap_cache *cache;
        int tableno = 0;
 
        int index = 1;
@@ -637,7 +638,7 @@ static int restore_inode(struct inode *pri, void *param)
        
        ENTRY; 
 
-       if(!pri) return 0;
+       if(!pri) RETURN(0);
 
        data = (struct snap_iterdata*) param;
 
@@ -687,8 +688,7 @@ static int restore_inode(struct inode *pri, void *param)
        else {
                CDEBUG(D_SNAP, "ino %lu is older, don't restore\n", pri->i_ino);
        }
-       EXIT;
-       return 0;
+       RETURN(0);
 }
 
 //int snap_restore(struct super_block *sb, void *data)
@@ -709,81 +709,81 @@ int snap_get_index_from_name(int tableno, char *name)
        int slot;
 
        if ( tableno < 0 || tableno > SNAP_MAX_TABLES ) {
-               CDEBUG(D_SNAP, ": invalid table number %d\n", tableno);
+               CERROR("invalid table number %d\n", tableno);
                return -EINVAL;
        }
 
        table = &snap_tables[tableno];
 
-       for ( slot = 0 ; slot < SNAP_MAX ; slot++ ) {
-               if(strncmp (&table->snap_items[slot].name[0], name, 
-                       SNAP_MAX_NAMELEN) == 0 ) {
+       for ( slot = 0 ; slot < table->tbl_count; slot++) {
+               if (!strcmp(&table->snap_items[slot].name[0], name)) {
                        return table->snap_items[slot].index;
                }
        }
        return -EINVAL;
 }
 
-int snap_iterate_func(int len, struct snap_ioc_data *ioc_data, unsigned int cmd)
+int snap_iterate_func( struct ioc_snap_tbl_data *data, unsigned int cmd)
 {
-       struct snap_iterdata data;
+       struct snapshot_operations      *snapops;
+       struct snap_iterdata iterate_data;
        struct super_block *sb;
        struct snap_cache *cache;
        struct snap_table *table;
-       char name[SNAP_MAX_NAMELEN];
-       int index, tableno, name_len, slot, rc;
-       
-       kdev_t dev ;
+       int index, tableno, slot, rc;
 
        ENTRY;
+       
+       if (!(cache = snap_find_cache((kdev_t)data->dev)))
+               RETURN(-ENODEV);
 
-       dev = ioc_data->dev;
-       cache = snap_find_cache(dev); 
-       if ( !cache ) 
-                RETURN(-EINVAL);
+       snapops = filter_c2csnapops(cache->cache_filter);
+       if (!snapops || !snapops->set_meta_attr)
+               RETURN(-EINVAL);
+
+       tableno = data->no;
+       if (tableno < 0 || tableno > SNAP_MAX_TABLES) {
+               CERROR("invalid table number %d\n", tableno);
+               RETURN(-EINVAL);
+       }
 
        sb = cache->cache_sb;
-       tableno = cache->cache_snap_tableno;
        table = &snap_tables[tableno];
-
-       name_len = len - sizeof(kdev_t);        
-       memset(name, 0, SNAP_MAX_NAMELEN);      
-       if(name_len > SNAP_MAX_NAMELEN)
-               name_len = SNAP_MAX_NAMELEN;
-       if(name_len < 0 ) 
-               name_len = 0;
-       memcpy(name, ioc_data->name, name_len);
        
-       if ((index = snap_get_index_from_name (tableno, name)) < 0) 
+       index = snap_get_index_from_name(tableno, data->snaps[0].name);
+       if (index < 0) {
+               CERROR("Could not find %s in snaptable\n", 
+                      data->snaps[0].name);
                RETURN(-EINVAL);
-       
-       data.dev = dev;
-       data.index = index;
-       data.tableno = tableno;
+       }
+       iterate_data.dev = (kdev_t)data->dev;
+       iterate_data.index = index;
+       iterate_data.tableno = tableno;
        slot = snap_index2slot (table, index);
        if( slot < 0 ) 
                RETURN(-EINVAL);
        
-       data.time = table->snap_items[slot].time;
+       iterate_data.time = table->snap_items[slot].time;
        CDEBUG(D_SNAP, "dev %d, tableno %d, index %d, time %lu\n",
-               data.dev, data.tableno, data.index, data.time );
+              iterate_data.dev, iterate_data.tableno, 
+              iterate_data.index, iterate_data.time);
 
        switch (cmd) {
                case IOC_SNAP_DEBUG:
-                       rc = snap_print(sb, &data);     
+                       rc = snap_print(sb, &iterate_data);     
                        break;
                case IOC_SNAP_DELETE:
-                       rc = snaptable_delete_item(sb, &data);  
+                       rc = snaptable_delete_item(sb, &iterate_data);  
                        break;
                case IOC_SNAP_RESTORE:
-                       rc = snap_restore(sb, &data);   
+                       rc = snap_restore(sb, &iterate_data);   
                        break;
                default:
                        CERROR("unrecognized cmd %d \n", cmd);
                        rc = -EINVAL;
                        break;
        }
-       RETURN(0);
+       RETURN(rc);
 }
 
 #define BUF_SIZE 1024
@@ -872,7 +872,8 @@ int snap_ioctl (struct inode * inode, struct file * filp,
                }
                */
                memcpy(name, data->name, name_len);
-               printk("dev %d , len %d, name_len %d, find name is [%s]\n", dev, input.ioc_inlen, name_len, name);
+               printk("dev %d , len %d, name_len %d, find name is [%s]\n", 
+                       dev, input.ioc_inlen, name_len, name);
                cache = snap_find_cache(dev); 
                if ( !cache ) {
                        EXIT;
@@ -930,7 +931,7 @@ int snap_ioctl (struct inode * inode, struct file * filp,
        case IOC_SNAP_DELETE: 
        case IOC_SNAP_RESTORE:
        case IOC_SNAP_DEBUG:
-               rc = snap_iterate_func(input.ioc_inlen, karg, cmd);
+               rc = snap_iterate_func(karg, cmd);
                break;
 #ifdef SNAP_DEBUG
        case IOC_SNAP_DEVFAIL: