Commit 54165329 authored by Robert Read's avatar Robert Read Committed by David S. Miller

[PATCH] InterMezzo for 2.5

This is the initial port of InterMezzo for 2.5.  It now compiles,
mounts, and completes I/Os successfully, but we are aware that more
needs to be done and we will do it as quickly as possible.
parent f8d0366a
......@@ -4,9 +4,11 @@
obj-$(CONFIG_INTERMEZZO_FS) += intermezzo.o
intermezzo-objs := journal_reiserfs.o cache.o journal.o presto.o vfs.o \
psdev.o upcall.o methods.o sysctl.o dcache.o dir.o \
super.o journal_ext2.o journal_ext3.o journal_xfs.o \
inode.o file.o journal_obdfs.o
intermezzo-objs := cache.o dcache.o dir.o ext_attr.o file.o fileset.o \
inode.o io_daemon.o journal.o journal_ext2.o journal_ext3.o \
journal_obdfs.o journal_reiserfs.o journal_tmpfs.o journal_xfs.o \
kml_reint.o kml_unpack.o methods.o presto.o psdev.o replicator.o \
super.o sysctl.o upcall.o vfs.o
include $(TOPDIR)/Rules.make
/*
*
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
* Copyright (C) 2000 Stelias Computing, Inc.
* Copyright (C) 2000 Red Hat, Inc.
*
* This file is part of InterMezzo, http://www.inter-mezzo.org.
*
* InterMezzo is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* InterMezzo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with InterMezzo; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define __NO_VERSION__
......@@ -19,14 +32,14 @@
#include <linux/ext2_fs.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/time.h>
#include <linux/sched.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/smp_lock.h>
#include <linux/blkdev.h>
#include <linux/init.h>
#include <linux/intermezzo_fs.h>
#include <linux/intermezzo_upcall.h>
#include <linux/intermezzo_psdev.h>
/*
......@@ -37,24 +50,27 @@
The methods for the cache are set up in methods.
*/
extern kmem_cache_t * presto_dentry_slab;
/* the intent of this hash is to have collision chains of length 1 */
#define CACHES_BITS 8
#define CACHES_SIZE (1 << CACHES_BITS)
#define CACHES_MASK CACHES_SIZE - 1
static struct list_head presto_caches[CACHES_SIZE];
static inline int presto_cache_hash(struct super_block *sb)
static inline int presto_cache_hash(kdev_t dev)
{
return (CACHES_MASK) & ((unsigned long)sb / L1_CACHE_BYTES);
return (CACHES_MASK) & ((0x000F & (major(dev)) << 8) + (0x000F & minor(dev)));
}
inline void presto_cache_add(struct presto_cache *cache, struct super_block *sb)
inline void presto_cache_add(struct presto_cache *cache, kdev_t dev)
{
list_add(&cache->cache_chain,
&presto_caches[presto_cache_hash(sb)]);
&presto_caches[presto_cache_hash(dev)]);
cache->cache_dev = dev;
}
inline void presto_init_cache_hash(void)
inline void presto_cache_init_hash(void)
{
int i;
for ( i = 0; i < CACHES_SIZE; i++ ) {
......@@ -63,17 +79,18 @@ inline void presto_init_cache_hash(void)
}
/* map a device to a cache */
struct presto_cache *presto_find_cache(struct super_block *sb)
struct presto_cache *presto_cache_find(kdev_t dev)
{
struct presto_cache *cache;
struct list_head *lh, *tmp;
lh = tmp = &(presto_caches[presto_cache_hash(sb)]);
lh = tmp = &(presto_caches[presto_cache_hash(dev)]);
while ( (tmp = lh->next) != lh ) {
cache = list_entry(tmp, struct presto_cache, cache_chain);
if (cache->cache_sb == sb)
if ( kdev_same(cache->cache_dev, dev) ) {
return cache;
}
}
return NULL;
}
......@@ -82,85 +99,19 @@ struct presto_cache *presto_find_cache(struct super_block *sb)
struct presto_cache *presto_get_cache(struct inode *inode)
{
struct presto_cache *cache;
ENTRY;
/* find the correct presto_cache here, based on the device */
cache = presto_find_cache(inode->i_sb);
cache = presto_cache_find(to_kdev_t(inode->i_dev));
if ( !cache ) {
printk("WARNING: no presto cache for dev %s, ino %ld\n",
inode->i_sb->s_id, inode->i_ino);
CERROR("WARNING: no presto cache for dev %x, ino %ld\n",
inode->i_dev, inode->i_ino);
EXIT;
return NULL;
}
EXIT;
return cache;
}
/* list cache mount points for ioctl's or /proc/fs/intermezzo/mounts */
int presto_sprint_mounts(char *buf, int buflen, int minor)
{
int len = 0;
int i;
struct list_head *head, *tmp;
struct presto_cache *cache;
buf[0] = '\0';
for (i=0 ; i<CACHES_SIZE ; i++) {
head = tmp = &presto_caches[i];
while ( (tmp = tmp->next) != head ) {
cache = list_entry(tmp, struct presto_cache,
cache_chain);
if ( !cache->cache_root_fileset || !cache->cache_mtpt)
continue;
if ((minor != -1) &&
(cache->cache_psdev->uc_minor != minor))
continue;
if ( strlen(cache->cache_root_fileset) +
strlen(cache->cache_mtpt) +
strlen(cache->cache_psdev->uc_devname) +
4 > buflen - len)
break;
len += sprintf(buf + len, "%s %s %s\n",
cache->cache_root_fileset,
cache->cache_mtpt,
cache->cache_psdev->uc_devname);
}
}
buf[buflen-1] = '\0';
CDEBUG(D_SUPER, "%s\n", buf);
return len;
}
#ifdef CONFIG_KREINT
/* get mount point by volname
Arthur Ma, 2000.12.25
*/
int presto_get_mount (char *buf, int buflen, char *volname)
{
int i;
struct list_head *head, *tmp;
struct presto_cache *cache = NULL;
char *path = "";
buf[0] = '\0';
for (i=0 ; i<CACHES_SIZE ; i++) {
head = tmp = &presto_caches[i];
while ( (tmp = tmp->next) != head ) {
cache = list_entry(tmp, struct presto_cache,
cache_chain);
if ( !cache->cache_root_fileset || !cache->cache_mtpt)
continue;
if ( strcmp(cache->cache_root_fileset, volname) == 0)
break;
}
}
if (cache != NULL)
path = cache->cache_mtpt;
strncpy (buf, path, buflen);
return strlen (buf);
}
#endif
/* another debugging routine: check fs is InterMezzo fs */
int presto_ispresto(struct inode *inode)
{
......@@ -171,27 +122,25 @@ int presto_ispresto(struct inode *inode)
cache = presto_get_cache(inode);
if ( !cache )
return 0;
return (inode->i_sb == cache->cache_sb);
return kdev_same(to_kdev_t(inode->i_dev), cache->cache_dev);
}
/* setup a cache structure when we need one */
struct presto_cache *presto_init_cache(void)
struct presto_cache *presto_cache_init(void)
{
struct presto_cache *cache;
/* make a presto_cache structure for the hash */
PRESTO_ALLOC(cache, struct presto_cache *, sizeof(struct presto_cache));
PRESTO_ALLOC(cache, sizeof(struct presto_cache));
if ( cache ) {
memset(cache, 0, sizeof(struct presto_cache));
INIT_LIST_HEAD(&cache->cache_chain);
INIT_LIST_HEAD(&cache->cache_fset_list);
}
cache->cache_lock = SPIN_LOCK_UNLOCKED;
cache->cache_reserved = 0;
}
return cache;
}
/* free a cache structure and all of the memory it is pointing to */
inline void presto_free_cache(struct presto_cache *cache)
{
......@@ -199,12 +148,12 @@ inline void presto_free_cache(struct presto_cache *cache)
return;
list_del(&cache->cache_chain);
if (cache->cache_mtpt)
PRESTO_FREE(cache->cache_mtpt, strlen(cache->cache_mtpt) + 1);
if (cache->cache_type)
PRESTO_FREE(cache->cache_type, strlen(cache->cache_type) + 1);
if (cache->cache_root_fileset)
PRESTO_FREE(cache->cache_root_fileset, strlen(cache->cache_root_fileset) + 1);
if (cache->cache_sb && cache->cache_sb->s_root &&
presto_d2d(cache->cache_sb->s_root)) {
kmem_cache_free(presto_dentry_slab,
presto_d2d(cache->cache_sb->s_root));
cache->cache_sb->s_root->d_fsdata = NULL;
}
PRESTO_FREE(cache, sizeof(struct presto_cache));
}
......@@ -227,11 +176,12 @@ int presto_reserve_space(struct presto_cache *cache, loff_t req)
EXIT;
return 0;
}
spin_lock(&cache->cache_lock);
avail = filter->o_trops->tr_avail(cache, sb);
CDEBUG(D_SUPER, "ESC::%ld +++> %ld \n", (long) cache->cache_reserved,
(long) (cache->cache_reserved + req));
CDEBUG(D_SUPER, "ESC::Avail::%ld \n", (long) avail);
spin_lock(&cache->cache_lock);
if (req + cache->cache_reserved > avail) {
spin_unlock(&cache->cache_lock);
EXIT;
......@@ -240,6 +190,7 @@ int presto_reserve_space(struct presto_cache *cache, loff_t req)
cache->cache_reserved += req;
spin_unlock(&cache->cache_lock);
EXIT;
return 0;
}
......
This diff is collapsed.
This diff is collapsed.
/*
* Extended attribute handling for presto.
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
* Copyright (C) 2001 Tacit Networks, Inc.
* Author: Shirish H. Phatak <shirish@tacitnetworks.com>
*
* This file is part of InterMezzo, http://www.inter-mezzo.org.
*
* Copyright (C) 2001. All rights reserved.
* Shirish H. Phatak
* Tacit Networks, Inc.
* InterMezzo is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* InterMezzo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with InterMezzo; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Extended attribute handling for presto.
*/
#define __NO_VERSION__
......@@ -14,6 +29,7 @@
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/smp_lock.h>
#include <linux/unistd.h>
#include <asm/system.h>
......@@ -22,18 +38,16 @@
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/locks.h>
#include <linux/smp_lock.h>
#include <linux/string.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <asm/segment.h>
#include <linux/smp_lock.h>
#include <linux/intermezzo_fs.h>
#include <linux/intermezzo_upcall.h>
#include <linux/intermezzo_psdev.h>
#include <linux/intermezzo_kml.h>
#ifdef CONFIG_FS_EXT_ATTR
#include <linux/ext_attr.h>
......@@ -41,9 +55,6 @@
extern inline void presto_debug_fail_blkdev(struct presto_file_set *fset,
unsigned long value);
extern int presto_prep(struct dentry *, struct presto_cache **,
struct presto_file_set **);
/* VFS interface */
/* XXX! Fixme test for user defined attributes */
......@@ -75,7 +86,7 @@ int presto_set_ext_attr(struct inode *inode,
* we do a reverse mapping from inode to the first dentry
*/
if (list_empty(&inode->i_dentry)) {
printk("No alias for inode %d\n", (int) inode->i_ino);
CERROR("No alias for inode %d\n", (int) inode->i_ino);
EXIT;
return -EINVAL;
}
......@@ -99,12 +110,13 @@ int presto_set_ext_attr(struct inode *inode,
* (works for ext3)
*/
if (flags & EXT_ATTR_FLAG_USER) {
PRESTO_ALLOC(buf, char *, buffer_len);
PRESTO_ALLOC(buf, buffer_len);
if (!buf) {
printk("InterMezzo: out of memory!!!\n");
CERROR("InterMezzo: out of memory!!!\n");
return -ENOMEM;
}
if (copy_from_user(buf, buffer, buffer_len))
error = copy_from_user(buf, buffer, buffer_len);
if (error)
return -EFAULT;
} else
buf = buffer;
......@@ -172,7 +184,7 @@ int lento_set_ext_attr(const char *path, const char *name,
fset = presto_fset(dentry);
error = -EINVAL;
if ( !fset ) {
printk("No fileset!\n");
CERROR("No fileset!\n");
EXIT;
goto exit_dentry;
}
......
This diff is collapsed.
This diff is collapsed.
/*
* Super block/filesystem wide operations
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
* Copryright (C) 1996 Peter J. Braam <braam@maths.ox.ac.uk> and
* Copyright (C) 1996 Peter J. Braam <braam@maths.ox.ac.uk> and
* Michael Callahan <callahan@maths.ox.ac.uk>
*
* Copyright (C) 1999 Carnegie Mellon University
* Rewritten for Linux 2.1. Peter Braam <braam@cs.cmu.edu>
* Copyright (C) Carnegie Mellon University
*
* This file is part of InterMezzo, http://www.inter-mezzo.org.
*
* InterMezzo is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* InterMezzo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with InterMezzo; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Super block/filesystem wide operations
*/
#define __NO_VERSION__
......@@ -15,6 +31,7 @@
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/smp_lock.h>
#include <linux/unistd.h>
#include <asm/system.h>
......@@ -23,33 +40,25 @@
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/smp_lock.h>
#include <linux/string.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <asm/segment.h>
#include <linux/intermezzo_fs.h>
#include <linux/intermezzo_upcall.h>
#include <linux/intermezzo_psdev.h>
extern int presto_remount(struct super_block *, int *, char *);
int presto_excluded_gid = PRESTO_EXCL_GID;
extern int presto_prep(struct dentry *, struct presto_cache **,
struct presto_file_set **);
extern void presto_free_cache(struct presto_cache *);
void presto_set_ops(struct inode *inode, struct filter_fs *filter)
{
ENTRY;
if (inode->i_gid == presto_excluded_gid ) {
EXIT;
CDEBUG(D_INODE, "excluded methods for %ld at %p, %p\n",
inode->i_ino, inode->i_op, inode->i_fop);
if (!inode || is_bad_inode(inode))
return;
}
if (S_ISREG(inode->i_mode)) {
if ( !filter_c2cfiops(filter) ) {
filter_setup_file_ops(filter,
......@@ -63,8 +72,8 @@ void presto_set_ops(struct inode *inode, struct filter_fs *filter)
} else if (S_ISDIR(inode->i_mode)) {
inode->i_op = filter_c2udiops(filter);
inode->i_fop = filter_c2udfops(filter);
CDEBUG(D_INODE, "set dir methods for %ld to %p lookup %p\n",
inode->i_ino, inode->i_op, inode->i_op->lookup);
CDEBUG(D_INODE, "set dir methods for %ld to %p ioctl %p\n",
inode->i_ino, inode->i_op, inode->i_fop->ioctl);
} else if (S_ISLNK(inode->i_mode)) {
if ( !filter_c2csiops(filter)) {
filter_setup_symlink_ops(filter,
......@@ -86,7 +95,7 @@ void presto_read_inode(struct inode *inode)
cache = presto_get_cache(inode);
if ( !cache ) {
printk("PRESTO: BAD, BAD: cannot find cache\n");
CERROR("PRESTO: BAD, BAD: cannot find cache\n");
make_bad_inode(inode);
return ;
}
......@@ -96,35 +105,50 @@ void presto_read_inode(struct inode *inode)
CDEBUG(D_INODE, "presto_read_inode: ino %ld, gid %d\n",
inode->i_ino, inode->i_gid);
// if (inode->i_gid == presto_excluded_gid)
// return;
presto_set_ops(inode, cache->cache_filter);
/* XXX handle special inodes here or not - probably not? */
}
void presto_put_super(struct super_block *sb)
static void presto_put_super(struct super_block *sb)
{
struct presto_cache *cache;
struct upc_comm *psdev;
struct upc_channel *channel;
struct super_operations *sops;
struct list_head *lh;
int err;
ENTRY;
cache = presto_find_cache(sb);
cache = presto_cache_find(to_kdev_t(sb->s_dev));
if (!cache) {
EXIT;
goto exit;
}
psdev = &upc_comms[presto_c2m(cache)];
channel = &izo_channels[presto_c2m(cache)];
sops = filter_c2csops(cache->cache_filter);
err = izo_clear_all_fsetroots(cache);
if (err) {
CERROR("%s: err %d\n", __FUNCTION__, err);
}
PRESTO_FREE(cache->cache_vfsmount, sizeof(struct vfsmount));
/* look at kill_super - fsync_super is not exported GRRR but
probably not needed */
unlock_super(sb);
shrink_dcache_parent(cache->cache_root);
dput(cache->cache_root);
//fsync_super(sb);
lock_super(sb);
if (sops->write_super)
sops->write_super(sb);
if (sops->put_super)
sops->put_super(sb);
/* free any remaining async upcalls when the filesystem is unmounted */
lh = psdev->uc_pending.next;
while ( lh != &psdev->uc_pending) {
spin_lock(&channel->uc_lock);
lh = channel->uc_pending.next;
while ( lh != &channel->uc_pending) {
struct upc_req *req;
req = list_entry(lh, struct upc_req, rq_chain);
......@@ -136,6 +160,8 @@ void presto_put_super(struct super_block *sb)
PRESTO_FREE(req->rq_data, req->rq_bufsize);
PRESTO_FREE(req, sizeof(struct upc_req));
}
list_del(&cache->cache_channel_list);
spin_unlock(&channel->uc_lock);
presto_free_cache(cache);
......@@ -146,18 +172,16 @@ void presto_put_super(struct super_block *sb)
return ;
}
struct super_operations presto_super_ops = {
.read_inode = presto_read_inode,
.put_super = presto_put_super,
};
/* symlinks can be chowned */
struct inode_operations presto_sym_iops = {
setattr: presto_setattr
.setattr = presto_setattr
};
/* NULL for now */
struct file_operations presto_sym_fops;
struct super_operations presto_super_ops = {
read_inode: presto_read_inode,
put_super: presto_put_super,
remount_fs: presto_remount
};
MODULE_LICENSE("GPL");
This diff is collapsed.
/*
* Intermezzo. (C) 1998 Peter J. Braam
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
* Copyright (C) 1998 Peter J. Braam <braam@clusterfs.com>
*
* This file is part of InterMezzo, http://www.inter-mezzo.org.
*
* InterMezzo is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* InterMezzo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with InterMezzo; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/smp_lock.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/string.h>
#include <linux/ext2_fs.h>
#include <linux/intermezzo_fs.h>
#include <linux/intermezzo_upcall.h>
#include <linux/intermezzo_psdev.h>
#include <linux/intermezzo_kml.h>
#if defined(CONFIG_EXT2_FS)
......@@ -46,7 +62,7 @@ static void *presto_e2_trans_start(struct presto_file_set *fset, struct inode *i
return ERR_PTR(-ENOSPC);
}
if ( (op != PRESTO_OP_UNLINK && op != PRESTO_OP_RMDIR)
if ( (op != KML_OPCODE_UNLINK && op != KML_OPCODE_RMDIR)
&& avail_kmlblocks < 6 ) {
return ERR_PTR(-ENOSPC);
}
......@@ -58,7 +74,14 @@ static void presto_e2_trans_commit(struct presto_file_set *fset, void *handle)
do {} while (0);
}
static int presto_e2_has_all_data(struct inode *inode)
{
BUG();
return 0;
}
struct journal_ops presto_ext2_journal_ops = {
tr_all_data: presto_e2_has_all_data,
tr_avail: presto_e2_freespace,
tr_start: presto_e2_trans_start,
tr_commit: presto_e2_trans_commit,
......
/*
* Intermezzo. (C) 1998 Peter J. Braam
* Intermezzo. (C) 2000 Red Hat, Inc.
* Intermezzo. (C) 2000 Los Alamos National Laboratory
* Intermezzo. (C) 2000 TurboLinux, Inc.
* Intermezzo. (C) 2001 Mountain View Data, Inc.
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
* Copyright (C) 1998 Peter J. Braam <braam@clusterfs.com>
* Copyright (C) 2000 Red Hat, Inc.
* Copyright (C) 2000 Los Alamos National Laboratory
* Copyright (C) 2000 TurboLinux, Inc.
* Copyright (C) 2001 Mountain View Data, Inc.
* Copyright (C) 2001 Tacit Networks, Inc. <phil@off.net>
*
* This file is part of InterMezzo, http://www.inter-mezzo.org.
*
* InterMezzo is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* InterMezzo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with InterMezzo; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/types.h>
#include <linux/param.h>
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/smp_lock.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/string.h>
#include <linux/smp_lock.h>
......@@ -26,9 +45,7 @@
#endif
#include <linux/intermezzo_fs.h>
#include <linux/intermezzo_upcall.h>
#include <linux/intermezzo_psdev.h>
#include <linux/intermezzo_kml.h>
#if defined(CONFIG_EXT3_FS) || defined (CONFIG_EXT3_FS_MODULE)
......@@ -52,9 +69,9 @@
static loff_t presto_e3_freespace(struct presto_cache *cache,
struct super_block *sb)
{
loff_t freebl = le32_to_cpu(sb->u.ext3_sb.s_es->s_free_blocks_count);
loff_t freebl = le32_to_cpu(EXT3_SB(sb)->s_es->s_free_blocks_count);
loff_t avail = freebl -
le32_to_cpu(sb->u.ext3_sb.s_es->s_r_blocks_count);
le32_to_cpu(EXT3_SB(sb)->s_es->s_r_blocks_count);
return (avail << EXT3_BLOCK_SIZE_BITS(sb));
}
......@@ -77,13 +94,13 @@ static void *presto_e3_trans_start(struct presto_file_set *fset,
return NULL;
}
avail_kmlblocks = inode->i_sb->u.ext3_sb.s_es->s_free_blocks_count;
avail_kmlblocks = EXT3_SB(inode->i_sb)->s_es->s_free_blocks_count;
if ( avail_kmlblocks < 3 ) {
return ERR_PTR(-ENOSPC);
}
if ( (op != PRESTO_OP_UNLINK && op != PRESTO_OP_RMDIR)
if ( (op != KML_OPCODE_UNLINK && op != KML_OPCODE_RMDIR)
&& avail_kmlblocks < 6 ) {
return ERR_PTR(-ENOSPC);
}
......@@ -105,52 +122,71 @@ static void *presto_e3_trans_start(struct presto_file_set *fset,
and operations involving the LML records
*/
switch (op) {
case PRESTO_OP_TRUNC:
case KML_OPCODE_TRUNC:
jblocks = one_path_blks + extra_name_blks + trunc_blks
+ EXT3_DELETE_TRANS_BLOCKS;
break;
case PRESTO_OP_RELEASE:
case KML_OPCODE_KML_TRUNC:
/* Hopefully this is a little better, but I'm still mostly
* guessing here. */
/* unlink 1 */
jblocks = extra_name_blks + trunc_blks +
EXT3_DELETE_TRANS_BLOCKS + 2;
/* unlink 2 */
jblocks += extra_name_blks + trunc_blks +
EXT3_DELETE_TRANS_BLOCKS + 2;
/* rename 1 */
jblocks += 2 * extra_path_blks + trunc_blks +
2 * EXT3_DATA_TRANS_BLOCKS + 2 + 3;
/* rename 2 */
jblocks += 2 * extra_path_blks + trunc_blks +
2 * EXT3_DATA_TRANS_BLOCKS + 2 + 3;
break;
case KML_OPCODE_RELEASE:
/*
jblocks = one_path_blks + lml_blks + 2*trunc_blks;
*/
jblocks = one_path_blks;
break;
case PRESTO_OP_SETATTR:
case KML_OPCODE_SETATTR:
jblocks = one_path_blks + trunc_blks + 1 ;
break;
case PRESTO_OP_CREATE:
case KML_OPCODE_CREATE:
jblocks = one_path_blks + trunc_blks
+ EXT3_DATA_TRANS_BLOCKS + 3 + 2;
break;
case PRESTO_OP_LINK:
case KML_OPCODE_LINK:
jblocks = one_path_blks + trunc_blks
+ EXT3_DATA_TRANS_BLOCKS + 2;
break;
case PRESTO_OP_UNLINK:
case KML_OPCODE_UNLINK:
jblocks = one_path_blks + extra_name_blks + trunc_blks
+ EXT3_DELETE_TRANS_BLOCKS + 2;
break;
case PRESTO_OP_SYMLINK:
case KML_OPCODE_SYMLINK:
jblocks = one_path_blks + extra_path_blks + trunc_blks
+ EXT3_DATA_TRANS_BLOCKS + 5;
break;
case PRESTO_OP_MKDIR:
case KML_OPCODE_MKDIR:
jblocks = one_path_blks + trunc_blks
+ EXT3_DATA_TRANS_BLOCKS + 4 + 2;
break;
case PRESTO_OP_RMDIR:
case KML_OPCODE_RMDIR:
jblocks = one_path_blks + extra_name_blks + trunc_blks
+ EXT3_DELETE_TRANS_BLOCKS + 1;
break;
case PRESTO_OP_MKNOD:
case KML_OPCODE_MKNOD:
jblocks = one_path_blks + trunc_blks +
EXT3_DATA_TRANS_BLOCKS + 3 + 2;
break;
case PRESTO_OP_RENAME:
case KML_OPCODE_RENAME:
jblocks = one_path_blks + extra_path_blks + trunc_blks +
2 * EXT3_DATA_TRANS_BLOCKS + 2 + 3;
break;
case PRESTO_OP_WRITE:
case KML_OPCODE_WRITE:
jblocks = one_path_blks;
/* add this when we can wrap our transaction with
that of ext3_file_write (ordered writes)
......@@ -162,7 +198,8 @@ static void *presto_e3_trans_start(struct presto_file_set *fset,
return NULL;
}
CDEBUG(D_JOURNAL, "creating journal handle (%d blocks)\n", jblocks);
CDEBUG(D_JOURNAL, "creating journal handle (%d blocks) for op %d\n",
jblocks, op);
/* journal_start/stop does not do its own locking while updating
* the handle/transaction information. Hence we create our own
* critical section to protect these calls. -SHP
......@@ -173,7 +210,7 @@ static void *presto_e3_trans_start(struct presto_file_set *fset,
return handle;
}
void presto_e3_trans_commit(struct presto_file_set *fset, void *handle)
static void presto_e3_trans_commit(struct presto_file_set *fset, void *handle)
{
if ( presto_no_journal(fset) || !handle)
return;
......@@ -184,7 +221,7 @@ void presto_e3_trans_commit(struct presto_file_set *fset, void *handle)
unlock_kernel();
}
void presto_e3_journal_file_data(struct inode *inode)
static void presto_e3_journal_file_data(struct inode *inode)
{
#ifdef EXT3_JOURNAL_DATA_FL
EXT3_I(inode)->i_flags |= EXT3_JOURNAL_DATA_FL;
......@@ -193,11 +230,56 @@ void presto_e3_journal_file_data(struct inode *inode)
#endif
}
/* The logic here is a slightly modified version of ext3/inode.c:block_to_path
*/
static int presto_e3_has_all_data(struct inode *inode)
{
int ptrs = EXT3_ADDR_PER_BLOCK(inode->i_sb);
int ptrs_bits = EXT3_ADDR_PER_BLOCK_BITS(inode->i_sb);
const long direct_blocks = EXT3_NDIR_BLOCKS,
indirect_blocks = ptrs,
double_blocks = (1 << (ptrs_bits * 2));
long block = (inode->i_size + inode->i_sb->s_blocksize - 1) >>
inode->i_sb->s_blocksize_bits;
ENTRY;
if (inode->i_size == 0) {
EXIT;
return 1;
}
if (block < direct_blocks) {
/* No indirect blocks, no problem. */
} else if (block < indirect_blocks + direct_blocks) {
block++;
} else if (block < double_blocks + indirect_blocks + direct_blocks) {
block += 2;
} else if (((block - double_blocks - indirect_blocks - direct_blocks)
>> (ptrs_bits * 2)) < ptrs) {
block += 3;
}
block *= (inode->i_sb->s_blocksize / 512);
CDEBUG(D_CACHE, "Need %ld blocks, have %ld.\n", block, inode->i_blocks);
if (block > inode->i_blocks) {
EXIT;
return 0;
}
EXIT;
return 1;
}
struct journal_ops presto_ext3_journal_ops = {
tr_avail: presto_e3_freespace,
tr_start: presto_e3_trans_start,
tr_commit: presto_e3_trans_commit,
tr_journal_data: presto_e3_journal_file_data
.tr_all_data = presto_e3_has_all_data,
.tr_avail = presto_e3_freespace,
.tr_start = presto_e3_trans_start,
.tr_commit = presto_e3_trans_commit,
.tr_journal_data = presto_e3_journal_file_data,
.tr_ilookup = presto_iget_ilookup
};
#endif /* CONFIG_EXT3_FS */
/*
* Intermezzo. (C) 1998 Peter J. Braam
* Intermezzo. (C) 2000 Red Hat, Inc.
* Intermezzo. (C) 2000 Los Alamos National Laboratory
* Intermezzo. (C) 2000 TurboLinux, Inc.
* Intermezzo. (C) 2001 Mountain View Data, Inc.
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
* Copyright (C) 1998 Peter J. Braam <braam@clusterfs.com>
* Copyright (C) 2000 Red Hat, Inc.
* Copyright (C) 2000 Los Alamos National Laboratory
* Copyright (C) 2000 TurboLinux, Inc.
* Copyright (C) 2001 Mountain View Data, Inc.
*
* This file is part of InterMezzo, http://www.inter-mezzo.org.
*
* InterMezzo is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* InterMezzo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with InterMezzo; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/types.h>
#include <linux/param.h>
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/smp_lock.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/string.h>
#ifdef CONFIG_OBDFS_FS
......@@ -23,9 +41,7 @@
#endif
#include <linux/intermezzo_fs.h>
#include <linux/intermezzo_upcall.h>
#include <linux/intermezzo_psdev.h>
#include <linux/intermezzo_kml.h>
#ifdef CONFIG_OBDFS_FS
......@@ -162,17 +178,17 @@ void presto_obdfs_trans_commit(struct presto_file_set *fset, void *handle)
void presto_obdfs_journal_file_data(struct inode *inode)
{
#ifdef EXT3_JOURNAL_DATA_FL
EXT3_I(inode)->i_flags |= EXT3_JOURNAL_DATA_FL;
inode->u.ext3_i.i_flags |= EXT3_JOURNAL_DATA_FL;
#else
#warning You must have a facility to enable journaled writes for recovery!
#endif
}
struct journal_ops presto_obdfs_journal_ops = {
tr_avail: presto_obdfs_freespace,
tr_start: presto_obdfs_trans_start,
tr_commit: presto_obdfs_trans_commit,
tr_journal_data: presto_obdfs_journal_file_data
.tr_avail = presto_obdfs_freespace,
.tr_start = presto_obdfs_trans_start,
.tr_commit = presto_obdfs_trans_commit,
.tr_journal_data = presto_obdfs_journal_file_data
};
#endif
/*
* Intermezzo. (C) 1998 Peter J. Braam
* Intermezzo. (C) 2000 Red Hat, Inc.
* Intermezzo. (C) 2000 Los Alamos National Laboratory
* Intermezzo. (C) 2000 TurboLinux, Inc.
* Intermezzo. (C) 2001 Mountain View Data, Inc.
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
* Copyright (C) 1998 Peter J. Braam <braam@clusterfs.com>
* Copyright (C) 2000 Red Hat, Inc.
* Copyright (C) 2000 Los Alamos National Laboratory
* Copyright (C) 2000 TurboLinux, Inc.
* Copyright (C) 2001 Mountain View Data, Inc.
*
* This file is part of InterMezzo, http://www.inter-mezzo.org.
*
* InterMezzo is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* InterMezzo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with InterMezzo; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/types.h>
#include <linux/param.h>
#include <linux/time.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/smp_lock.h>
#include <linux/smp_lock.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/string.h>
#if 0
......@@ -26,9 +44,8 @@
#endif
#include <linux/intermezzo_fs.h>
#include <linux/intermezzo_upcall.h>
#include <linux/intermezzo_psdev.h>
#include <linux/intermezzo_kml.h>
#if defined(CONFIG_REISERFS_FS) || defined(CONFIG_REISERFS_FS_MODULE)
......@@ -52,9 +69,9 @@ static void *presto_reiserfs_trans_start(struct presto_file_set *fset,
__u32 avail_kmlblocks;
struct reiserfs_transaction_handle *th ;
PRESTO_ALLOC(th, struct reiserfs_transaction_handle *, sizeof(*th));
PRESTO_ALLOC(th, sizeof(*th));
if (!th) {
printk("presto: No memory for trans handle\n");
CERROR("presto: No memory for trans handle\n");
return NULL;
}
......@@ -81,36 +98,44 @@ static void *presto_reiserfs_trans_start(struct presto_file_set *fset,
CDEBUG(D_JOURNAL, "creating journal handle (%d blocks)\n", jblocks);
lock_kernel();
//journal_begin(th, inode->i_sb, jblocks);
journal_begin(th, inode->i_sb, jblocks);
unlock_kernel();
return th;
}
void presto_reiserfs_trans_commit(struct presto_file_set *fset, void *handle)
static void presto_reiserfs_trans_commit(struct presto_file_set *fset,
void *handle)
{
int jblocks;
jblocks = 3 + JOURNAL_PER_BALANCE_CNT * 4;
lock_kernel();
//journal_end(handle, fset->fset_cache->cache_sb, jblocks);
journal_end(handle, fset->fset_cache->cache_sb, jblocks);
unlock_kernel();
PRESTO_FREE(handle, sizeof(struct reiserfs_transaction_handle));
}
void presto_reiserfs_journal_file_data(struct inode *inode)
static void presto_reiserfs_journal_file_data(struct inode *inode)
{
#ifdef EXT3_JOURNAL_DATA_FL
EXT3_I(inode)->i_flags |= EXT3_JOURNAL_DATA_FL;
inode->u.ext3_i.i_flags |= EXT3_JOURNAL_DATA_FL;
#else
#warning You must have a facility to enable journaled writes for recovery!
#endif
}
static int presto_reiserfs_has_all_data(struct inode *inode)
{
BUG();
return 0;
}
struct journal_ops presto_reiserfs_journal_ops = {
tr_avail: presto_reiserfs_freespace,
tr_start: presto_reiserfs_trans_start,
tr_commit: presto_reiserfs_trans_commit,
tr_journal_data: presto_reiserfs_journal_file_data
.tr_all_data = presto_reiserfs_has_all_data,
.tr_avail = presto_reiserfs_freespace,
.tr_start = presto_reiserfs_trans_start,
.tr_commit = presto_reiserfs_trans_commit,
.tr_journal_data = presto_reiserfs_journal_file_data
};
#endif
......
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
* Copyright (C) 1998 Peter J. Braam <braam@clusterfs.com>
* Copyright (C) 2000 Red Hat, Inc.
* Copyright (C) 2000 Los Alamos National Laboratory
* Copyright (C) 2000 TurboLinux, Inc.
* Copyright (C) 2001 Mountain View Data, Inc.
* Copyright (C) 2001 Tacit Networks, Inc. <phil@off.net>
*
* This file is part of InterMezzo, http://www.inter-mezzo.org.
*
* InterMezzo is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* InterMezzo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with InterMezzo; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/types.h>
#include <linux/param.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/smp_lock.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/string.h>
#include <linux/smp_lock.h>
#if defined(CONFIG_TMPFS)
#include <linux/jbd.h>
#if defined(CONFIG_EXT3)
#include <linux/ext3_fs.h>
#include <linux/ext3_jbd.h>
#endif
#endif
#include <linux/intermezzo_fs.h>
#include <linux/intermezzo_psdev.h>
#if defined(CONFIG_TMPFS)
/* space requirements:
presto_do_truncate:
used to truncate the KML forward to next fset->chunksize boundary
- zero partial block
- update inode
presto_write_record:
write header (< one block)
write one path (< MAX_PATHLEN)
possibly write another path (< MAX_PATHLEN)
write suffix (< one block)
presto_update_last_rcvd
write one block
*/
static loff_t presto_tmpfs_freespace(struct presto_cache *cache,
struct super_block *sb)
{
return (1<<30);
}
/* start the filesystem journal operations */
static void *presto_tmpfs_trans_start(struct presto_file_set *fset,
struct inode *inode,
int op)
{
return (void *)1;
}
static void presto_tmpfs_trans_commit(struct presto_file_set *fset, void *handle)
{
return;
}
static void presto_tmpfs_journal_file_data(struct inode *inode)
{
return;
}
/* The logic here is a slightly modified version of ext3/inode.c:block_to_path
*/
static int presto_tmpfs_has_all_data(struct inode *inode)
{
return 0;
}
struct journal_ops presto_tmpfs_journal_ops = {
tr_all_data: presto_tmpfs_has_all_data,
tr_avail: presto_tmpfs_freespace,
tr_start: presto_tmpfs_trans_start,
tr_commit: presto_tmpfs_trans_commit,
tr_journal_data: presto_tmpfs_journal_file_data,
tr_ilookup: presto_tmpfs_ilookup,
tr_add_ilookup: presto_add_ilookup_dentry
};
#endif /* CONFIG_EXT3_FS */
/*
* * Intermezzo. (C) 1998 Peter J. Braam
* */
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
* Copyright (C) 1998 Peter J. Braam <braam@clusterfs.com>
*
* This file is part of InterMezzo, http://www.inter-mezzo.org.
*
* InterMezzo is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* InterMezzo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with InterMezzo; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/smp_lock.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/string.h>
#if 0
/* XFS Support not there yet */
#ifdef CONFIG_FS_XFS
#include <linux/xfs_fs.h>
#endif
#include <linux/intermezzo_fs.h>
#include <linux/intermezzo_upcall.h>
#include <linux/intermezzo_psdev.h>
#include <linux/intermezzo_kml.h>
#include <linux/intermezzo_journal.h>
#if 0
......@@ -118,18 +136,27 @@ static void presto_xfs_trans_commit(struct presto_file_set *fset, void *handle)
xfs_trans_stop(handle);
}
void presto_xfs_journal_file_data(struct inode *inode)
static void presto_xfs_journal_file_data(struct inode *inode)
{
return;
}
static int presto_xfs_has_all_data(struct inode *inode)
{
BUG();
return 0;
}
struct journal_ops presto_xfs_journal_ops = {
tr_avail: presto_xfs_freespace,
tr_start: presto_xfs_trans_start,
tr_commit: presto_xfs_trans_commit,
tr_journal_data: presto_xfs_journal_file_data
.tr_all_data = presto_xfs_has_all_data,
.tr_avail = presto_xfs_freespace,
.tr_start = presto_xfs_trans_start,
.tr_commit = presto_xfs_trans_commit,
.tr_journal_data = presto_xfs_journal_file_data
};
#endif /* CONFIG_XFS_FS */
#endif
#endif /* CONFIG_XFS_FS */
This diff is collapsed.
This diff is collapsed.
/*
*
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
* Copyright (C) 2000 Stelias Computing, Inc.
* Copyright (C) 2000 Red Hat, Inc.
......@@ -7,6 +7,22 @@
*
* Extended Attribute Support
* Copyright (C) 2001 Shirish H. Phatak, Tacit Networks, Inc.
*
* This file is part of InterMezzo, http://www.inter-mezzo.org.
*
* InterMezzo is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* InterMezzo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with InterMezzo; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdarg.h>
......@@ -20,9 +36,10 @@
#include <linux/ext2_fs.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/time.h>
#include <linux/sched.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/smp_lock.h>
#include <linux/blkdev.h>
#include <linux/init.h>
#define __NO_VERSION__
......@@ -149,6 +166,16 @@ void filter_setup_journal_ops(struct filter_fs *ops, char *cache_type)
FDEBUG(D_SUPER, "ops at %p\n", ops);
}
if ( strlen(cache_type) == strlen("tmpfs") &&
memcmp(cache_type, "tmpfs", strlen("tmpfs")) == 0 ) {
#if defined(CONFIG_TMPFS)
ops->o_trops = &presto_tmpfs_journal_ops;
#else
ops->o_trops = NULL;
#endif
FDEBUG(D_SUPER, "ops at %p\n", ops);
}
if ( strlen(cache_type) == strlen("reiserfs") &&
memcmp(cache_type, "reiserfs", strlen("reiserfs")) == 0 ) {
#if 0
......@@ -163,7 +190,7 @@ void filter_setup_journal_ops(struct filter_fs *ops, char *cache_type)
if ( strlen(cache_type) == strlen("xfs") &&
memcmp(cache_type, "xfs", strlen("xfs")) == 0 ) {
#if 0
//#if defined(CONFIG_XFS_FS) || defined (CONFIG_XFS_FS_MODULE)
/*#if defined(CONFIG_XFS_FS) || defined (CONFIG_XFS_FS_MODULE) */
ops->o_trops = &presto_xfs_journal_ops;
#else
ops->o_trops = NULL;
......@@ -206,6 +233,13 @@ struct filter_fs *filter_get_filter_fs(const char *cache_type)
ops = &filter_oppar[FILTER_FS_EXT3];
FDEBUG(D_SUPER, "ops at %p\n", ops);
}
if ( strlen(cache_type) == strlen("tmpfs") &&
memcmp(cache_type, "tmpfs", strlen("tmpfs")) == 0 ) {
ops = &filter_oppar[FILTER_FS_TMPFS];
FDEBUG(D_SUPER, "ops at %p\n", ops);
}
if ( strlen(cache_type) == strlen("reiserfs") &&
memcmp(cache_type, "reiserfs", strlen("reiserfs")) == 0 ) {
ops = &filter_oppar[FILTER_FS_REISERFS];
......@@ -218,7 +252,7 @@ struct filter_fs *filter_get_filter_fs(const char *cache_type)
}
if (ops == NULL) {
printk("prepare to die: unrecognized cache type for Filter\n");
CERROR("prepare to die: unrecognized cache type for Filter\n");
}
return ops;
FEXIT;
......@@ -342,7 +376,7 @@ void filter_setup_dir_ops(struct filter_fs *cache, struct inode *inode, struct i
memcpy(filter_c2udfops(cache), cache_fops, sizeof(*cache_fops));
/* unconditional filtering operations */
filter_c2udfops(cache)->open = filter_fops->open;
filter_c2udfops(cache)->ioctl = filter_fops->ioctl;
FEXIT;
}
......@@ -373,7 +407,7 @@ void filter_setup_file_ops(struct filter_fs *cache, struct inode *inode, struct
memcpy(pr_iops, cache_iops, sizeof(*cache_iops));
/* copy dir fops */
printk("*** cache file ops at %p\n", cache_fops);
CERROR("*** cache file ops at %p\n", cache_fops);
memcpy(filter_c2uffops(cache), cache_fops, sizeof(*cache_fops));
/* assign */
......@@ -382,6 +416,8 @@ void filter_setup_file_ops(struct filter_fs *cache, struct inode *inode, struct
pr_iops->setattr = filter_iops->setattr;
if (cache_iops->getattr)
pr_iops->getattr = filter_iops->getattr;
/* XXX Should this be conditional rmr ? */
pr_iops->permission = filter_iops->permission;
#ifdef CONFIG_FS_EXT_ATTR
/* For now we assume that posix acls are handled through extended
* attributes. If this is not the case, we must explicitly trap and
......@@ -396,6 +432,7 @@ void filter_setup_file_ops(struct filter_fs *cache, struct inode *inode, struct
filter_c2uffops(cache)->open = filter_fops->open;
filter_c2uffops(cache)->release = filter_fops->release;
filter_c2uffops(cache)->write = filter_fops->write;
filter_c2uffops(cache)->ioctl = filter_fops->ioctl;
FEXIT;
}
......@@ -454,7 +491,7 @@ void filter_setup_dentry_ops(struct filter_fs *cache,
filter_dop, sizeof(*filter_dop));
if (cache_dop && cache_dop != filter_dop && cache_dop->d_revalidate){
printk("WARNING: filter overriding revalidation!\n");
CERROR("WARNING: filter overriding revalidation!\n");
}
return;
}
This diff is collapsed.
This diff is collapsed.
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
* Copyright (C) 2001 Cluster File Systems, Inc. <braam@clusterfs.com>
* Copyright (C) 2001 Tacit Networks, Inc. <phil@off.net>
*
* This file is part of InterMezzo, http://www.inter-mezzo.org.
*
* InterMezzo is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* InterMezzo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with InterMezzo; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Manage RCVD records for clients in the kernel
*
*/
#define __NO_VERSION__
#include <linux/module.h>
#include <stdarg.h>
#include <asm/uaccess.h>
#include <linux/errno.h>
#include <linux/intermezzo_fs.h>
/*
* this file contains a hash table of replicators/clients for a
* fileset. It allows fast lookup and update of reintegration status
*/
struct izo_offset_rec {
struct list_head or_list;
char or_uuid[16];
loff_t or_offset;
};
#define RCACHE_BITS 8
#define RCACHE_SIZE (1 << RCACHE_BITS)
#define RCACHE_MASK (RCACHE_SIZE - 1)
static struct list_head *
izo_rep_cache(void)
{
int i;
struct list_head *cache;
PRESTO_ALLOC(cache, sizeof(struct list_head) * RCACHE_SIZE);
if (cache == NULL) {
CERROR("intermezzo-fatal: no memory for replicator cache\n");
return NULL;
}
memset(cache, 0, sizeof(struct list_head) * RCACHE_SIZE);
for (i = 0; i < RCACHE_SIZE; i++)
INIT_LIST_HEAD(&cache[i]);
return cache;
}
static struct list_head *
izo_rep_hash(struct list_head *cache, char *uuid)
{
return &cache[(RCACHE_MASK & uuid[1])];
}
static void
izo_rep_cache_clean(struct presto_file_set *fset)
{
int i;
struct list_head *bucket;
struct list_head *tmp;
if (fset->fset_clients == NULL)
return;
for (i = 0; i < RCACHE_SIZE; i++) {
tmp = bucket = &fset->fset_clients[i];
tmp = tmp->next;
while (tmp != bucket) {
struct izo_offset_rec *offrec;
tmp = tmp->next;
list_del(tmp);
offrec = list_entry(tmp, struct izo_offset_rec,
or_list);
PRESTO_FREE(offrec, sizeof(struct izo_offset_rec));
}
}
}
struct izo_offset_rec *
izo_rep_cache_find(struct presto_file_set *fset, char *uuid)
{
struct list_head *buck = izo_rep_hash(fset->fset_clients, uuid);
struct list_head *tmp = buck;
struct izo_offset_rec *rec = NULL;
while ( (tmp = tmp->next) != buck ) {
rec = list_entry(tmp, struct izo_offset_rec, or_list);
if ( memcmp(rec->or_uuid, uuid, sizeof(rec->or_uuid)) == 0 )
return rec;
}
return NULL;
}
static int
izo_rep_cache_add(struct presto_file_set *fset, struct izo_rcvd_rec *rec,
loff_t offset)
{
struct izo_offset_rec *offrec;
if (izo_rep_cache_find(fset, rec->lr_uuid)) {
CERROR("izo: duplicate client entry %s off %Ld\n",
fset->fset_name, offset);
return -EINVAL;
}
PRESTO_ALLOC(offrec, sizeof(*offrec));
if (offrec == NULL) {
CERROR("izo: cannot allocate offrec\n");
return -ENOMEM;
}
memcpy(offrec->or_uuid, rec->lr_uuid, sizeof(rec->lr_uuid));
offrec->or_offset = offset;
list_add(&offrec->or_list,
izo_rep_hash(fset->fset_clients, rec->lr_uuid));
return 0;
}
int
izo_rep_cache_init(struct presto_file_set *fset)
{
struct izo_rcvd_rec rec;
loff_t offset = 0, last_offset = 0;
fset->fset_clients = izo_rep_cache();
if (fset->fset_clients == NULL) {
CERROR("Error initializing client cache\n");
return -ENOMEM;
}
while ( presto_fread(fset->fset_rcvd.fd_file, (char *)&rec,
sizeof(rec), &offset) == sizeof(rec) ) {
int rc;
if ((rc = izo_rep_cache_add(fset, &rec, last_offset)) < 0) {
izo_rep_cache_clean(fset);
return rc;
}
last_offset = offset;
}
return 0;
}
/*
* Return local last_rcvd record for the client. Update or create
* if necessary.
*
* XXX: After this call, any -EINVAL from izo_rcvd_get is a real error.
*/
int
izo_repstatus(struct presto_file_set *fset, __u64 client_kmlsize,
struct izo_rcvd_rec *lr_client, struct izo_rcvd_rec *lr_server)
{
int rc;
rc = izo_rcvd_get(lr_server, fset, lr_client->lr_uuid);
if (rc < 0 && rc != -EINVAL) {
return rc;
}
/* client is new or has been reset. */
if (rc < 0 || (client_kmlsize == 0 && lr_client->lr_remote_offset == 0)) {
memset(lr_server, 0, sizeof(*lr_server));
memcpy(lr_server->lr_uuid, lr_client->lr_uuid, sizeof(lr_server->lr_uuid));
rc = izo_rcvd_write(fset, lr_server);
if (rc < 0)
return rc;
}
/* update intersync */
rc = izo_upc_repstatus(presto_f2m(fset), fset->fset_name, lr_server);
return rc;
}
loff_t
izo_rcvd_get(struct izo_rcvd_rec *rec, struct presto_file_set *fset, char *uuid)
{
struct izo_offset_rec *offrec;
struct izo_rcvd_rec tmprec;
loff_t offset;
offrec = izo_rep_cache_find(fset, uuid);
if (offrec == NULL) {
CDEBUG(D_SPECIAL, "izo_get_rcvd: uuid not in hash.\n");
return -EINVAL;
}
offset = offrec->or_offset;
if (rec == NULL)
return offset;
if (presto_fread(fset->fset_rcvd.fd_file, (char *)&tmprec,
sizeof(tmprec), &offset) != sizeof(tmprec)) {
CERROR("izo_get_rcvd: Unable to read from last_rcvd file offset "
"%Lu\n", offset);
return -EIO;
}
memcpy(rec->lr_uuid, tmprec.lr_uuid, sizeof(tmprec.lr_uuid));
rec->lr_remote_recno = le64_to_cpu(tmprec.lr_remote_recno);
rec->lr_remote_offset = le64_to_cpu(tmprec.lr_remote_offset);
rec->lr_local_recno = le64_to_cpu(tmprec.lr_local_recno);
rec->lr_local_offset = le64_to_cpu(tmprec.lr_local_offset);
rec->lr_last_ctime = le64_to_cpu(tmprec.lr_last_ctime);
return offrec->or_offset;
}
/* Try to lookup the UUID in the hash. Insert it if it isn't found. Write the
* data to the file.
*
* Returns the offset of the beginning of the record in the last_rcvd file. */
loff_t
izo_rcvd_write(struct presto_file_set *fset, struct izo_rcvd_rec *rec)
{
struct izo_offset_rec *offrec;
loff_t offset, rc;
ENTRY;
offrec = izo_rep_cache_find(fset, rec->lr_uuid);
if (offrec == NULL) {
/* I don't think it should be possible for an entry to be not in
* the hash table without also having an invalid offset, but we
* handle it gracefully regardless. */
write_lock(&fset->fset_rcvd.fd_lock);
offset = fset->fset_rcvd.fd_offset;
fset->fset_rcvd.fd_offset += sizeof(*rec);
write_unlock(&fset->fset_rcvd.fd_lock);
rc = izo_rep_cache_add(fset, rec, offset);
if (rc < 0) {
EXIT;
return rc;
}
} else
offset = offrec->or_offset;
rc = presto_fwrite(fset->fset_rcvd.fd_file, (char *)rec, sizeof(*rec),
&offset);
if (rc == sizeof(*rec))
/* presto_fwrite() advances 'offset' */
rc = offset - sizeof(*rec);
EXIT;
return rc;
}
loff_t
izo_rcvd_upd_remote(struct presto_file_set *fset, char * uuid, __u64 remote_recno,
__u64 remote_offset)
{
struct izo_rcvd_rec rec;
loff_t rc;
ENTRY;
rc = izo_rcvd_get(&rec, fset, uuid);
if (rc < 0)
return rc;
rec.lr_remote_recno = remote_recno;
rec.lr_remote_offset = remote_offset;
rc = izo_rcvd_write(fset, &rec);
EXIT;
if (rc < 0)
return rc;
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*/
#ifndef __FILTER_H_
#define __FILTER_H_ 1
......@@ -59,12 +63,13 @@ struct filter_fs {
struct snapshot_ops *o_snops;
};
#define FILTER_FS_TYPES 5
#define FILTER_FS_TYPES 6
#define FILTER_FS_EXT2 0
#define FILTER_FS_EXT3 1
#define FILTER_FS_REISERFS 2
#define FILTER_FS_XFS 3
#define FILTER_FS_OBDFS 4
#define FILTER_FS_TMPFS 5
extern struct filter_fs filter_oppar[FILTER_FS_TYPES];
struct filter_fs *filter_get_filter_fs(const char *cache_type);
......@@ -96,7 +101,7 @@ void filter_setup_dentry_ops(struct filter_fs *cache, struct dentry_operations *
#define PRESTO_DEBUG
#ifdef PRESTO_DEBUG
/* debugging masks */
#define D_SUPER 1 /* print results returned by Venus */
#define D_SUPER 1
#define D_INODE 2 /* print entry and exit into procedure */
#define D_FILE 4
#define D_CACHE 8 /* cache debugging */
......
This diff is collapsed.
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*/
#ifndef __PRESTO_PSDEV_H
#define __PRESTO_PSDEV_H
#ifdef PRESTO_DEVEL
# define PRESTO_FS_NAME "izofs"
# define PRESTO_PSDEV_NAME "/dev/izo"
# define PRESTO_PSDEV_MAJOR 186
#else
# define PRESTO_FS_NAME "InterMezzo"
# define PRESTO_PSDEV_NAME "/dev/intermezzo"
# define PRESTO_PSDEV_MAJOR 185
#endif
#define MAX_PRESTODEV 16
#define MAX_CHANNEL 16
#define PROCNAME_SIZE 32
#include <linux/smp_lock.h>
#include <linux/smp_lock.h>
#include <linux/version.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
#define wait_queue_head_t struct wait_queue *
#define DECLARE_WAITQUEUE(name,task) \
struct wait_queue name = { task, NULL }
#define init_waitqueue_head(arg)
#else
#ifndef __initfunc
#define __initfunc(arg) arg
#endif
#endif
/* represents state of a /dev/presto */
/* represents state of an instance reached with /dev/intermezzo */
/* communication pending & processing queues */
struct upc_comm {
struct upc_channel {
unsigned int uc_seq;
wait_queue_head_t uc_waitq; /* Lento wait queue */
struct list_head uc_pending;
struct list_head uc_processing;
spinlock_t uc_lock;
int uc_pid; /* Lento's pid */
int uc_hard; /* allows signals during upcalls */
int uc_no_filter;
......@@ -43,15 +28,15 @@ struct upc_comm {
long uc_errorval; /* for testing I/O failures */
struct list_head uc_cache_list;
int uc_minor;
char * uc_devname;
};
#define ISLENTO(minor) (current->pid == upc_comms[minor].uc_pid \
|| current->parent->pid == upc_comms[minor].uc_pid)
#define ISLENTO(minor) (current->pid == izo_channels[minor].uc_pid \
|| current->real_parent->pid == izo_channels[minor].uc_pid \
|| current->real_parent->real_parent->pid == izo_channels[minor].uc_pid)
extern struct upc_comm upc_comms[MAX_PRESTODEV];
extern struct upc_channel izo_channels[MAX_CHANNEL];
/* messages between presto filesystem in kernel and Venus */
/* message types between presto filesystem in kernel */
#define REQ_READ 1
#define REQ_WRITE 2
#define REQ_ASYNC 4
......@@ -60,10 +45,10 @@ extern struct upc_comm upc_comms[MAX_PRESTODEV];
struct upc_req {
struct list_head rq_chain;
caddr_t rq_data;
u_short rq_flags;
u_short rq_bufsize;
u_short rq_rep_size;
u_short rq_opcode; /* copied from data to save lookup */
int rq_flags;
int rq_bufsize;
int rq_rep_size;
int rq_opcode; /* copied from data to save lookup */
int rq_unique;
wait_queue_head_t rq_sleep; /* process' wait queue */
unsigned long rq_posttime;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment