From: wangdi Date: Fri, 9 Jan 2004 16:26:23 +0000 (+0000) Subject: fix some bugs in snapfs X-Git-Tag: 1.0.3~98 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=c955653af59279f2c772c8bdcdafbf825e8bd10a;p=fs%2Flustre-release.git fix some bugs in snapfs --- diff --git a/lustre/snapfs/cache.c b/lustre/snapfs/cache.c index c92e870..68efe98 100644 --- a/lustre/snapfs/cache.c +++ b/lustre/snapfs/cache.c @@ -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) diff --git a/lustre/snapfs/clonefs.c b/lustre/snapfs/clonefs.c index 708b083..66d3862 100644 --- a/lustre/snapfs/clonefs.c +++ b/lustre/snapfs/clonefs.c @@ -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 { diff --git a/lustre/snapfs/dir.c b/lustre/snapfs/dir.c index a1636f2..f34f28d 100644 --- a/lustre/snapfs/dir.c +++ b/lustre/snapfs/dir.c @@ -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); } diff --git a/lustre/snapfs/file.c b/lustre/snapfs/file.c index c6795aa..78cc9ab 100644 --- a/lustre/snapfs/file.c +++ b/lustre/snapfs/file.c @@ -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; diff --git a/lustre/snapfs/inode.c b/lustre/snapfs/inode.c index 9f43d0d..2c07000 100644 --- a/lustre/snapfs/inode.c +++ b/lustre/snapfs/inode.c @@ -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; } diff --git a/lustre/snapfs/snap.c b/lustre/snapfs/snap.c index a5032a6..dba867f 100644 --- a/lustre/snapfs/snap.c +++ b/lustre/snapfs/snap.c @@ -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); diff --git a/lustre/snapfs/snapfs_internal.h b/lustre/snapfs/snapfs_internal.h index d55698c..936f66c 100644 --- a/lustre/snapfs/snapfs_internal.h +++ b/lustre/snapfs/snapfs_internal.h @@ -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; diff --git a/lustre/snapfs/snaptable.c b/lustre/snapfs/snaptable.c index 84c414b..12c212a 100644 --- a/lustre/snapfs/snaptable.c +++ b/lustre/snapfs/snaptable.c @@ -42,7 +42,7 @@ int snap_index2slot(struct snap_table *snap_table, int snap_index) { int slot; - for ( slot=0 ; slottbl_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; } diff --git a/lustre/snapfs/super.c b/lustre/snapfs/super.c index 8b68cff..587075b 100644 --- a/lustre/snapfs/super.c +++ b/lustre/snapfs/super.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -223,6 +224,7 @@ snapfs_read_super ( sb->s_root->d_op, ¤tfs_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; }