From e3e169c0c22305b9e3c27035e785b3c55a24eb25 Mon Sep 17 00:00:00 2001 From: wangdi Date: Mon, 2 Feb 2004 16:48:15 +0000 Subject: [PATCH] update smfs --- lustre/smfs/Makefile.am | 4 +-- lustre/smfs/cache.c | 82 +++++++++++++++++++++++++++++++++++++++--- lustre/smfs/dir.c | 2 +- lustre/smfs/file.c | 24 +++++++++++++ lustre/smfs/inode.c | 6 ++-- lustre/smfs/sm_fs.c | 54 ++++++++++++++++++++++++++++ lustre/smfs/smfs_internal.h | 9 +++-- lustre/smfs/super.c | 80 ++++++++++++++++++++++++++++++++++------- lustre/smfs/symlink.c | 21 +++++++++++ lustre/smfs/sysctl.c | 87 +++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 346 insertions(+), 23 deletions(-) create mode 100644 lustre/smfs/file.c create mode 100644 lustre/smfs/sm_fs.c create mode 100644 lustre/smfs/symlink.c create mode 100644 lustre/smfs/sysctl.c diff --git a/lustre/smfs/Makefile.am b/lustre/smfs/Makefile.am index 764dcfd..96265da 100644 --- a/lustre/smfs/Makefile.am +++ b/lustre/smfs/Makefile.am @@ -10,7 +10,7 @@ MODULE = smfs modulefs_DATA = smfs.o EXTRA_PROGRAMS = smfs -smfs_SOURCES = super.c options.c inode.c cache.c dir.c - +smfs_SOURCES = super.c options.c inode.c cache.c dir.c +smfs_SOURCES += sysctl.c file.c symlink.c sm_fs.c include $(top_srcdir)/Rules diff --git a/lustre/smfs/cache.c b/lustre/smfs/cache.c index 5008615..0f013d3 100644 --- a/lustre/smfs/cache.c +++ b/lustre/smfs/cache.c @@ -18,6 +18,7 @@ extern struct file_operations smfs_file_fops; extern struct address_space_operations smfs_file_aops; extern struct inode_operations smfs_sym_iops; extern struct file_operations smfs_sym_fops; +extern struct super_operations smfs_super_ops; inline struct super_operations *cache_sops(struct sm_ops *smfs_ops) { @@ -70,7 +71,7 @@ void init_smfs_cache() } void cleanup_smfs_cache() { - + return; } static void setup_sm_symlink_ops(struct inode *cache_inode, @@ -169,7 +170,7 @@ static void setup_sm_file_ops(struct inode *cache_inode, if (cache_inode->i_op->getxattr) iops->getxattr = cache_iops->getxattr; if (cache_inode->i_op->listxattr) - iops->setxattr = cache_iops->setxattr; + iops->listxattr = cache_iops->listxattr; if (cache_inode->i_op->removexattr) iops->removexattr = cache_iops->removexattr; } @@ -181,14 +182,71 @@ static void setup_sm_file_ops(struct inode *cache_inode, } return; } -void sm_setup_inode_ops(struct inode *cache_inode, struct inode *inode) + +static void setup_sm_sb_ops(struct super_block *cache_sb, + struct super_block *sb, + struct super_operations *smfs_sops) +{ + struct smfs_super_info *smb; + struct super_operations *sops; + + ENTRY; + + smb = S2SMI(sb); + + if (smb->ops_check & SB_OPS_CHECK) + return; + smb->ops_check |= SB_OPS_CHECK; + sops = cache_sops(&smfs_operations); + memset(sops, 0, sizeof (struct super_operations)); + + if (cache_sb->s_op) { + if (cache_sb->s_op->read_inode) + sops->read_inode = smfs_sops->read_inode; + if (cache_sb->s_op->read_inode2) + sops->read_inode2 = smfs_sops->read_inode2; + if (cache_sb->s_op->dirty_inode) + sops->dirty_inode = smfs_sops->dirty_inode; + if (cache_sb->s_op->write_inode) + sops->write_inode = smfs_sops->write_inode; + if (cache_sb->s_op->put_inode) + sops->put_inode = smfs_sops->put_inode; + if (cache_sb->s_op->delete_inode) + sops->delete_inode = smfs_sops->delete_inode; + if (cache_sb->s_op->put_super) + sops->put_super = smfs_sops->put_super; + if (cache_sb->s_op->write_super) + sops->write_super = smfs_sops->write_super; + if (cache_sb->s_op->write_super_lockfs) + sops->write_super_lockfs = smfs_sops->write_super_lockfs; + if (cache_sb->s_op->unlockfs) + sops->unlockfs = smfs_sops->unlockfs; + if (cache_sb->s_op->statfs) + sops->statfs = smfs_sops->statfs; + if (cache_sb->s_op->remount_fs) + sops->remount_fs = smfs_sops->remount_fs; + if (cache_sb->s_op->clear_inode) + sops->clear_inode = smfs_sops->clear_inode; + if (cache_sb->s_op->umount_begin) + sops->umount_begin = smfs_sops->umount_begin; + if (cache_sb->s_op->fh_to_dentry) + sops->fh_to_dentry = smfs_sops->fh_to_dentry; + if (cache_sb->s_op->dentry_to_fh) + sops->dentry_to_fh = smfs_sops->dentry_to_fh; + if (cache_sb->s_op->show_options) + sops->show_options = smfs_sops->show_options; + } + + return; +} +void sm_set_inode_ops(struct inode *cache_inode, struct inode *inode) { /* XXX now set the correct snap_{file,dir,sym}_iops */ if (S_ISDIR(inode->i_mode)) { inode->i_op = cache_diops(&smfs_operations); inode->i_fop = cache_dfops(&smfs_operations); } else if (S_ISREG(inode->i_mode)) { - if (!cache_fiops(&smfs_operations) ) { + if (!cache_fiops(&smfs_operations)) { setup_sm_file_ops(cache_inode, inode, &smfs_file_iops, &smfs_file_fops, @@ -213,4 +271,20 @@ void sm_setup_inode_ops(struct inode *cache_inode, struct inode *inode) inode->i_ino, inode->i_op); } } +void sm_set_sb_ops (struct super_block *cache_sb, + struct super_block *sb) +{ + struct smfs_super_info *smb; + + smb = S2SMI(sb); + + if (smb->ops_check & SB_OPS_CHECK) + return; + smb->ops_check |= SB_OPS_CHECK; + if (!cache_sops(&smfs_operations)) { + setup_sm_sb_ops(cache_sb, sb, &smfs_super_ops); + } + sb->s_op = cache_sops(&smfs_operations); + return; +} diff --git a/lustre/smfs/dir.c b/lustre/smfs/dir.c index b0108b2..3583f7b 100644 --- a/lustre/smfs/dir.c +++ b/lustre/smfs/dir.c @@ -85,7 +85,7 @@ static int smfs_create(struct inode *dir, if (!inode) GOTO(exit, rc); - sm_setup_inode_ops(cache_inode, inode); + sm_set_inode_ops(cache_inode, inode); exit: d_unalloc(cache_dentry); RETURN(rc); diff --git a/lustre/smfs/file.c b/lustre/smfs/file.c new file mode 100644 index 0000000..751f13a --- /dev/null +++ b/lustre/smfs/file.c @@ -0,0 +1,24 @@ +/* + * file.c + */ + +#define DEBUG_SUBSYSTEM S_SM + +#include +#include +#include +#include +#include +#include +#include +#include "smfs_internal.h" + +struct address_space_operations smfs_file_aops = { +}; + +struct file_operations smfs_file_fops = { +}; + +struct inode_operations smfs_file_iops = { +}; + diff --git a/lustre/smfs/inode.c b/lustre/smfs/inode.c index 37b86ed..8769913 100644 --- a/lustre/smfs/inode.c +++ b/lustre/smfs/inode.c @@ -36,7 +36,7 @@ static void smfs_read_inode(struct inode *inode) CDEBUG(D_INODE, "read_inode ino %lu icount %d \n", inode->i_ino, atomic_read(&inode->i_count)); - sm_setup_inode_ops(cache_inode, inode); + sm_set_inode_ops(cache_inode, inode); CDEBUG(D_INODE, "read_inode ino %lu icount %d \n", inode->i_ino, atomic_read(&inode->i_count)); @@ -61,9 +61,11 @@ static void smfs_clear_inode(struct inode *inode) clear_inode(cache_inode); return; } -struct super_operations currentfs_super_ops = { + +struct super_operations smfs_super_ops = { read_inode: smfs_read_inode, clear_inode: smfs_clear_inode, + put_super: smfs_put_super, }; diff --git a/lustre/smfs/sm_fs.c b/lustre/smfs/sm_fs.c new file mode 100644 index 0000000..d83c6f4 --- /dev/null +++ b/lustre/smfs/sm_fs.c @@ -0,0 +1,54 @@ +/* + * fs/smfs/sm_fs.c + * + * A storage management file system. + * + */ +#define EXPORT_SYMTAB +#define DEBUG_SUBSYSTEM S_SM + +#include +#include +#include +#include +#include +#include +#include + +#include "smfs_internal.h" + +int sm_stack = 0; +long sm_kmemory = 0; + + +MODULE_AUTHOR("Peter J. Braam "); +MODULE_DESCRIPTION("Smfs file system filters v0.01"); + +extern int init_smfs(void); +extern int cleanup_smfs(void); +extern int init_snap_sysctl(void); + +static int __init smfs_init(void) +{ + int err; + + if ( (err = init_smfs()) ) { + printk("Error initializing snapfs, %d\n", err); + return -EINVAL; + } + + if ( (err = init_smfs_proc_sys()) ) { + printk("Error initializing snapfs proc sys, %d\n", err); + return -EINVAL; + } + + return 0; +} + +static void __exit smfs_cleanup(void) +{ + cleanup_smfs(); +} +module_init(smfs_init); +module_exit(smfs_cleanup); + diff --git a/lustre/smfs/smfs_internal.h b/lustre/smfs/smfs_internal.h index fe6b574..ad58e8e 100644 --- a/lustre/smfs/smfs_internal.h +++ b/lustre/smfs/smfs_internal.h @@ -46,16 +46,21 @@ struct option { char *value; struct list_head list; }; + +extern int init_smfs_proc_sys(void); /*options.c*/ extern int get_opt(struct option **option, char **pos); extern void cleanup_option(void); extern int init_option(char *data); /*cache.c*/ -void sm_setup_inode_ops(struct inode *cache_inode, struct inode *inode); +void sm_set_inode_ops(struct inode *cache_inode, struct inode *inode); void sm_set_sb_ops(struct super_block *cache_sb, struct super_block *sb); void init_smfs_cache(void); void cleanup_smfs_cache(void); - +/*super.c*/ +int init_smfs(void); +int cleanup_smfs(void); +void smfs_put_super(struct super_block *sb); /*sysctl.c*/ extern int sm_debug_level; extern int sm_inodes; diff --git a/lustre/smfs/super.c b/lustre/smfs/super.c index 53fe4f1..2cb0346 100644 --- a/lustre/smfs/super.c +++ b/lustre/smfs/super.c @@ -8,14 +8,18 @@ * * Author: Peter J. Braam */ -#define DEBUG_SUBSYSTEM S_SNAP +#define DEBUG_SUBSYSTEM S_SM +#include #include #include #include #include -#include #include +#include +#include +#include +#include #include #include #include "smfs_internal.h" @@ -56,6 +60,19 @@ static int get_fd(struct file *filp) write_unlock(&files->file_lock); RETURN(-1); } +static int close_fd(int fd) +{ + struct files_struct *files = current->files; + + write_lock(&files->file_lock); + + files->fd[fd] = NULL; + __put_unused_fd(files, fd); + + write_unlock(&files->file_lock); + return 0; +} + #define MAX_LOOP_DEVICES 256 static char *parse_path2dev(struct super_block *sb, char *dev_path) { @@ -66,22 +83,48 @@ static char *parse_path2dev(struct super_block *sb, char *dev_path) filp = filp_open(dev_path, 0, 0); if (!filp) RETURN(NULL); - if (S_ISREG(filp->f_dentry->d_inode->i_mode)) { /*here we must walk through all the snap cache to *find the loop device */ + + fd = get_unused_fd(); + if (!fd) RETURN(NULL); + + fd_install(fd, filp); + SM_ALLOC(name, strlen("/dev/loop/") + 2); + for (i = 0; i < MAX_LOOP_DEVICES; i++) { fd = get_fd(filp); - error = sb->s_bdev->bd_op->ioctl(filp->f_dentry->d_inode, - filp, LOOP_SET_FD, - (unsigned long)&fd); - if (!error) { - filp_close(filp, current->files); - /*FIXME later, the loop file should + if (fd > 0) { + struct block_device_operations *bd_ops; + struct dentry *dentry; + struct nameidata nd; + /*FIXME later, the loop file should *be different for different system*/ - SM_ALLOC(name, strlen("/dev/loop/") + 2); - sprintf(name, "dev/loop/%d", i); - RETURN(name); + + sprintf(name, "/dev/loop/%d", i); + + if (path_init(name, LOOKUP_FOLLOW, &nd)) { + error = path_walk(name, &nd); + if (error) { + path_release(&nd); + SM_FREE(name, sizeof(name) + 1); + RETURN(NULL); + } + } else { + SM_FREE(name, sizeof(name) + 1); + RETURN(NULL); + } + dentry = nd.dentry; + bd_ops = get_blkfops(LOOP_MAJOR); + error = bd_ops->ioctl(dentry->d_inode, + filp, LOOP_SET_FD, + (unsigned long)fd); + path_release(&nd); + if (!error) { + filp_close(filp, current->files); + RETURN(name); + } } } } @@ -129,6 +172,19 @@ err_out: return err; } +static int sm_umount_cache(struct super_block *sb) +{ + struct smfs_super_info *smb = S2SMI(sb); + + mntput(smb->smsi_mnt); + return 0; +} +void smfs_put_super(struct super_block *sb) +{ + if (sb) + sm_umount_cache(sb); + return; +} struct super_block * smfs_read_super( diff --git a/lustre/smfs/symlink.c b/lustre/smfs/symlink.c new file mode 100644 index 0000000..4174846 --- /dev/null +++ b/lustre/smfs/symlink.c @@ -0,0 +1,21 @@ +/* + * fs/snap/snap.c + * + * A snap shot file system. + * + */ +#define DEBUG_SUBSYSTEM S_SNAP + +#include +#include +#include +#include +#include + +#include "smfs_internal.h" + +struct inode_operations smfs_sym_iops = { +}; + +struct file_operations smfs_sym_fops = { +}; diff --git a/lustre/smfs/sysctl.c b/lustre/smfs/sysctl.c new file mode 100644 index 0000000..6ec1f9b --- /dev/null +++ b/lustre/smfs/sysctl.c @@ -0,0 +1,87 @@ +/* + * Sysctrl entries for Snapfs + */ + +/* /proc entries */ + +#define DEBUG_SUBSYSTEM S_SNAP + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "smfs_internal.h" + + +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry *proc_smfs_root; +#endif + + +/* SYSCTL below */ + +static struct ctl_table_header *smfs_table_header = NULL; +/* 0x100 to avoid any chance of collisions at any point in the tree with + * non-directories + */ +#define PSDEV_SMFS (0x130) + +#define PSDEV_DEBUG 1 /* control debugging */ +#define PSDEV_TRACE 2 /* control enter/leave pattern */ + +/* These are global control options */ +#define ENTRY_CNT 3 + +int sm_print_entry = 1; +int sm_debug_level = 0; + +/* XXX - doesn't seem to be working in 2.2.15 */ +static struct ctl_table smfs_ctltable[] = +{ + {PSDEV_DEBUG, "debug", &sm_debug_level, sizeof(int), 0644, NULL, &proc_dointvec}, + {PSDEV_TRACE, "trace", &sm_print_entry, sizeof(int), 0644, NULL, &proc_dointvec}, + {0} +}; + +static ctl_table smfs_table[2] = { + {PSDEV_SMFS, "smfs", NULL, 0, 0555, smfs_ctltable}, + {0} +}; + + +int __init init_smfs_proc_sys(void) +{ +#ifdef CONFIG_PROC_FS + proc_smfs_root = proc_mkdir("smfs", proc_root_fs); + if (!proc_smfs_root) { + printk(KERN_ERR "SMFS: error registering /proc/fs/smfs\n"); + RETURN(-ENOMEM); + } + proc_smfs_root->owner = THIS_MODULE; +#endif + +#ifdef CONFIG_SYSCTL + if ( !smfs_table_header ) + smfs_table_header = + register_sysctl_table(smfs_table, 0); +#endif + return 0; +} + +void cleanup_smfs_proc_sys(void) +{ +#ifdef CONFIG_SYSCTL + if ( smfs_table_header ) + unregister_sysctl_table(smfs_table_header); + smfs_table_header = NULL; +#endif +#if CONFIG_PROC_FS + remove_proc_entry("smfs", proc_root_fs); +#endif +} + -- 1.8.3.1