I did my testing on a Pentium based system with a SunOS 4.1.3/Solaris 2.3
disk attached to it. The patch was made against 1.3.100, but it will
also work against pre2.0.1 and pre2.0.1.
Gordon Chaffee
chaffee@bugs-bunny.cs.berkeley.edu
diff -u --new-file --recursive linux-1.3.100 linux
diff -u --new-file --recursive linux-1.3.100/fs/ufs/Makefile linux/fs/ufs/Makefile
--- linux-1.3.100/fs/ufs/Makefile Tue Apr 23 01:13:25 1996
+++ linux/fs/ufs/Makefile Wed May 8 01:06:13 1996
@@ -9,7 +9,7 @@
O_TARGET := ufs.o
O_OBJS := ufs_dir.o ufs_file.o ufs_inode.o ufs_namei.o \
- ufs_super.o ufs_symlink.o
+ ufs_super.o ufs_symlink.o ufs_swap.o
M_OBJS := $(O_TARGET)
include $(TOPDIR)/Rules.make
diff -u --new-file --recursive linux-1.3.100/fs/ufs/ufs_dir.c linux/fs/ufs/ufs_dir.c
--- linux-1.3.100/fs/ufs/ufs_dir.c Sun May 5 16:50:08 1996
+++ linux/fs/ufs/ufs_dir.c Sun May 12 10:11:22 1996
@@ -10,7 +10,10 @@
*
*/
+#include <linux/kernel.h>
#include <linux/fs.h>
+#include <linux/ufs_fs.h>
+#include "ufs_swap.h"
/* XXX */
extern int ufs_lookup (struct inode *, const char *, int, struct inode **);
@@ -30,10 +33,12 @@
struct buffer_head * bh;
struct direct * de;
struct super_block * sb;
+ int swap;
if (!inode || !S_ISDIR(inode->i_mode))
return -EBADF;
sb = inode->i_sb;
+ swap = inode->i_sb->u.ufs_sb.s_flags & UFS_SWAP_FLAG;
if (inode->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
printk("ufs_readdir: ino %lu f_pos %lu\n",
@@ -47,7 +52,6 @@
while (!error && !stored && filp->f_pos < inode->i_size) {
lblk = (filp->f_pos) >> sb->s_blocksize_bits;
- blk = ufs_bmap(inode, lblk);
/* XXX - ufs_bmap() call needs error checking */
blk = ufs_bmap(inode, lblk);
bh = bread (sb->s_dev, blk, sb->s_blocksize);
@@ -66,17 +70,24 @@
* to make sure. */
if (filp->f_version != inode->i_version) {
for (i = 0; i < sb->s_blocksize && i < offset; ) {
+ int reclen;
de = (struct direct *)
(bh->b_data + i);
+ if (swap) {
+ reclen = ufs_swap32(de->d_reclen);
+ } else {
+ reclen = de->d_reclen;
+ }
+
/* It's too expensive to do a full
* dirent test each time round this
* loop, but we do have to test at
* least that it is non-zero. A
* failure will be detected in the
* dirent test below. */
- if (de->d_reclen < 1)
+ if (reclen < 1)
break;
- i += de->d_reclen;
+ i += reclen;
}
offset = i;
filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
@@ -87,9 +98,15 @@
while (!error && filp->f_pos < inode->i_size
&& offset < sb->s_blocksize) {
de = (struct direct *) (bh->b_data + offset);
+ if (swap) {
+ ufs_swap_direct(de); /* Swap forward */
+ }
/* XXX - put in a real ufs_check_dir_entry() */
if ((de->d_reclen == 0) || (de->d_namlen == 0)) {
filp->f_pos = (filp->f_pos & (sb->s_blocksize - 1)) + sb->s_blocksize;
+ if (swap) {
+ ufs_swap_direct(de); /* Swap back */
+ }
brelse(bh);
return stored;
}
@@ -100,6 +117,9 @@
next block. */
filp->f_pos = (filp->f_pos & (sb->s_blocksize - 1))
+ sb->s_blocksize;
+ if (swap) {
+ ufs_swap_direct(de); /* Swap back */
+ }
brelse (bh);
return stored;
}
@@ -121,13 +141,24 @@
de->d_name, de->d_ino);
}
error = filldir(dirent, de->d_name, de->d_namlen, filp->f_pos, de->d_ino);
- if (error)
+ if (error) {
+ if (swap) {
+ ufs_swap_direct(de); /* Swap back */
+ }
break;
- if (version != inode->i_version)
+ }
+ if (version != inode->i_version) {
+ if (swap) {
+ ufs_swap_direct(de); /* Swap back */
+ }
goto revalidate;
+ }
stored ++;
}
filp->f_pos += de->d_reclen;
+ if (swap) {
+ ufs_swap_direct(de); /* Swap back */
+ }
}
offset = 0;
brelse (bh);
diff -u --new-file --recursive linux-1.3.100/fs/ufs/ufs_file.c linux/fs/ufs/ufs_file.c
--- linux-1.3.100/fs/ufs/ufs_file.c Sun May 5 16:50:09 1996
+++ linux/fs/ufs/ufs_file.c Sun May 12 13:25:55 1996
@@ -10,7 +10,10 @@
*
*/
+#include <linux/kernel.h>
#include <linux/fs.h>
+#include <linux/ufs_fs.h>
+#include "ufs_swap.h"
/*
* Return values:
@@ -20,7 +23,9 @@
int ufs_bmap (struct inode * inode, int block)
{
unsigned long int fsblkno, phys_block, lfsblkno;
- struct buffer_head * bh;
+ struct buffer_head * bh, *bh_ib;
+ unsigned long int size, page, offset;
+ int swap;
/*
* Note that contrary to what the BSD source calls these things,
@@ -52,16 +57,18 @@
* fsblkno is the physical 8192-block
* phys_block is the 1024-block
*/
+
+ swap = inode->i_sb->u.ufs_sb.s_flags & UFS_SWAP_FLAG;
lfsblkno = block>>3;
- if (block < UFS_NDADDR) {
+ if (lfsblkno < UFS_NDADDR) {
/* It's a direct block */
fsblkno = inode->u.ufs_i.ui_db[lfsblkno]; /* XXX */
#if 0
phys_block = ufs_cgdmin(inode->i_sb, ufs_ino2cg(inode)) +
blkno%(inode->i_sb->u.ufs_sb.s_fpg);
#endif
- phys_block = fsblkno + ((block & 0x7)<<10); /* XXX */
+ phys_block = fsblkno + (block & 0x7); /* XXX */
if (inode->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
printk("ufs_bmap: mapped ino %lu logical %u to %lu (phys %lu)\n",
inode->i_ino, block, fsblkno, phys_block);
@@ -69,25 +76,76 @@
return(phys_block);
} else {
/* Need to use indirect blocks */
- /* XXX - bmap through indirect blocks not implemented */
- block -= UFS_NDADDR;
- if (block < (inode->i_sb->s_blocksize/sizeof(__u32))) {
- bh = bread(inode->i_dev, inode->u.ufs_i.ui_ib[0],
+ lfsblkno -= UFS_NDADDR;
+
+ size = inode->i_sb->s_blocksize/sizeof(__u32);
+ if (lfsblkno < size * (UFS_BSIZE / inode->i_sb->s_blocksize)) {
+ page = lfsblkno / size; /* XXX */
+ offset = lfsblkno & (size - 1);
+ bh = bread(inode->i_dev, inode->u.ufs_i.ui_ib[0] +page,
BLOCK_SIZE);
if (bh == NULL) {
printk("ufs_bmap: can't map block %u, ino %lu\n",
- block + UFS_NDADDR, inode->i_ino);
+ block, inode->i_ino);
return(0);
}
- phys_block = ((__u32 *)bh->b_data)[block];
+ phys_block = ((__u32 *)bh->b_data)[offset];
+ if (swap) {
+ phys_block = ufs_swap32(phys_block);
+ }
+ phys_block += block & 0x7;
brelse(bh);
- printk("ufs_bmap: imap ino %lu block %u phys %lu\n",
- inode->i_ino, block + UFS_NDADDR, phys_block);
+ if (inode->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
+ printk("ufs_bmap: imap ino %lu block %u phys %lu\n",
+ inode->i_ino, block, phys_block);
+ }
return(phys_block);
- } else {
- printk("ufs_bmap: ino %lu: indirect blocks not implemented\n",
- inode->i_ino);
- return(0);
+ }
+ else {
+ /* XXX - bmap through anything beyond the first
+ * block not working. This code was guesswork
+ * that tried to read with a double indirect
+ * block scheme. */
+ lfsblkno -= size;
+ if (lfsblkno < size * size) {
+ bh_ib = bread(inode->i_dev, inode->u.ufs_i.ui_ib[1],
+ BLOCK_SIZE);
+ if (bh_ib == NULL) {
+ printk("ufs_bmap: 1. can't map block %u, ino %lu\n",
+ block, inode->i_ino);
+ return(0);
+ }
+ phys_block = ((__u32 *)bh_ib->b_data)[lfsblkno/size];
+ if (swap) {
+ phys_block = ufs_swap32(phys_block);
+ }
+
+ bh = bread(inode->i_dev, phys_block, BLOCK_SIZE);
+ if (bh == NULL) {
+ printk("ufs_bmap: 2. can't map block %u, ino %lu, phys_block %lu\n",
+ block, inode->i_ino, phys_block);
+ return(0);
+ }
+ phys_block = ((__u32 *)bh->b_data)[lfsblkno&(size-1)];
+ if (swap) {
+ phys_block = ufs_swap32(phys_block);
+ }
+ phys_block += block & 0x7;
+ brelse(bh);
+ brelse(bh_ib);
+ printk("ufs_bmap: imap ino %lu block %u phys %lu\n",
+ inode->i_ino, block, phys_block);
+#if 1
+ return(0);
+#else
+ return(phys_block);
+#endif
+
+ } else {
+ printk("ufs_bmap: ino %lu: indirect blocks not implemented\n",
+ inode->i_ino);
+ return(0);
+ }
}
}
diff -u --new-file --recursive linux-1.3.100/fs/ufs/ufs_inode.c linux/fs/ufs/ufs_inode.c
--- linux-1.3.100/fs/ufs/ufs_inode.c Sun May 5 16:50:09 1996
+++ linux/fs/ufs/ufs_inode.c Sun May 12 10:12:48 1996
@@ -13,6 +13,7 @@
#include <linux/fs.h>
#include <linux/ufs_fs.h>
#include <linux/sched.h>
+#include "ufs_swap.h"
extern struct inode_operations ufs_file_inode_operations;
extern struct inode_operations ufs_dir_inode_operations;
@@ -43,8 +44,10 @@
struct super_block * sb;
struct ufs_inode * ufsip;
struct buffer_head * bh;
+ int swap;
sb = inode->i_sb;
+ swap = inode->i_sb->u.ufs_sb.s_flags & UFS_SWAP_FLAG;
if (ufs_ino_ok(inode)) {
printk("ufs_read_inode: bad inum %lu", inode->i_ino);
@@ -70,6 +73,9 @@
ufsip = (struct ufs_inode *)bh->b_data;
ufsip += (inode->i_ino%(sb->u.ufs_sb.s_inopb/sb->u.ufs_sb.s_fsfrag));
+ if (swap) {
+ ufs_swap_inode(ufsip); /* Swap forward */
+ }
/*
* Copy data to the in-core inode.
@@ -127,9 +133,10 @@
* for the rw code, we may want to mark these inodes as read-only.
* XXX - bug Linus to make i_size a __u64 instead of a __u32.
*/
- inode->u.ufs_i.ui_size = ((__u64)(ufsip->ui_size.val[0])<<32) | (__u64)(ufsip->ui_size.val[1]);
- inode->i_size = ufsip->ui_size.val[1]; /* XXX - endianity */
- if (ufsip->ui_size.val[0] != 0) {
+ /* XXX: Need endian fix here */
+ inode->u.ufs_i.ui_size = ufsip->ui_size;
+ inode->i_size = inode->u.ufs_i.ui_size & 0xffffffff;
+ if ((ufsip->ui_size & ~0xffffffff) != 0) {
inode->i_size = 0xffffffff;
printk("ufs_read_inode: file too big ino %lu dev %u/%u, faking size\n",
inode->i_ino, MAJOR(inode->i_dev), MINOR(inode->i_dev));
@@ -197,6 +204,10 @@
inode->u.ufs_i.ui_gid = ufsip->ui_gid;
inode->u.ufs_i.ui_oeftflag = ufsip->ui_oeftflag;
+ if (swap) {
+ ufs_swap_inode(ufsip); /* Swap back */
+ }
+
brelse(bh);
if (inode->i_sb->u.ufs_sb.s_flags & (UFS_DEBUG|UFS_DEBUG_INODE)) {
@@ -208,20 +219,29 @@
void ufs_put_inode (struct inode * inode)
{
+ int swap;
if (inode->i_nlink)
return;
printk("ufs_put_inode: nlink == 0 for inum %lu on dev %d/%d\n",
inode->i_ino, MAJOR(inode->i_dev), MINOR(inode->i_dev));
+
+ swap = inode->i_sb->u.ufs_sb.s_flags & UFS_SWAP_FLAG;
+
ufs_print_inode(inode);
panic("ufs_put_inode: fs is read only, and nlink == 0");
- /* XXX - this code goes here eventually
+#if 0
+ /* XXX - this code goes here eventually */
+ if (swap) {
+ ufs_swap_inode(ufsip);
+ }
+
inode->i_size = 0;
if (inode->i_blocks)
ufs_truncate(inode);
ufs_free_inode(inode);
- */
+#endif
return;
}
diff -u --new-file --recursive linux-1.3.100/fs/ufs/ufs_namei.c linux/fs/ufs/ufs_namei.c
--- linux-1.3.100/fs/ufs/ufs_namei.c Sun May 5 16:50:09 1996
+++ linux/fs/ufs/ufs_namei.c Sun May 12 10:10:16 1996
@@ -10,7 +10,10 @@
*
*/
+#include <linux/kernel.h>
#include <linux/fs.h>
+#include <linux/ufs_fs.h>
+#include "ufs_swap.h"
extern unsigned int ufs_bmap(struct inode * inode, int block); /* XXX */
@@ -39,7 +42,8 @@
{
unsigned long int lfragno, fragno;
struct buffer_head * bh;
- struct direct * d;
+ struct direct * d, *dold;
+ int swap;
/*
* Touching /xyzzy in a filesystem toggles debugging messages.
@@ -50,6 +54,7 @@
printk("UFS debugging %s\n",
(dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) ?
"on": "off");
+ iput(dir);
return(-ENOENT);
}
@@ -62,6 +67,7 @@
printk("UFS inode debugging %s\n",
(dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG_INODE) ?
"on": "off");
+ iput(dir);
return(-ENOENT);
}
@@ -71,6 +77,7 @@
printk("UFS namei debugging %s\n",
(dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG_NAMEI) ?
"on": "off");
+ iput(dir);
return(-ENOENT);
}
@@ -80,6 +87,7 @@
printk("UFS symlink debugging %s\n",
(dir->i_sb->u.ufs_sb.s_flags & UFS_DEBUG_LINKS) ?
"on": "off");
+ iput(dir);
return(-ENOENT);
}
@@ -88,6 +96,8 @@
dir->i_ino, name);
}
+ swap = dir->i_sb->u.ufs_sb.s_flags & UFS_SWAP_FLAG;
+
/* XXX - do I want i_blocks in 512-blocks or 1024-blocks? */
for (lfragno = 0; lfragno < (dir->i_blocks)>>1; lfragno++) {
fragno = ufs_bmap(dir, lfragno);
@@ -99,15 +109,20 @@
}
if (fragno == 0) {
/* XXX - bug bug bug */
+ iput(dir);
return(-ENOENT);
}
bh = bread(dir->i_dev, fragno, dir->i_sb->s_blocksize);
if (bh == NULL) {
printk("ufs_lookup: bread failed: ino %lu, lfragno %lu",
dir->i_ino, lfragno);
+ iput(dir);
return(-EIO);
}
d = (struct direct *)(bh->b_data);
+ if (swap) {
+ ufs_swap_direct(d); /* Initial swap */
+ }
while (((char *)d - bh->b_data + d->d_reclen) <=
dir->i_sb->s_blocksize) {
/* XXX - skip block if d_reclen or d_namlen is 0 */
@@ -127,7 +142,11 @@
(ufs_match(len, name, d))) {
/* We have a match */
*result = iget(dir->i_sb, d->d_ino);
+ if (swap) {
+ ufs_swap_direct(d); /* Swap back */
+ }
brelse(bh);
+ iput(dir);
return(0);
} else {
/* XXX - bounds checking */
@@ -136,10 +155,19 @@
name, len, d->d_name, d->d_namlen);
}
}
+ dold = d;
d = (struct direct *)((char *)d + d->d_reclen);
+ if (swap) {
+ ufs_swap_direct(dold); /* Swap back */
+ ufs_swap_direct(d); /* Initial swap */
+ }
}
+ if (swap) {
+ ufs_swap_direct(d); /* Swap back */
+ }
brelse(bh);
}
+ iput(dir);
return(-ENOENT);
}
diff -u --new-file --recursive linux-1.3.100/fs/ufs/ufs_super.c linux/fs/ufs/ufs_super.c
--- linux-1.3.100/fs/ufs/ufs_super.c Sun May 12 13:28:43 1996
+++ linux/fs/ufs/ufs_super.c Sun May 12 08:57:17 1996
@@ -25,6 +25,7 @@
#include <linux/ufs_fs.h>
#include <linux/module.h>
#include <linux/locks.h>
+#include "ufs_swap.h"
#include <asm/segment.h>
@@ -99,6 +100,7 @@
{
struct ufs_superblock * usb;
struct buffer_head * bh1, *bh2;
+ int swap;
/* sb->s_dev and sb->s_flags are set by our caller
* data is the mystery argument to sys_mount()
@@ -139,13 +141,18 @@
brelse(bh1);
brelse(bh2);
- if (usb->fs_magic != UFS_MAGIC) {
- /* XXX - replace hard-coded constant with a byte-swap macro */
- if (usb->fs_magic == 0x54190100) {
- printk ("ufs_read_super: can't grok byteswapped fs on dev %d/%d\n",
- MAJOR(sb->s_dev), MINOR(sb->s_dev));
- silent = 1;
- }
+ swap = 0;
+ if (usb->fs_magic == UFS_MAGIC_SWAP) {
+ printk("ufs_read_super: handling a byte swapped filesystem\n");
+ swap = 1;
+ ufs_swap_superblock(usb); /* Swap forward */
+ } else if (usb->fs_magic != UFS_MAGIC) {
+#if 0
+ printk ("ufs_read_super: can't grok byteswapped fs on dev %d/%d\n",
+ MAJOR(sb->s_dev), MINOR(sb->s_dev));
+ silent = 1;
+#endif
+
sb->s_dev = 0;
unlock_super (sb);
if (!silent)
@@ -220,7 +227,7 @@
/* sb->s_wait */
/* XXX - sb->u.ufs_sb */
sb->u.ufs_sb.s_raw_sb = usb; /* XXX - maybe move this to the top */
- sb->u.ufs_sb.s_flags = 0;
+ sb->u.ufs_sb.s_flags = swap ? UFS_SWAP_FLAG : 0;
sb->u.ufs_sb.s_ncg = usb->fs_ncg;
sb->u.ufs_sb.s_ipg = usb->fs_ipg;
sb->u.ufs_sb.s_fpg = usb->fs_fpg;
@@ -280,6 +287,7 @@
tmp.f_fsid.val[0] = sb->u.ufs_sb.s_raw_sb->fs_id[0];
tmp.f_fsid.val[1] = sb->u.ufs_sb.s_raw_sb->fs_id[1];
tmp.f_namelen = MAXNAMLEN;
+
/* tmp.f_spare[6] */
memcpy_tofs(buf, &tmp, bufsiz);
diff -u --new-file --recursive linux-1.3.100/fs/ufs/ufs_swap.c linux/fs/ufs/ufs_swap.c
--- linux-1.3.100/fs/ufs/ufs_swap.c Wed Dec 31 16:00:00 1969
+++ linux/fs/ufs/ufs_swap.c Sun May 12 10:09:01 1996
@@ -0,0 +1,137 @@
+/*
+ * linux/fs/ufs/ufs_swap.c
+ *
+ * Copyright (C) 1996
+ * Gordon Chaffee (chaffee@plateau.cs.berkeley.edu)
+ */
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/ufs_fs.h>
+#include "ufs_swap.h"
+
+void
+ufs_swap_csum(struct csum * x)
+{
+ x->cs_ndir = ufs_swap32(x->cs_ndir); /* number of directories */
+ x->cs_nbfree = ufs_swap32(x->cs_nbfree); /* number of free blocks */
+ x->cs_nifree = ufs_swap32(x->cs_nifree); /* number of free inodes */
+ x->cs_nffree = ufs_swap32(x->cs_nffree); /* number of free frags */
+};
+
+void
+ufs_swap_timeval(struct timeval * x)
+{
+ x->tv_sec = ufs_swap32(x->tv_sec);
+ x->tv_usec = ufs_swap32(x->tv_usec);
+};
+
+
+void
+ufs_swap_superblock(struct ufs_superblock * x)
+{
+ x->fs_link = ufs_swap32(x->fs_link); /* UNUSED */
+ x->fs_rlink = ufs_swap32(x->fs_rlink); /* UNUSED */
+ x->fs_sblkno = ufs_swap32(x->fs_sblkno);
+ x->fs_cblkno = ufs_swap32(x->fs_cblkno);
+ x->fs_iblkno = ufs_swap32(x->fs_iblkno);
+ x->fs_dblkno = ufs_swap32(x->fs_dblkno);
+ x->fs_cgoffset = ufs_swap32(x->fs_cgoffset);
+ x->fs_cgmask = ufs_swap32(x->fs_cgmask);
+
+ /* XXX: Questionable since this was declared as time_t */
+ x->fs_time = ufs_swap32(x->fs_time);
+
+ x->fs_size = ufs_swap32(x->fs_size);
+ x->fs_dsize = ufs_swap32(x->fs_dsize);
+ x->fs_ncg = ufs_swap32(x->fs_ncg);
+ x->fs_bsize = ufs_swap32(x->fs_bsize);
+ x->fs_fsize = ufs_swap32(x->fs_fsize);
+ x->fs_frag = ufs_swap32(x->fs_frag);
+ x->fs_minfree = ufs_swap32(x->fs_minfree);
+ x->fs_rotdelay = ufs_swap32(x->fs_rotdelay);
+ x->fs_rps = ufs_swap32(x->fs_rps);
+ x->fs_bmask = ufs_swap32(x->fs_bmask);
+ x->fs_fmask = ufs_swap32(x->fs_fmask);
+ x->fs_bshift = ufs_swap32(x->fs_bshift);
+ x->fs_fshift = ufs_swap32(x->fs_fshift);
+ x->fs_maxcontig = ufs_swap32(x->fs_maxcontig);
+ x->fs_maxbpg = ufs_swap32(x->fs_maxbpg);
+ x->fs_fragshift = ufs_swap32(x->fs_fragshift);
+ x->fs_fsbtodb = ufs_swap32(x->fs_fsbtodb);
+ x->fs_sbsize = ufs_swap32(x->fs_sbsize);
+ x->fs_csmask = ufs_swap32(x->fs_csmask);
+ x->fs_csshift = ufs_swap32(x->fs_csshift);
+ x->fs_nindir = ufs_swap32(x->fs_nindir);
+ x->fs_inopb = ufs_swap32(x->fs_inopb);
+ x->fs_nspf = ufs_swap32(x->fs_nspf);
+ x->fs_optim = ufs_swap32(x->fs_optim);
+ x->fs_XXX1 = ufs_swap32(x->fs_XXX1);
+ x->fs_interleave = ufs_swap32(x->fs_interleave);
+ x->fs_trackskew = ufs_swap32(x->fs_trackskew);
+ x->fs_id[0] = ufs_swap32(x->fs_id[0]);
+ x->fs_id[1] = ufs_swap32(x->fs_id[1]);
+ x->fs_csaddr = ufs_swap32(x->fs_csaddr);
+ x->fs_cssize = ufs_swap32(x->fs_cssize);
+ x->fs_cgsize = ufs_swap32(x->fs_cgsize);
+ x->fs_ntrak = ufs_swap32(x->fs_ntrak);
+ x->fs_nsect = ufs_swap32(x->fs_nsect);
+ x->fs_spc = ufs_swap32(x->fs_spc);
+ x->fs_ncyl = ufs_swap32(x->fs_ncyl);
+ x->fs_cpg = ufs_swap32(x->fs_cpg);
+ x->fs_ipg = ufs_swap32(x->fs_ipg);
+ x->fs_fpg = ufs_swap32(x->fs_fpg);
+
+ ufs_swap_csum(&x->fs_cstotal);
+
+ x->fs_cgrotor = ufs_swap32(x->fs_cgrotor);
+ x->fs_cpc = ufs_swap32(x->fs_cpc);
+ x->fs_state = ufs_swap32(x->fs_state);
+
+ x->fs_qbmask = ufs_swap64(x->fs_qbmask);
+ x->fs_qfmask = ufs_swap64(x->fs_qfmask);
+
+ x->fs_postblformat = ufs_swap32(x->fs_postblformat);
+ x->fs_nrpos = ufs_swap32(x->fs_nrpos);
+ x->fs_postbloff = ufs_swap32(x->fs_postbloff);
+ x->fs_rotbloff = ufs_swap32(x->fs_rotbloff);
+ x->fs_magic = ufs_swap32(x->fs_magic);
+}
+
+void
+ufs_swap_inode(struct ufs_inode *x)
+{
+ int i;
+
+ x->ui_mode = ufs_swap16(x->ui_mode);
+ x->ui_nlink = ufs_swap16(x->ui_nlink);
+ x->ui_suid = ufs_swap16(x->ui_suid);
+ x->ui_sgid = ufs_swap16(x->ui_sgid);
+ x->ui_size = ufs_swap64(x->ui_size);
+
+ ufs_swap_timeval(&x->ui_atime);
+ ufs_swap_timeval(&x->ui_mtime);
+ ufs_swap_timeval(&x->ui_ctime);
+
+ for (i = 0; i < UFS_NDADDR; i++) {
+ x->ui_db[i] = ufs_swap32(x->ui_db[i]);
+ }
+ for (i = 0; i < UFS_NINDIR; i++) {
+ x->ui_ib[i] = ufs_swap32(x->ui_ib[i]);
+ }
+
+ x->ui_flags = ufs_swap32(x->ui_flags);
+ x->ui_blocks = ufs_swap32(x->ui_blocks);
+ x->ui_gen = ufs_swap32(x->ui_gen);
+ x->ui_shadow = ufs_swap32(x->ui_shadow);
+ x->ui_uid = ufs_swap32(x->ui_uid);
+ x->ui_gid = ufs_swap32(x->ui_gid);
+ x->ui_oeftflag = ufs_swap32(x->ui_oeftflag);
+}
+
+void
+ufs_swap_direct(struct direct *x)
+{
+ x->d_ino = ufs_swap32(x->d_ino);
+ x->d_reclen = ufs_swap16(x->d_reclen);
+ x->d_namlen = ufs_swap16(x->d_namlen);
+};
diff -u --new-file --recursive linux-1.3.100/fs/ufs/ufs_swap.h linux/fs/ufs/ufs_swap.h
--- linux-1.3.100/fs/ufs/ufs_swap.h Wed Dec 31 16:00:00 1969
+++ linux/fs/ufs/ufs_swap.h Sun May 12 00:57:41 1996
@@ -0,0 +1,33 @@
+/*
+ * linux/fs/ufs/ufs_swap.h
+ *
+ * Copyright (C) 1996
+ * Gordon Chaffee (chaffee@plateau.cs.berkeley.edu)
+ */
+#define ufs_swap32(x) \
+ ((__u32)((((x) & 0x000000ffUL) << 24) | \
+ (((x) & 0x0000ff00UL) << 8) | \
+ (((x) & 0x00ff0000UL) >> 8) | \
+ (((x) & 0xff000000UL) >> 24)))
+
+#define ufs_swap16(x) \
+ ((__u16)((((unsigned short int)(x) & 0x00ff) << 8) | \
+ (((__u16)(x) & 0xff00) >> 8)))
+
+static __inline__ __u64 ufs_swap64(__u64 x)
+{
+ __u32 *ip, *op;
+ __u64 y;
+
+ ip = (__u32 *) &x;
+ op = (__u32 *) &y;
+ op[0] = ufs_swap32(ip[1]);
+ op[1] = ufs_swap32(ip[0]);
+ return y;
+}
+
+extern void ufs_swap_csum(struct csum *x);
+extern void ufs_swap_timeval(struct timeval *x);
+extern void ufs_swap_superblock(struct ufs_superblock *x);
+extern void ufs_swap_inode(struct ufs_inode *x);
+extern void ufs_swap_direct(struct direct *x);
diff -u --new-file --recursive linux-1.3.100/fs/ufs/ufs_symlink.c linux/fs/ufs/ufs_symlink.c
--- linux-1.3.100/fs/ufs/ufs_symlink.c Sun May 5 16:50:09 1996
+++ linux/fs/ufs/ufs_symlink.c Wed May 8 01:40:33 1996
@@ -11,6 +11,7 @@
*/
#include <linux/fs.h>
+#include <linux/ufs_fs.h>
#include <linux/sched.h>
#include <asm/segment.h>
diff -u --new-file --recursive linux-1.3.100/include/linux/ufs_fs.h linux/include/linux/ufs_fs.h
--- linux-1.3.100/include/linux/ufs_fs.h Sun May 5 17:09:01 1996
+++ linux/include/linux/ufs_fs.h Sun May 12 00:40:15 1996
@@ -24,6 +24,7 @@
#define UFS_SBSIZE 8192
#define UFS_MAGIC 0x00011954
+#define UFS_MAGIC_SWAP 0x54190100
#define UFS_FSIZE 1024
#define UFS_BSIZE 8192
@@ -46,6 +47,7 @@
#define UFS_DEBUG_INODE 0x00000002
#define UFS_DEBUG_NAMEI 0x00000004
#define UFS_DEBUG_LINKS 0x00000008
+#define UFS_SWAP_FLAG 0x00000010
/* Test if the inode number is valid. */
@@ -83,10 +85,6 @@
__u32 cs_nffree; /* number of free frags */
};
-typedef struct _ufsquad {
- __u32 val[2];
-} ufsquad;
-
/*
* This is the actual superblock, as it is laid out on the disk.
*/
@@ -150,8 +148,8 @@
__u16 fs_opostbl[16][8]; /* old rotation block list head */
__s32 fs_sparecon[55]; /* reserved for future constants */
__s32 fs_state; /* file system state time stamp */
- ufsquad fs_qbmask; /* ~usb_bmask - for use with __s64 size */
- ufsquad fs_qfmask; /* ~usb_fmask - for use with __s64 size */
+ __u64 fs_qbmask; /* ~usb_bmask - for use with __s64 size */
+ __u64 fs_qfmask; /* ~usb_fmask - for use with __s64 size */
__s32 fs_postblformat; /* format of positional layout tables */
__s32 fs_nrpos; /* number of rotational positions */
__s32 fs_postbloff; /* (__s16) rotation block list head */
@@ -169,7 +167,7 @@
__u16 ui_nlink; /* 0x2 */
__u16 ui_suid; /* 0x4 */
__u16 ui_sgid; /* 0x6 */
- ufsquad ui_size; /* 0x8 */ /* XXX - should be __u64 */
+ __u64 ui_size; /* 0x8 */ /* XXX - should be __u64 */
struct timeval ui_atime; /* 0x10 */
struct timeval ui_mtime; /* 0x18 */
struct timeval ui_ctime; /* 0x20 */
diff -u --new-file --recursive linux-1.3.100/include/linux/ufs_fs.h.save linux/include/linux/ufs_fs.h.save
--- linux-1.3.100/include/linux/ufs_fs.h.save Wed Dec 31 16:00:00 1969
+++ linux/include/linux/ufs_fs.h.save Sun May 5 17:09:01 1996
@@ -0,0 +1,198 @@
+/*
+ * linux/include/linux/ufs_fs.h
+ *
+ * Copyright (C) 1996
+ * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
+ * Laboratory for Computer Science Research Computing Facility
+ * Rutgers, The State University of New Jersey
+ *
+ * $Id: ufs_fs.h,v 1.1 1996/04/21 14:45:11 davem Exp $
+ *
+ */
+
+#ifndef __LINUX_UFS_FS_H
+#define __LINUX_UFS_FS_H
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/stat.h>
+
+#define UFS_BBLOCK 0
+#define UFS_BBSIZE 8192
+#define UFS_SBLOCK 8192
+#define UFS_SBSIZE 8192
+
+#define UFS_MAGIC 0x00011954
+
+#define UFS_FSIZE 1024
+#define UFS_BSIZE 8192
+
+#define UFS_NDADDR 12
+#define UFS_NINDIR 3
+
+#define UFS_ROOTINO 2
+
+#define UFS_USEEFT ((__u16)65535)
+
+#define UFS_FSOK 0x7c269d38
+#define UFS_FSACTIVE ((char)0x00)
+#define UFS_FSCLEAN ((char)0x01)
+#define UFS_FSSTABLE ((char)0x02)
+#define UFS_FSBAD ((char)0xff)
+
+/* Flags for ufs_sb_info */
+#define UFS_DEBUG 0x00000001
+#define UFS_DEBUG_INODE 0x00000002
+#define UFS_DEBUG_NAMEI 0x00000004
+#define UFS_DEBUG_LINKS 0x00000008
+
+
+/* Test if the inode number is valid. */
+#define ufs_ino_ok(inode) ((inode->i_ino < 2) && \
+ (inode->i_ino > (inode->i_sb->u.ufs_sb.s_ncg * inode->i_sb->u.ufs_sb.s_ipg - 1)))
+
+/* Convert (sb,cg) to the first physical block number for that cg. */
+#define ufs_cgstart(sb, cg) \
+ (((sb)->u.ufs_sb.s_fpg * (cg)) + (sb)->u.ufs_sb.s_cgoffset * ((cg) & ~((sb)->u.ufs_sb.s_cgmask)))
+
+/* Convert (sb,cg) to the first phys. block number for inodes in that cg. */
+#define ufs_cgimin(sb, cg) (ufs_cgstart((sb), (cg)) + (sb)->u.ufs_sb.s_iblkno)
+#define ufs_cgdmin(sb, cg) (ufs_cgstart((sb), (cg)) + (sb)->u.ufs_sb.s_dblkno)
+
+/* Convert an inode number to a cg number. */
+/* XXX - this can be optimized if s_ipg is a power of 2. */
+#define ufs_ino2cg(inode) ((inode)->i_ino/(inode)->i_sb->u.ufs_sb.s_ipg)
+
+#define MAXNAMLEN 255
+
+struct direct {
+ __u32 d_ino; /* inode number of this entry */
+ __u16 d_reclen; /* length of this entry */
+ __u16 d_namlen; /* actual length of d_name */
+ char d_name[MAXNAMLEN + 1]; /* file name */
+};
+
+#define MAXMNTLEN 512
+#define MAXCSBUFS 32
+
+struct csum {
+ __u32 cs_ndir; /* number of directories */
+ __u32 cs_nbfree; /* number of free blocks */
+ __u32 cs_nifree; /* number of free inodes */
+ __u32 cs_nffree; /* number of free frags */
+};
+
+typedef struct _ufsquad {
+ __u32 val[2];
+} ufsquad;
+
+/*
+ * This is the actual superblock, as it is laid out on the disk.
+ */
+struct ufs_superblock {
+ __u32 fs_link; /* UNUSED */
+ __u32 fs_rlink; /* UNUSED */
+ __u32 fs_sblkno;
+ __u32 fs_cblkno;
+ __u32 fs_iblkno;
+ __u32 fs_dblkno;
+ __u32 fs_cgoffset;
+ __u32 fs_cgmask;
+ time_t fs_time; /* XXX - check type */
+ __u32 fs_size;
+ __u32 fs_dsize;
+ __u32 fs_ncg;
+ __u32 fs_bsize;
+ __u32 fs_fsize;
+ __u32 fs_frag;
+ __u32 fs_minfree;
+ __u32 fs_rotdelay;
+ __u32 fs_rps;
+ __u32 fs_bmask;
+ __u32 fs_fmask;
+ __u32 fs_bshift;
+ __u32 fs_fshift;
+ __u32 fs_maxcontig;
+ __u32 fs_maxbpg;
+ __u32 fs_fragshift;
+ __u32 fs_fsbtodb;
+ __u32 fs_sbsize;
+ __u32 fs_csmask;
+ __u32 fs_csshift;
+ __u32 fs_nindir;
+ __u32 fs_inopb;
+ __u32 fs_nspf;
+ __u32 fs_optim;
+ __u32 fs_XXX1;
+ __u32 fs_interleave;
+ __u32 fs_trackskew;
+ __u32 fs_id[2];
+ __u32 fs_csaddr;
+ __u32 fs_cssize;
+ __u32 fs_cgsize;
+ __u32 fs_ntrak;
+ __u32 fs_nsect;
+ __u32 fs_spc;
+ __u32 fs_ncyl;
+ __u32 fs_cpg;
+ __u32 fs_ipg;
+ __u32 fs_fpg;
+ struct csum fs_cstotal;
+ __u8 fs_fmod;
+ __u8 fs_clean;
+ __u8 fs_ronly;
+ __u8 fs_flags;
+ __u8 fs_fsmnt[MAXMNTLEN];
+ __u32 fs_cgrotor;
+ struct csum * fs_csp[MAXCSBUFS];
+ __u32 fs_cpc;
+ __u16 fs_opostbl[16][8]; /* old rotation block list head */
+ __s32 fs_sparecon[55]; /* reserved for future constants */
+ __s32 fs_state; /* file system state time stamp */
+ ufsquad fs_qbmask; /* ~usb_bmask - for use with __s64 size */
+ ufsquad fs_qfmask; /* ~usb_fmask - for use with __s64 size */
+ __s32 fs_postblformat; /* format of positional layout tables */
+ __s32 fs_nrpos; /* number of rotational positions */
+ __s32 fs_postbloff; /* (__s16) rotation block list head */
+ __s32 fs_rotbloff; /* (__u8) blocks for each rotation */
+ __s32 fs_magic; /* magic number */
+ __u8 fs_space[1]; /* list of blocks for each rotation */
+
+};
+
+/*
+ * structure of an on-disk inode
+ */
+struct ufs_inode {
+ __u16 ui_mode; /* 0x0 */
+ __u16 ui_nlink; /* 0x2 */
+ __u16 ui_suid; /* 0x4 */
+ __u16 ui_sgid; /* 0x6 */
+ ufsquad ui_size; /* 0x8 */ /* XXX - should be __u64 */
+ struct timeval ui_atime; /* 0x10 */
+ struct timeval ui_mtime; /* 0x18 */
+ struct timeval ui_ctime; /* 0x20 */
+ __u32 ui_db[UFS_NDADDR]; /* 0x28 data blocks */
+ __u32 ui_ib[UFS_NINDIR]; /* 0x58 indirect blocks */
+ __u32 ui_flags; /* 0x64 unused */
+ __u32 ui_blocks; /* 0x68 blocks in use */
+ __u32 ui_gen; /* 0x6c generation number XXX - what is this? */
+ __u32 ui_shadow; /* 0x70 shadow inode XXX - what is this?*/
+ __u32 ui_uid; /* 0x74 long EFT version of uid */
+ __u32 ui_gid; /* 0x78 long EFT version of gid */
+ __u32 ui_oeftflag; /* 0x7c reserved */
+};
+
+extern int init_ufs_fs(void);
+
+#endif /* __LINUX_UFS_FS_H */
+/*
+ * Local Variables: ***
+ * c-indent-level: 8 ***
+ * c-continued-statement-offset: 8 ***
+ * c-brace-offset: -8 ***
+ * c-argdecl-indent: 0 ***
+ * c-label-offset: -8 ***
+ * End: ***
+ */
diff -u --new-file --recursive linux-1.3.100/include/linux/ufs_fs_i.h.save linux/include/linux/ufs_fs_i.h.save
--- linux-1.3.100/include/linux/ufs_fs_i.h.save Wed Dec 31 16:00:00 1969
+++ linux/include/linux/ufs_fs_i.h.save Sun May 5 17:09:01 1996
@@ -0,0 +1,30 @@
+/*
+ * linux/include/linux/ufs_fs_i.h
+ *
+ * Copyright (C) 1996
+ * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
+ * Laboratory for Computer Science Research Computing Facility
+ * Rutgers, The State University of New Jersey
+ *
+ * $Id: ufs_fs_i.h,v 1.1 1996/04/21 14:45:13 davem Exp $
+ *
+ */
+
+#ifndef _LINUX_UFS_FS_I_H
+#define _LINUX_UFS_FS_I_H
+
+#include <linux/ufs_fs.h>
+
+struct ufs_inode_info {
+ __u64 ui_size;
+ __u32 ui_flags;
+ __u32 ui_gen;
+ __u32 ui_shadow;
+ __u32 ui_uid;
+ __u32 ui_gid;
+ __u32 ui_oeftflag;
+ __u32 ui_db[UFS_NDADDR];
+ __u32 ui_ib[UFS_NINDIR];
+};
+
+#endif /* _LINUX_UFS_FS_I_H */
diff -u --new-file --recursive linux-1.3.100/include/linux/ufs_fs_sb.h.save linux/include/linux/ufs_fs_sb.h.save
--- linux-1.3.100/include/linux/ufs_fs_sb.h.save Wed Dec 31 16:00:00 1969
+++ linux/include/linux/ufs_fs_sb.h.save Tue Apr 23 01:13:29 1996
@@ -0,0 +1,43 @@
+/*
+ * linux/include/linux/ufs_fs_sb.h
+ *
+ * Copyright (C) 1996
+ * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
+ * Laboratory for Computer Science Research Computing Facility
+ * Rutgers, The State University of New Jersey
+ *
+ * $Id: ufs_fs_sb.h,v 1.1 1996/04/21 14:45:15 davem Exp $
+ *
+ */
+
+#ifndef __LINUX_UFS_FS_SB_H
+#define __LINUX_UFS_FS_SB_H
+
+
+struct ufs_sb_info {
+ struct ufs_superblock * s_raw_sb;
+ __u32 s_flags; /* internal flags for UFS code */
+ __u32 s_ncg; /* used in ufs_read_inode */
+ __u32 s_ipg; /* used in ufs_read_inode */
+ __u32 s_fpg;
+ __u32 s_fsize;
+ __u32 s_bsize;
+ __u32 s_iblkno;
+ __u32 s_dblkno;
+ __u32 s_cgoffset;
+ __u32 s_cgmask;
+ __u32 s_inopb;
+ __u32 s_fsfrag;
+};
+
+#endif /* __LINUX_UFS_FS_SB_H */
+
+/*
+ * Local Variables: ***
+ * c-indent-level: 8 ***
+ * c-continued-statement-offset: 8 ***
+ * c-brace-offset: -8 ***
+ * c-argdecl-indent: 0 ***
+ * c-label-offset: -8 ***
+ * End: ***
+ */