--- /dev/null
+#ifndef __LINUX_SIM_OBD_H
+#define __LINUX_SIM_OBD_H
+
+#include <linux/fs.h>
+#include <linux/ext2_fs.h>
+
+#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 */
+++ /dev/null
-#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 */
--- /dev/null
+#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
+++ /dev/null
-#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
+++ /dev/null
-/*
- * 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
-
+++ /dev/null
-#ifndef __LINUX_SIM_OBD_H
-#define __LINUX_SIM_OBD_H
-
-#include <linux/fs.h>
-#include <linux/ext2_fs.h>
-#include <linux/malloc.h>
-#include <linux/vmalloc.h>
-
-#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 */
--- /dev/null
+/*
+ * An implementation of a loadable kernel mode driver providing
+ * multiple kernel/user space bidirectional communications links.
+ *
+ * Author: Alan Cox <alan@cymru.net>
+ *
+ * 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 <braam@maths.ox.ac.uk>
+ * Michael Callahan <mjc@emmy.smith.edu>
+ *
+ * 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 <linux/config.h> /* for CONFIG_PROC_FS */
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/lp.h>
+#include <linux/malloc.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/delay.h>
+#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <asm/io.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/poll.h>
+#include <asm/uaccess.h>
+
+#include <linux/obd_support.h>
+#include <linux/obd_class.h>
+
+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
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) {
#include <asm/uaccess.h>
#include <linux/utsname.h>
-#include <linux/sim_obd.h>
-#include <linux/presto.h>
-#include <linux/obd_psdev.h>
-#include <linux/presto_upcall.h>
+#include <linux/obd_support.h>
struct ctl_table_header *obd_table_header = NULL;