From 2ce63e7c1278fa87883b3060a7a0c4d98b5ccd15 Mon Sep 17 00:00:00 2001 From: pschwan Date: Sat, 5 Jun 1999 19:02:00 +0000 Subject: [PATCH] A couple days of changes--much improvement. --- lustre/include/linux/presto.h | 140 ---------------------- lustre/include/linux/sym_obd.h | 120 ++++++++++++++++--- lustre/obdclass/obdcontrol | 264 +++++++++++++++++++++++++++++++++++++++++ lustre/obdclass/sysctl.c | 108 +++++++++++++++++ 4 files changed, 478 insertions(+), 154 deletions(-) create mode 100755 lustre/obdclass/obdcontrol create mode 100644 lustre/obdclass/sysctl.c diff --git a/lustre/include/linux/presto.h b/lustre/include/linux/presto.h index a6ead3d..98e5976 100755 --- a/lustre/include/linux/presto.h +++ b/lustre/include/linux/presto.h @@ -1,17 +1,6 @@ #ifndef __PRESTO_H_ #define __PRESTO_H_ 1 -/* super.c */ -#if 0 -extern struct super_block * ext2_read_super (struct super_block * sb, - void * data, - int silent); -#endif -extern struct file_system_type presto_fs_type; -extern int init_presto_fs(void); - -int presto_ispresto(struct inode *); - struct bottomfs { struct super_operations *bottom_sops; @@ -26,137 +15,8 @@ struct bottomfs { }; extern struct bottomfs *the_bottom; -/* inode.c */ -void presto_read_inode(struct inode *inode); -int presto_notify_change(struct dentry *de, struct iattr *iattr); - -/* dcache.c */ -extern struct dentry_operations presto_dentry_operations; - -/* dir.c */ -extern struct inode_operations presto_dir_iops; -extern struct inode_operations presto_file_iops; -extern struct inode_operations presto_sym_iops; -extern struct file_operations presto_dir_fops; -extern struct file_operations presto_file_fops; -extern struct file_operations presto_sym_fops; - -void presto_setup_file_ops(struct inode *); -void presto_setup_symlink_ops(struct inode *); - -int presto_lookup(struct inode * dir, struct dentry *dentry); -int presto_dir_open(struct inode *inode, struct file *file); -int presto_file_open(struct inode *inode, struct file *file); -int presto_file_release(struct inode *inode, struct file *file); - -int presto_mkdir(struct inode *inode, struct dentry *, int mode); -int presto_create(struct inode *inode, struct dentry *, int mode); -int presto_unlink(struct inode *inode, struct dentry *); -int presto_rmdir(struct inode *inode, struct dentry *); -int presto_symlink(struct inode *, struct dentry *, const char *); -int presto_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry); - -int lento_journal(char *page); - -/* intermezzo.c */ -#define PRESTO_ATTR 0x00000001 /* attributes cached */ -#define PRESTO_DATA 0x00000002 /* data cached */ -#define PRESTO_VOLROOT 0x00000004 /* this dentry is root of volume */ -#define PRESTO_HASPERMIT 0x00000008 /* we have a permit to WB */ - -#define EISVOLROOT 0x2001 - -int presto_chk(struct dentry *dentry, int flag); -void presto_set(struct dentry *dentry, int flag); -void presto_permit(struct inode *); -int presto_mark_dentry(const char *path, int and_bits, int or_bits); - -/* journal.c */ - -#define JOURNAL_PAGE PAGE_SIZE - - -#define PRESTO_CREATE 1 -#define PRESTO_MKDIR 2 -#define PRESTO_UNLINK 3 -#define PRESTO_RMDIR 4 -#define PRESTO_CLOSE 5 -#define PRESTO_SYMLINK 6 -#define PRESTO_RENAME 7 -#define PRESTO_SETATTR 8 -#define PRESTO_LINK 9 - -void journal_create(struct inode *dirinode, struct inode *fileinode, int len, const char *name, int mode); -void journal_symlink(struct inode *inode, int len, const char *name, const char *target); -void journal_mkdir(struct inode *inode, int len, const char *name, int mode); -void journal_unlink(struct inode *inode, int len, const char *name); -void journal_rmdir(struct inode *inode, int len, const char *name); -void journal_rename(struct inode *old_dir, struct inode *old_file, - struct inode *new_dir, int new_len, const char *new_name); -void journal_setattr(struct inode *, int uid, int gid, int fsize, int atime, - int mtime, int ctime, int mode, unsigned int flags, - unsigned int valid); -void journal_close(struct inode *inode); -void journal_link(struct inode *src, struct inode *tpdiri, - struct inode *ti, int len, const char *name); -void journal_fetch(void); - /* sysctl.c */ void presto_sysctl_init(void); void presto_sysctl_clean(void); -/* global variables */ -extern int presto_debug; -extern int presto_print_entry; - -/* debugging masks */ -#define D_SUPER 1 /* print results returned by Venus */ -#define D_INODE 2 /* print entry and exit into procedure */ -#define D_FILE 4 -#define D_CACHE 8 /* cache debugging */ -#define D_MALLOC 16 /* print malloc, de-alloc information */ -#define D_JOURNAL 32 -#define D_UPCALL 64 /* up and downcall debugging */ -#define D_PSDEV 128 -#define D_PIOCTL 256 -#define D_SPECIAL 512 -#define D_TIMING 1024 -#define D_DOWNCALL 2048 - -#if 0 -#define CDEBUG(mask, format, a...) \ - do { \ - if (presto_debug & mask) { \ - printk("(%s,l. %d): ", __FUNCTION__, __LINE__); \ - printk(format, ## a); } \ -} while (0) ; -#else -#define CDEBUG(mask, format, a...) ; -#endif - -#define ENTRY \ - if(presto_print_entry) printk("Process %d entered %s\n",current->pid,__FUNCTION__) - -#define EXIT \ - if(presto_print_entry) printk("Process %d leaving %s\n",current->pid,__FUNCTION__) - - -#define PRESTO_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 PRESTO_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) - #endif diff --git a/lustre/include/linux/sym_obd.h b/lustre/include/linux/sym_obd.h index 10f2b53..87c86b2 100755 --- a/lustre/include/linux/sym_obd.h +++ b/lustre/include/linux/sym_obd.h @@ -9,22 +9,99 @@ /* * 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_UNUSED1 2 +#define D_UNUSED2 4 +#define D_UNUSED3 8 +#define D_UNUSED4 16 +#define D_UNUSED5 32 +#define D_UNUSED6 64 +#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 SYM_OBD_DEBUG -# define obd_debug(f, a...) { \ - printk ("SYM OBD DEBUG (%s, %d): %s:", \ - __FILE__, __LINE__, __FUNCTION__); \ - printk (f, ## a); \ - } -#else -# define obd_debug(f, a...) /**/ -#endif +#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 /* SYM_OBD_DEBUG */ + +# define CDEBUG(mask, format, a...) ; +# define ENTRY ; +# define EXIT ; + +#endif /* SYM_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) + /* * ioctl commands */ +struct ioc_prealloc { + long alloc; /* user sets it to the number of inodes requesting to be + * preallocated. kernel sets it to the actual number of + * succesfully preallocate inodes */ + long inodes[32]; /* actual inode numbers */ +}; + #define OBD_IOC_CREATE _IOR('f', 3, long) #define OBD_IOC_SETUP _IOW('f', 4, long) #define OBD_IOC_SYNC _IOR('f', 5, long) +#define OBD_IOC_DESTROY _IOW('f', 6, long) + +#define OBD_IOC_DEC_USE_COUNT _IO('f', 8) + /* balloc.c */ int obd_new_block (const struct inode * inode, unsigned long goal, @@ -33,9 +110,23 @@ void obd_free_blocks (const struct inode * inode, unsigned long block, unsigned long count); unsigned long obd_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 */ -int obd_sync_file(struct file * file, struct dentry *dentry); +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); /* inode.c */ void obd_read_inode (struct inode * inode); @@ -50,11 +141,8 @@ struct buffer_head * obd_getblk (struct inode * inode, long block, int create, int * err); /* interface.c */ -extern struct inode * obd_inode_new (int inode_hint, int * err); -extern void obd_inode_destroy (struct inode * inode); -extern unsigned long obd_count_free_inodes (struct super_block * sb); -extern void obd_check_inodes_bitmap (struct super_block * sb); -unsigned long obd_count_free_inodes (struct super_block * sb); +extern int obd_create (struct super_block * sb, int inode_hint, int * err); +extern void obd_unlink (struct inode * inode); /* ioctl.c */ int obd_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, @@ -69,6 +157,10 @@ int obd_remount (struct super_block * sb, int * flags, char * data); struct super_block * obd_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); diff --git a/lustre/obdclass/obdcontrol b/lustre/obdclass/obdcontrol new file mode 100755 index 0000000..6967bdc --- /dev/null +++ b/lustre/obdclass/obdcontrol @@ -0,0 +1,264 @@ +#!/usr/bin/perl + +#use strict; +BEGIN { require "asm/errno.ph" }; +BEGIN { require "asm/ioctl.ph" }; + +# p2ph generated invalid macros for ioctl stuff, so I override some of it here +eval 'sub OBD_IOC_CREATE () { &_IOC(2, ord(\'f\'), 3, 4);}' unless + defined(&OBD_IOC_CREATE); +eval 'sub OBD_IOC_SETUP () { &_IOC(1, ord(\'f\'), 4, 4);}' unless + defined(&OBD_IOC_SETUP); +eval 'sub OBD_IOC_SYNC () { &_IOC(2, ord(\'f\'), 5, 4);}' unless + defined(&OBD_IOC_SYNC); +eval 'sub OBD_IOC_DESTROY () { &_IOC(1, ord(\'f\'), 6, 4);}' unless + defined(&OBD_IOC_DESTROY); +eval 'sub OBD_IOC_DEC_USE_COUNT () { &_IOC(0, ord(\'f\'), 8, 0);}' unless + defined(&OBD_IOC_DEC_USE_COUNT); + +use Getopt::Long; +use File::stat; +use Storable; +use Carp; +use Term::ReadLine; +use IO::Handle; + +my ($device, $filesystem); +# startup options (I'll replace these when I have some to replace with) +GetOptions("device=s" => \$device, "fs=s" => $filesystem) || die "Getoptions"; + +$device = "/dev/obd" unless $device; +$filesystem = "/dev/loop0" unless $filesystem; + +# get a console for the app +my $term = new Term::ReadLine 'obdcontrol '; +my $attribs = $term->Attribs; +$term->ornaments('md,me,,'); # bold face prompt + +# make sure stdout is not buffered +STDOUT->autoflush(1); + +my $line; +my $command; +my $arg; + +my %commands = + ('create' => {func => "Create", doc => "create: creates a new inode"}, + 'setup' => {func => "Setup", doc => "setup: initializes the environment"}, + 'sync' => {func => "Sync", doc => "sync: flushes buffers to disk"}, + 'destroy' => {func => "Destroy", doc => "setup: destroys an inode"}, + 'dec_use_count' => {func => "Decusecount", doc => "decreases the module use count so that it can be unmounted following an oops"}, + 'help' => {func => \&Help, doc => "help: this message"}, + 'quit' => {func => \&Quit, doc => "see \"exit\""}, + 'exit' => {func => \&Quit, doc => "see \"quit\""} + ); + +# +# setup completion function +# +my @jcm_cmd_list = keys %commands; + +$attribs->{attempted_completion_function} = \&completeme; +#------------------------------------------------------------------------------ +# Open the device, as we need an FD for the ioctl +sysopen(DEV_OBD, $device, 0); + +if (!defined($::st = stat($filesystem))) { + die "Unable to stat $filesystem.\n"; +} + +# Get on with the show +process_line(); + +#------------------------------------------------------------------------------ +sub completeme { + my ($text, $line, $start, $end) = @_; + if (substr($line, 0, $start) =~ /^\s*$/) { + $attribs->{completion_word} = \@jcm_cmd_list; + return $term->completion_matches($text, + $attribs->{'list_completion_function'}); + } +} + +sub find_command { + my $given = shift; + my $name; + my @completions = completeme($given, $given, 0, length($given)); + if ($#completions == 0) { + $name = shift @completions; + } + + return $name; +} + +# start making requests +sub process_line { + foo: + $line = $term->readline("obdcontrol > "); + execute_line($line); + goto foo; +} + +sub execute_line { + my $line = shift; + + my @arg = split(' ', $line); + my $word = shift @arg; + + my $cmd = find_command($word); + unless ($cmd) { + printf STDERR "$word: No such command, or not unique.\n"; + return (-1); + } + + if ($cmd eq "help" || $cmd eq "exit" || $cmd eq "quit") { + return (&{$commands{$cmd}->{func}}(@arg)); + } + + # Call the function. + return (&{$commands{$cmd}->{func}}(@arg)); +} + +sub Setup { + my $err = 0; + my $packed = pack("L", $::st->rdev()); + my $rc = ioctl(DEV_OBD, &OBD_IOC_SETUP, $packed); + + if (!defined $rc) { + print STDERR "ioctl failed: $!\n"; + } elsif ($rc eq "0 but true") { + print "Finished (success)\n"; + } else { + print "ioctl returned error code $rc.\n"; + } +} + +sub Create { + my $arg = shift; + my $quiet = shift; + my $err = "0"; + my $rc; + + if (defined($quiet) && !($quiet eq "quiet")) { + print "syntax: create [number of objects [quiet]]\n"; + return; + } + + if (!defined($arg) || scalar($arg) < 2) { + print "Creating 1 object...\n"; + $rc = ioctl(DEV_OBD, &OBD_IOC_CREATE, $err); + if (!defined($quiet)) { + my $ino = unpack("L", $err); + print "Created object #$ino.\n"; + } + } else { + my $i; + + print "Creating " . scalar($arg) . " objects...\n"; + for ($i = 0; $i < scalar($arg); $i++) { + $rc = ioctl(DEV_OBD, &OBD_IOC_CREATE, $err); + if (!($rc eq "0 but true") || $err < 0) { + last; + } elsif (!defined($quiet)) { + my $ino = unpack("L", $err); + print "Created object #$ino.\n"; + } + } + } + + if (!defined $rc) { + print STDERR "ioctl failed: $!\n"; + } elsif ($rc eq "0 but true") { + print "Finished (success)\n"; + } else { + print "ioctl returned error code $rc.\n"; + } +} + +sub Sync { + my $err = "0"; + my $rc = ioctl(DEV_OBD, &OBD_IOC_SYNC, $err); + + if (!defined $rc) { + print STDERR "ioctl failed: $!\n"; + } elsif ($rc eq "0 but true") { + print "Finished (success)\n"; + } else { + print "ioctl returned error code $rc.\n"; + } +} + +sub Destroy { + my $arg = shift; + + if (!defined($arg) || scalar($arg) < 1) { + print "destroy requires the object number to destroy.\n"; + return; + } + + print "Destroying object $arg...\n"; + my $packed = pack("L", $arg); + my $rc = ioctl(DEV_OBD, &OBD_IOC_DESTROY, $packed); + + if (!defined $rc) { + print STDERR "ioctl failed: $!\n"; + } elsif ($rc eq "0 but true") { + print "Finished (success)\n"; + } else { + print "ioctl returned error code $rc.\n"; + } +} + +sub Preallocate { + my $arg = shift; + + if (!defined($arg) || scalar($arg) < 1 || scalar($arg) > 32) { + $arg = 32; + } + + print "Preallocating $arg inodes...\n"; + my $packed = pack("Lx128", $arg); # alloc, inodes[32] + my $rc = ioctl(DEV_OBD, &OBD_IOC_PREALLOCATE, $packed); + + if (!defined $rc) { + print STDERR "ioctl failed: $!\n"; + } elsif ($rc eq "0 but true") { + my $alloc = unpack("L", $packed); + my @inodes = unpack("L32", $packed); + my $i; + + print "Got $alloc inodes: "; + for ($i = 1; $i <= $alloc; ++$i) { + print $inodes[$i] . " "; + } + print "\nFinished (success)\n"; + } else { + print "ioctl returned error code $rc.\n"; + } +} + +sub Decusecount { + my $rc = ioctl(DEV_OBD, &OBD_IOC_DEC_USE_COUNT, NULL); + + if (!defined $rc) { + print STDERR "ioctl failed: $!\n"; + } elsif ($rc eq "0 but true") { + print "Finished (success)\n"; + } else { + print "ioctl returned error code $rc.\n"; + } +} + +sub Help { + my $arg = shift; + + if ( !$arg || !$commands{$arg} ) { + print "Comands: ", join( ' ', @jcm_cmd_list), "\n"; + } else { + print "Usage: " . $commands{$arg}->{doc} . "\n"; + } +} + +sub Quit { + exit; +} diff --git a/lustre/obdclass/sysctl.c b/lustre/obdclass/sysctl.c new file mode 100644 index 0000000..c221e7a --- /dev/null +++ b/lustre/obdclass/sysctl.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +struct ctl_table_header *obd_table_header = NULL; + +static int vars[2]; +static int index = 0; + +static int obd_sctl_vars( ctl_table * table, int write, struct file * + filp, void * buffer, size_t * lenp ); +static int obd_sctl_reset( ctl_table * table, int write, struct file + * filp, void * buffer, size_t * lenp ); + + + +#define OBD_SYSCTL 1 + +#define OBD_DEBUG 1 /* control debugging */ +#define OBD_ENTRY 2 /* control enter/leave pattern */ +#define OBD_TIMEOUT 3 /* timeout on upcalls to become intrble */ +#define OBD_HARD 4 /* mount type "hard" or "soft" */ +#define OBD_VARS 5 +#define OBD_INDEX 6 +#define OBD_RESET 7 + +#define OBD_VARS_SLOT 2 + +static ctl_table obd_table[] = { + {OBD_DEBUG, "debug", &obd_debug_level, sizeof(int), 0644, NULL, &proc_dointvec}, + {OBD_ENTRY, "trace", &obd_print_entry, sizeof(int), 0644, NULL, &proc_dointvec}, + {OBD_VARS, "vars", &vars[0], sizeof(int), 0644, NULL, &proc_dointvec}, + {OBD_INDEX, "index", &index, sizeof(int), 0644, NULL, &obd_sctl_vars}, + {OBD_RESET, "reset", NULL, 0, 0644, NULL, &obd_sctl_reset}, + { 0 } +}; + +static ctl_table jukebox_table[] = { + {OBD_SYSCTL, "obd", NULL, 0, 0555, obd_table}, + {0} +}; + + +void obd_sysctl_init (void) +{ +#ifdef CONFIG_SYSCTL + if ( !obd_table_header ) + obd_table_header = register_sysctl_table(jukebox_table, 0); +#endif +} + +void obd_sysctl_clean (void) +{ +#ifdef CONFIG_SYSCTL + if ( obd_table_header ) + unregister_sysctl_table(obd_table_header); + obd_table_header = NULL; +#endif +} + +int obd_sctl_reset (ctl_table * table, int write, + struct file * filp, void * buffer, + size_t * lenp) +{ + if ( write ) { + /* do something here */ + vars[0]=0; + vars[1]=0; + } + + *lenp = 0; + return 0; +} + +int obd_sctl_vars (ctl_table * table, int write, + struct file * filp, void * buffer, + size_t * lenp) +{ + int rc; + + rc = proc_dointvec(table, write, filp, buffer, lenp); + + if ( rc ) + return rc; + + if ( index < 0 || index > 1 ) { + printk("Index illegal!\n"); + index = 0; + } else { + obd_table[OBD_VARS_SLOT].data = &vars[index]; + } + + return rc; +} -- 1.8.3.1