Whamcloud - gitweb
fix some bugs in snapfs
authorwangdi <wangdi>
Fri, 9 Jan 2004 16:26:23 +0000 (16:26 +0000)
committerwangdi <wangdi>
Fri, 9 Jan 2004 16:26:23 +0000 (16:26 +0000)
lustre/snapfs/cache.c
lustre/snapfs/clonefs.c
lustre/snapfs/dir.c
lustre/snapfs/file.c
lustre/snapfs/inode.c
lustre/snapfs/snap.c
lustre/snapfs/snapfs_internal.h
lustre/snapfs/snaptable.c
lustre/snapfs/super.c

index c92e870..68efe98 100644 (file)
@@ -54,9 +54,9 @@ inline void snap_init_cache_hash(void)
 struct snap_cache *snap_find_cache(kdev_t dev)
 {
        struct snap_cache *cache;
-       struct list_head *lh, *tmp;
+       struct list_head *lh;
 
-       lh = tmp = &(snap_caches[snap_cache_hash(dev)]);
+       lh = &(snap_caches[snap_cache_hash(dev)]);
         list_for_each_entry(cache, lh, cache_chain) { 
                if ( cache->cache_dev == dev )
                        return cache;
@@ -78,6 +78,23 @@ struct snap_cache *snap_init_cache(void)
         }
        return cache;
 }
+/*walk through the cache structure*/
+int snap_cache_process(snap_cache_cb_t cb, void* in, unsigned long* out)
+{
+       int i = 0;
+
+       for (i = 0; i < CACHES_SIZE; i++) {
+               struct snap_cache *cache;
+               struct list_head *lh = &(snap_caches[i]);
+               list_for_each_entry(cache, lh, cache_chain) {   
+                       if (cb(cache, in, out))
+                               goto exit;
+               }
+       }
+exit:
+       return 0;
+}
+
 
 /* free a cache structure and all of the memory it is pointing to */
 inline void snap_free_cache(struct snap_cache *cache)
