diff -ruN linux-source-2.6.24.orig/fs/asfs/symlink.c linux-source-2.6.24/fs/asfs/symlink.c --- linux-source-2.6.24.orig/fs/asfs/symlink.c 1970-01-01 03:00:00.000000000 +0300 +++ linux-source-2.6.24/fs/asfs/symlink.c 2008-12-14 23:05:05.000000000 +0300 @@ -0,0 +1,247 @@ +/* + * + * Amiga Smart File System, Linux implementation + * version: 1.0beta12 + * + * Copyright (C) 2003,2004,2005,2006 Marek 'March' Szyprowski <marek@xxxxxxxx> + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/slab.h> +#include <linux/fs.h> +#include <linux/buffer_head.h> +#include <linux/vfs.h> +#include <linux/pagemap.h> +#include <linux/nls.h> +#include "asfs_fs.h" + +#include <asm/byteorder.h> +#include <asm/uaccess.h> + +int asfs_symlink_readpage(struct file *file, struct page *page) +{ + struct buffer_head *bh; + struct fsSoftLink *slinkcont; + struct inode *inode = page->mapping->host; + struct super_block *sb = inode->i_sb; + struct nls_table *nls_io = ASFS_SB(sb)->nls_io; + struct nls_table *nls_disk = ASFS_SB(sb)->nls_disk; + char *link = kmap(page); + int i = 0, j = 0; + char c, lc = 0, *prefix, *lf, *p; + wchar_t uni; + int clen; + + asfs_debug("asfs_read_symlink from node %d\n", (int)inode->i_ino); + + if (!(bh = asfs_breadcheck(sb, ASFS_I(inode)->firstblock, ASFS_SOFTLINK_ID))) { + SetPageError(page); + kunmap(page); + unlock_page(page); + return -EIO; + } + slinkcont = (struct fsSoftLink *) bh->b_data; + + lf = slinkcont->string; + prefix = ASFS_SB(sb)->prefix ? ASFS_SB(sb)->prefix : "/"; + + asfs_debug("asfs_read_symlink: link target %s\n", lf); + + if ((p = strchr(lf,':'))) { /* Handle assign or volume name */ + if (ASFS_SB(sb)->root_volume && + strncmp(lf, ASFS_SB(sb)->root_volume, strlen(ASFS_SB(sb)->root_volume)) == 0) { + /* global root volume name found */ + link[i++] = '/'; + lf = p+1; + } else { + /* adding volume prefix */ + while (i < 1023 && (c = prefix[i])) + link[i++] = c; + while (i < 1023 && lf[j] != ':') + { + c = lf[j++]; + if (ASFS_SB(sb)->flags & ASFS_VOL_LOWERCASE) + c = asfs_lowerchar(c); + if (nls_io) + { + clen = nls_disk->char2uni(&c, 1, &uni); + if (clen>0) { + clen = nls_io->uni2char(uni, &link[i], NLS_MAX_CHARSET_SIZE); + if (clen>0) + i += clen; + } + if (clen<0) + link[i++] = '?'; + } else + link[i++] = c; + } + if (i < 1023) + link[i++] = '/'; + j++; + } + lc = '/'; + } + + while (i < 1023 && (c = lf[j])) { + if (c == '/' && lc == '/' && i < 1020) { /* parent dir */ + link[i++] = '.'; + link[i++] = '.'; + } + lc = c; + if (nls_io) + { + clen = nls_disk->char2uni(&c, 1, &uni); + if (clen>0) { + clen = nls_io->uni2char(uni, &link[i], NLS_MAX_CHARSET_SIZE); + if (clen>0) + i += clen; + } + if (clen<0) + link[i++] = '?'; + } else + link[i++] = c; + j++; + } + link[i] = '\0'; + + SetPageUptodate(page); + kunmap(page); + unlock_page(page); + asfs_brelse(bh); + return 0; +} + +#ifdef CONFIG_ASFS_RW + +int asfs_write_symlink(struct inode *symfile, const char *symname) +{ + struct super_block *sb = symfile->i_sb; + struct buffer_head *bh; + struct fsSoftLink *slinkcont; + struct nls_table *nls_io = ASFS_SB(sb)->nls_io; + struct nls_table *nls_disk = ASFS_SB(sb)->nls_disk; + char *p, c, lc; + int i, maxlen, pflen; + wchar_t uni; + int clen, blen; + + asfs_debug("asfs_write_symlink %s to node %d\n", symname, (int)symfile->i_ino); + + if (!(bh = asfs_breadcheck(sb, ASFS_I(symfile)->firstblock, ASFS_SOFTLINK_ID))) { + return -EIO; + } + slinkcont = (struct fsSoftLink *) bh->b_data; + + /* translating symlink target path */ + + maxlen = sb->s_blocksize - sizeof(struct fsSoftLink) - 2; + i = 0; + p = slinkcont->string; + lc = '/'; + + if (*symname == '/') { + while (*symname == '/') + symname++; + if (ASFS_SB(sb)->prefix && + strncmp(symname-1, ASFS_SB(sb)->prefix, (pflen = strlen(ASFS_SB(sb)->prefix))) == 0) { + /* found volume prefix, ommiting it */ + symname += pflen; + blen = strlen(symname); + while (*symname != '/' && *symname != '\0') { + if (nls_io) { + clen = nls_io->char2uni(symname, blen, &uni); + if (clen>0) { + symname += clen; + blen -= clen; + clen = nls_disk->uni2char(uni, p, NLS_MAX_CHARSET_SIZE); + if (clen>0) + p += clen; + } + else + { + symname++; + blen--; + } + if (clen<0) + *p++ = '?'; + } else { + *p++ = *symname++; + } + i++; + } + symname++; + *p++ = ':'; + } else if (ASFS_SB(sb)->root_volume) { /* adding root volume name */ + while (ASFS_SB(sb)->root_volume[i]) + *p++ = ASFS_SB(sb)->root_volume[i++]; + *p++ = ':'; + } else { /* do nothing */ + *p++ = '/'; + } + i++; + } + + blen = strlen(symname); + while (i < maxlen && (c = *symname)) { + if (c == '.' && lc == '/' && symname[1] == '.' && symname[2] == '/') { + *p++ = '/'; + i++; + symname += 3; + blen -= 3; + lc = '/'; + } else if (c == '.' && lc == '/' && symname[1] == '/') { + symname += 2; + blen -= 2; + lc = '/'; + } else { + if (nls_io) { + clen = nls_io->char2uni(symname, blen, &uni); + if (clen>0) { + symname += clen; + blen -= clen; + clen = nls_disk->uni2char(uni, p, NLS_MAX_CHARSET_SIZE); + if (clen>0) + lc = *p; + p += clen; + } else { + symname++; + blen--; + } + if (clen<0) { + *p++ = '?'; + lc = '?'; + } + } else { + *p++ = c; + lc = *p; + symname++; + blen--; + } + i++; + } + if (lc == '/') + while (*symname == '/') + { + symname++; + blen--; + } + } + *p = 0; + + asfs_debug("asfs_write_symlink: saved %s\n", slinkcont->string); + + asfs_bstore(sb, bh); + asfs_brelse(bh); + + return 0; +} + +#endif diff -ruN linux-source-2.6.24.orig/fs/Kconfig linux-source-2.6.24/fs/Kconfig --- linux-source-2.6.24.orig/fs/Kconfig 2008-01-25 01:58:37.000000000 +0300 +++ linux-source-2.6.24/fs/Kconfig 2008-12-14 23:05:05.000000000 +0300 @@ -1105,6 +1105,53 @@ To compile this file system support as a module, choose M here: the module will be called ecryptfs. +config ASFS_FS + tristate "Amiga SFS file system support (EXPERIMENTAL)" + select NLS + depends on EXPERIMENTAL + help + + The Amiga Smart FileSystem (SFS) is the file system used on hard + disks by Amiga(tm) and MorphOS(tm) systems. Say Y if you want + to be able to read files from an Amiga SFS partition on your hard + drive. + + For more information read <file:Documentation/filesystems/asfs.txt> + + To compile this file system support as a module, choose M here: the + module will be called asfs. + + If unsure, say N. + +config ASFS_DEFAULT_CODEPAGE + string "Default codepage for SFS" + depends on ASFS_FS + default "" + help + This option should be set to the codepage of your SFS filesystems. + It can be overridden with the 'codepage' mount option. Leave it blank + or enter 'none' to disable filename converting. + + Use full codepage name (for example 'cp1251' instead of '1251') here, + this allows to specify any character set, not only numbered one (like + 'iso8859-2'). + + If unsure, leave it blank. + +config ASFS_RW + bool "Amiga SFS write support (DANGEROUS)" + depends on ASFS_FS + help + + If you say Y here, you will be able to write to ASFS file + systems as well as read from them. The read-write support in ASFS + is in beta stage. This means that useing it to write files to SFS + partitions is DANGEROUS and COULD corrupt the filesystem. + + For more information read <file:Documentation/filesystems/asfs.txt> + + If unsure, say N. + config HFS_FS tristate "Apple Macintosh file system support (EXPERIMENTAL)" depends on BLOCK && EXPERIMENTAL diff -ruN linux-source-2.6.24.orig/fs/Makefile linux-source-2.6.24/fs/Makefile --- linux-source-2.6.24.orig/fs/Makefile 2008-01-25 01:58:37.000000000 +0300 +++ linux-source-2.6.24/fs/Makefile 2008-12-14 23:05:05.000000000 +0300 @@ -100,6 +100,7 @@ obj-$(CONFIG_EFS_FS) += efs/ obj-$(CONFIG_JFFS2_FS) += jffs2/ obj-$(CONFIG_AFFS_FS) += affs/ +obj-$(CONFIG_ASFS_FS) += asfs/ obj-$(CONFIG_ROMFS_FS) += romfs/ obj-$(CONFIG_QNX4FS_FS) += qnx4/ obj-$(CONFIG_AUTOFS_FS) += autofs/ diff -ruN linux-source-2.6.24.orig/include/linux/amigasfs.h linux-source-2.6.24/include/linux/amigasfs.h --- linux-source-2.6.24.orig/include/linux/amigasfs.h 1970-01-01 03:00:00.000000000 +0300 +++ linux-source-2.6.24/include/linux/amigasfs.h 2008-12-14 23:05:05.000000000 +0300 @@ -0,0 +1,276 @@ +#ifndef __LINUX_AMIGASFS_H +#define __LINUX_AMIGASFS_H + +#include <linux/types.h> + +/* some helper macros... */ +#define ASFS_MAKE_ID(a,b,c,d) (((a)&0xff)<<24|((b)&0xff)<<16|((c)&0xff)<<8|((d)&0xff)) + +/* Amiga SFS block IDs */ +#define ASFS_ROOTID ASFS_MAKE_ID('S','F','S','\0') +#define ASFS_OBJECTCONTAINER_ID ASFS_MAKE_ID('O','B','J','C') +#define ASFS_BNODECONTAINER_ID ASFS_MAKE_ID('B','N','D','C') +#define ASFS_NODECONTAINER_ID ASFS_MAKE_ID('N','D','C',' ') +#define ASFS_HASHTABLE_ID ASFS_MAKE_ID('H','T','A','B') +#define ASFS_SOFTLINK_ID ASFS_MAKE_ID('S','L','N','K') +#define ASFS_ADMINSPACECONTAINER_ID ASFS_MAKE_ID('A','D','M','C') +#define ASFS_BITMAP_ID ASFS_MAKE_ID('B','T','M','P') +#define ASFS_TRANSACTIONFAILURE_ID ASFS_MAKE_ID('T','R','F','A') + +/* Amiga SFS defines and magic values */ + +#define ASFS_MAGIC 0xa0ff +#define ASFS_MAXFN (105u) +#define ASFS_MAXFILESIZE 0x8FFFFFFE + +#define ASFS_STRUCTURE_VERISON (3) +#define ASFS_BLCKFACCURACY (5) + +#define ASFS_ROOTBITS_CASESENSITIVE (128) +#define ASFS_READONLY (512) +#define ASFS_VOL_LOWERCASE (1024) + +#define ASFS_ROOTNODE (1) +#define ASFS_RECYCLEDNODE (2) + +#define OTYPE_HIDDEN (1) +#define OTYPE_HARDLINK (32) +#define OTYPE_LINK (64) +#define OTYPE_DIR (128) + +#define MSB_MASK (1ul << 31) + +#define NODE_STRUCT_SIZE (10) /* (sizeof(struct fsObjectNode)) */ +#define NODECONT_BLOCK_COUNT ((sb->s_blocksize - sizeof(struct fsNodeContainer)) / sizeof(u32)) + +#define ASFS_ALWAYSFREE (16) /* keep this amount of blocks free */ + +#define ASFS_BLOCKCHUNKS (16) /* try to allocate this number of blocks in one request */ + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +/* amigados protection bits */ + +#define FIBB_SCRIPT 6 /* program is a script (execute) file */ +#define FIBB_PURE 5 /* program is reentrant and reexecutable */ +#define FIBB_ARCHIVE 4 /* cleared whenever file is changed */ +#define FIBB_READ 3 /* ignored by old filesystem */ +#define FIBB_WRITE 2 /* ignored by old filesystem */ +#define FIBB_EXECUTE 1 /* ignored by system, used by Shell */ +#define FIBB_DELETE 0 /* prevent file from being deleted */ + +#define FIBF_SCRIPT (1<<FIBB_SCRIPT) +#define FIBF_PURE (1<<FIBB_PURE) +#define FIBF_ARCHIVE (1<<FIBB_ARCHIVE) +#define FIBF_READ (1<<FIBB_READ) +#define FIBF_WRITE (1<<FIBB_WRITE) +#define FIBF_EXECUTE (1<<FIBB_EXECUTE) +#define FIBF_DELETE (1<<FIBB_DELETE) + +/* name hashing macro */ + +#define HASHCHAIN(x) (u16)(x % (u16)(((sb->s_blocksize) - sizeof(struct fsHashTable))>>2)) + +/* Each block has its own header with checksum and id, its called fsBlockHeader */ + +struct fsBlockHeader { + __be32 id; /* 4 character id string of this block */ + __be32 checksum; /* The checksum */ + __be32 ownblock; /* The blocknumber of the block this block is stored at */ +}; + +/* On-disk "super block", called fsRootBlock */ + +struct fsRootBlock { + struct fsBlockHeader bheader; + + __be16 version; /* Version number of the filesystem block structure */ + __be16 sequencenumber; /* The Root with the highest sequencenumber is valid */ + + __be32 datecreated; /* Creation date (when first formatted). Cannot be changed. */ + u8 bits; /* various settings, see defines below. */ + u8 pad1; + u16 pad2; + + u32 reserved1[2]; + + __be32 firstbyteh; /* The first byte of our partition from the start of the */ + __be32 firstbyte; /* disk. firstbyteh = upper 32 bits, firstbyte = lower 32 bits. */ + + __be32 lastbyteh; /* The last byte of our partition, excluding this one. */ + __be32 lastbyte; + + __be32 totalblocks; /* size of this partition in blocks */ + __be32 blocksize; /* blocksize used */ + + u32 reserved2[2]; + u32 reserved3[8]; + + __be32 bitmapbase; /* location of the bitmap */ + __be32 adminspacecontainer; /* location of first adminspace container */ + __be32 rootobjectcontainer; /* location of the root objectcontainer */ + __be32 extentbnoderoot; /* location of the root of the extentbnode B-tree */ + __be32 objectnoderoot; /* location of the root of the objectnode tree */ + + u32 reserved4[3]; +}; + +/* On disk inode, called fsObject */ + +struct fsObject { + __be16 owneruid; + __be16 ownergid; + __be32 objectnode; + __be32 protection; + + union { + struct { + __be32 data; + __be32 size; + } file; + + struct { + __be32 hashtable; /* for directories & root, 0 means no hashblock */ + __be32 firstdirblock; + } dir; + } object; + + __be32 datemodified; + u8 bits; + + u8 name[0]; + u8 comment[0]; +}; + +/* On disk block containging a number of fsObjects */ + +struct fsObjectContainer { + struct fsBlockHeader bheader; + + __be32 parent; + __be32 next; + __be32 previous; /* 0 for the first block in the directory chain */ + + struct fsObject object[0]; +}; + +/* BTree structures, used to collect file data position on disk */ + +struct fsExtentBNode { + __be32 key; /* data! */ + __be32 next; + __be32 prev; + __be16 blocks; /* The size in blocks of the region this Extent controls */ +}; + +struct BNode { + __be32 key; + __be32 data; +}; + +struct BTreeContainer { + __be16 nodecount; + u8 isleaf; + u8 nodesize; /* Must be a multiple of 2 */ + + struct BNode bnode[0]; +}; + +/* On disk block with BTreeContainer */ + +struct fsBNodeContainer { + struct fsBlockHeader bheader; + struct BTreeContainer btc; +}; + +/* On disk block with soft link data */ + +struct fsSoftLink { + struct fsBlockHeader bheader; + __be32 parent; + __be32 next; + __be32 previous; + u8 string[0]; +}; + +/* On disk block with hashtable data */ + +struct fsHashTable { + struct fsBlockHeader bheader; + __be32 parent; + __be32 hashentry[0]; +}; + +/* On disk block with node index and some helper structures */ + +struct fsNodeContainer { + struct fsBlockHeader bheader; + __be32 nodenumber; + __be32 nodes; + __be32 node[0]; +}; + +struct fsNode { + __be32 data; +}; + +struct fsObjectNode { + struct fsNode node; + __be32 next; + __be16 hash16; +} __attribute__ ((packed)); + +/* Some adminspace and bitmap block structures */ + +struct fsAdminSpace { + __be32 space; + __be32 bits; +/* Set bits are used blocks, bit 31 is the first block in the AdminSpace. */ +}; + +struct fsAdminSpaceContainer { + struct fsBlockHeader bheader; + + __be32 next; + __be32 previous; + + u8 bits; + u8 pad1; + u16 pad2; + + struct fsAdminSpace adminspace[0]; +}; + +struct fsBitmap { + struct fsBlockHeader bheader; + + __be32 bitmap[0]; + +/* Bits are 1 if the block is free, and 0 if full. + Bitmap must consist of an integral number of longwords. */ +}; + +/* The fsRootInfo structure has all kinds of information about the format + of the disk. */ + +struct fsRootInfo { + __be32 deletedblocks; /* Amount in blocks which deleted files consume. */ + __be32 deletedfiles; /* Number of deleted files in recycled. */ + __be32 freeblocks; /* Cached number of free blocks on disk. */ + + __be32 datecreated; + + __be32 lastallocatedblock; /* Block which was most recently allocated */ + __be32 lastallocatedadminspace; /* AdminSpaceContainer which most recently was used to allocate a block */ + __be32 lastallocatedextentnode; /* ExtentNode which was most recently created */ + __be32 lastallocatedobjectnode; /* ObjectNode which was most recently created */ + + __be32 rovingpointer; +}; + +#endif -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html