All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pavel Fedin <sonic.amiga@gmail.com>
To: Phillip Lougher <phillip@lougher.demon.co.uk>
Cc: linux-fsdevel@vger.kernel.org
Subject: [PATCH 2/9] Amiga SmartFileSystem, revision 2
Date: Fri, 13 Feb 2009 09:54:16 +0300	[thread overview]
Message-ID: <1191150250.20090213095416@gmail.com> (raw)
In-Reply-To: <4994506C.1000209@lougher.demon.co.uk>

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);
+}


  parent reply	other threads:[~2009-02-13  6:54 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-09 13:18 Corrupted ASFS patch Pavel Fedin
2009-02-09 13:31 ` maximilian attems
2009-02-12  8:24   ` Re[2]: " Pavel Fedin
2009-02-12  9:42     ` Phillip Lougher
2009-02-12 10:52       ` Re[2]: " Pavel Fedin
2009-02-12 16:38         ` Phillip Lougher
2009-02-13  6:53           ` [PATCH 1/9] Amiga SmartFileSystem, revision 2 Pavel Fedin
2009-02-13  6:54           ` Pavel Fedin [this message]
2009-02-13  6:55           ` [PATCH 3/9] " Pavel Fedin
2009-02-13  6:55           ` [PATCH 4/9] " Pavel Fedin
2009-02-13  6:56           ` [PATCH 5/9] " Pavel Fedin
2009-02-13  6:56           ` [PATCH 6/9] " Pavel Fedin
2009-02-13  6:56           ` [PATCH 7/9] " Pavel Fedin
2009-02-13  6:57           ` [PATCH 8/9] " Pavel Fedin
2009-02-13  6:57           ` [PATCH 9/9] " Pavel Fedin

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=1191150250.20090213095416@gmail.com \
    --to=sonic.amiga@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=phillip@lougher.demon.co.uk \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.