From: braam Date: Sat, 11 Sep 1999 06:25:42 +0000 (+0000) Subject: Much cleaner separation of the class and simulated obd code. X-Git-Tag: v1_7_100~6188 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=03e10888c589ef46adbb92e8eb9d47886e5a6271 Much cleaner separation of the class and simulated obd code. --- diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h new file mode 100644 index 0000000..a124b36 --- /dev/null +++ b/lustre/include/linux/obd_class.h @@ -0,0 +1,114 @@ +#ifndef __LINUX_SIM_OBD_H +#define __LINUX_SIM_OBD_H + +#include +#include + +#define OBD_PSDEV_MAJOR 120 +#define MAX_OBD_DEVICES 2 + +struct obd_conn_info { + unsigned int conn_id; /* handle */ + unsigned long conn_ino; /* root inode number */ + unsigned long conn_blocksize; + unsigned char conn_blocksize_bits; +}; + +struct obd_type { + struct list_head typ_chain; + struct obd_ops *typ_ops; + char *typ_name; + int typ_refcount; +}; + +struct obd_device { + struct obd_type *obd_type; + int refcnt; + struct super_block * sb; + unsigned int last_id; + unsigned long prealloc_quota; + struct list_head clients; +}; + +#define OBD_FL_SETUP 0x1 + +struct obd_ops { + int (*o_connect)(int minor, struct obd_conn_info *info); + int (*o_disconnect)(unsigned int conn_id); + int (*o_setup) (struct obd_device *dev, void *data); + int (*o_cleanup)(struct obd_device *dev); + int (*o_setattr)(unsigned int conn_id, unsigned long id, struct iattr *iattr); + int (*o_getattr)(unsigned int conn_id, unsigned long id, struct iattr *iattr); + int (*o_statfs)(unsigned int conn_id, struct statfs *statfs); + int (*o_create)(struct obd_device *, int prealloc_ino, int *er); + int (*o_destroy)(unsigned int conn_id, unsigned long ino); + unsigned long (*o_read)(unsigned int conn_id, unsigned long ino, char *buf, unsigned long count, loff_t offset, int *err); + unsigned long (*o_write)(unsigned int conn_id, unsigned long ino, char *buf, unsigned long count, loff_t offset, int *err); + long (*o_preallocate)(unsigned int conn_id, int req, long inodes[32], int *err); + void (*o_cleanup_device)(int dev); +}; + +int obd_register_type(struct obd_ops *ops, char *nm); + + +struct obd_client { + struct list_head cli_chain; + kdev_t minor; + unsigned int cli_id; + unsigned long cli_prealloc_quota; + struct list_head cli_prealloc_inodes; +}; + +struct obd_prealloc_inode { + struct list_head obd_prealloc_chain; + unsigned long inode; +}; + +/* + * ioctl commands + */ +struct oic_prealloc_s { + unsigned long cli_id; + unsigned long alloc; /* user sets it to the number of inodes requesting + * to be preallocated. kernel sets it to the actual number + * of succesfully preallocated inodes */ + long inodes[32]; /* actual inode numbers */ +}; +struct oic_attr_s { + unsigned int conn_id; + unsigned long inode; + + struct iattr iattr; +}; +struct oic_rw_s { + unsigned int conn_id; + unsigned long inode; + char * buf; + unsigned long count; + loff_t offset; +}; + +#define OBD_IOC_CREATE _IOR ('f', 3, long) +#define OBD_IOC_SETUP_SUPER _IOW ('f', 4, long) +#define OBD_IOC_CLEANUP_SUPER _IO ('f', 5 ) +#define OBD_IOC_DESTROY _IOW ('f', 6, long) +#define OBD_IOC_PREALLOCATE _IOWR('f', 7, long) +#define OBD_IOC_DEC_USE_COUNT _IO ('f', 8 ) +#define OBD_IOC_SETATTR _IOW ('f', 9, long) +#define OBD_IOC_GETATTR _IOR ('f', 10, long) +#define OBD_IOC_READ _IOWR('f', 11, long) +#define OBD_IOC_WRITE _IOWR('f', 12, long) +#define OBD_IOC_CONNECT _IOR ('f', 13, long) +#define OBD_IOC_DISCONNECT _IOW ('f', 14, long) +#define OBD_IOC_STATFS _IOWR('f', 15, long) +#define OBD_IOC_SYNC _IOR ('f', 16, long) + +#define OBD_IOC_DEC_FS_USE_COUNT _IO ('f', 32 ) + + +/* sysctl.c */ +extern void obd_sysctl_init (void); +extern void obd_sysctl_clean (void); + + +#endif /* __LINUX_SIM_OBD_H */ diff --git a/lustre/include/linux/obd_psdev.h b/lustre/include/linux/obd_psdev.h deleted file mode 100755 index 15bcd42..0000000 --- a/lustre/include/linux/obd_psdev.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef __LINUX_OBD_PSDEV_H -#define __LINUX_OBD_PSDEV_H - -#define OBD_PSDEV_MAJOR 120 - -#define ISLENTO (current->pid == psdev_vcomm.vc_pid) - -/* communication pending & processing queues */ -struct vcomm { - unsigned int vc_seq; - struct wait_queue *vc_waitq; /* Lento wait queue */ - struct list_head vc_pending; - struct list_head vc_processing; - int vc_inuse; - int vc_pid; /* Lento's pid */ -}; - -extern void obd_psdev_detach(int unit); -extern int init_obd_psdev(void); -struct vcomm psdev_vcomm; - -/* messages between presto filesystem in kernel and Venus */ -extern int presto_hard; -extern unsigned long presto_timeout; - -#define REQ_READ 1 -#define REQ_WRITE 2 -#define REQ_ASYNC 4 - -struct upc_req { - struct list_head rq_chain; - caddr_t rq_data; - u_short rq_flags; - u_short rq_read_size; /* Size is at most 5000 bytes */ - u_short rq_rep_size; - u_short rq_opcode; /* copied from data to save lookup */ - int rq_unique; - struct wait_queue *rq_sleep; /* process' wait queue */ - unsigned long rq_posttime; -}; - -#endif /* __LINUX_OBD_PSDEV_H */ diff --git a/lustre/include/linux/obd_sim.h b/lustre/include/linux/obd_sim.h new file mode 100644 index 0000000..090efa7 --- /dev/null +++ b/lustre/include/linux/obd_sim.h @@ -0,0 +1,104 @@ +#ifndef _OBD_SIM +#define _OBD_SIM + +/* obd_sim.c */ +extern struct obd_ops sim_obd_ops; +inline long ext2_block_map (struct inode * inode, long block); + +/* balloc.c */ +int ext2_new_block (const struct inode * inode, unsigned long goal, + u32 * prealloc_count, u32 * prealloc_block, int * err); +void ext2_free_blocks (const struct inode * inode, unsigned long block, + unsigned long count); +unsigned long ext2_count_free_blocks (struct super_block * sb); +int ext2_group_sparse(int group); +struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb, + unsigned int block_group, + struct buffer_head ** bh); + +/* bitmap.c */ +unsigned long ext2_count_free(struct buffer_head * map, unsigned int numchars); + +/* fsync.c */ +extern int obd_sync_file(struct file * file, struct dentry *dentry); + +/* ialloc.c */ +extern void ext2_free_inode (struct inode * inode); +extern struct inode * ext2_new_inode (const struct inode * dir, int mode, + int * err); +extern unsigned long ext2_count_free_inodes (struct super_block * sb); +extern void ext2_check_inodes_bitmap (struct super_block * sb); +extern int load_inode_bitmap (struct super_block * sb, + unsigned int block_group); + +/* inode.c */ +void obd_read_inode (struct inode * inode); +void obd_write_inode (struct inode * inode); +void obd_put_inode (struct inode * inode); +void obd_delete_inode (struct inode * inode); +void obd_discard_prealloc_blocks (struct inode * inode); +int obd_sync_inode (struct inode *inode); +struct buffer_head * obd_bread (struct inode * inode, int block, + int create, int *err); +struct buffer_head * obd_getblk (struct inode * inode, long block, + int create, int * err); + +/* interface.c */ +void obd_cleanup_device(int dev); +extern int obd_create (struct obd_device *, int inode_hint, int * err); +extern void obd_unlink (struct inode * inode); +extern struct obd_client * obd_client(int cli_id); +extern void obd_cleanup_client (struct obd_device * obddev, + struct obd_client * cli); +void obd_cleanup_device(int dev); +int obd_cleanup_super(struct obd_device * obddev); +int obd_setup_super(struct obd_device * obddev, void *data); +long obd_preallocate_inodes(unsigned int conn_id, + int req, long inodes[32], int * err); +long obd_preallocate_quota(struct super_block * sb, struct obd_client * cli, + unsigned long req, int * err); +int obd_connect (int minor, struct obd_conn_info * conninfo); +int obd_disconnect (unsigned int conn_id); +int obd_setattr(unsigned int conn_id, unsigned long ino, struct iattr * iattr); +int obd_getattr(unsigned int conn_id, unsigned long ino, struct iattr * iattr); +int obd_destroy(unsigned int conn_id, unsigned long ino); +int obd_statfs(unsigned int conn_id, struct statfs * statfs); +unsigned long obd_read(unsigned int conn_id, unsigned long ino, char * buf, + unsigned long count, loff_t offset, int * err); +unsigned long obd_write (unsigned int conn_id, unsigned long ino, char * buf, + unsigned long count, loff_t offset, int * err); + + +/* super.c */ +#define ext2_warning obd_warning +#undef ext2_error +#define ext2_error obd_warning +#define ext2_panic obd_warning +#ifdef EXT2FS_DEBUG +# undef ext2_debug +# define ext2_debug(format, a...) CDEBUG(D_EXT2, format, ## a) +#endif + +#define obd_error obd_warning +#define obd_panic obd_warning +#define obd_warning(sb, func, format, a...) CDEBUG(D_WARNING, format, ## a) + +int obd_remount (struct super_block * sb, int * flags, char * data); +struct super_block * ext2_read_super (struct super_block * sb, void * data, + int silent); + +/* truncate.c */ +void obd_truncate (struct inode * inode); + +/* operations */ +/* dir.c */ +extern struct inode_operations ext2_dir_inode_operations; + +/* file.c */ +extern struct file_operations ext2_file_operations; +extern struct inode_operations ext2_file_inode_operations; + +/* super.c */ +extern struct super_operations ext2_sops; + +#endif diff --git a/lustre/include/linux/presto.h b/lustre/include/linux/presto.h deleted file mode 100755 index 98e5976..0000000 --- a/lustre/include/linux/presto.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __PRESTO_H_ -#define __PRESTO_H_ 1 - -struct bottomfs { - struct super_operations *bottom_sops; - - struct inode_operations *bottom_dir_iops; - struct inode_operations *bottom_file_iops; - struct inode_operations *bottom_sym_iops; - - struct file_operations *bottom_dir_fops; - struct file_operations *bottom_file_fops; - struct file_operations *bottom_sym_fops; - kdev_t bottom_dev; -}; -extern struct bottomfs *the_bottom; - -/* sysctl.c */ -void presto_sysctl_init(void); -void presto_sysctl_clean(void); - -#endif diff --git a/lustre/include/linux/presto_upcall.h b/lustre/include/linux/presto_upcall.h deleted file mode 100755 index 50e91445..0000000 --- a/lustre/include/linux/presto_upcall.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Based on cfs.h from Coda, but revamped for increased simplicity. - * Linux modifications by Peter Braam, Aug 1996 - * Rewritten for InterMezzo - */ - -#ifndef _PRESTO_HEADER_ -#define _PRESTO_HEADER_ - - -/* upcall.c */ -#define SYNCHRONOUS 0 -#define ASYNCHRONOUS 1 - -int lento_permit(ino_t ino); -int lento_opendir(ino_t ino, int async); -int lento_open(ino_t ino); -int lento_journal(char *page); - - - -/* - * Kernel <--> Lento communications. - */ - -/* downcalls */ -#define LENTO_PERMIT 1 -#define LENTO_JOURNAL 2 -#define LENTO_OPENDIR 3 -#define LENTO_OPEN 4 -#define LENTO_SIGNAL 5 - -/* upcalls */ -#define PRESTO_RELEASE_JOURNAL 51 -#define PRESTO_MARK 52 - -#define LENTO_DOWNCALL(opcode) (opcode <= PRESTO_MARK && opcode >= PRESTO_RELEASE_JOURNAL) - -/* Lento <-> Presto RPC arguments */ -struct lento_up_hdr { - unsigned int opcode; - unsigned int unique; /* Keep multiple outstanding msgs distinct */ - u_short pid; /* Common to all */ - u_short uid; -}; - -/* This structure _must_ sit at the beginning of the buffer */ -struct lento_down_hdr { - unsigned int opcode; - unsigned int unique; - unsigned int result; -}; - -/* lento_permit: */ -struct lento_permit_in { - struct lento_up_hdr uh; - ino_t ino; -}; -struct lento_permit_out { - struct lento_down_hdr dh; -}; - - -/* lento_opendir: */ -struct lento_opendir_in { - struct lento_up_hdr uh; - ino_t ino; - int async; -}; -struct lento_opendir_out { - struct lento_down_hdr dh; -}; - - -/* lento_open: */ -struct lento_open_in { - struct lento_up_hdr uh; - ino_t ino; -}; -struct lento_open_out { - struct lento_down_hdr dh; -}; - -/* lento_mark_dentry */ -struct lento_mark_dentry { - struct lento_down_hdr dh; - int and_flag; - int or_flag; - char path[0]; -}; - -/* NB: every struct below begins with an up_hdr */ -union up_args { - struct lento_up_hdr uh; - struct lento_permit_in lento_permit; - struct lento_open_in lento_open; - struct lento_opendir_in lento_opendir; -}; - -union down_args { - struct lento_down_hdr dh; - struct lento_permit_out lento_permit; - struct lento_open_out lento_open; - struct lento_opendir_out lento_opendir; -}; - -union lento_downcalls { - struct lento_down_hdr dch; - struct lento_mark_dentry mark; -}; - -int lento_upcall(int read_size, int *rep_size, - union up_args *buffer, int async); -#endif - diff --git a/lustre/include/linux/sim_obd.h b/lustre/include/linux/sim_obd.h deleted file mode 100755 index a96cd4d..0000000 --- a/lustre/include/linux/sim_obd.h +++ /dev/null @@ -1,267 +0,0 @@ -#ifndef __LINUX_SIM_OBD_H -#define __LINUX_SIM_OBD_H - -#include -#include -#include -#include - -#define SIM_OBD_DEBUG - -/* - * Debug code - */ -/* global variables */ -extern int obd_debug_level; -extern int obd_print_entry; - -/* debugging masks */ -#define D_PSDEV 1 /* debug information from psdev.c */ -#define D_INODE 2 -#define D_UNUSED2 4 -#define D_UNUSED3 8 -#define D_UNUSED4 16 -#define D_WARNING 32 /* misc warnings */ -#define D_EXT2 64 /* anything from ext2_debug */ -#define D_MALLOC 128 /* print malloc, free information */ -#define D_CACHE 256 /* cache-related items */ -#define D_INFO 512 /* general information, especially from interface.c */ -#define D_IOCTL 1024 /* ioctl related information */ -#define D_BLOCKS 2048 /* ext2 block allocation */ - -#ifdef SIM_OBD_DEBUG -#define CDEBUG(mask, format, a...) \ - do { \ - if (obd_debug_level & mask) { \ - printk("(%s,l. %d): ", __FUNCTION__, __LINE__); \ - printk(format, ## a); } \ - } while (0) - -#define ENTRY \ - if (obd_print_entry) \ - printk("Process %d entered %s\n", current->pid, __FUNCTION__) - -#define EXIT \ - if (obd_print_entry) \ - printk("Process %d leaving %s\n", current->pid, __FUNCTION__) - -#else /* SIM_OBD_DEBUG */ - -# define CDEBUG ; -# define ENTRY ; -# define EXIT ; - -#endif /* SIM_OBD_DEBUG */ - - - -#define OBD_ALLOC(ptr, cast, size) \ -do { \ - if (size <= 4096) { \ - ptr = (cast)kmalloc((unsigned long) size, GFP_KERNEL); \ - CDEBUG(D_MALLOC, "kmalloced: %x at %x.\n", \ - (int) size, (int) ptr); \ - } else { \ - ptr = (cast)vmalloc((unsigned long) size); \ - CDEBUG(D_MALLOC, "vmalloced: %x at %x.\n", \ - (int) size, (int) ptr); \ - } \ - if (ptr == 0) { \ - printk("kernel malloc returns 0 at %s:%d\n", \ - __FILE__, __LINE__); \ - } \ - memset(ptr, 0, size); \ -} while (0) - -#define OBD_FREE(ptr,size) \ -do { \ - if (size <= 4096) { \ - kfree_s((ptr), (size)); \ - CDEBUG(D_MALLOC, "kfreed: %x at %x.\n", \ - (int) size, (int) ptr); \ - } else { \ - vfree((ptr)); \ - CDEBUG(D_MALLOC, "vfreed: %x at %x.\n", \ - (int) size, (int) ptr); \ - } \ -} while (0) - - - - -#define MAX_OBD_DEVICES 2 -struct obd_conn_info { - unsigned int conn_id; /* handle */ - unsigned long conn_ino; /* root inode number */ - unsigned long conn_blocksize; - unsigned char conn_blocksize_bits; -}; - -struct obd_device { - int refcnt; - struct super_block * sb; - unsigned int last_id; - unsigned long prealloc_quota; - struct list_head clients; -}; - -struct obd_client { - struct list_head cli_chain; - kdev_t minor; - unsigned int cli_id; - unsigned long cli_prealloc_quota; - struct list_head cli_prealloc_inodes; -}; - -struct obd_prealloc_inode { - struct list_head obd_prealloc_chain; - unsigned long inode; -}; - -/* - * ioctl commands - */ -struct oic_prealloc_s { - unsigned long cli_id; - unsigned long alloc; /* user sets it to the number of inodes requesting - * to be preallocated. kernel sets it to the actual number - * of succesfully preallocated inodes */ - long inodes[32]; /* actual inode numbers */ -}; -struct oic_attr_s { - unsigned int conn_id; - unsigned long inode; - - struct iattr iattr; -}; -struct oic_rw_s { - unsigned int conn_id; - unsigned long inode; - char * buf; - unsigned long count; - loff_t offset; -}; - -#define OBD_IOC_CREATE _IOR ('f', 3, long) -#define OBD_IOC_SETUP_SUPER _IOW ('f', 4, long) -#define OBD_IOC_CLEANUP_SUPER _IO ('f', 5 ) -#define OBD_IOC_DESTROY _IOW ('f', 6, long) -#define OBD_IOC_PREALLOCATE _IOWR('f', 7, long) -#define OBD_IOC_DEC_USE_COUNT _IO ('f', 8 ) -#define OBD_IOC_SETATTR _IOW ('f', 9, long) -#define OBD_IOC_GETATTR _IOR ('f', 10, long) -#define OBD_IOC_READ _IOWR('f', 11, long) -#define OBD_IOC_WRITE _IOWR('f', 12, long) -#define OBD_IOC_CONNECT _IOR ('f', 13, long) -#define OBD_IOC_DISCONNECT _IOW ('f', 14, long) -#define OBD_IOC_STATFS _IOWR('f', 15, long) -#define OBD_IOC_SYNC _IOR ('f', 16, long) - - - -#define OBD_IOC_DEC_FS_USE_COUNT _IO ('f', 32 ) - -/* balloc.c */ -int ext2_new_block (const struct inode * inode, unsigned long goal, - u32 * prealloc_count, u32 * prealloc_block, int * err); -void ext2_free_blocks (const struct inode * inode, unsigned long block, - unsigned long count); -unsigned long ext2_count_free_blocks (struct super_block * sb); -int ext2_group_sparse(int group); -struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb, - unsigned int block_group, - struct buffer_head ** bh); - - -/* bitmap.c */ -unsigned long ext2_count_free(struct buffer_head * map, unsigned int numchars); - -/* fsync.c */ -extern int obd_sync_file(struct file * file, struct dentry *dentry); - -/* ialloc.c */ -extern void ext2_free_inode (struct inode * inode); -extern struct inode * ext2_new_inode (const struct inode * dir, int mode, - int * err); -extern unsigned long ext2_count_free_inodes (struct super_block * sb); -extern void ext2_check_inodes_bitmap (struct super_block * sb); -extern int load_inode_bitmap (struct super_block * sb, - unsigned int block_group); - -/* inode.c */ -void obd_read_inode (struct inode * inode); -void obd_write_inode (struct inode * inode); -void obd_put_inode (struct inode * inode); -void obd_delete_inode (struct inode * inode); -void obd_discard_prealloc_blocks (struct inode * inode); -int obd_sync_inode (struct inode *inode); -struct buffer_head * obd_bread (struct inode * inode, int block, - int create, int *err); -struct buffer_head * obd_getblk (struct inode * inode, long block, - int create, int * err); - -/* interface.c */ -void obd_cleanup_device(int dev); -extern int obd_create (struct super_block * sb, int inode_hint, int * err); -extern void obd_unlink (struct inode * inode); -extern struct obd_client * obd_client(int cli_id); -extern void obd_cleanup_client (struct obd_device * obddev, - struct obd_client * cli); -void obd_cleanup_device(int dev); -int obd_cleanup_super(struct obd_device * obddev); -int obd_setup_super(struct obd_device * obddev, int sbdev); -long obd_preallocate_inodes(unsigned int conn_id, - int req, long inodes[32], int * err); -long obd_preallocate_quota(struct super_block * sb, struct obd_client * cli, - unsigned long req, int * err); -int obd_connect (int minor, struct obd_conn_info * conninfo); -int obd_disconnect (unsigned int conn_id); -int obd_setattr(unsigned int conn_id, unsigned long ino, struct iattr * iattr); -int obd_getattr(unsigned int conn_id, unsigned long ino, struct iattr * iattr); -int obd_destroy(unsigned int conn_id, unsigned long ino); -int obd_statfs(unsigned int conn_id, struct statfs * statfs); -unsigned long obd_read(unsigned int conn_id, unsigned long ino, char * buf, - unsigned long count, loff_t offset, int * err); -unsigned long obd_write (unsigned int conn_id, unsigned long ino, char * buf, - unsigned long count, loff_t offset, int * err); - -/* ioctl.c */ -int obd_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, - unsigned long arg); - -/* super.c */ -#define ext2_warning obd_warning -#undef ext2_error -#define ext2_error obd_warning -#define ext2_panic obd_warning -#ifdef EXT2FS_DEBUG -# undef ext2_debug -# define ext2_debug(format, a...) CDEBUG(D_EXT2, format, ## a) -#endif - -#define obd_error obd_warning -#define obd_panic obd_warning -#define obd_warning(sb, func, format, a...) CDEBUG(D_WARNING, format, ## a) - -int obd_remount (struct super_block * sb, int * flags, char * data); -struct super_block * ext2_read_super (struct super_block * sb, void * data, - int silent); - -/* sysctl.c */ -extern void obd_sysctl_init (void); -extern void obd_sysctl_clean (void); - -/* truncate.c */ -void obd_truncate (struct inode * inode); - -/* operations */ -/* dir.c */ -extern struct inode_operations ext2_dir_inode_operations; - -/* file.c */ -extern struct file_operations ext2_file_operations; -extern struct inode_operations ext2_file_inode_operations; - -/* super.c */ -extern struct super_operations ext2_sops; -#endif /* __LINUX_SIM_OBD_H */ diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c new file mode 100644 index 0000000..b33ee67 --- /dev/null +++ b/lustre/obdclass/class_obd.c @@ -0,0 +1,502 @@ +/* + * An implementation of a loadable kernel mode driver providing + * multiple kernel/user space bidirectional communications links. + * + * Author: Alan Cox + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Adapted to become the Linux 2.0 Coda pseudo device + * Peter Braam + * Michael Callahan + * + * Changes for Linux 2.1 + * Copyright (c) 1997 Carnegie-Mellon University + * + * Redone again for Intermezzo + * Copyright (c) 1998 Peter J. Braam + * + * Hacked up again for simulated OBD + * Copyright (c) 1999 Stelias Computing, Inc. + * (authors {pschwan,braam}@stelias.com) + * Copyright (C) 1999 Seagate Technology, Inc. + * + * + */ + +#define EXPORT_SYMTAB + +#include /* for CONFIG_PROC_FS */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +int obd_print_entry = 1; +int obd_debug_level = 4095; +struct obd_device obd_dev[MAX_OBD_DEVICES]; +struct list_head obd_types; + +static int obd_class_open(struct inode * inode, struct file * file) +{ + int dev; + ENTRY; + + if (!inode) + return -EINVAL; + dev = MINOR(inode->i_rdev); + if (dev >= MAX_OBD_DEVICES) + return -ENODEV; + obd_dev[dev].refcnt++; + CDEBUG(D_PSDEV, "Refcount now %d\n", obd_dev[dev].refcnt++); + + MOD_INC_USE_COUNT; + EXIT; + return 0; +} + +static int obd_class_release(struct inode * inode, struct file * file) +{ + int dev; + ENTRY; + + if (!inode) + return -EINVAL; + dev = MINOR(inode->i_rdev); + if (dev >= MAX_OBD_DEVICES) + return -ENODEV; + fsync_dev(inode->i_rdev); + if (obd_dev[dev].refcnt <= 0) + printk(KERN_ALERT "presto_psdev_release: refcount(%d) <= 0\n", + obd_dev[dev].refcnt); + obd_dev[dev].refcnt--; + + CDEBUG(D_PSDEV, "Refcount now %d\n", obd_dev[dev].refcnt++); + + MOD_DEC_USE_COUNT; + + EXIT; + return 0; +} + +static struct obd_type *obd_nm_to_type(char *nm) +{ + struct list_head *tmp; + struct obd_type *type; + + tmp = &obd_types; + while ( (tmp = tmp->next) != &obd_types ) { + type = list_entry(tmp, struct obd_type, typ_chain); + if (strlen(type->typ_name) == strlen(nm) && + strcmp(type->typ_name, nm) == 0 ) { + return type; + } + } + return NULL; +} + +static int obd_class_ioctl (struct inode * inode, struct file * filp, + unsigned int cmd, unsigned long arg) +{ + int err, i_ino, dev; + struct obd_device *obddev; + struct oic_rw_s rw_s; /* read, write */ + long int cli_id; /* connect, disconnect */ + + struct oic_prealloc_s prealloc; /* preallocate */ + if (!inode) + return -EINVAL; + dev = MINOR(inode->i_rdev); + if (dev > MAX_OBD_DEVICES) + return -ENODEV; + + obddev = &obd_dev[dev]; + + /* has this minor been registered? */ + if (cmd != OBD_IOC_SETUP_SUPER && !obd_dev[dev].obd_type) + return -ENODEV; + + switch (cmd) { + case OBD_IOC_SETUP_SUPER: { + struct obd_type *type; + + struct setup { + int setup_data; + char setup_type[24]; + } input; + + if ( obddev->obd_type ) { + CDEBUG(D_IOCTL, "Device %d already setup (type %s)\n", + dev, obddev->obd_type->typ_name); + return -1; + } + + /* get data structures */ + if ( (err= copy_from_user(&input, (void *) arg, sizeof(struct setup))) ) + return err; + + type = obd_nm_to_type(input.setup_type); + if ( !type ) { + CDEBUG(D_IOCTL, "Trying to register non existent type %s\n", + input.setup_type); + return -1; + } + obddev->obd_type = type; + + CDEBUG(D_IOCTL, "Registering %d, type %s\n", + dev, input.setup_type); + if ( obddev->obd_type->typ_ops->o_setup(obddev, + &input.setup_data)){ + obddev->obd_type = NULL; + return -1; + } else { + type->typ_refcount++; + return 0; + } + + + } + case OBD_IOC_CLEANUP_SUPER: + + /* cleanup has no argument */ + if ( obddev->obd_type->typ_refcount ) + obddev->obd_type->typ_refcount--; + else + printk("OBD_CLEANUP: refcount wrap!\n"); + + if ( obddev->obd_type->typ_ops->o_cleanup ) + return obddev->obd_type->typ_ops->o_cleanup(obddev); + else + return 0; + + case OBD_IOC_CONNECT: + { + struct obd_conn_info conninfo; + + if (obddev->obd_type->typ_ops->o_connect(dev, &conninfo)) + return -EINVAL; + + return copy_to_user((int *)arg, &conninfo, + sizeof(struct obd_conn_info)); + } + case OBD_IOC_DISCONNECT: + /* frees data structures */ + get_user(cli_id, (int *) arg); + + obddev->obd_type->typ_ops->o_disconnect(cli_id); + return 0; + + case OBD_IOC_SYNC: + /* sync doesn't need a connection ID, because it knows + * what device it was called on, and can thus get the + * superblock that it needs. */ + if (!obddev->sb || !obddev->sb->s_dev) { + CDEBUG(D_IOCTL, "fatal: device not initialized.\n"); + err = -EINVAL; + } else { + if ((err = fsync_dev(obddev->sb->s_dev))) + CDEBUG(D_IOCTL, "sync: fsync_dev failure\n"); + else + CDEBUG(D_IOCTL, "sync: success\n"); + } + + return put_user(err, (int *) arg); + case OBD_IOC_CREATE: + /* similarly, create doesn't need a connection ID for + * the same reasons. */ + if (!obddev->sb) { + CDEBUG(D_IOCTL, "fatal: device not initialized.\n"); + return put_user(-EINVAL, (int *) arg); + } + + i_ino = obddev->obd_type->typ_ops->o_create(obddev, 0, &err); + if (err) { + CDEBUG(D_IOCTL, "create: obd_inode_new failure\n"); + /* 0 is the only error value */ + return put_user(0, (int *) arg); + } + + return put_user(i_ino, (int *) arg); + case OBD_IOC_DESTROY: + { + struct destroy_s { + unsigned int conn_id; + unsigned int ino; + } destroy; + copy_from_user(&destroy, (int *)arg, sizeof(struct destroy_s)); + if ( !obddev->obd_type || + !obddev->obd_type->typ_ops->o_destroy) + return -EINVAL; + + return obddev->obd_type->typ_ops->o_destroy(destroy.conn_id, destroy.ino); + } + case OBD_IOC_SETATTR: + { + int err; + struct tmp { + unsigned int conn_id; + unsigned long ino; + struct iattr iattr; + } foo; + + err= copy_from_user(&foo, (int *)arg, sizeof(struct tmp)); + if (err) + return err; + + if ( !obddev->obd_type || + !obddev->obd_type->typ_ops->o_setattr) + return -EINVAL; + + return obddev->obd_type->typ_ops->o_setattr(foo.conn_id, foo.ino, &foo.iattr); + } + + case OBD_IOC_GETATTR: + { + int err; + struct tmp { + unsigned int conn_id; + unsigned long ino; + } foo; + struct iattr iattr; + copy_from_user(&foo, (int *)arg, sizeof(struct tmp)); + + if ( !obddev->obd_type || + !obddev->obd_type->typ_ops->o_getattr) + return -EINVAL; + + if (obddev->obd_type->typ_ops->o_getattr(foo.conn_id, + foo.ino, &iattr)) + return -EINVAL; + + err = copy_to_user((int *)arg, &iattr, sizeof(iattr)); + return err; + } + + case OBD_IOC_READ: + { + int err; + + err = copy_from_user(&rw_s, (int *)arg, sizeof(struct oic_rw_s)); + if ( err ) + return err; + + if ( !obddev->obd_type->typ_ops || + !obddev->obd_type->typ_ops->o_read ) + return -EINVAL; + + rw_s.count = obddev->obd_type->typ_ops->o_read(rw_s.conn_id, + rw_s.inode, + rw_s.buf, + rw_s.count, + rw_s.offset, + &err); + if ( err ) + return err; + + err = copy_to_user((int*)arg, &rw_s.count, + sizeof(unsigned long)); + return err; + } + + case OBD_IOC_WRITE: + { + int err; + + copy_from_user(&rw_s, (int *)arg, sizeof(struct oic_rw_s)); + CDEBUG(D_IOCTL, "\n"); + if ( !obddev->obd_type->typ_ops->o_write ) + return -EINVAL; + rw_s.count = + obddev->obd_type->typ_ops->o_write(rw_s.conn_id, + rw_s.inode, + rw_s.buf, + rw_s.count, + rw_s.offset, + &err); + + printk("Result rw_s.count %ld\n", rw_s.count); + return (int)rw_s.count; + copy_to_user((int *)arg, &rw_s.count, + sizeof(unsigned long)); + return err; + } + case OBD_IOC_PREALLOCATE: + copy_from_user(&prealloc, (int *)arg, + sizeof(struct oic_prealloc_s)); + + if (!obddev->sb || !obddev->sb->s_dev) { + CDEBUG(D_IOCTL, "fatal: device not initialized.\n"); + return -EINVAL; + } + + if (!obddev->obd_type || + !obddev->obd_type->typ_ops->o_preallocate) + return -EINVAL; + + prealloc.alloc = + obddev->obd_type->typ_ops->o_preallocate(prealloc.cli_id, prealloc.alloc, + prealloc.inodes, &err); + if ( err ) + return err; + return copy_to_user((int *)arg, &prealloc, + sizeof(struct oic_prealloc_s)); + case OBD_IOC_STATFS: + { + struct statfs *tmp; + unsigned int conn_id; + + tmp = (void *)arg + sizeof(unsigned int); + get_user(conn_id, (int *) arg); + if ( !obddev->obd_type || + !obddev->obd_type->typ_ops->o_statfs) + return -EINVAL; + + return obddev->obd_type->typ_ops->o_statfs(conn_id, tmp); + } + default: + printk("invalid ioctl: cmd = %u, arg = %lu\n", cmd, arg); + return -ENOTTY; + } +} + +/* Driver interface done, utility functions follow */ + +int obd_register_type(struct obd_ops *ops, char *nm) +{ + struct obd_type *type; + + if ( obd_nm_to_type(nm) ) { + CDEBUG(D_IOCTL, "Type %s already registered\n", nm); + return -1; + } + + OBD_ALLOC(type, struct obd_type * , sizeof(*type)); + if ( !type ) + return -ENOMEM; + memset(type, 0, sizeof(*type)); + INIT_LIST_HEAD(&type->typ_chain); + + list_add(&type->typ_chain, obd_types.next); + type->typ_ops = ops; + type->typ_name = nm; + return 0; +} + +int obd_unregister_type(char *nm) +{ + struct obd_type *type = obd_nm_to_type(nm); + + if ( !type ) + return -1; + + if ( type->typ_refcount ) + return -1; + + list_del(&type->typ_chain); + OBD_FREE(type, sizeof(*type)); + return 0; +} + +/* declare character device */ +static struct file_operations obd_psdev_fops = { + NULL, /* llseek */ + NULL, /* read */ + NULL, /* write */ + NULL, /* presto_psdev_readdir */ + NULL, /* poll */ + obd_class_ioctl, /* ioctl */ + NULL, /* presto_psdev_mmap */ + obd_class_open, /* open */ + NULL, + obd_class_release, /* release */ + NULL, /* fsync */ + NULL, /* fasync */ + NULL, /* check_media_change */ + NULL, /* revalidate */ + NULL /* lock */ +}; + + +/* modules setup */ + +int init_obd(void) +{ + int i; + + printk(KERN_INFO "OBD class driver v0.002, braam@stelias.com\n"); + + INIT_LIST_HEAD(&obd_types); + + if (register_chrdev(OBD_PSDEV_MAJOR,"obd_psdev", + &obd_psdev_fops)) { + printk(KERN_ERR "obd_psdev: unable to get major %d\n", + OBD_PSDEV_MAJOR); + return -EIO; + } + + for (i = 0; i < MAX_OBD_DEVICES; i++) { + obd_dev[i].obd_type = 0; + obd_dev[i].refcnt = 0; + obd_dev[i].sb = NULL; + obd_dev[i].last_id = 0; + INIT_LIST_HEAD(&obd_dev[i].clients); + } + + obd_sysctl_init(); + + return 0; +} + +EXPORT_SYMBOL(obd_register_type); +EXPORT_SYMBOL(obd_unregister_type); + +EXPORT_SYMBOL(obd_print_entry); +EXPORT_SYMBOL(obd_debug_level); +EXPORT_SYMBOL(obd_dev); + +#ifdef MODULE +int init_module(void) +{ + return init_obd(); +} + +void cleanup_module(void) +{ + int i; + ENTRY; + + unregister_chrdev(OBD_PSDEV_MAJOR, "obd_psdev"); + for (i = 0; i < MAX_OBD_DEVICES; i++) { + struct obd_device *obddev = &obd_dev[i]; + if ( obddev->obd_type && + obddev->obd_type->typ_ops->o_cleanup_device ) + return obddev->obd_type->typ_ops->o_cleanup_device(i); + } + + obd_sysctl_clean(); +} +#endif diff --git a/lustre/obdclass/obdcontrol b/lustre/obdclass/obdcontrol index ceb889e..ab31b64 100755 --- a/lustre/obdclass/obdcontrol +++ b/lustre/obdclass/obdcontrol @@ -172,7 +172,8 @@ sub execute_line { sub Setup { my $err = 0; - my $packed = pack("L", $::st->rdev()); + + my $packed = pack("La24", $::st->rdev(), "sim_obd"); my $rc = ioctl(DEV_OBD, &OBD_IOC_SETUP_SUPER, $packed); if (!defined $rc) { diff --git a/lustre/obdclass/sysctl.c b/lustre/obdclass/sysctl.c index e36a48c..3716464 100644 --- a/lustre/obdclass/sysctl.c +++ b/lustre/obdclass/sysctl.c @@ -11,10 +11,7 @@ #include #include -#include -#include -#include -#include +#include struct ctl_table_header *obd_table_header = NULL;