[Top] [All Lists]

Patch to make XFS to work on ramdisk

To: linux-xfs@xxxxxxxxxxx
Subject: Patch to make XFS to work on ramdisk
From: Bo Yang <kealia@xxxxxxxxx>
Date: Thu, 5 Aug 2004 17:16:45 -0700
Sender: linux-xfs-bounce@xxxxxxxxxxx

Appended is a patch to make XFS to work on ramdisk.

I tried to use ramdisk as the external logging device to measure the
logging overhead.  It didn't work. Creating an XFS file system on a
ramdisk didn't work, either.  In both cases, mkfs.xfs would work. But
while mounting the ramdisk, I got error complaining about wrong wrong
fs type. The following is the complete output:

[root@stor01 xfsprogs-2.5.6.orig]# mkfs/mkfs.xfs -f /dev/ram0
mkfs.xfs: warning - cannot set blocksize on block device /dev/ram0:
Invalid argument
meta-data=/dev/ram0              isize=256    agcount=4, agsize=4096 blks
         =                       sectsz=512
data     =                       bsize=4096   blocks=16384, imaxpct=25
         =                       sunit=0      swidth=0 blks, unwritten=1
naming   =version 2              bsize=4096
log      =internal log           bsize=4096   blocks=1200, version=1
         =                       sectsz=512   sunit=0 blks
realtime =none                   extsz=65536  blocks=0, rtextents=0
[root@stor01 xfsprogs-2.5.6.orig]# mount /dev/ram0 /mnt/ramdisk
mount: you must specify the filesystem type
[root@stor01 xfsprogs-2.5.6.orig]# mount -t xfs /dev/ram0 /mnt/ramdisk
mount: wrong fs type, bad option, bad superblock on /dev/ram0,
       or too many mounted file systems
[root@stor01 xfsprogs-2.5.6.orig]#

During debugging, I found pages containing superblock and meta data
created by mkfs.xfs on ramdisk was corrupted somehow before mounting.
It turns out this is caused by the semantics of BLKFLSBUF of ramdisk
(rd_ioctl() in kernel 2.4.25).  I assume the expected semantics of
BLKFLSBUG on a normal block device is to: 1) flush buffers to device;
2)  release buffers from main memory. Apparently a ramdisk cannot do
both at the same time. It just invalidates all its pages in page cache
and returns. So the XFS meta data is lost.

XFS tools' mkfs.xfs makes an ioctl() call to do BLKFLSBUF after
creating the file system. This caused the problem. I noticed ext3
somehow does not call this after mkfs.ext3. I haven't checked whether
it's the ramdisk implementation that should get fixed. I changed XFS
tools a little bit so it does not call BLKFLSBUF on a ramdisk.

The following patch is for xfsprogs-2.5.6. It works on kernel 2.4.25.
With it I've successfully used ramdisk as an external logging device
and used XFS directly on a ramdisk. I booted the kernel with option
"ramdisk=65536 ramdisk_blocksize=512".

- Bo Yang

diff -Naur --exclude=CVS --exclude=builddefs --exclude=platform_defs.h
xfsprogs-2.5.6.orig/include/ramdisk.h xfsprogs-2.5.6/include/ramdisk.h
--- xfsprogs-2.5.6.orig/include/ramdisk.h       Wed Dec 31 16:00:00 1969
+++ xfsprogs-2.5.6/include/ramdisk.h    Thu Aug  5 15:40:31 2004
@@ -0,0 +1,5 @@
+/* RAMDISK major number */
+#ifndef __RAMDISK_H__
+#define RAMDISK_MAJOR                   1  /* ramdisk major number */
+#endif  /* #ifndef __RAMDISK_H__ */
diff -Naur --exclude=CVS --exclude=builddefs --exclude=platform_defs.h
xfsprogs-2.5.6.orig/libxfs/init.c xfsprogs-2.5.6/libxfs/init.c
--- xfsprogs-2.5.6.orig/libxfs/init.c   Mon Mar  8 11:29:21 2004
+++ xfsprogs-2.5.6/libxfs/init.c        Thu Aug  5 15:42:35 2004
@@ -31,6 +31,7 @@

 #include <xfs/libxfs.h>
+#include <xfs/ramdisk.h>
 #include <sys/stat.h>
 #include "init.h"

@@ -159,7 +160,9 @@
                        dev_map[d].dev = dev_map[d].fd = 0;

-                       platform_flush_device(fd);
+                        if (major(dev) != RAMDISK_MAJOR) {
+                               platform_flush_device(fd);
+                        }

diff -Naur --exclude=CVS --exclude=builddefs --exclude=platform_defs.h
xfsprogs-2.5.6.orig/libxfs/linux.c xfsprogs-2.5.6/libxfs/linux.c
--- xfsprogs-2.5.6.orig/libxfs/linux.c  Mon Mar  8 11:29:21 2004
+++ xfsprogs-2.5.6/libxfs/linux.c       Thu Aug  5 15:44:21 2004
@@ -114,9 +114,9 @@
 platform_set_blocksize(int fd, char *path, int blocksize)
        if (ioctl(fd, BLKBSZSET, &blocksize) < 0) {
-               fprintf(stderr, _("%s: warning - cannot set blocksize "
+               fprintf(stderr, _("%s: warning - cannot set blocksize to %d "
                                "on block device %s: %s\n"),
-                       progname, path, strerror(errno));
+                       progname, blocksize, path, strerror(errno));

<Prev in Thread] Current Thread [Next in Thread>