summaryrefslogtreecommitdiffstats
path: root/fs/ufs
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-12-16 06:06:25 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-12-16 06:06:25 +0000
commitaa944aa3453e47706685bc562711a9e87375941e (patch)
tree8fb37a65f205a90412917ca2b91c429263ef1790 /fs/ufs
parent967c65a99059fd459b956c1588ce0ba227912c4e (diff)
Merge with Linux 2.1.72, part 2.
The new signal code with exception of the code for the rt signals. The definitions in <asm/siginfo.h> and <asm/ucontext.h> are currently just stolen from the Alpha and will need to be overhauled.
Diffstat (limited to 'fs/ufs')
-rw-r--r--fs/ufs/ufs_swab.c138
-rw-r--r--fs/ufs/ufs_swab.h59
2 files changed, 197 insertions, 0 deletions
diff --git a/fs/ufs/ufs_swab.c b/fs/ufs/ufs_swab.c
new file mode 100644
index 000000000..2dc4061a0
--- /dev/null
+++ b/fs/ufs/ufs_swab.c
@@ -0,0 +1,138 @@
+/*
+ * linux/fs/ufs/ufs_swab.c
+ *
+ * Copyright (C) 1997
+ * Francois-Rene Rideau <rideau@ens.fr>
+ *
+ */
+
+/*
+ * For inspiration, you might wanna check sys/ufs/ffs/fs.h from whateverBSD
+ *
+ * NOTES
+ * 19970406 - Fare <rideau@ens.fr>
+ * 1) I began from old very preliminary 2.0.x sources,
+ * but it was underfeatured;
+ * I later saw that 2.1.1 sources had a *global* UFS byteswap flag.
+ * EVIL: imagine that a swabbed partition be mounted
+ * while a non-swabbed partition are active (that sucks!)
+ * I merged that source tree with mine.
+ * 2) I hope no one is using obNNUUXXIIous byteorder.
+ * That's the only thing I might have broken,
+ * though I rather think it's a fix:
+ * instead of __u64 like BSD,
+ * the former driver used an explicitly bigendian array of __u32!
+ * 3) I provide a few macros that use GCC C Extensions.
+ * Port to other compilers would require avoiding them.
+ * in any case, 64 bit (long long) support is required,
+ * unless you're ready to workaround
+ * 4) the swab routines below depend on the precise name and order
+ * of the structure elements. Watch out any modification in ufs_fs.h!!!
+ * 5) putting byteswapping stuff in ufs_swab* seems cleaner to me.
+ * 6) These sources should work with both 2.0 and 2.1 kernels...
+ *
+ * 19971013 - Fare <rideaufr@issy.cnet.fr>
+ * 1) Ported to 2.1.57
+ * 2) instead of byteswapping, use [bl]e_to_cpu:
+ * it might be that we run on a VAX!
+ *
+ * HOWTO continue adding swab support:
+ * basically, anywhere metadata is bread() (i.e. mapped to block device),
+ * data should either be SWAB()ed on the fly,
+ * or copied to a buffer and globally bswap_ufs_*() there.
+ *
+ */
+
+#include <linux/fs.h>
+#include "ufs_swab.h"
+
+static __inline__ void n_be16_to_cpus(__u16*p,unsigned n) {
+#ifndef __BIG_ENDIAN
+ unsigned i;
+ for(i=0;i<n;i++) {
+ be16_to_cpus(&p[i]);
+ }
+#endif
+}
+static __inline__ void n_be32_to_cpus(__u32*p,unsigned n) {
+#ifndef __BIG_ENDIAN
+ unsigned i;
+ for(i=0;i<n;i++) {
+ be32_to_cpus(&p[i]);
+ }
+#endif
+}
+static __inline__ void n_le16_to_cpus(__u16*p,unsigned n) {
+#ifndef __LITTLE_ENDIAN
+ unsigned i;
+ for(i=0;i<n;i++) {
+ le16_to_cpus(&p[i]);
+ }
+#endif
+}
+static __inline__ void n_le32_to_cpus(__u32*p,unsigned n) {
+#ifndef __LITTLE_ENDIAN
+ unsigned i;
+ for(i=0;i<n;i++) {
+ le32_to_cpus(&p[i]);
+ }
+#endif
+}
+
+#define __length_before(p,member) \
+ ((unsigned)(((char*)&((p)->member))-(char*)(p)))
+#define __length_since(p,member) \
+ ((unsigned)(sizeof(*p)-__length_before(p,member)))
+#define __length_between(p,begin,after_end) \
+ ((unsigned)(__length_before(p,after_end)-__length_before(p,begin)))
+#define be32_to_cpus__between(s,begin,after_end) \
+ n_be32_to_cpus((__u32*)&((s).begin), \
+ __length_between(&s,begin,after_end)/4)
+#define le32_to_cpus__between(s,begin,after_end) \
+ n_le32_to_cpus((__u32*)&((s).begin), \
+ __length_between(&s,begin,after_end)/4)
+#define be32_to_cpus__since(s,begin) \
+ n_be32_to_cpus((__u32*)&((s).begin), \
+ __length_since(&s,begin)/4)
+#define le32_to_cpus__since(s,begin) \
+ n_le32_to_cpus((__u32*)&((s).begin), \
+ __length_since(&s,begin)/4)
+#define be16_to_cpus__between(s,begin,after_end) \
+ n_be16_to_cpus((__u16*)&((s).begin), \
+ __length_between(&s,begin,after_end)/2)
+#define le16_to_cpus__between(s,begin,after_end) \
+ n_le16_to_cpus((__u16*)&((s).begin), \
+ __length_between(&s,begin,after_end)/2)
+
+/*
+ * Here are the whole-structure swabping routines...
+ */
+
+extern void ufs_superblock_be_to_cpus(struct ufs_superblock * usb) {
+#ifndef __BIG_ENDIAN
+ be32_to_cpus__between(*usb,fs_link,fs_fmod);
+ /* XXX - I dunno what to do w/ fs_csp,
+ * but it is unused by the current code, so that's ok for now.
+ */
+ be32_to_cpus(&usb->fs_cpc);
+ be16_to_cpus__between(*usb,fs_opostbl,fs_sparecon);
+ be32_to_cpus__between(*usb,fs_sparecon,fs_qbmask);
+ be64_to_cpus(&usb->fs_qbmask);
+ be64_to_cpus(&usb->fs_qfmask);
+ be32_to_cpus__between(*usb,fs_postblformat,fs_magic);
+#endif
+}
+extern void ufs_superblock_le_to_cpus(struct ufs_superblock * usb) {
+#ifndef __LITTLE_ENDIAN
+ le32_to_cpus__between(*usb,fs_link,fs_fmod);
+ /* XXX - I dunno what to do w/ fs_csp,
+ * but it is unused by the current code, so that's ok for now.
+ */
+ le32_to_cpus(&usb->fs_cpc);
+ le16_to_cpus__between(*usb,fs_opostbl,fs_sparecon);
+ le32_to_cpus__between(*usb,fs_sparecon,fs_qbmask);
+ le64_to_cpus(&usb->fs_qbmask);
+ le64_to_cpus(&usb->fs_qfmask);
+ le32_to_cpus__between(*usb,fs_postblformat,fs_magic);
+#endif
+}
diff --git a/fs/ufs/ufs_swab.h b/fs/ufs/ufs_swab.h
new file mode 100644
index 000000000..921fb3d79
--- /dev/null
+++ b/fs/ufs/ufs_swab.h
@@ -0,0 +1,59 @@
+/*
+ * linux/fs/ufs/ufs_swab.h
+ *
+ * Copyright (C) 1997
+ * Francois-Rene Rideau <rideau@ens.fr>
+ *
+ */
+
+#ifndef _UFS_SWAB_H
+#define _UFS_SWAB_H
+
+
+/*
+ * Notes:
+ * (1) HERE WE ASSUME EITHER BIG OR LITTLE ENDIAN UFSes
+ * in case there are ufs implementations that have strange bytesexes,
+ * you'll need to modify code here as well as in ufs_super.c and ufs_fs.h
+ * to support them.
+ * (2) for a read/write ufs driver, we should distinguish
+ * between byteswapping for read or write accesses!
+ */
+
+#include <linux/ufs_fs.h>
+#include <asm/byteorder.h>
+
+/*
+ * These are only valid inside ufs routines,
+ * after bytesex has been initialized to sb->u.ufs_sb.s_flags&UFS_BYTESEX
+ */
+#define SWAB16(x) ufs_swab16(bytesex,x)
+#define SWAB32(x) ufs_swab32(bytesex,x)
+#define SWAB64(x) ufs_swab64(bytesex,x)
+
+extern __inline__ __const__ __u16 ufs_swab16(__u32 bytesex, __u16 x) {
+ if (bytesex == UFS_LITTLE_ENDIAN) {
+ return le16_to_cpu(x);
+ } else {
+ return be16_to_cpu(x);
+ }
+}
+extern __inline__ __const__ __u32 ufs_swab32(__u32 bytesex, __u32 x) {
+ if (bytesex == UFS_LITTLE_ENDIAN) {
+ return le32_to_cpu(x);
+ } else {
+ return be32_to_cpu(x);
+ }
+}
+extern __inline__ __const__ __u64 ufs_swab64(__u32 bytesex, __u64 x) {
+ if (bytesex == UFS_LITTLE_ENDIAN) {
+ return le64_to_cpu(x);
+ } else {
+ return be64_to_cpu(x);
+ }
+}
+
+extern void ufs_superblock_le_to_cpus(struct ufs_superblock * usb);
+extern void ufs_superblock_be_to_cpus(struct ufs_superblock * usb);
+
+#endif /* _UFS_SWAB_H */