diff -ruN linux-source-2.6.24.orig/fs/asfs/asfs_fs.h linux-source-2.6.24/fs/asfs/asfs_fs.h --- linux-source-2.6.24.orig/fs/asfs/asfs_fs.h 1970-01-01 03:00:00.000000000 +0300 +++ linux-source-2.6.24/fs/asfs/asfs_fs.h 2008-12-14 23:34:17.000000000 +0300 @@ -0,0 +1,218 @@ +#ifndef __LINUX_ASFS_FS_H +#define __LINUX_ASFS_FS_H + +#include <linux/types.h> +#include <linux/fs.h> +#include <linux/buffer_head.h> +#include <asm/byteorder.h> +#include <linux/amigasfs.h> + +#define asfs_debug(fmt,arg...) /* no debug at all */ +//#define asfs_debug(fmt,arg...) printk(fmt,##arg) /* general debug infos */ + +#if !defined (__BIG_ENDIAN) && !defined (__LITTLE_ENDIAN) +#error Endianes must be known for ASFS to work. Sorry. +#endif + +#define ASFS_MAXFN_BUF (ASFS_MAXFN + 4) +#define ASFS_DEFAULT_UID 0 +#define ASFS_DEFAULT_GID 0 +#define ASFS_DEFAULT_MODE 0644 /* default permission bits for files, dirs have same permission, but with "x" set */ + +/* Extent structure located in RAM (e.g. inside inode structure), + currently used to store last used extent */ + +struct inramExtent { + u32 startblock; /* Block from begginig of the file */ + u32 key; + u32 next; + u16 blocks; +}; + +/* inode in-kernel data */ + +struct asfs_inode_info { + u32 firstblock; + u32 hashtable; + int modified; + loff_t mmu_private; + struct inramExtent ext_cache; + struct inode vfs_inode; +}; + +/* short cut to get to the asfs specific inode data */ +static inline struct asfs_inode_info *ASFS_I(struct inode *inode) +{ + return list_entry(inode, struct asfs_inode_info, vfs_inode); +} + +/* Amiga SFS superblock in-core data */ + +struct asfs_sb_info { + u32 totalblocks; + u32 rootobjectcontainer; + u32 extentbnoderoot; + u32 objectnoderoot; + + u32 adminspacecontainer; + u32 bitmapbase; + u32 freeblocks; + u32 blocks_inbitmap; + u32 blocks_bitmap; + u32 block_rovingblockptr; + + uid_t uid; + gid_t gid; + umode_t mode; + u16 flags; + char *prefix; + char *root_volume; /* Volume prefix for absolute symlinks. */ + char *iocharset; + char *codepage; + struct nls_table *nls_io; + struct nls_table *nls_disk; +}; + +/* short cut to get to the asfs specific sb data */ +static inline struct asfs_sb_info *ASFS_SB(struct super_block *sb) +{ + return sb->s_fs_info; +} + +/* io inline code */ + +u32 asfs_calcchecksum(void *block, u32 blocksize); + +static inline int +asfs_check_block(struct fsBlockHeader *block, u32 blocksize, u32 n, u32 id) +{ + if (asfs_calcchecksum(block, blocksize) == + be32_to_cpu(((struct fsBlockHeader *) block)->checksum) && + n == be32_to_cpu(((struct fsBlockHeader *) block)->ownblock) && + id == be32_to_cpu(((struct fsBlockHeader *) block)->id)) + return TRUE; + return FALSE; +} + +/* get fs structure from block and do some checks... */ +static inline struct buffer_head * +asfs_breadcheck(struct super_block *sb, u32 n, u32 type) +{ + struct buffer_head *bh; + if ((bh = sb_bread(sb, n))) { + if (asfs_check_block ((void *)bh->b_data, sb->s_blocksize, n, type)) { + return bh; /* all okay */ + } + brelse(bh); + } + return NULL; /* error */ +} + +static inline struct buffer_head * +asfs_getzeroblk(struct super_block *sb, int block) +{ + struct buffer_head *bh; + bh = sb_getblk(sb, block); + lock_buffer(bh); + memset(bh->b_data, 0, sb->s_blocksize); + set_buffer_uptodate(bh); + unlock_buffer(bh); + return bh; +} + +static inline void +asfs_bstore(struct super_block *sb, struct buffer_head *bh) +{ + ((struct fsBlockHeader *) (bh->b_data))->checksum = + cpu_to_be32(asfs_calcchecksum(bh->b_data, sb->s_blocksize)); + mark_buffer_dirty(bh); +} + +static inline void asfs_brelse(struct buffer_head *bh) +{ + brelse(bh); +} + +static inline void dec_count(struct inode *inode) +{ + inode->i_nlink--; + mark_inode_dirty(inode); +} + +/* all prototypes */ + +/* adminspace.c */ +int asfs_allocadminspace(struct super_block *sb, u32 * block); +int asfs_freeadminspace(struct super_block *sb, u32 block); +int asfs_markspace(struct super_block *sb, u32 block, u32 blocks); +int asfs_freespace(struct super_block *sb, u32 block, u32 blocks); +int asfs_findspace(struct super_block *sb, u32 maxneeded, u32 start, u32 end, + u32 * returned_block, u32 * returned_blocks); + +/* dir.c */ +int asfs_readdir(struct file *filp, void *dirent, filldir_t filldir); +struct dentry *asfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd); + +/* extents.c */ +int asfs_getextent(struct super_block *sb, u32 key, struct buffer_head **ret_bh, + struct fsExtentBNode **ret_ebn); +int asfs_deletebnode(struct super_block *sb, struct buffer_head *cb, u32 key); +int asfs_deleteextents(struct super_block *sb, u32 key); +int asfs_addblocks(struct super_block *sb, u16 blocks, u32 newspace, + u32 objectnode, u32 * io_lastextentbnode); + +/* file.c */ +int asfs_readpage(struct file *file, struct page *page); +sector_t asfs_bmap(struct address_space *mapping, sector_t block); +int asfs_writepage(struct page *page, struct writeback_control *wbc); +int asfs_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata); +void asfs_truncate(struct inode *inode); +int asfs_file_open(struct inode *inode, struct file *filp); +int asfs_file_release(struct inode *inode, struct file *filp); + +/* inode.c */ +struct inode *asfs_get_root_inode(struct super_block *sb); +void asfs_read_locked_inode(struct inode *inode, void *arg); + +/* namei */ +u8 asfs_lowerchar(u8 c); +int asfs_check_name(const u8 *name, int len); +int asfs_namecmp(u8 *s, u8 *ct, int casesensitive, struct nls_table *t); +u16 asfs_hash(u8 *name, int casesensitive); +void asfs_translate(u8 *to, u8 *from, struct nls_table *nls_to, struct nls_table *nls_from, int limit); + +/* nodes */ +int asfs_getnode(struct super_block *sb, u32 nodeno, + struct buffer_head **ret_bh, struct fsObjectNode **ret_node); +int asfs_createnode(struct super_block *sb, struct buffer_head **returned_cb, + struct fsNode **returned_node, u32 * returned_nodeno); +int asfs_deletenode(struct super_block *sb, u32 objectnode); + +/* objects */ +struct fsObject *asfs_nextobject(struct fsObject *obj); +struct fsObject *asfs_find_obj_by_name(struct super_block *sb, + struct fsObjectContainer *objcont, u8 * name); +int asfs_readobject(struct super_block *sb, u32 objectnode, + struct buffer_head **cb, struct fsObject **returned_object); +int asfs_createobject(struct super_block *sb, struct buffer_head **io_cb, + struct fsObject **io_o, struct fsObject *src_o, + u8 * objname, int force); +int asfs_deleteobject(struct super_block *sb, struct buffer_head *cb, + struct fsObject *o); +int asfs_renameobject(struct super_block *sb, struct buffer_head *cb1, + struct fsObject *o1, struct buffer_head *cbparent, + struct fsObject *oparent, u8 * newname); + +int asfs_addblockstofile(struct super_block *sb, struct buffer_head *objcb, + struct fsObject *o, u32 blocks, u32 * newspace, + u32 * addedblocks); +int asfs_truncateblocksinfile(struct super_block *sb, struct buffer_head *bh, + struct fsObject *o, u32 newsize); + +/* symlink.c */ +int asfs_symlink_readpage(struct file *file, struct page *page); +int asfs_write_symlink(struct inode *symfile, const char *symname); + +#endif diff -ruN linux-source-2.6.24.orig/fs/asfs/bitfuncs.c linux-source-2.6.24/fs/asfs/bitfuncs.c --- linux-source-2.6.24.orig/fs/asfs/bitfuncs.c 1970-01-01 03:00:00.000000000 +0300 +++ linux-source-2.6.24/fs/asfs/bitfuncs.c 2008-12-14 23:05:05.000000000 +0300 @@ -0,0 +1,171 @@ +/* + * + * 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 <asm/byteorder.h> +#include "bitfuncs.h" + +/* Bitmap (bm) functions: + These functions perform bit-operations on regions of memory which + are a multiple of 4 bytes in length. Bitmap is in bigendian byte order. +*/ + +/* This function finds the first set bit in a region of memory starting + with /bitoffset/. The region of memory is /longs/ longs long. It + returns the bitoffset of the first set bit it finds. */ + +int bmffo(u32 *bitmap, int longs, int bitoffset) +{ + u32 *scan = bitmap; + int longoffset, bit; + + longoffset = bitoffset >> 5; + longs -= longoffset; + scan += longoffset; + + bitoffset = bitoffset & 0x1F; + + if (bitoffset != 0) { + if ((bit = bfffo(be32_to_cpu(*scan), bitoffset)) >= 0) { + return (bit + ((scan - bitmap) << 5)); + } + scan++; + longs--; + } + + while (longs-- > 0) { + if (*scan++ != 0) { + return (bfffo(be32_to_cpu(*--scan), 0) + ((scan - bitmap) << 5)); + } + } + + return (-1); +} + +/* This function finds the first unset bit in a region of memory starting + with /bitoffset/. The region of memory is /longs/ longs long. It + returns the bitoffset of the first unset bit it finds. */ + +int bmffz(u32 *bitmap, int longs, int bitoffset) +{ + u32 *scan = bitmap; + int longoffset, bit; + + longoffset = bitoffset >> 5; + longs -= longoffset; + scan += longoffset; + + bitoffset = bitoffset & 0x1F; + + if (bitoffset != 0) { + if ((bit = bfffz(be32_to_cpu(*scan), bitoffset)) >= 0) { + return (bit + ((scan - bitmap) << 5)); + } + scan++; + longs--; + } + + while (longs-- > 0) { + if (*scan++ != 0xFFFFFFFF) { + return (bfffz(be32_to_cpu(*--scan), 0) + ((scan - bitmap) << 5)); + } + } + + return (-1); +} + +/* This function clears /bits/ bits in a region of memory starting + with /bitoffset/. The region of memory is /longs/ longs long. If + the region of memory is too small to clear /bits/ bits then this + function exits after having cleared all bits till the end of the + memory region. In any case it returns the number of bits which + were actually cleared. */ + +int bmclr(u32 *bitmap, int longs, int bitoffset, int bits) +{ + u32 *scan = bitmap; + int longoffset; + int orgbits = bits; + + longoffset = bitoffset >> 5; + longs -= longoffset; + scan += longoffset; + + bitoffset = bitoffset & 0x1F; + + if (bitoffset != 0) { + if (bits < 32) { + *scan = cpu_to_be32(bfclr(be32_to_cpu(*scan), bitoffset, bits)); + } else { + *scan = cpu_to_be32(bfclr(be32_to_cpu(*scan), bitoffset, 32)); + } + scan++; + longs--; + bits -= 32 - bitoffset; + } + + while (bits > 0 && longs-- > 0) { + if (bits > 31) { + *scan++ = 0; + } else { + *scan = cpu_to_be32(bfclr(be32_to_cpu(*scan), 0, bits)); + } + bits -= 32; + } + + if (bits <= 0) { + return (orgbits); + } + return (orgbits - bits); +} + +/* This function sets /bits/ bits in a region of memory starting + with /bitoffset/. The region of memory is /longs/ longs long. If + the region of memory is too small to set /bits/ bits then this + function exits after having set all bits till the end of the + memory region. In any case it returns the number of bits which + were actually set. */ + +int bmset(u32 *bitmap, int longs, int bitoffset, int bits) +{ + u32 *scan = bitmap; + int longoffset; + int orgbits = bits; + + longoffset = bitoffset >> 5; + longs -= longoffset; + scan += longoffset; + + bitoffset = bitoffset & 0x1F; + + if (bitoffset != 0) { + if (bits < 32) { + *scan = cpu_to_be32(bfset(be32_to_cpu(*scan), bitoffset, bits)); + } else { + *scan = cpu_to_be32(bfset(be32_to_cpu(*scan), bitoffset, 32)); + } + scan++; + longs--; + bits -= 32 - bitoffset; + } + + while (bits > 0 && longs-- > 0) { + if (bits > 31) { + *scan++ = 0xFFFFFFFF; + } else { + *scan = cpu_to_be32(bfset(be32_to_cpu(*scan), 0, bits)); + } + bits -= 32; + } + + if (bits <= 0) { + return (orgbits); + } + return (orgbits - bits); +} -- 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