From: Christoph Hellwig <hch@caldera.de>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] System V filesystem update
Date: Sun, 2 Sep 2001 17:33:57 +0200 [thread overview]
Message-ID: <20010902173357.C11520@caldera.de> (raw)
Hi Linus,
the appended patch updates the System V filesystem driver to the latest
version from Alan's tree.
The follwoing updates are included:
o add SCO fast symlink support (me)
o add readonly SCO AFS support (me)
o be more graceful in the case of a wrong filesystem type (aeb)
Please apply,
Christoph
--
Of course it doesn't work. We've performed a software upgrade.
diff -uNr -Xdontdiff ../master/linux-2.4.10-pre3/fs/sysv/Makefile linux/fs/sysv/Makefile
--- ../master/linux-2.4.10-pre3/fs/sysv/Makefile Mon Jul 2 23:03:04 2001
+++ linux/fs/sysv/Makefile Sun Sep 2 17:04:47 2001
@@ -9,7 +9,8 @@
O_TARGET := sysv.o
-obj-y := ialloc.o balloc.o inode.o itree.o file.o dir.o namei.o super.o
+obj-y := ialloc.o balloc.o inode.o itree.o file.o dir.o \
+ namei.o super.o symlink.o
obj-m := $(O_TARGET)
include $(TOPDIR)/Rules.make
diff -uNr -Xdontdiff ../master/linux-2.4.10-pre3/fs/sysv/balloc.c linux/fs/sysv/balloc.c
--- ../master/linux-2.4.10-pre3/fs/sysv/balloc.c Mon Jul 2 23:03:04 2001
+++ linux/fs/sysv/balloc.c Sun Sep 2 17:04:47 2001
@@ -46,6 +46,14 @@
unsigned count;
unsigned block = fs32_to_cpu(sb, nr);
+ /*
+ * This code does not work at all for AFS (it has a bitmap
+ * free list). As AFS is supposed to be read-only no one
+ * should call this for an AFS filesystem anyway...
+ */
+ if (sb->sv_type == FSTYPE_AFS)
+ return;
+
if (block < sb->sv_firstdatazone || block >= sb->sv_nzones) {
printk("sysv_free_block: trying to free block not in datazone\n");
return;
@@ -154,6 +162,14 @@
unsigned block;
int n;
+ /*
+ * This code does not work at all for AFS (it has a bitmap
+ * free list). As AFS is supposed to be read-only we just
+ * lie and say it has no free block at all.
+ */
+ if (sb->sv_type == FSTYPE_AFS)
+ return 0;
+
lock_super(sb);
sb_count = fs32_to_cpu(sb, *sb->sv_free_blocks);
diff -uNr -Xdontdiff ../master/linux-2.4.10-pre3/fs/sysv/inode.c linux/fs/sysv/inode.c
--- ../master/linux-2.4.10-pre3/fs/sysv/inode.c Wed Jul 18 03:53:55 2001
+++ linux/fs/sysv/inode.c Sun Sep 2 17:16:38 2001
@@ -131,8 +131,11 @@
inode->i_fop = &sysv_dir_operations;
inode->i_mapping->a_ops = &sysv_aops;
} else if (S_ISLNK(inode->i_mode)) {
- inode->i_op = &sysv_symlink_inode_operations;
- inode->i_mapping->a_ops = &sysv_aops;
+ if (inode->i_blocks) {
+ inode->i_op = &sysv_symlink_inode_operations;
+ inode->i_mapping->a_ops = &sysv_aops;
+ } else
+ inode->i_op = &sysv_fast_symlink_inode_operations;
} else
init_special_inode(inode, inode->i_mode, rdev);
}
@@ -196,7 +199,6 @@
attr->ia_mode = COH_KLUDGE_NOT_SYMLINK;
inode_setattr(inode, attr);
-
return 0;
}
diff -uNr -Xdontdiff ../master/linux-2.4.10-pre3/fs/sysv/super.c linux/fs/sysv/super.c
--- ../master/linux-2.4.10-pre3/fs/sysv/super.c Mon Jul 2 23:03:04 2001
+++ linux/fs/sysv/super.c Sun Sep 2 17:04:47 2001
@@ -26,11 +26,16 @@
#include <linux/sysv_fs.h>
#include <linux/init.h>
-/* The following functions try to recognize specific filesystems.
+/*
+ * The following functions try to recognize specific filesystems.
+ *
* We recognize:
* - Xenix FS by its magic number.
* - SystemV FS by its magic number.
* - Coherent FS by its funny fname/fpack field.
+ * - SCO AFS by s_nfree == 0xffff
+ * - V7 FS has no distinguishing features.
+ *
* We discriminate among SystemV4 and SystemV2 FS by the assumption that
* the time stamp is not < 01-01-1980.
*/
@@ -197,7 +202,19 @@
sb->sv_bytesex = BYTESEX_BE;
else
return 0;
- if (sbd->s_time < JAN_1_1980) {
+
+ if (fs16_to_cpu(sb, sbd->s_nfree) == 0xffff) {
+ sb->sv_type = FSTYPE_AFS;
+ if (!(sb->s_flags & MS_RDONLY)) {
+ printk("SysV FS: SCO EAFS on %s detected, "
+ "forcing read-only mode.\n",
+ bdevname(sb->s_dev));
+ sb->s_flags |= MS_RDONLY;
+ }
+ return sbd->s_type;
+ }
+
+ if (fs32_to_cpu(sb, sbd->s_time) < JAN_1_1980) {
/* this is likely to happen on SystemV2 FS */
if (sbd->s_type > 3 || sbd->s_type < 1)
return 0;
@@ -261,6 +278,7 @@
[FSTYPE_SYSV2] "SystemV Release 2",
[FSTYPE_COH] "Coherent",
[FSTYPE_V7] "V7",
+ [FSTYPE_AFS] "AFS",
};
static void (*flavour_setup[])(struct super_block *) = {
@@ -269,6 +287,7 @@
[FSTYPE_SYSV2] detected_sysv2,
[FSTYPE_COH] detected_coherent,
[FSTYPE_V7] detected_v7,
+ [FSTYPE_AFS] detected_sysv4,
};
static int complete_read_super(struct super_block *sb, int silent, int size)
@@ -294,7 +313,8 @@
sb->sv_toobig_block = 10 + bsize_4 * (1 + bsize_4 * (1 + bsize_4));
sb->sv_ind_per_block_bits = n_bits-2;
- sb->sv_ninodes = (sb->sv_firstdatazone - sb->sv_firstinodezone) << sb->sv_inodes_per_block_bits;
+ sb->sv_ninodes = (sb->sv_firstdatazone - sb->sv_firstinodezone)
+ << sb->sv_inodes_per_block_bits;
sb->s_blocksize = bsize;
sb->s_blocksize_bits = n_bits;
@@ -346,13 +366,10 @@
sb->sv_block_base = 0;
for (i = 0; i < sizeof(flavours)/sizeof(flavours[0]) && !size; i++) {
- struct buffer_head *next_bh;
- next_bh = bread(dev, flavours[i].block, BLOCK_SIZE);
- if (!next_bh)
- continue;
brelse(bh);
- bh = next_bh;
-
+ bh = bread(dev, flavours[i].block, BLOCK_SIZE);
+ if (!bh)
+ continue;
size = flavours[i].test(sb, bh);
}
@@ -411,8 +428,10 @@
static struct super_block *v7_read_super(struct super_block *sb,void *data,
int silent)
{
- struct buffer_head *bh;
+ struct buffer_head *bh, *bh2 = NULL;
kdev_t dev = sb->s_dev;
+ struct v7_super_block *v7sb;
+ struct sysv_inode *v7i;
if (440 != sizeof (struct v7_super_block))
panic("V7 FS: bad super-block size");
@@ -422,23 +441,41 @@
sb->sv_type = FSTYPE_V7;
sb->sv_bytesex = BYTESEX_PDP;
- set_blocksize(dev,512);
+ set_blocksize(dev, 512);
if ((bh = bread(dev, 1, 512)) == NULL) {
if (!silent)
- printk("VFS: unable to read V7 FS superblock on device "
- "%s.\n", bdevname(dev));
+ printk("VFS: unable to read V7 FS superblock on "
+ "device %s.\n", bdevname(dev));
goto failed;
}
+ /* plausibility check on superblock */
+ v7sb = (struct v7_super_block *) bh->b_data;
+ if (fs16_to_cpu(sb,v7sb->s_nfree) > V7_NICFREE ||
+ fs16_to_cpu(sb,v7sb->s_ninode) > V7_NICINOD ||
+ fs32_to_cpu(sb,v7sb->s_time) == 0)
+ goto failed;
+
+ /* plausibility check on root inode: it is a directory,
+ with a nonzero size that is a multiple of 16 */
+ if ((bh2 = bread(dev, 2, 512)) == NULL)
+ goto failed;
+ v7i = (struct sysv_inode *)(bh2->b_data + 64);
+ if ((fs16_to_cpu(sb,v7i->i_mode) & ~0777) != S_IFDIR ||
+ (fs32_to_cpu(sb,v7i->i_size) == 0) ||
+ (fs32_to_cpu(sb,v7i->i_size) & 017) != 0)
+ goto failed;
+ brelse(bh2);
sb->sv_bh1 = bh;
sb->sv_bh2 = bh;
if (complete_read_super(sb, silent, 1))
return sb;
- brelse(bh);
failed:
+ brelse(bh2);
+ brelse(bh);
return NULL;
}
diff -uNr -Xdontdiff ../master/linux-2.4.10-pre3/fs/sysv/symlink.c linux/fs/sysv/symlink.c
--- ../master/linux-2.4.10-pre3/fs/sysv/symlink.c Thu Jan 1 01:00:00 1970
+++ linux/fs/sysv/symlink.c Sun Sep 2 17:04:47 2001
@@ -0,0 +1,25 @@
+/*
+ * linux/fs/sysv/symlink.c
+ *
+ * Handling of System V filesystem fast symlinks extensions.
+ * Aug 2001, Christoph Hellwig (hch@caldera.de)
+ */
+
+#include <linux/fs.h>
+
+static int sysv_readlink(struct dentry *dentry, char *buffer, int buflen)
+{
+ char *s = (char *)dentry->d_inode->u.sysv_i.i_data;
+ return vfs_readlink(dentry, buffer, buflen, s);
+}
+
+static int sysv_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+ char *s = (char *)dentry->d_inode->u.sysv_i.i_data;
+ return vfs_follow_link(nd, s);
+}
+
+struct inode_operations sysv_fast_symlink_inode_operations = {
+ readlink: sysv_readlink,
+ follow_link: sysv_follow_link,
+};
diff -uNr -Xdontdiff ../master/linux-2.4.10-pre3/include/linux/sysv_fs.h linux/include/linux/sysv_fs.h
--- ../master/linux-2.4.10-pre3/include/linux/sysv_fs.h Tue Aug 14 20:03:14 2001
+++ linux/include/linux/sysv_fs.h Sun Sep 2 17:10:45 2001
@@ -325,6 +325,7 @@
FSTYPE_SYSV2,
FSTYPE_COH,
FSTYPE_V7,
+ FSTYPE_AFS,
FSTYPE_END,
};
@@ -373,6 +374,7 @@
extern struct inode_operations sysv_file_inode_operations;
extern struct inode_operations sysv_dir_inode_operations;
+extern struct inode_operations sysv_fast_symlink_inode_operations;
extern struct file_operations sysv_file_operations;
extern struct file_operations sysv_dir_operations;
extern struct address_space_operations sysv_aops;
reply other threads:[~2001-09-02 15:34 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20010902173357.C11520@caldera.de \
--to=hch@caldera.de \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@transmeta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).