Skip to content
Snippets Groups Projects
Commit 2ce63e7c authored by Phil Schwan's avatar Phil Schwan
Browse files

A couple days of changes--much improvement.

parent 139a736b
No related branches found
No related tags found
No related merge requests found
#ifndef __PRESTO_H_ #ifndef __PRESTO_H_
#define __PRESTO_H_ 1 #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 bottomfs {
struct super_operations *bottom_sops; struct super_operations *bottom_sops;
...@@ -26,137 +15,8 @@ struct bottomfs { ...@@ -26,137 +15,8 @@ struct bottomfs {
}; };
extern struct bottomfs *the_bottom; 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 */ /* sysctl.c */
void presto_sysctl_init(void); void presto_sysctl_init(void);
void presto_sysctl_clean(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 #endif
...@@ -9,22 +9,99 @@ ...@@ -9,22 +9,99 @@
/* /*
* Debug code * 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 #ifdef SYM_OBD_DEBUG
# define obd_debug(f, a...) { \ #define CDEBUG(mask, format, a...) \
printk ("SYM OBD DEBUG (%s, %d): %s:", \ do { \
__FILE__, __LINE__, __FUNCTION__); \ if (obd_debug_level & mask) { \
printk (f, ## a); \ printk("(%s,l. %d): ", __FUNCTION__, __LINE__); \
} printk(format, ## a); } \
#else } while (0);
# define obd_debug(f, a...) /**/
#endif #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 * 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_CREATE _IOR('f', 3, long)
#define OBD_IOC_SETUP _IOW('f', 4, long) #define OBD_IOC_SETUP _IOW('f', 4, long)
#define OBD_IOC_SYNC _IOR('f', 5, 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 */ /* balloc.c */
int obd_new_block (const struct inode * inode, unsigned long goal, 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, ...@@ -33,9 +110,23 @@ void obd_free_blocks (const struct inode * inode, unsigned long block,
unsigned long count); unsigned long count);
unsigned long obd_count_free_blocks (struct super_block * sb); unsigned long obd_count_free_blocks (struct super_block * sb);
int ext2_group_sparse(int group); 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 */ /* 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 */ /* inode.c */
void obd_read_inode (struct inode * inode); void obd_read_inode (struct inode * inode);
...@@ -50,11 +141,8 @@ struct buffer_head * obd_getblk (struct inode * inode, long block, ...@@ -50,11 +141,8 @@ struct buffer_head * obd_getblk (struct inode * inode, long block,
int create, int * err); int create, int * err);
/* interface.c */ /* interface.c */
extern struct inode * obd_inode_new (int inode_hint, int * err); extern int obd_create (struct super_block * sb, int inode_hint, int * err);
extern void obd_inode_destroy (struct inode * inode); extern void obd_unlink (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);
/* ioctl.c */ /* ioctl.c */
int obd_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, 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); ...@@ -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, struct super_block * obd_read_super (struct super_block * sb, void * data,
int silent); int silent);
/* sysctl.c */
extern void obd_sysctl_init (void);
extern void obd_sysctl_clean (void);
/* truncate.c */ /* truncate.c */
void obd_truncate (struct inode * inode); void obd_truncate (struct inode * inode);
......
#!/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;
}
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/sysctl.h>
#include <linux/swapctl.h>
#include <linux/proc_fs.h>
#include <linux/malloc.h>
#include <linux/stat.h>
#include <linux/ctype.h>
#include <asm/bitops.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/utsname.h>
#include <linux/sym_obd.h>
#include <linux/presto.h>
#include <linux/obd_psdev.h>
#include <linux/presto_upcall.h>
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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment