--- /dev/null
+/* object based disk file system
+ *
+ * This software is licensed under the GPL. See the file COPYING in the
+ * top directory of this distribution for details.
+ *
+ * Copyright (C), 1999, Stelias Computing Inc
+ *
+ *
+ */
+
+
+#ifndef _INOFS_H
+#define INOFS_H
+#include <linux/obd_class.h>
+
+/* super.c */
+void inofs_read_inode(struct inode *inode);
+
+
+/* file.c */
+ssize_t inofs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos);
+
+
+/* rw.c */
+struct page *inofs_getpage(struct inode *inode, unsigned long offset, int create, int locked);
+int inofs_writepage(struct file *file, struct page *page);
+int inofs_write_one_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf);
+
+/* namei.c */
+struct dentry *inofs_lookup(struct inode * dir, struct dentry *dentry);
+int inofs_create (struct inode * dir, struct dentry * dentry, int mode);
+int inofs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
+int inofs_rmdir(struct inode *dir, struct dentry *dentry);
+int inofs_unlink(struct inode *dir, struct dentry *dentry);
+int inofs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev);
+int inofs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
+int inofs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry);
+int inofs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry);
+/* dir.c */
+int inofs_readdir(struct file * filp, void * dirent, filldir_t filldir);
+int inofs_check_dir_entry (const char * function, struct inode * dir,
+ struct ext2_dir_entry_2 * de,
+ struct page * page,
+ unsigned long offset);
+
+struct inofs_sb_info {
+ struct obd_conn_info osi_conn_info;
+ struct super_block *osi_super;
+ struct obd_device *osi_obd;
+ struct obd_ops *osi_ops;
+};
+
+void inofs_sysctl_init(void);
+void inofs_sysctl_clean(void);
+
+struct inofs_inode_info;
+
+extern struct file_operations inofs_file_ops;
+extern struct inode_operations inofs_inode_ops;
+
+static inline struct obd_ops *iops(struct inode *i)
+{
+ struct inofs_sb_info *sbi = (struct inofs_sb_info *) i->i_sb->u.generic_sbp;
+ return sbi->osi_ops;
+}
+
+#define NOLOCK 0
+#define LOCKED 1
+
+
+#define INOFS_SUPER_MAGIC 0x4711
+
+#endif
+
};
-
-#define OBD_PROGRAM 100003
-#define OBD_VERSION 2
-#define OBDPROC_NULL 0
-#define OBDPROC_GETATTR 1
-#define OBDPROC_SETATTR 2
-#define OBDPROC_ROOT 3
-#define OBDPROC_LOOKUP 4
-#define OBDPROC_READLINK 5
-#define OBDPROC_READ 6
-#define OBDPROC_WRITECACHE 7
-#define OBDPROC_WRITE 8
-#define OBDPROC_CREATE 9
-#define OBDPROC_REMOVE 10
-#define OBDPROC_RENAME 11
-#define OBDPROC_LINK 12
-#define OBDPROC_SYMLINK 13
-#define OBDPROC_MKDIR 14
-
-
-
extern struct rpc_program obd_program;
-
-
-
-
struct obd_target {
struct sockaddr_in tgt_addr;
int tgt_flags;
struct rpc_obd {
- struct rpc_clnt * client; /* RPC client handle */
- struct sockaddr_in addr;
+ struct rpc_clnt * handle; /* RPC client handle */
+ struct sockaddr_in addr;
int flags; /* various flags */
+ int timeo;
+ int retrans;
int rsize; /* read size */
int wsize; /* write size */
unsigned int bsize; /* server block size */
};
+#define OBD_PROGRAM 300001
+#define OBD_VERSION 1
+#define OBDPROC_NULL 0
+#define OBDPROC_ECHOINT 1
+
+#ifdef OBD_NEED_XDR_TYPES
+
+struct obd_echoint_in {
+ __u32 in;
+};
+
+struct obd_echoint_out {
+ __u32 out;
+};
+
+
+#endif /* OBD_NEED_XDR_TYPES */
+
+
+int obd_proc_echoint(struct rpc_obd *target, __u32 in, __u32 *out);
+
+
#endif
#define D_INFO 512 /* general information, especially from interface.c */
#define D_IOCTL 1024 /* ioctl related information */
#define D_BLOCKS 2048 /* ext2 block allocation */
+#define D_RPC 4096 /* ext2 block allocation */
#ifdef SIM_OBD_DEBUG
#define CDEBUG(mask, format, a...) \
#ifndef _OBDFS_H
#define OBDFS_H
-#include <../obd/linux/obd_class.h>
+#include <linux/obd_class.h>
/* super.c */
void obdfs_read_inode(struct inode *inode);
--- /dev/null
+include ../config.mk
+
+MODULE = obdclass.o
+
+CFILES = genops.c class_obd.c sysctl.c
+
+include ../make.rules
\ No newline at end of file
include ../config.mk
-MODDIR = $(PREFIX)/lib/modules/$(UTS_RELEASE)
+MODULE = obdfs.o
+CFILES=file.c dir.c sysctl.c super.c rw.c namei.c # symlink.c
-ifndef CFLAGS
-# Don't remove "-O2" or bad things will happen!
-KFLAGS = -O2 -Wall -Wstrict-prototypes -pipe -I../obd
-endif
-
-CPPFLAGS = $(PCDEBUG) -D__KERNEL__ -DMODULE -I../include \
- -I. -I$(LINUX)/include $(SMPFLAG)
-COFLAGS = -kv
-
-ifeq ($(CONFIG_MODVERSIONS),"y")
-CFLAGS= $(KFLAGS) $(MFLAG)
-else
-CFLAGS= $(KFLAGS)
-endif
-
-SRCS=file.c dir.c sysctl.c super.c rw.c namei.c # symlink.c
-OBJS=$(SRCS:%.c=%.o)
-
-MODULES = obdfs.o
-
-all: ../.prereq.ok kcheck $(MODULES)
-
-showvar:
- @echo CFLAGS $(CFLAGS)
- @echo CPPFLAGS $(CPPFLAGS)
- @echo MODDIR $(MODDIR)
- @echo UTS_RELEASE $(UTS_RELEASE)
- @echo SRCS $(SRCS)
- @echo OBJS $(OBJS)
-
-clean:
- rm -f core core.* *.o *.d .*.o *.s *.a *~ .depend .depfiles/*.d
-
-MODDIR = $(PREFIX)/lib/modules/$(UTS_RELEASE)
-
-install: $(MODULES) ../.prereq.ok kcheck
- -mkdir -p $(MODDIR)/fs
- install -o root -g root -m 644 $(MODULES) $(MODDIR)/fs/
-
-# Stuff to automatically maintain dependency files
-
-.c.o:
- $(CC) -MD $(CFLAGS) $(CPPFLAGS) -c $<
- @mkdir -p .depfiles ; mv $*.d .depfiles
-
-kcheck:
- @. ../config.out ; \
- if [ "$$CHECK" != "" ] ; then \
- if [ "`cksum < $$CHECK`" != "$$CKSUM" ] ; then \
- /bin/echo -n "Kernel configuration has changed." ; \
- /bin/echo " Please re-run 'make config'." ; \
- exit 1 ; \
- fi ; \
- fi
-
-obdfs.o: $(OBJS)
- $(LD) -m "`ld --help | awk '/supported emulations/ {print $$4}'`" -r -o $@ $(OBJS)
-
--include $(SRCS:%.c=.depfiles/%.d)
+include ../make.rules
\ No newline at end of file
#include <linux/locks.h>
#include <linux/quotaops.h>
#include <linux/iobuf.h>
-#include "obdfs.h"
+#include <linux/obdfs.h>
#include <linux/obd_support.h>
#if 0
#include <linux/smp_lock.h>
#include <linux/obd_support.h>
-#include "obdfs.h"
+#include <linux/obdfs.h>
static inline void remove_suid(struct inode *inode)
{
#include <linux/iobuf.h>
#include <linux/obd_support.h>
-#include "obdfs.h"
+#include <linux/obdfs.h>
/*
* define how far ahead to read directories while searching them.
+++ /dev/null
-Considerations for an API between OBD's and OBDFS
-
-
-OBDFS
-
-Methods needed:
-
-struct super_operations {
- void (*read_inode) (struct inode *);
- void (*write_inode) (struct inode *);
- void (*put_inode) (struct inode *);
- void (*delete_inode) (struct inode *);
- int (*notify_change) (struct dentry *, struct iattr *);
- void (*put_super) (struct super_block *);
- void (*write_super) (struct super_block *);
- int (*statfs) (struct super_block *, struct statfs *, int);
-* int (*remount_fs) (struct super_block *, int *, char *);
- void (*clear_inode) (struct inode *);
-* void (*umount_begin) (struct super_block *);
-};
-
-
-read_inode:
-
-Called from function iget(ino, dev) - through get_new_inode.
-Typically called only when a VFS inode is instantiated by FS, i.e.
-upon lookup, create, mkdir, or upon mounting for the / inode.
-
- - executed for new inodes and for existing inodes
- - for new inodes, avoid traffic to disk
-
-E.g:
-
-lookup("name in dir-inode")
-{
- get data from dir-inode;
- find ino of "name" in this data;
- iget(sb(dev), ino);
- ---> calls read_inode
- ----> obd_getattr(obj-no = ino)
-}
-
-create("name in dir-inode")
-{
- get ino for name from pre-alloced obj-no's
- ---> may call obd_prealloc_ids(hint)
-
- iget(sb(dev), ino)
- ---> call read_inode
- ---> do not contact OBD, fill in from FS
-
- change data from dir-inode, to contain ("name, ino");
-}
-
-mkdir("name in dir-inode")
-{
- as above
-}
-
-read_super(dev, data)
-{
- struct obdfs_sb *sb = ... ;
- obd_connect(dev, &sb->obdfs_conn_info);
-
- iget(sb, sb->obdfs_conn_info->conn_ino);
-
-
-}
-
-We currently have:
-
-struct obd_conn_info {
- unsigned int conn_id;
- unsigned long conn_ino;
- unsigned long conn_blocksize;
- unsigned char conn_blocksize_bits;
-};
-
-read_inode(inode)
-{
- struct iattr attr;
-
-
- if ( inode in inode_attr cache ) {
- get_attr_from_cache(inode, &attr);
- } else {
- obd_getattr(conn_id, inode->i_ino, &attr);
- }
-
- inode_setattr(inode, &attr);
-}
-
-Write_inode is called from the bdflush (sync_dev) routines, through
-write_inode, sync_inode, sync_list, sync_inodes etc:
-
-void sync_dev(kdev_t dev)
-{
- sync_buffers(dev, 0);
- sync_supers(dev);
- sync_inodes(dev);
- sync_buffers(dev, 0);
- DQUOT_SYNC(dev);
- /*
- * FIXME(eric) we need to sync the physical devices here.
- * This is because some (scsi) controllers have huge amounts of
- * cache onboard (hundreds of Mb), and we need to instruct
- * them to commit all of the dirty memory to disk, and we should
- * not return until this has happened.
- *
- * This would need to get implemented by going through the assorted
- * layers so that each block major number can be synced, and this
- * would call down into the upper and mid-layer scsi.
- */
-}
-
-This sync_inodes function is responsible (for "block" disk file
-systems) for copying the modified inode metadata into the buffer
-cache. The sync_buffers call which follows sync_inodes is responsible
-for writing back this meta data. For OBD's this is different.
-
-I expect the following routine to be there:
-
-sync_inode_pages(dev,0);
-sync_supers(dev);
-sync_inode_metadata(dev);
-
-
-The statfs function should return simple summary information available
-on the disk: %free, total space, etc. May require a new obd_command.
-
-Similarly write_super would instruct the disk to commit any pending
-data. This is called from do_unmount just before put_super (the
-latter breaks down the vm super block structure).
-
-Write_super should:
-- undo pre-allocated inode numbers
-
-The disk itself also needs a cleanup function.
-
-struct file_operations {
- loff_t (*llseek) (struct file *, loff_t, int);
- ssize_t (*read) (struct file *, char *, size_t, loff_t *);
- ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
- int (*readdir) (struct file *, void *, filldir_t);
- unsigned int (*poll) (struct file *, struct poll_table_struct *);
- int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
- int (*mmap) (struct file *, struct vm_area_struct *);
- int (*open) (struct inode *, struct file *);
- int (*flush) (struct file *);
- int (*release) (struct inode *, struct file *);
- int (*fsync) (struct file *, struct dentry *);
- int (*fasync) (int, struct file *, int);
- int (*check_media_change) (kdev_t dev);
- int (*revalidate) (kdev_t dev);
- int (*lock) (struct file *, int, struct file_lock *);
-};
-
-
-struct inode_operations {
- struct file_operations * default_file_ops;
- int (*create) (struct inode *,struct dentry *,int);
- struct dentry * (*lookup) (struct inode *,struct dentry *);
- int (*link) (struct dentry *,struct inode *,struct dentry *);
- int (*unlink) (struct inode *,struct dentry *);
- int (*symlink) (struct inode *,struct dentry *,const char *);
- int (*mkdir) (struct inode *,struct dentry *,int);
- int (*rmdir) (struct inode *,struct dentry *);
- int (*mknod) (struct inode *,struct dentry *,int,int);
- int (*rename) (struct inode *, struct dentry *,
- struct inode *, struct dentry *);
- int (*readlink) (struct dentry *, char *,int);
- struct dentry * (*follow_link) (struct dentry *, struct dentry *, unsigned int);
- /*
- * the order of these functions within the VFS template has been
- * changed because SMP locking has changed: from now on all get_block,
- * readpage, writepage and flushpage functions are supposed to do
- * whatever locking they need to get proper SMP operation - for
- * now in most cases this means a lock/unlock_kernel at entry/exit.
- * [The new order is also slightly more logical :)]
- */
- /*
- * Generic block allocator exported by the lowlevel fs. All metadata
- * details are handled by the lowlevel fs, all 'logical data content'
- * details are handled by the highlevel block layer.
- */
- int (*get_block) (struct inode *, long, struct buffer_head *, int);
-
- int (*readpage) (struct file *, struct page *);
- int (*writepage) (struct file *, struct page *);
- int (*flushpage) (struct inode *, struct page *, unsigned long);
-
- void (*truncate) (struct inode *);
- int (*permission) (struct inode *, int);
- int (*smap) (struct inode *,int);
- int (*revalidate) (struct dentry *);
-};
-
-
#include <linux/pagemap.h>
#include <linux/smp_lock.h>
-#include <../obd/linux/obd_support.h>
-#include <../obd/linux/obd_sim.h>
-#include <obdfs.h>
+#include <linux/obd_support.h>
+#include <linux/obd_sim.h>
+#include <linux/obdfs.h>
int console_loglevel;
#include <linux/obd_support.h>
#include <linux/obd_class.h>
#include <linux/obd_sim.h> /* XXX for development/debugging only */
-#include <obdfs.h>
+#include <linux/obdfs.h>
/* VFS super_block ops */
static struct super_block *obdfs_read_super(struct super_block *, void *, int);
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <asm/statfs.h>
+#include <unistd.h>
+
+#define OBD_IOC_CREATE _IOR('f', 3, long)
+#define OBD_IOC_SETUP _IOW('f', 4, long)
+#define OBD_IOC_SYNC _IOR('f', 16, long)
+#define OBD_IOC_DESTROY _IOW('f', 6, long)
+#define OBD_IOC_STATFS _IORW('f', 15, long)
+
+#define LOOP_DEVICE "/dev/loop0"
+#define OBD_DEVICE "/dev/obd"
+
+int main (int argc, char * argv[])
+{
+ int fd, rc, err = -1;
+ struct stat stat_buf;
+ struct statfs stfs;
+
+
+ if (argc < 2) {
+ printf("syntax: %s command [argument]\n", argv[0]);
+ printf("Where command is one of \"setup\", \"create\", \"destroy\", or \"sync\".\n");
+ exit(1);
+ }
+ if (stat(LOOP_DEVICE, &stat_buf)) {
+ printf("Couldn't stat(" LOOP_DEVICE ").\n");
+ exit(1);
+ }
+ printf("Device: %u\n", (unsigned int) stat_buf.st_rdev);
+
+ fd = open (OBD_DEVICE, O_RDONLY);
+ if (fd == -1) {
+ printf("Couldn't open " OBD_DEVICE ".\n");
+ exit(1);
+ }
+
+ if (!strcmp(argv[1], "setup")) {
+ rc = ioctl(fd, OBD_IOC_SETUP, &stat_buf.st_rdev);
+ fprintf(stderr, "rc = %d, errno = %d\n", rc, errno);
+ } else if (!strcmp(argv[1], "create")) {
+ int iter, i;
+
+ if (argc < 3) {
+ printf("create requires a nonzero argument.\n");
+ exit(1);
+ }
+
+ iter = atoi(argv[2]);
+ if (iter < 1) {
+ printf("create requires a nonzero argument.\n");
+ exit(1);
+ }
+ printf("creating %d objects...\n", iter);
+
+ for (i = 0; i < iter; i++) {
+ if ((rc = ioctl(fd, OBD_IOC_CREATE, &err))) {
+ fprintf(stderr, "Error; aborting.\n");
+ break;
+ }
+ if ((rc = ioctl(fd, OBD_IOC_DESTROY, &err))) {
+ fprintf(stderr, "Error; aborting.\n");
+ break;
+ }
+ }
+ fprintf(stderr, "rc = %d, errno = %d, err = %d\n",
+ rc, errno, err);
+ } else if (!strcmp(argv[1], "sync")) {
+ rc = ioctl(fd, OBD_IOC_SYNC, &err);
+ fprintf(stderr, "rc = %d, errno = %d, err = %d\n",
+ rc, errno, err);
+ } else if (!strcmp(argv[1], "destroy")) {
+ int ino;
+
+ if (argc < 3) {
+ printf("destroy requires a nonzero inode number.\n");
+ exit(1);
+ }
+
+ ino = atoi(argv[2]);
+ if (ino < 1) {
+ printf("destroy requires a nonzero inode number.\n");
+ exit(1);
+ }
+
+ rc = ioctl(fd, OBD_IOC_DESTROY, &ino);
+ fprintf(stderr, "rc = %d, errno = %d\n", rc, errno);
+ } else {
+ printf("Invalid command, run with no arguments for help.\n");
+ }
+ close(fd);
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+/* Beware when setting FSROOT that I've not made any attempts to avoid buffer
+ * overruns below--this is a test program, it's a static buffer. */
+#define FSROOT "/mnt"
+#define OBD_ITERATIONS 10000
+
+int main (int argc, char * argv[])
+{
+ int fd, rc, err = -1;
+ struct stat stat_buf;
+
+ if (argc < 2) {
+ printf("syntax: %s command\n", argv[0]);
+ printf("Where command is one of \"setup\" or \"create\".\n");
+ exit(1);
+ }
+
+ if (!strcmp(argv[1], "setup")) {
+ printf("This is silly.\n");
+ } else if (!strcmp(argv[1], "create")) {
+ int i, iter;
+
+ if (argc < 3) {
+ printf("create requires a nonzero argument.\n");
+ exit(1);
+ }
+
+ iter = atoi(argv[2]);
+
+ if (iter < 1) {
+ printf("create requires a nonzero argument.\n");
+ exit(1);
+ }
+ printf("creating %d files...\n", iter);
+
+ for (i = 0; i < iter; i++) {
+ fd = creat(FSROOT "/foo123", S_IRWXU);
+ close(fd);
+ unlink(FSROOT "/foo123");
+ }
+ } else {
+ printf("Invalid command, run with no arguments for help.\n");
+ }
+
+ return 0;
+}