Skip to content
Snippets Groups Projects
Commit e3e169c0 authored by Wang Di's avatar Wang Di
Browse files

update smfs

parent 3128827f
No related branches found
No related tags found
No related merge requests found
......@@ -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
......@@ -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;
}
......@@ -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);
......
/*
* file.c
*/
#define DEBUG_SUBSYSTEM S_SM
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/unistd.h>
#include <linux/pagemap.h>
#include "smfs_internal.h"
struct address_space_operations smfs_file_aops = {
};
struct file_operations smfs_file_fops = {
};
struct inode_operations smfs_file_iops = {
};
......@@ -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,
};
......
/*
* fs/smfs/sm_fs.c
*
* A storage management file system.
*
*/
#define EXPORT_SYMTAB
#define DEBUG_SUBSYSTEM S_SM
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/unistd.h>
#include <linux/miscdevice.h>
#include "smfs_internal.h"
int sm_stack = 0;
long sm_kmemory = 0;
MODULE_AUTHOR("Peter J. Braam <braam@cs.cmu.edu>");
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);
......@@ -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;
......
......@@ -8,14 +8,18 @@
*
* Author: Peter J. Braam <braam@mountainviewdata.com>
*/
#define DEBUG_SUBSYSTEM S_SNAP
#define DEBUG_SUBSYSTEM S_SM
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/utime.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/loop.h>
#include <linux/errno.h>
#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(
......
/*
* fs/snap/snap.c
*
* A snap shot file system.
*
*/
#define DEBUG_SUBSYSTEM S_SNAP
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/string.h>
#include "smfs_internal.h"
struct inode_operations smfs_sym_iops = {
};
struct file_operations smfs_sym_fops = {
};
/*
* Sysctrl entries for Snapfs
*/
/* /proc entries */
#define DEBUG_SUBSYSTEM S_SNAP
#include <linux/module.h>
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#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
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment