X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fsnapfs%2Fsuper.c;h=bfeecde9bf63f19d73f8f741195599278e34ca29;hb=36e1612c1d41dd66d7347c133d9e79a26f4f74cf;hp=8b68cffc38518cc3c1145eafaffa5f92e5da82a4;hpb=d3e48db0f036c113fd014e7440d504579f443b69;p=fs%2Flustre-release.git diff --git a/lustre/snapfs/super.c b/lustre/snapfs/super.c index 8b68cff..bfeecde 100644 --- a/lustre/snapfs/super.c +++ b/lustre/snapfs/super.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,42 @@ static void put_filesystem(struct file_system_type *fs) __MOD_DEC_USE_COUNT(fs->owner); } +static struct vfsmount* get_vfsmount(struct super_block *sb) +{ + struct vfsmount *rootmnt, *mnt, *ret = NULL; + struct list_head *end, *list; + + rootmnt = mntget(current->fs->rootmnt); + end = list = &rootmnt->mnt_list; + do { + mnt = list_entry(list, struct vfsmount, mnt_list); + if (mnt->mnt_sb == sb) { + ret = mnt; + break; + } + list = list->next; + } while (end != list); + mntput(current->fs->rootmnt); + return ret; +} + +void get_snap_current_mnt(struct super_block *sb) +{ + struct vfsmount *mnt; + + mnt = get_vfsmount(sb); + if (mnt) + mntget(mnt); +} +void put_snap_current_mnt(struct super_block *sb) +{ + struct vfsmount *mnt; + + mnt = get_vfsmount(sb); + if (mnt) + mntput(mnt); +} + /* In get_opt we get options in opt, value in opt_value * we must remember to free opt and opt_value*/ static char * snapfs_options(char *options, char **cache_type, @@ -223,6 +260,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 +306,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 +352,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; } @@ -386,6 +459,8 @@ clone_read_super( CDEBUG(D_SUPER, "sb %lx, &sb->u.generic_sbp: %lx\n", (ulong) sb, (ulong) &sb->u.generic_sbp); + + get_snap_current_mnt(snap_cache->cache_sb); out_err: cleanup_option(); if (err)