struct ext2_dir_entry_2 * de,
struct page * page,
unsigned long offset);
+/* symlink.c */
+int obdfs_readlink (struct dentry *, char *, int);
+struct dentry *obdfs_follow_link(struct dentry *, struct dentry *, unsigned int);
struct obdfs_sb_info {
struct obd_conn osi_conn;
extern struct file_operations obdfs_file_ops;
extern struct inode_operations obdfs_inode_ops;
+extern struct inode_operations obdfs_symlink_inode_operations;
static inline struct obd_ops *iops(struct inode *i)
{
rmmod obdext2
rmmod obdclass
-
+[ "`lsmod | grep loop`" ] && rmmod loop
echo "NEW OBDFS setup..." >> /var/log/messages
-./obdcontrol -f << EOF
+../class/obdcontrol -f << EOF
attach ext2_obd
setup
quit
include ../config.mk
MODULE = obdfs.o
-CFILES=file.c dir.c sysctl.c super.c rw.c namei.c # symlink.c
+CFILES=file.c dir.c sysctl.c super.c rw.c namei.c symlink.c
-include ../make.rules
\ No newline at end of file
+include ../make.rules
/*
- * linux/fs/ext2/namei.c
+ * linux/fs/obdfs/namei.c
*
* Copyright (C) 1992, 1993, 1994, 1995
* Remy Card (card@masi.ibp.fr)
*
* from
*
- * linux/fs/minix/namei.c
+ * linux/fs/ext2/namei.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
const char * unhashed = "";
if ( subdirs )
- dentry = list_entry(tmp, struct dentry, d_child);
- else
- dentry = list_entry(tmp, struct dentry, d_alias);
+ dentry = list_entry(tmp, struct dentry, d_child);
+ else
+ dentry = list_entry(tmp, struct dentry, d_alias);
if (list_empty(&dentry->d_hash))
unhashed = "(unhashed)";
ino_t ino;
ENTRY;
-
/*
* N.B. Several error exits in ext2_new_inode don't set err.
*/
ino = iops(dir)->o_create(iid(dir), 0, &err);
- if ( ino == -1 )
+ if ( ino == -1 ) {
+ EXIT;
return -1;
+ }
inode = iget(dir->i_sb, ino);
- if (!inode)
+ if (!inode) {
+ EXIT;
return err;
+ }
inode->i_mode = S_IFLNK | S_IRWXUGO;
- inode->i_op = &obdfs_inode_ops;
+ inode->i_op = &obdfs_symlink_inode_operations;
for (l = 0; l < inode->i_sb->s_blocksize - 1 &&
symname [l]; l++)
;
- if (l >= sizeof (inode->u.ext2_i.i_data)) {
+ /* For obdfs we always use normal (not fast) symlinks
+ if (l >= sizeof (inode->u.ext2_i.i_data)) { */
CDEBUG(D_INODE, "l=%d, normal symlink\n", l);
name_page = obdfs_getpage(inode, 0, 1, LOCKED);
inode->i_nlink--;
mark_inode_dirty(inode);
iput (inode);
+ EXIT;
return err;
}
link = (char *)page_address(name_page);
- } else {
+ /* } else {
link = (char *) inode->u.ext2_i.i_data;
CDEBUG(D_INODE, "l=%d, fast symlink\n", l);
- }
+ } */
i = 0;
while (i < inode->i_sb->s_blocksize - 1 && (c = *(symname++)))
link[i++] = c;
link[i] = 0;
- if (name_page) {
+
+ /* if (name_page) { */
iops(inode)->o_brw(WRITE, iid(inode), inode, name_page, 1);
PDEBUG(name_page, "symlink");
UnlockPage(name_page);
page_cache_release(name_page);
- }
+ /* } */
+
inode->i_size = i;
mark_inode_dirty(inode);
d_instantiate(dentry, inode);
err = 0;
out:
+ EXIT;
return err;
out_no_entry:
struct inode_operations obdfs_inode_ops = {
&obdfs_file_ops, /* default directory file-ops */
obdfs_create, /* create */
- obdfs_lookup, /* lookup */
+ obdfs_lookup, /* lookup */
obdfs_link, /* link */
obdfs_unlink, /* unlink */
obdfs_symlink, /* symlink */
obdfs_rmdir, /* rmdir */
obdfs_mknod, /* mknod */
obdfs_rename, /* rename */
- NULL, /* readlink */
+ obdfs_readlink, /* readlink */
NULL, /* follow_link */
- NULL, /* get_block */
+ NULL, /* get_block */
obdfs_readpage, /* readpage */
- obdfs_writepage, /* writepage */
+ obdfs_writepage,/* writepage */
NULL, /* truncate */
NULL, /* permission */
- NULL /* revalidate */
+ NULL /* revalidate */
};
#include <linux/errno.h>
#include <linux/fs.h>
-#include <linux/ext2_fs.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/stat.h>
+#include <linux/locks.h>
+
+#include <linux/obd_support.h> /* for ENTRY and EXIT only */
+#include <linux/obdfs.h>
static int obdfs_readlink (struct dentry *, char *, int);
static struct dentry *obdfs_follow_link(struct dentry *, struct dentry *, unsigned int);
-static struct dentry * ext2_follow_link(struct dentry * dentry,
- struct dentry *base,
- unsigned int follow)
+/*
+ * symlinks can't do much...
+ */
+struct inode_operations obdfs_symlink_inode_operations = {
+ NULL, /* no file-operations */
+ NULL, /* create */
+ NULL, /* lookup */
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ obdfs_readlink, /* readlink */
+ obdfs_follow_link, /* follow_link */
+ NULL, /* get_block */
+ NULL, /* readpage */
+ NULL, /* writepage */
+ NULL, /* truncate */
+ NULL, /* permission */
+ NULL /* revalidate */
+};
+
+static struct dentry * obdfs_follow_link(struct dentry * dentry,
+ struct dentry *base,
+ unsigned int follow)
{
struct inode *inode = dentry->d_inode;
struct page *page = NULL;
- int error;
char * link;
+ ENTRY;
link = (char *) inode->u.ext2_i.i_data;
if (inode->i_blocks) {
- if (!(page = obdfs_getpage(inode, 0, 0, &error))) {
+ IDEBUG(inode);
+ page = obdfs_getpage(inode, 0, 0, 0);
+ PDEBUG(page, "follow_link");
+ if (!page) {
dput(base);
+ EXIT;
return ERR_PTR(-EIO);
}
- link = bh->b_data;
+ link = (char *)page_address(page);
}
UPDATE_ATIME(inode);
base = lookup_dentry(link, base, follow);
- if (bh)
- brelse(bh);
+ if (page) {
+ page_cache_release(page);
+ }
+ EXIT;
return base;
}
-static int ext2_readlink (struct dentry * dentry, char * buffer, int buflen)
+static int obdfs_readlink (struct dentry * dentry, char * buffer, int buflen)
{
struct inode *inode = dentry->d_inode;
- struct buffer_head * bh = NULL;
+ struct page *page = NULL;
char * link;
int i;
+ ENTRY;
if (buflen > inode->i_sb->s_blocksize - 1)
buflen = inode->i_sb->s_blocksize - 1;
link = (char *) inode->u.ext2_i.i_data;
if (inode->i_blocks) {
- int err;
- bh = ext2_bread (inode, 0, 0, &err);
- if (!bh) {
- if(err < 0) /* indicate type of error */
- return err;
+ IDEBUG(inode);
+ page = obdfs_getpage(inode, 0, 0, 0);
+ PDEBUG(page, "readlink");
+ if (!page) {
+ EXIT;
return 0;
}
- link = bh->b_data;
+ link = (char *)page_address(page);
}
i = 0;
i++;
if (copy_to_user(buffer, link, i))
i = -EFAULT;
- if (bh)
- brelse (bh);
+ if (page) {
+ page_cache_release(page);
+ }
+ EXIT;
return i;
-}
+} /* obdfs_readlink */
#!/bin/sh
rm -f TAGS ; find . -name '*.h' -or -name '*.c' | xargs etags
+rm -f tags ; ctags -R *