Brian, you write:> When trying to build ext3 as a module, I get the follwing errors
> during the kernel link:
>
> kernel/kernel.o(__ksymtab+0x540): undefined reference to
`jfs_prelock_buffer_check'
> kernel/kernel.o(__ksymtab+0x548): undefined reference to
`jfs_preclean_buffer_check'
> fs/fs.o: In function `set_blocksize':
> fs/fs.o(.text+0x300e): undefined reference to
`jfs_preclean_buffer_check'
> fs/fs.o: In function `refile_buffer':
> ll_rw_blk.o(.text+0x568): undefined reference to
`jfs_preclean_buffer_check'
> drivers/block/block.a(ll_rw_blk.o): In function `make_request':
> ll_rw_blk.o(.text+0x75b): undefined reference to
`jfs_prelock_buffer_check'
> ll_rw_blk.o(.text+0xced): undefined reference to
`jfs_preclean_buffer_check'
These ones could be removed because they are debugging only, I think. If
fs.h and locks.h had something like:
#ifdef CONFIG_JFS
#include <linux/jfs.h>
#endif
these checks could be under #if defined(JFS_DEBUG) &&
defined(CONFIG_JFS)
(and we wouldn't need the explicit prototypes in the code). I think
Stephen intends to remove these checks once ext3 is out of beta.
> fs/fs.o(.text+0x341f): undefined reference to
`journal_remove_checkpoint'
> drivers/block/block.a(ll_rw_blk.o): In function `add_request':
Don't know about this one. It calls buffer_unlink (inline function),
and journal_drop_transaction (which doesn't call any other JFS code).
Concievably, if those functions were moved into the kernel proper (via
inline code or by splitting it into a separate object file) then JFS
could be made modular. Might be a headache getting the linking/ifdefs
right, however.
> The modularity of jfs is tied to the modularity of ext3 in the config
> files so it gets made as a module when ext3 is. My guess is that jfs
> is not really module ready.
I have a patch (below) which allows building ext3 as a module. I've sent
it to Stephen, but he hasn't gotten around to putting it in the official
ext3 release. In most cases, once you are running ext3 you want to
use it for the root filesystem as well. However, for testing, it would
be nice to have as a module. Because of the JFS code, you would still
need a new kernel anyways, unlike most filesystem modules (e.g. presto)
which can simply be insmod'ed into a running kernel.
My patch does not yet attempt to make JFS a module. Without this patch,
I think you would also have compile errors on a kernel where CONFIG_EXT3_FS
is set to "n", after the ext3 patch had been applied.
Cheers, Andreas
=========================================================================diff
-ru -x .[a-z]* linux/fs/Config.in /usr/src/linux/fs/Config.in
--- linux/fs/Config.in Fri Jul 14 01:20:53 2000
+++ /usr/src/linux/fs/Config.in Thu Jul 6 14:13:47 2000
@@ -57,6 +57,10 @@
tristate 'ROM filesystem support' CONFIG_ROMFS_FS
tristate 'Second extended fs support' CONFIG_EXT2_FS
tristate 'Second extended fs development code' CONFIG_EXT3_FS
+# CONFIG_JFS should be its own option, but for now we make it depend on ext3
+if [ "$CONFIG_EXT3_FS" != "n" ]; then
+ define_bool CONFIG_JFS y
+fi
tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS
tristate 'UFS filesystem support' CONFIG_UFS_FS
diff -ru -x .[a-z]* linux/fs/Makefile /usr/src/linux/fs/Makefile
--- linux/fs/Makefile Fri Jul 14 01:20:54 2000
+++ /usr/src/linux/fs/Makefile Thu Jul 6 14:13:47 2000
@@ -51,13 +51,17 @@
endif
ifeq ($(CONFIG_EXT3_FS),y)
-SUB_DIRS += ext3 jfs
+SUB_DIRS += ext3
else
ifeq ($(CONFIG_EXT3_FS),m)
- MOD_SUB_DIRS += ext3 jfs
+ MOD_SUB_DIRS += ext3
endif
endif
+ifeq ($(CONFIG_JFS),y)
+SUB_DIRS += jfs
+endif
+
ifeq ($(CONFIG_FAT_FS),y)
SUB_DIRS += fat
else
diff -ru linux-2.2.16-3.ext3/fs/buffer.c.~1~ linux-2.2.16-3.ext3/fs/buffer.c
--- linux-2.2.16-3.ext3/fs/buffer.c.~1~ Wed Jul 5 17:45:26 2000
+++ linux-2.2.16-3.ext3/fs/buffer.c Thu Jul 6 15:53:39 2000
@@ -867,8 +867,10 @@
can now unlink it from its original transaction: there's no
need to keep the transaction pinned in the log once the datat
is safely on disk. */
+#ifdef CONFIG_JFS
if (dispose == BUF_CLEAN && buf->b_cp_transaction)
journal_remove_checkpoint(buf);
+#endif
}
/*
diff -ru -x .[a-z]* linux/fs/jfs/journal.c /usr/src/linux/fs/jfs/journal.c
--- linux/fs/jfs/journal.c Fri Jul 14 01:20:54 2000
+++ /usr/src/linux/fs/jfs/journal.c Thu Jul 13 00:55:03 2000
@@ -49,6 +49,11 @@
EXPORT_SYMBOL(journal_enable_debug);
#endif
+/* JFS debugging only: */
+void jfs_prelock_buffer_check(struct buffer_head *bh);
+void jfs_preclean_buffer_check(struct buffer_head *bh);
+EXPORT_SYMBOL(jfs_prelock_buffer_check);
+EXPORT_SYMBOL(jfs_preclean_buffer_check);
EXPORT_SYMBOL(journal_start);
EXPORT_SYMBOL(journal_restart);
diff -ru -x .[a-z]* linux/fs/jfs/transaction.c
/usr/src/linux/fs/jfs/transaction.c
--- linux/fs/jfs/transaction.c Fri Jul 14 01:20:54 2000
+++ /usr/src/linux/fs/jfs/transaction.c Thu Jul 6 14:13:41 2000
@@ -35,25 +35,6 @@
static inline void
blist_del_buffer(struct buffer_head **, struct buffer_head *);
-
-/*
- * Journal locking.
- *
- * We need to lock the journal during transaction state changes so that
- * nobody ever tries to take a handle on the running transaction while
- * we are in the middle of moving it to the commit phase.
- *
- * Note that the locking is completely interrupt unsafe. We never touch
- * journal structures from interrupts.
- */
-
-void __wait_on_journal (journal_t * journal)
-{
- while (journal->j_locked)
- sleep_on (&journal->j_wait_lock);
-}
-
-
/*
* get_transaction: obtain a new transaction_t object.
*
diff -ru -x .[a-z]* linux/include/linux/fs.h /usr/src/linux/include/linux/fs.h
--- linux/include/linux/fs.h Fri Jul 14 01:22:38 2000
+++ /usr/src/linux/include/linux/fs.h Wed Jul 12 18:07:35 2000
@@ -852,8 +852,10 @@
extern inline void mark_buffer_clean(struct buffer_head * bh)
{
+#if defined(CONFIG_JFS)
extern void jfs_preclean_buffer_check(struct buffer_head *);
jfs_preclean_buffer_check(bh); /* @@@ Expensive debugging */
+#endif
if (test_and_clear_bit(BH_Dirty, &bh->b_state)) {
if (bh->b_list == BUF_DIRTY)
refile_buffer(bh);
diff -ru -x .[a-z]* linux/include/linux/jfs.h /usr/src/linux/include/linux/jfs.h
--- linux/include/linux/jfs.h Fri Jul 14 01:22:38 2000
+++ /usr/src/linux/include/linux/jfs.h Wed Jul 12 18:07:35 2000
@@ -421,8 +422,23 @@
extern int set_transaction_state (transaction_t *, int);
-/* Transaction locking */
-extern void __wait_on_journal (journal_t *);
+/*
+ * Transaction locking
+ *
+ * We need to lock the journal during transaction state changes so that
+ * nobody ever tries to take a handle on the running transaction while
+ * we are in the middle of moving it to the commit phase.
+ *
+ * Note that the locking is completely interrupt unsafe. We never touch
+ * journal structures from interrupts.
+ */
+
+static inline void __wait_on_journal (journal_t * journal)
+{
+ while (journal->j_locked)
+ sleep_on (&journal->j_wait_lock);
+}
+
/* Journal locking. In 2.2, we assume that the kernel lock is already
* held. */
diff -ru linux-2.2.16-3.ext3/include/linux/locks.h.~1~
linux-2.2.16-3.ext3/include/linux/locks.h
--- linux-2.2.16-3.ext3/include/linux/locks.h.~1~ Wed Jul 5 17:57:00 2000
+++ linux-2.2.16-3.ext3/include/linux/locks.h Thu Jul 6 15:53:39 2000
@@ -8,8 +8,6 @@
#include <linux/pagemap.h>
#endif
-extern void jfs_prelock_buffer_check(struct buffer_head *);
-
/*
* Buffer cache locking - note that interrupts may only unlock, not
* lock buffers.
@@ -22,8 +22,11 @@
extern inline void lock_buffer(struct buffer_head * bh)
{
+#if defined(CONFIG_JFS)
+ extern void jfs_prelock_buffer_check(struct buffer_head *);
/* @@@ Debugging for the journaling code */
jfs_prelock_buffer_check(bh);
+#endif
while (test_and_set_bit(BH_Lock, &bh->b_state))
__wait_on_buffer(bh);
}
diff -ru -x .[a-z]* linux/include/linux/sysctl.h
/usr/src/linux/include/linux/sysctl.h
--- linux/include/linux/sysctl.h Fri Jul 14 01:20:40 2000
+++ /usr/src/linux/include/linux/sysctl.h Thu Jul 6 14:13:41 2000
@@ -423,7 +422,8 @@
FS_MAXFILE=7, /* int:maximum number of filedescriptors that can be allocated
*/
FS_DENTRY=8,
FS_NRSUPER=9, /* int:current number of allocated super_blocks */
- FS_MAXSUPER=10 /* int:maximum number of super_blocks that can be allocated */
+ FS_MAXSUPER=10, /* int:maximum number of super_blocks that can be allocated */
+ FS_JFSDEBUG=11, /* int:current debugging level for jfs_debug messages */
};
/* CTL_DEBUG names: */
--- linux-2.2.18-pre21/kernel/ksyms.c.orig Fri Nov 17 17:03:10 2000
+++ linux-2.2.18-pre21/kernel/ksyms.c Sat Nov 18 09:58:24 2000
@@ -70,9 +70,6 @@
};
#endif
-extern void jfs_preclean_buffer_check(struct buffer_head *);
-extern void jfs_prelock_buffer_check(struct buffer_head *);
-
#ifdef CONFIG_KMOD
EXPORT_SYMBOL(request_module);
@@ -256,10 +253,6 @@
EXPORT_SYMBOL(max_segments);
EXPORT_SYMBOL(max_readahead);
EXPORT_SYMBOL(show_buffers);
-
-/* JFS debugging only: */
-EXPORT_SYMBOL(jfs_prelock_buffer_check);
-EXPORT_SYMBOL(jfs_preclean_buffer_check);
/* tty routines */
EXPORT_SYMBOL(tty_hangup);
diff -ru -x .[a-z]* linux/kernel/sysctl.c /usr/src/linux/kernel/sysctl.c
--- linux/kernel/sysctl.c Fri Jul 14 01:20:54 2000
+++ /usr/src/linux/kernel/sysctl.c Thu Jul 6 14:13:41 2000
@@ -285,8 +282,8 @@
0644, NULL, &proc_dointvec},
{FS_DENTRY, "dentry-state", &dentry_stat, 6*sizeof(int),
0444, NULL, &proc_dointvec},
-#if defined(CONFIG_EXT3_FS) && defined(JFS_DEBUG)
- {KERN_SHMMAX, "jfs-debug", &journal_enable_debug, sizeof (int),
+#if defined(CONFIG_JFS) && defined(JFS_DEBUG)
+ {FS_JFSDEBUG, "jfs-debug", &journal_enable_debug, sizeof (int),
0644, NULL, &proc_dointvec},
#endif
{0}
--
Andreas Dilger \ "If a man ate a pound of pasta and a pound of antipasto,
\ would they cancel out, leaving him still hungry?"
http://www-mddsp.enel.ucalgary.ca/People/adilger/ -- Dogbert