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

the last two weeks' work

parent efed045f
No related branches found
No related tags found
No related merge requests found
#include <../obd/linux/sym_obd.h>
struct obdfs_sb_info {
struct obd_conn_info osi_conn_info;
struct super_block *osi_super;
int osi_obd_minor;
};
void obdfs_sysctl_init(void);
void obdfs_sysctl_clean(void);
struct obdfs_inode_info;
#define OBDFS_SUPER_MAGIC 0x4711
......@@ -3,6 +3,8 @@
#include <linux/fs.h>
#include <linux/ext2_fs.h>
#include <linux/malloc.h>
#include <linux/vmalloc.h>
#define SYM_OBD_DEBUG
......@@ -85,24 +87,73 @@ do { \
} while (0)
#define MAX_DEVICES 128
struct obd_conn_info {
unsigned int conn_id;
unsigned long conn_ino;
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 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 */
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;
#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)
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_DEC_USE_COUNT _IO('f', 8)
#define OBD_IOC_SETATTR _IOR('f', 9, long)
#define OBD_IOC_READ _IOWR('f', 10, long)
#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_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_DEC_FS_USE_COUNT _IO ('f', 16 )
/* balloc.c */
int ext2_new_block (const struct inode * inode, unsigned long goal,
......@@ -128,6 +179,8 @@ 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);
......@@ -144,18 +197,26 @@ struct buffer_head * obd_getblk (struct inode * inode, long block,
/* interface.c */
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);
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 */
struct oic_setattr_s {
unsigned long inode;
struct iattr iattr;
};
struct oic_read_s {
unsigned long inode;
char * buf;
unsigned long count;
loff_t offset;
};
int obd_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
unsigned long arg);
......@@ -192,4 +253,7 @@ extern struct inode_operations ext2_dir_inode_operations;
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_SYM_OBD_H */
......@@ -13,10 +13,32 @@ 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_PREALLOCATE () { &_IOC(3, ord(\'f\'), 7, 4);}' unless
defined(&OBD_IOC_PREALLOCATE);
eval 'sub OBD_IOC_DEC_USE_COUNT () { &_IOC(0, ord(\'f\'), 8, 0);}' unless
defined(&OBD_IOC_DEC_USE_COUNT);
eval 'sub OBD_IOC_READ () { &_IOC(3, ord(\'f\'), 10, 4);}' unless
eval 'sub OBD_IOC_SETATTR () { &_IOC(1, ord(\'f\'), 9, 4);}' unless
defined(&OBD_IOC_SETATTR);
eval 'sub OBD_IOC_GETATTR () { &_IOC(2, ord(\'f\'), 10, 4);}' unless
defined(&OBD_IOC_GETATTR);
eval 'sub OBD_IOC_READ () { &_IOC(3, ord(\'f\'), 11, 4);}' unless
defined(&OBD_IOC_READ);
eval 'sub OBD_IOC_WRITE () { &_IOC(3, ord(\'f\'), 12, 4);}' unless
defined(&OBD_IOC_WRITE);
eval 'sub OBD_IOC_CONNECT () { &_IOC(2, ord(\'f\'), 13, 4);}' unless
defined(&OBD_IOC_CONNECT);
eval 'sub OBD_IOC_DISCONNECT () { &_IOC(1, ord(\'f\'), 14, 4);}' unless
defined(&OBD_IOC_DISCONNECT);
eval 'sub OBD_IOC_STATFS () { &_IOC(3, ord(\'f\'), 15, 4);}' unless
defined(&OBD_IOC_STATFS);
eval 'sub ATTR_MODE () {1;}' unless defined(&ATTR_MODE);
eval 'sub ATTR_UID () {2;}' unless defined(&ATTR_UID);
eval 'sub ATTR_GID () {4;}' unless defined(&ATTR_GID);
eval 'sub ATTR_SIZE () {8;}' unless defined(&ATTR_SIZE);
eval 'sub ATTR_ATIME () {16;}' unless defined(&ATTR_ATIME);
eval 'sub ATTR_MTIME () {32;}' unless defined(&ATTR_MTIME);
eval 'sub ATTR_CTIME () {64;}' unless defined(&ATTR_CTIME);
use Getopt::Long;
use File::stat;
......@@ -47,10 +69,17 @@ my $arg;
my %commands =
('create' => {func => "Create", doc => "create: creates a new inode"},
'setup' => {func => "Setup", doc => "setup: initializes the environment"},
'connect' => {func => "Connect", doc => "connect: allocates client ID for this session"},
'disconnect' => {func => "Disconnect", doc => "disconnect [id]: frees client resources"},
'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 the module can be removed following an oops"},
'read' => {func => "Read", doc => "read <inode> <count> [offset]"},
'write' => {func => "Write", doc => "write <inode> <offset> <text>"},
'setattr' => {func => "Setattr", doc => "setattr [mode [uid [gid [size [atime [mtime [ctime]]]]]]]"},
'getattr' => {func => "Getattr", doc => "getattr [inode]: displays inode object attributes"},
'preallocate' => {func => "Preallocate", doc => "preallocate [num]: requests preallocation of num inodes."},
'statfs' => {func => "Statfs", doc => "statfs: filesystem status information"},
'help' => {func => \&Help, doc => "help: this message"},
'quit' => {func => \&Quit, doc => "see \"exit\""},
'exit' => {func => \&Quit, doc => "see \"quit\""}
......@@ -136,10 +165,66 @@ sub Setup {
}
}
sub Connect {
my $id = 0;
my $ino = 0;
my $bs = 0;
my $bs_b = 0;
my $rc;
# unsigned int conn_id;
# unsigned long conn_ino;
# unsigned long conn_blocksize;
# unsigned char conn_blocksize_bits;
my $packed = pack("ILLC", $id, $ino, $bs, $bs_b);
$rc = ioctl(DEV_OBD, &OBD_IOC_CONNECT, $packed);
($id, $ino, $bs, $bs_b) = unpack("ILLC", $packed);
if (!defined $rc) {
print STDERR "ioctl failed: $!\n";
} elsif ($rc eq "0 but true") {
$::client_id = $id;
print "Client ID : $id\n";
print "Root inode : $ino\n";
print "Blocksize : $bs\n";
print "Blocksize bits: $bs_b\n";
print "Finished (success)\n";
} else {
print "ioctl returned error code $rc.\n";
}
}
sub Disconnect {
my $id = shift;
if (!defined($id)) {
$id = $::client_id;
}
if (!defined($id)) {
print "syntax: disconnect [client ID]\n";
print "When client ID is not given, the last valid client ID to be returned by a\n";
print "connect command this session is used; there is no such ID.\n";
return;
}
my $packed = pack("L", $id);
my $rc = ioctl(DEV_OBD, &OBD_IOC_DISCONNECT, $packed);
if (!defined $rc) {
print STDERR "ioctl failed: $!\n";
} elsif ($rc eq "0 but true") {
$::client_id = undef;
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")) {
......@@ -147,11 +232,13 @@ sub Create {
return;
}
my $packed = pack("I", $::client_id);
if (!defined($arg) || scalar($arg) < 2) {
print "Creating 1 object...\n";
$rc = ioctl(DEV_OBD, &OBD_IOC_CREATE, $err);
my $packed = pack("I", 0);
$rc = ioctl(DEV_OBD, &OBD_IOC_CREATE, $packed);
if (!defined($quiet)) {
my $ino = unpack("L", $err);
my $ino = unpack("L", $packed);
print "Created object #$ino.\n";
}
} else {
......@@ -159,11 +246,11 @@ sub Create {
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) {
$rc = ioctl(DEV_OBD, &OBD_IOC_CREATE, $packed);
my $ino = unpack("L", $packed);
if (!($rc eq "0 but true") || $packed == 0) {
last;
} elsif (!defined($quiet)) {
my $ino = unpack("L", $err);
print "Created object #$ino.\n";
}
}
......@@ -192,6 +279,10 @@ sub Sync {
}
sub Destroy {
if (!defined($id)) {
$id = $::client_id;
}
my $arg = shift;
if (!defined($arg) || scalar($arg) < 1) {
......@@ -200,7 +291,7 @@ sub Destroy {
}
print "Destroying object $arg...\n";
my $packed = pack("L", $arg);
my $packed = pack("IL", $::client_id, $arg);
my $rc = ioctl(DEV_OBD, &OBD_IOC_DESTROY, $packed);
if (!defined $rc) {
......@@ -212,11 +303,121 @@ sub Destroy {
}
}
sub Getattr {
if (!defined($::client_id)) {
print "You must first ``connect''.\n";
return;
}
my $inode = shift;
if (!defined($inode) || scalar($inode) < 1) {
print "invalid arguments; type \"help getattr\" for a synopsis\n";
return;
}
# see Setattr
my $packed = pack("ILsx2lLLLI", $::client_id, $inode, 0, 0, 0, 0, 0, 0, 0,
0);
my $rc = ioctl(DEV_OBD, &OBD_IOC_GETATTR, $packed);
if (!defined $rc) {
print STDERR "ioctl failed: $!\n";
} elsif ($rc eq "0 but true") {
my ($valid, $mode, $uid, $gid, $size, $atime, $mtime, $ctime, $flags);
($valid, $mode, $uid, $gid, $size, $atime, $mtime, $ctime, $flags) =
unpack("ISssx2lLLLI", $packed);
printf("Inode: %d Mode: %04d\n", $inode, $mode);
printf("User: %6d Group: %6d Size: %d\n", $uid, $gid, $size);
printf("ctime: %08lx -- %s\n", $ctime, scalar(gmtime($ctime)));
printf("atime: %08lx -- %s\n", $atime, scalar(gmtime($atime)));
printf("mtime: %08lx -- %s\n", $mtime, scalar(gmtime($mtime)));
printf("flags: %08x\n", $flags);
print "Finished (success)\n";
} else {
print "ioctl returned error code $rc.\n";
}
}
sub Setattr {
if (!defined($::client_id)) {
print "You must first ``connect''.\n";
return;
}
my $inode = shift;
my $valid = 0;
my $mode = shift;
my $uid = shift;
my $gid = shift;
my $size = shift;
my $atime = shift;
my $mtime = shift;
my $ctime = shift;
if (defined($uid)) {
$valid |= &ATTR_UID;
}
if (defined($gid)) {
$valid |= &ATTR_GID;
}
if (defined($size)) {
$valid |= &ATTR_SIZE;
}
if (defined($atime)) {
$valid |= &ATTR_ATIME;
}
if (defined($mtime)) {
$valid |= &ATTR_MTIME;
}
if (defined($ctime)) {
$valid |= &ATTR_CTIME;
}
if (defined($mode)) {
$valid |= &ATTR_MODE;
}
if (!defined($inode) || scalar($inode) < 1) {
print "invalid arguments; type \"help setattr\" for a synopsis\n";
return;
}
#struct iattr {
# unsigned int ia_valid; (32)
# umode_t ia_mode; (16)
# uid_t ia_uid; (16)
# gid_t ia_gid; (16)
# -- 16 bit alignment here! --
# off_t ia_size; (32)
# time_t ia_atime; (32)
# time_t ia_mtime; (32)
# time_t ia_ctime; (32)
# unsigned int ia_attr_flags; (32)
#};
my $packed = pack("ILLSssx2ILLLL", $::client_id, $inode, $valid, $mode,
$uid, $gid, $size, $atime, $mtime, $ctime, 0);
my $rc = ioctl(DEV_OBD, &OBD_IOC_SETATTR, $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 Read {
if (!defined($::client_id)) {
print "You must first ``connect''.\n";
return;
}
my $inode = shift;
my $count = shift;
my $offset = shift;
if (!defined($inode) || scalar($inode) < 1 || !defined($count) ||
$count < 1 || (defined($offset) && $offset < 0)) {
print "invalid arguments; type \"help read\" for a synopsis\n";
......@@ -234,10 +435,12 @@ sub Read {
my $buf = sprintf("%${count}s", " ");
die "suck" if (length($buf) != $count);
my $packed = pack("LpLLL", $inode, $buf, $count, 0, $offset);
# the perl we're using doesn't support pack type Q, and offset is 64 bits
my $packed = pack("ILpLLL", $::client_id, $inode, $buf, $count, 0, $offset);
my $rc = ioctl(DEV_OBD, &OBD_IOC_READ, $packed);
$retval = unpack("x4x4L", $packed);
$retval = unpack("L", $packed);
if (!defined $rc) {
print STDERR "ioctl failed: $!\n";
......@@ -254,28 +457,79 @@ sub Read {
}
}
# Unused for now
sub Write {
if (!defined($::client_id)) {
print "You must first ``connect''.\n";
return;
}
my $inode = shift;
my $offset = shift;
my $text = join(' ', @_);
my $count = length($text);
if (!defined($inode) || scalar($inode) < 1 || !defined($offset) ||
scalar($offset) < 0) {
print "invalid arguments; type \"help write\" for a synopsis\n";
return;
}
if (!defined($text)) {
$text = "";
$count = 0;
}
print("Writing $count bytes starting at byte $offset to object " .
"$inode...\n");
# the perl we're using doesn't support pack type Q
my $packed = pack("ILpLLL", $::client_id, $inode, $text, $count, 0, $offset);
my $rc = ioctl(DEV_OBD, &OBD_IOC_WRITE, $packed);
$retval = unpack("L", $packed);
if (!defined $rc) {
print STDERR "ioctl failed: $!\n";
} elsif ($rc eq "0 but true") {
if ($retval >= 0) {
print "\nWrote $retval of an attempted $count bytes.\n";
print "Finished (success)\n";
} else {
print "Finished (error $retval)\n";
}
} else {
print "ioctl returned error code $rc.\n";
}
}
sub Preallocate {
my $arg = shift;
if (!defined($::client_id)) {
print "You must first ``connect''.\n";
return;
}
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 $packed = pack("LLx128", $::client_id, $arg);
# client id, 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 $alloc = unpack("x4L", $packed);
my @inodes = unpack("x8L32", $packed);
my $i;
print "Got $alloc inodes: ";
for ($i = 1; $i <= $alloc; ++$i) {
print $inodes[$i] . " ";
foreach $i (@inodes) {
print $i . " ";
}
print "\nFinished (success)\n";
} else {
......@@ -295,6 +549,44 @@ sub Decusecount {
}
}
sub Statfs {
if (!defined($::client_id)) {
print "You must first ``connect''.\n";
return;
}
# struct statfs {
# long f_type;
# long f_bsize;
# long f_blocks;
# long f_bfree;
# long f_bavail;
# long f_files;
# long f_ffree;
# __kernel_fsid_t f_fsid; (64 bits)
# long f_namelen;
# long f_spare[6];
# };
my $packed = pack("LLLLLLLIILL6", $::client_id, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0);
my $rc = ioctl(DEV_OBD, &OBD_IOC_STATFS, $packed);
if (!defined $rc) {
print STDERR "ioctl failed: $!\n";
} elsif ($rc eq "0 but true") {
my ($bsize, $blocks, $bfree, $bavail, $files, $ffree) =
unpack("x4LLLLLL", $packed);
print("$bsize byte blocks: $blocks, " . ($blocks - $bfree) . " used, " .
"$bfree free ($bavail available).\n");
print "$files files, " . ($files - $ffree) . " used, $ffree free.\n";
print "Finished (success)\n";
} else {
print "ioctl returned error code $rc.\n";
}
}
sub Help {
my $arg = shift;
......@@ -306,5 +598,9 @@ sub Help {
}
sub Quit {
if ($::client_id) {
print "Disconnecting active session ($::client_id)...";
Disconnect($::client_id);
}
exit;
}
#
# Makefile 1.00 Peter Braam <braam@cs.cmu.edu>
#
include ../config.mk
MODDIR = $(PREFIX)/lib/modules/$(UTS_RELEASE)
ifndef CFLAGS
# Don't remove "-O2" or bad things will happen!
KFLAGS = -O2 -Wall -Wstrict-prototypes -Winline -pipe -I../obd
endif
CPPFLAGS = $(PCDEBUG) -D__KERNEL__ -DMODULE -I../include \
-I. -I$(LINUX)/include $(SMPFLAG)
COFLAGS = -kv
CFLAGS= $(KFLAGS) $(MFLAG)
SRCS=sysctl.c super.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)
/*
* OBDFS Super operations
*
* Copryright (C) 1996 Peter J. Braam <braam@stelias.com>
*/
#define EXPORT_SYMTAB
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/locks.h>
#include <linux/unistd.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/stat.h>
#include <asm/uaccess.h>
#include <linux/vmalloc.h>
#include <asm/segment.h>
#include <../obd/linux/sym_obd.h>
#include <obdfs.h>
/* DEBUGGING! */
#undef MOD_INC_USE_COUNT
#define MOD_INC_USE_COUNT
#undef MOD_DEC_USE_COUNT
#define MOD_DEC_USE_COUNT
/* VFS super_block ops */
static struct super_block *obdfs_read_super(struct super_block *, void *, int);
static void obdfs_read_inode(struct inode *);
static int obdfs_notify_change(struct dentry *dentry, struct iattr *attr);
static void obdfs_write_inode(struct inode *);
static void obdfs_delete_inode(struct inode *);
static void obdfs_put_super(struct super_block *);
static int obdfs_statfs(struct super_block *sb, struct statfs *buf,
int bufsiz);
/* exported operations */
struct super_operations obdfs_super_operations =
{
obdfs_read_inode, /* read_inode */
obdfs_write_inode, /* write_inode */
NULL, /* put_inode */
obdfs_delete_inode, /* delete_inode */
obdfs_notify_change, /* notify_change */
obdfs_put_super, /* put_super */
NULL, /* write_super */
obdfs_statfs, /* statfs */
NULL /* remount_fs */
};
struct obdfs_sb_info obdfs_super_info;
int obd_minor = 0;
int obd_root_ino = 2;
static struct super_block * obdfs_read_super(struct super_block *sb,
void *data, int silent)
{
struct inode *root = 0;
struct obdfs_sb_info *sbi = NULL;
int error = 0;
ENTRY;
MOD_INC_USE_COUNT;
sbi = &obdfs_super_info;
if ( sbi->osi_super ) {
printk("Already mounted\n");
MOD_DEC_USE_COUNT;
return NULL;
}
error = obd_connect(obd_minor, &sbi->osi_conn_info);
if ( error ) {
printk("OBDFS: cannot connect to 0x%x.\n", obd_minor);
goto error;
}
sbi->osi_super = sb;
lock_super(sb);
sb->u.generic_sbp = sbi;
sb->s_blocksize = sbi->osi_conn_info.conn_blocksize;
sb->s_blocksize_bits = sbi->osi_conn_info.conn_blocksize_bits;
sb->s_magic = OBDFS_SUPER_MAGIC;
sb->s_op = &obdfs_super_operations;
/* make root inode */
root = iget(sb, sbi->osi_conn_info.conn_ino);
if (!root || is_bad_inode(root)) {
printk("OBDFS: bad iget for root\n");
sb->s_dev = 0;
error = ENOENT;
unlock_super(sb);
goto error;
}
printk("obdfs_read_super: rootinode is %ld dev %d\n",
root->i_ino, root->i_dev);
sb->s_root = d_alloc_root(root, NULL);
unlock_super(sb);
EXIT;
return sb;
error:
EXIT;
MOD_DEC_USE_COUNT;
if (sbi) {
sbi->osi_super = NULL;
}
if (root) {
iput(root);
}
sb->s_dev = 0;
return NULL;
}
static void obdfs_put_super(struct super_block *sb)
{
struct obdfs_sb_info *sbi;
ENTRY;
sb->s_dev = 0;
/* XXX flush stuff */
sbi = sb->u.generic_sbp;
sb->u.generic_sbp = NULL;
obd_disconnect(sbi->osi_conn_info.conn_id);
sbi->osi_super = NULL;
printk("OBDFS: Bye bye.\n");
memset(sbi, 0, sizeof(* sbi));
MOD_DEC_USE_COUNT;
EXIT;
}
/* all filling in of inodes postponed until lookup */
static void obdfs_read_inode(struct inode *inode)
{
struct iattr attr;
int error;
struct obdfs_sb_info *sbi = inode->i_sb->u.generic_sbp;
ENTRY;
error = obd_getattr(sbi->osi_conn_info.conn_id, inode->i_ino, &attr);
if (error) {
printk("obdfs_read_inode: ibd_getattr fails (%d)\n", error);
return;
}
inode_setattr(inode, &attr);
inode->i_op = NULL;
return;
}
static void inode_to_iattr(struct inode *inode, struct iattr *tmp)
{
tmp->ia_mode = inode->i_mode;
tmp->ia_uid = inode->i_uid;
tmp->ia_gid = inode->i_gid;
tmp->ia_size = inode->i_size;
tmp->ia_atime = inode->i_atime;
tmp->ia_mtime = inode->i_mtime;
tmp->ia_ctime = inode->i_ctime;
tmp->ia_attr_flags = inode->i_flags;
tmp->ia_valid = ~0;
}
static void obdfs_write_inode(struct inode *inode)
{
struct obdfs_sb_info *sbi;
struct iattr attr;
int error;
ENTRY;
inode_to_iattr(inode, &attr);
sbi = inode->i_sb->u.generic_sbp;
error = obd_setattr(sbi->osi_conn_info.conn_id, inode->i_ino, &attr);
if (error) {
printk("obdfs_write_inode: ibd_setattr fails (%d)\n", error);
return;
}
return;
}
static void obdfs_delete_inode(struct inode *inode)
{
struct obdfs_sb_info *sbi;
int error;
ENTRY;
sbi = inode->i_sb->u.generic_sbp;
error = obd_destroy(sbi->osi_conn_info.conn_id , inode->i_ino);
if (error) {
printk("obdfs_delete_node: ibd_destroy fails (%d)\n", error);
return;
}
EXIT;
}
static int obdfs_notify_change(struct dentry *de, struct iattr *iattr)
{
struct inode *inode = de->d_inode;
struct obdfs_sb_info * sbi;
int error;
ENTRY;
sbi = inode->i_sb->u.generic_sbp;
error = obd_setattr(sbi->osi_conn_info.conn_id, inode->i_ino, iattr);
if ( error ) {
printk("obdfs_notify_change: obd_setattr fails (%d)\n", error);
return error;
} else {
inode_setattr(inode, iattr);
}
EXIT;
return error;
}
static int obdfs_statfs(struct super_block *sb, struct statfs *buf,
int bufsize)
{
struct statfs tmp;
struct obdfs_sb_info * sbi;
int error;
ENTRY;
sbi = sb->u.generic_sbp;
error = obd_statfs(sbi->osi_conn_info.conn_id, &tmp);
if ( error ) {
printk("obdfs_notify_change: obd_statfs fails (%d)\n", error);
return error;
}
copy_to_user(buf, &tmp, (bufsize<sizeof(tmp)) ? bufsize : sizeof(tmp));
EXIT;
return error;
}
struct file_system_type obdfs_fs_type = {
"obdfs", 0, obdfs_read_super, NULL
};
int init_obdfs(void)
{
printk(KERN_INFO "OBDFS v0.1, braam@stelias.com\n");
obdfs_sysctl_init();
return register_filesystem(&obdfs_fs_type);
}
#ifdef MODULE
int init_module(void)
{
return init_obdfs();
}
void cleanup_module(void)
{
ENTRY;
obdfs_sysctl_clean();
}
void obdfs_psdev_dec_use_count(void)
{
MOD_DEC_USE_COUNT;
}
EXPORT_SYMBOL(obdfs_psdev_dec_use_count);
#endif
#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 *obdfs_table_header = NULL;
int obdfs_debug_level = 4095;
int obdfs_print_entry = 1;
#define OBDFS_SYSCTL 1
#define OBDFS_DEBUG 1 /* control debugging */
#define OBDFS_ENTRY 2 /* control enter/leave pattern */
#define OBDFS_TIMEOUT 3 /* timeout on upcalls to become intrble */
#define OBDFS_HARD 4 /* mount type "hard" or "soft" */
#define OBDFS_VARS 5
#define OBDFS_INDEX 6
#define OBDFS_RESET 7
#define OBDFS_VARS_SLOT 2
static ctl_table obdfs_table[] = {
{OBDFS_DEBUG, "debug", &obdfs_debug_level, sizeof(int), 0644, NULL, &proc_dointvec},
{OBDFS_ENTRY, "trace", &obdfs_print_entry, sizeof(int), 0644, NULL, &proc_dointvec},
{ 0 }
};
static ctl_table jukebox_table[] = {
{OBDFS_SYSCTL, "obdfs", NULL, 0, 0555, obdfs_table},
{0}
};
void obdfs_sysctl_init (void)
{
#ifdef CONFIG_SYSCTL
if ( !obdfs_table_header )
obdfs_table_header = register_sysctl_table(jukebox_table, 0);
#endif
}
void obdfs_sysctl_clean (void)
{
#ifdef CONFIG_SYSCTL
if ( obdfs_table_header )
unregister_sysctl_table(obdfs_table_header);
obdfs_table_header = NULL;
#endif
}
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