From: adilger Date: Wed, 15 Dec 1999 03:47:28 +0000 (+0000) Subject: include/linux/obdfs.h: add symlink_inode_operations, prototypes X-Git-Tag: v1_7_100~6165 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=8e1bef7b6c3874c554152e6317bf4ef28aa3ffa7 include/linux/obdfs.h: add symlink_inode_operations, prototypes obdfs/symlink.c, obdfs/namei.c: handle obdfs symlinks properly --- diff --git a/lustre/include/linux/obdfs.h b/lustre/include/linux/obdfs.h index afd03c8..ca8ebfb 100644 --- a/lustre/include/linux/obdfs.h +++ b/lustre/include/linux/obdfs.h @@ -41,6 +41,9 @@ int obdfs_check_dir_entry (const char * function, struct inode * dir, 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; @@ -58,6 +61,7 @@ struct obdfs_inode_info; 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) { diff --git a/lustre/obdclass/cleanup.sh b/lustre/obdclass/cleanup.sh index 8d39a73..1d8359b 100644 --- a/lustre/obdclass/cleanup.sh +++ b/lustre/obdclass/cleanup.sh @@ -11,4 +11,4 @@ EOF rmmod obdext2 rmmod obdclass - +[ "`lsmod | grep loop`" ] && rmmod loop diff --git a/lustre/obdclass/setup.sh b/lustre/obdclass/setup.sh index f905f81..be56e6e 100755 --- a/lustre/obdclass/setup.sh +++ b/lustre/obdclass/setup.sh @@ -12,7 +12,7 @@ insmod ../obdfs/obdfs.o echo "NEW OBDFS setup..." >> /var/log/messages -./obdcontrol -f << EOF +../class/obdcontrol -f << EOF attach ext2_obd setup quit diff --git a/lustre/obdfs/Makefile b/lustre/obdfs/Makefile index afb45cf..dd72518 100644 --- a/lustre/obdfs/Makefile +++ b/lustre/obdfs/Makefile @@ -5,6 +5,6 @@ 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 diff --git a/lustre/obdfs/namei.c b/lustre/obdfs/namei.c index 0eec7c8..4c074a4b 100644 --- a/lustre/obdfs/namei.c +++ b/lustre/obdfs/namei.c @@ -1,5 +1,5 @@ /* - * linux/fs/ext2/namei.c + * linux/fs/obdfs/namei.c * * Copyright (C) 1992, 1993, 1994, 1995 * Remy Card (card@masi.ibp.fr) @@ -8,7 +8,7 @@ * * from * - * linux/fs/minix/namei.c + * linux/fs/ext2/namei.c * * Copyright (C) 1991, 1992 Linus Torvalds * @@ -418,9 +418,9 @@ static void show_dentry(struct list_head * dlist, int subdirs) 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)"; @@ -841,24 +841,28 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symna 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); @@ -866,25 +870,28 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symna 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); @@ -905,6 +912,7 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symna d_instantiate(dentry, inode); err = 0; out: + EXIT; return err; out_no_entry: diff --git a/lustre/obdfs/rw.c b/lustre/obdfs/rw.c index a48332f..9c69f05 100644 --- a/lustre/obdfs/rw.c +++ b/lustre/obdfs/rw.c @@ -214,7 +214,7 @@ struct file_operations obdfs_file_ops = { 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 */ @@ -222,12 +222,12 @@ struct inode_operations obdfs_inode_ops = { 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 */ }; diff --git a/lustre/obdfs/symlink.c b/lustre/obdfs/symlink.c index 53bb167..c933a1a 100644 --- a/lustre/obdfs/symlink.c +++ b/lustre/obdfs/symlink.c @@ -22,58 +22,92 @@ #include #include -#include #include #include #include +#include + +#include /* for ENTRY and EXIT only */ +#include 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; @@ -81,7 +115,9 @@ static int ext2_readlink (struct dentry * dentry, char * buffer, int buflen) 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 */ diff --git a/lustre/scripts/maketags.sh b/lustre/scripts/maketags.sh index 58da5d1..39994a8 100755 --- a/lustre/scripts/maketags.sh +++ b/lustre/scripts/maketags.sh @@ -1,3 +1,4 @@ #!/bin/sh rm -f TAGS ; find . -name '*.h' -or -name '*.c' | xargs etags +rm -f tags ; ctags -R *