index 708b083..66d3862 100644 (file)
@@ -108,6 +108,7 @@ static void clonefs_read_inode(struct inode *inode)
                        inode->i_mapping->a_ops = &clonefs_file_address_ops;
        } else if (S_ISDIR(inode->i_mode)) {
                inode->i_op = &clonefs_dir_inode_ops;
+               inode->i_fop = &clonefs_dir_file_ops;
        } else if (S_ISLNK(inode->i_mode)) {
                inode->i_op = &clonefs_symlink_inode_ops;
        } else {
index a1636f2..f34f28d 100644 (file)
@@ -150,7 +150,6 @@ static int currentfs_create(struct inode *dir, struct dentry *dentry, int mode)
 {
        struct snap_cache       *cache;
        struct inode_operations *iops;
-       struct snapshot_operations *snapops;    
        void                    *handle = NULL;
        int                     rc;
 
@@ -165,16 +164,12 @@ static int currentfs_create(struct inode *dir, struct dentry *dentry, int mode)
                RETURN(-EINVAL);
        }
 
-       snapops = filter_c2csnapops(cache->cache_filter);
-       if (!snapops || !snapops->get_generation) 
-               RETURN(-EINVAL);
-
        handle = snap_trans_start(cache, dir, SNAP_OP_CREATE);
 
        if ( snap_needs_cow(dir) != -1 ) {
                CDEBUG(D_INODE, "snap_needs_cow for ino %lu \n",dir->i_ino);
                snap_debug_device_fail(dir->i_dev, SNAP_OP_CREATE, 1);
-               if (!(snap_do_cow(dir, get_parent_ino(dir), 0))) {
+               if ((snap_do_cow(dir, get_parent_ino(dir), 0))) {
                        CERROR("Do cow error\n");
                        RETURN(-EINVAL);
                }
@@ -205,7 +200,8 @@ static int currentfs_create(struct inode *dir, struct dentry *dentry, int mode)
         }
        CDEBUG(D_INODE, "inode %lu, i_op %p\n", dentry->d_inode->i_ino, dentry->d_inode->i_op);
        snap_debug_device_fail(dir->i_dev, SNAP_OP_CREATE, 3);
-       init_filter_data(dentry->d_inode, snapops, 0); exit:
+       init_filter_data(dentry->d_inode, 0); 
+exit:
        snap_trans_commit(cache, handle);
        RETURN(rc);
 }
index c6795aa..78cc9ab 100644 (file)
@@ -102,7 +102,7 @@ static ssize_t currentfs_write (struct file *filp, const char *buf,
        for( i=0; i<2; i++ ){
                if(block[i]!=-1 && aops->bmap(inode->i_mapping, block[i])) {
                        table = &snap_tables[cache->cache_snap_tableno];
-                       for (slot = table->tbl_count ; slot >= 1; slot--) {
+                       for (slot = table->tbl_count - 1; slot >= 1; slot--) {
                                struct address_space_operations *c_aops = 
                                        cache_inode->i_mapping->a_ops;
                                cache_inode = NULL;
@@ -179,7 +179,7 @@ static int currentfs_readpage(struct file *file, struct page *page)
 
        table = &snap_tables[cache->cache_snap_tableno];
 
-        for (slot = table->tbl_count ; slot >= 1; slot--)
+        for (slot = table->tbl_count - 1; slot >= 1; slot--)
         {
                struct address_space_operations *c_aops = 
                                        cache_inode->i_mapping->a_ops;
index 9f43d0d..2c07000 100644 (file)
@@ -49,14 +49,22 @@ int init_filter_info_cache()
 
 
 void init_filter_data(struct inode *inode, 
-                            struct snapshot_operations *snapops, 
                             int flag)
 {
        struct filter_inode_info *i;
+        struct snap_cache *cache;
+       struct snapshot_operations *snapops; 
 
-       if (inode->i_filterdata){
+       if (inode->i_filterdata || inode->i_ino & 0xF0000000)
                 return;
-        }
+       cache = snap_find_cache(inode->i_dev);
+       if (!cache) {
+               CERROR("currentfs_read_inode: cannot find cache\n");
+               make_bad_inode(inode);
+               return;
+       }
+       snapops = filter_c2csnapops(cache->cache_filter);
+       
        inode->i_filterdata = (struct filter_inode_info *) \
                              kmem_cache_alloc(filter_info_cache, SLAB_KERNEL);
        i = inode->i_filterdata;
@@ -118,7 +126,7 @@ static void currentfs_read_inode(struct inode *inode)
        }
        /*init filter_data struct 
         * FIXME flag should be set future*/
-       init_filter_data(inode, snapops, 0); 
+       init_filter_data(inode, 0); 
        return; 
 }
 
index a5032a6..dba867f 100644 (file)
@@ -76,7 +76,7 @@ struct inode *snap_redirect(struct inode *cache_inode,
        if (!redirected) {
                int index;
                clone_slot = snap_index2slot(table, clone_info->clone_index);
-               for (slot = table->tbl_count; slot >= clone_slot; slot --) {
+               for (slot = table->tbl_count-1; slot >= clone_slot; slot --) {
                        my_table[slot-clone_slot+1] = table->snap_items[slot].index;
                }
                index = table->tbl_count - clone_slot + 1;
@@ -113,7 +113,7 @@ int snap_do_cow(struct inode *inode, ino_t parent_ino, int del)
        }
 
        snap_last(cache, &snap);
-       ind = snapops->create_indirect(inode, snap.index, 0, parent_ino, del);
+       ind = snapops->create_indirect(inode, snap.index, snap.gen, parent_ino, del);
        if(!ind)
                RETURN(-EINVAL);                
        iput(ind);
index d55698c..936f66c 100644 (file)
@@ -253,6 +253,8 @@ extern int currentfs_is_under_dotsnap(struct dentry *de);
 /* cache.c */
 inline void snap_free_cache(struct snap_cache *cache);
 struct snap_cache *snap_find_cache(kdev_t dev);
+typedef int (*snap_cache_cb_t)(struct snap_cache*, void *in, unsigned long *out);
+int snap_cache_process(snap_cache_cb_t cb, void* in, unsigned long* out);
 
 /* snaptable.c */
 extern struct snap_table snap_tables[SNAP_MAX_TABLES];
@@ -280,8 +282,7 @@ int snap_set_indirect(struct inode *pri, ino_t ind_ino,
 extern struct super_operations currentfs_super_ops;
 void cleanup_filter_info_cache(void);
 int init_filter_info_cache(void);
-void init_filter_data(struct inode *inode, struct snapshot_operations *snapops,
-                    int flag);
+extern void init_filter_data(struct inode *inode, int flag);
 
 /* dir.c */
 extern struct inode_operations currentfs_dir_iops;
index 84c414b..12c212a 100644 (file)
@@ -42,7 +42,7 @@ 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 +133,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 +205,35 @@ 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);
+               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->count = cpu_to_le32((__u32)table->tbl_count) - 1;
        disk_snap_table->generation = cpu_to_le32((__u32)table->generation);
        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 +241,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)
@@ -438,7 +437,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 +452,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);
@@ -709,7 +710,7 @@ 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;
        }
 
index 8b68cff..587075b 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/loop.h>
 #include <linux/jbd.h>
 #include <linux/ext3_fs.h>
 #include <linux/snap.h>
@@ -223,6 +224,7 @@ snapfs_read_super (
                                        sb->s_root->d_op, 
                                        &currentfs_dentry_ops);
                sb->s_root->d_op = filter_c2udops(cache->cache_filter);
+               init_filter_data(sb->s_root->d_inode, 0); 
        }
         /*
          * Save a pointer to the snap_cache structure in the
@@ -268,7 +270,31 @@ static char *clonefs_options(char *options, char **devstr, char **namestr)
        }
        return pos;
 }
-
+static int snap_cache_lookup_ino_cb(struct snap_cache *cache, void *in, unsigned long *out)
+{
+       ino_t ino = *((unsigned long*)in);
+
+       if (cache) {
+               struct super_block *sb = cache->cache_sb;
+               kdev_t dev = sb->s_dev;
+
+               if (MAJOR(dev) != LOOP_MAJOR) 
+                       return 0;
+               if (sb->s_bdev->bd_op && sb->s_bdev->bd_op->ioctl) {
+                       struct inode *inode = sb->s_bdev->bd_inode;
+                       struct loop_info loop_info;
+
+                       sb->s_bdev->bd_op->ioctl(inode, NULL, LOOP_GET_INFO, 
+                                                (unsigned long)&loop_info);
+                       
+                       if(loop_info.lo_inode == ino) {
+                               *out = sb->s_dev; 
+                               return 1;
+                       }
+               }
+       }
+       return 0;       
+}
 static int snapfs_path2dev(char *dev_path, kdev_t *dev)
 {
        struct dentry *dentry;
@@ -290,8 +316,19 @@ static int snapfs_path2dev(char *dev_path, kdev_t *dev)
                path_release(&nd);
                return -ENODEV;
        }
-
-       *dev = kdev_t_to_nr(dentry->d_inode->i_rdev);
+       if (S_ISBLK(dentry->d_inode->i_mode)) {
+               *dev = kdev_t_to_nr(dentry->d_inode->i_rdev);
+       } else {
+               /*here we must walk through all the snap cache to 
+                *find the loop device */
+               kdev_t tmp;
+
+               if (snap_cache_process(snap_cache_lookup_ino_cb,
+                                      &dentry->d_inode->i_ino, 
+                                      (unsigned long*)&tmp))
+                       return -EINVAL;
+               *dev = tmp;
+       }
        path_release(&nd);
        return 0;
 }