From: Pavel Fedin <sonic.amiga@gmail.com>
To: Phillip Lougher <phillip@lougher.demon.co.uk>
Cc: linux-fsdevel@vger.kernel.org
Subject: [PATCH 3/9] Amiga SmartFileSystem, revision 2
Date: Fri, 13 Feb 2009 09:55:03 +0300 [thread overview]
Message-ID: <1039734863.20090213095503@gmail.com> (raw)
In-Reply-To: <4994506C.1000209@lougher.demon.co.uk>
diff -ruN linux-source-2.6.24.orig/fs/asfs/bitfuncs.h linux-source-2.6.24/fs/asfs/bitfuncs.h
--- linux-source-2.6.24.orig/fs/asfs/bitfuncs.h 1970-01-01 03:00:00.000000000 +0300
+++ linux-source-2.6.24/fs/asfs/bitfuncs.h 2008-12-14 23:42:39.000000000 +0300
@@ -0,0 +1,58 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef __BITFUNCS_H
+#define __BITFUNCS_H
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+#include <linux/bitops.h>
+
+/* Finds first set bit in /data/ starting at /bitoffset/. This function
+ considers the MSB to be the first bit. */
+static inline int bfffo(u32 data, int bitoffset)
+{
+ u32 mask = 0xffffffff >> bitoffset;
+ data &= mask;
+ return data == 0 ? -1 : 32-fls(data);
+}
+
+/* Finds first zero bit in /data/ starting at /bitoffset/. This function
+ considers the MSB to be the first bit. */
+static inline int bfffz(u32 data, int bitoffset)
+{
+ return bfffo(~data, bitoffset);
+}
+
+/* Sets /bits/ bits starting from /bitoffset/ in /data/.
+ /bits/ must be between 1 and 32. */
+static inline u32 bfset(u32 data, int bitoffset, int bits)
+{
+ u32 mask = ~((1 << (32 - bits)) - 1);
+ mask >>= bitoffset;
+ return data | mask;
+}
+
+/* Clears /bits/ bits starting from /bitoffset/ in /data/.
+ /bits/ must be between 1 and 32. */
+static inline u32 bfclr(u32 data, int bitoffset, int bits)
+{
+ u32 mask = ~((1 << (32 - bits)) - 1);
+ mask >>= bitoffset;
+ return data & ~mask;
+}
+
+/* bm??? functions assumes that in-memory bitmap is in bigendian byte order */
+int bmffo(u32 *, int, int);
+int bmffz(u32 *, int, int);
+int bmclr(u32 *, int, int, int);
+int bmset(u32 *, int, int, int);
+
+#endif
diff -ruN linux-source-2.6.24.orig/fs/asfs/Changes linux-source-2.6.24/fs/asfs/Changes
--- linux-source-2.6.24.orig/fs/asfs/Changes 1970-01-01 03:00:00.000000000 +0300
+++ linux-source-2.6.24/fs/asfs/Changes 2008-12-14 23:05:05.000000000 +0300
@@ -0,0 +1,120 @@
+
+Amiga Smart File System, Linux implementation
+
+Please direct bug reports to: marek@amiga.pl
+
+History:
+
+v1.0beta12 (03.12.2006)
+- adapted to 2.6.19 kernel VFS changes
+- fixed symlink write crash
+
+v1.0beta11 (22.09.2006)
+- adapted to 2.6.18 kernel VFS changes
+- made some functions static to reduce overhead in kernel namespace
+
+v1.0beta10 (13.06.2005)
+- fixed ugly bug introduced in beta9 that caused kernel crash on x86
+ (thanks to Emiliano for reporting it!)
+
+v1.0beta9 (17.03.2005)
+- added NLS support (thanks to Pavel Fedin!)
+
+v1.0beta8 (07.01.2005)
+- adapted to 2.6.10 kernel VFS changes
+- added workaround for buggy Mandrake kernel headers
+
+v1.0beta7 (25.06.2004)
+- small changes in documentation
+- code clean up: bitfuncs.c, super.c, inode.c, *.h, Makefile, added
+ asfs_ prefix to function names, made some functions static
+ (big thanks to Christoph Hellwig for advice!)
+- fixed minor bugs (inode leak in super.c, not-realesed buffer during
+ object renaming in inode.c)
+- now files/dirs are created with global ownership/permission bits
+
+v1.0beta6 (04.06.2004)
+- fixed: ASFS_SB(sb)->flags was always zero in 2.6.x code
+
+v1.0beta5 (07.05.2004)
+- finally fixed a problem with file size attrib. not being written
+ to disk
+- fixed some problems with GCC 3.x and debug enabled
+
+v1.0beta4 (12.04.2004)
+- removed dummy asfs_notify_change (this fixes major bug introduced
+ in 1.0beta3 - file size wasn't written to disk) until it will
+ be implemented completely
+
+v1.0beta3 (22.03.2004) - still beta
+- updated for 2.6.x kernels VFS changes
+- code clean-up
+- added dummy asfs_notify_change (chmod now returns no errors)
+- added symlinks write support
+- fixed: ASFS_SB(sb)->flags was always zero
+
+v1.0beta2 (11.01.2004) - special version for Pegasos][ kernel
+- separated read and write functions, can be compiled also
+ as read-only fs
+
+v1.0beta1 (02.12.2003) - first public beta with write support
+- added dentry hashing/comparing routines
+- code clean-up
+
+v1.0aplha4 (30.11.2003) - preparing for first public beta
+- fixed some problems with renaming/moving files
+- fixed two major bugs, which didn't occur when fs was mounted
+ on loopback device (newly allocated blocks were not written to
+ disk and state bits were not set correctly on newly mapped file
+ blocks)
+- fixed many small bugs in io code (some buffers were not freed)
+- added/modified sb locks in asfs_lookup and asfs_getblock
+- fixed serious bug in file block allocation routines
+
+v1.0aplha3 (23.11.2003)
+- added (hopefully) all byteswap code, should now work again on
+ little-endian systems (also with write support!)
+- updated documentation
+
+v1.0alpha2 (13.11.2003)
+- now alocates file blocks in chunks during one request
+- fixed some dead-locks, other fixes
+
+v1.0alpha (02.11.2003) - first working version with full write support
+- too much to list it here ;)
+
+... (working on write support)
+
+v0.7 (12.10.2003) - internal realase
+- added asfs_breadcheck, modified asfs_get_node, asfs_search_BTree,
+ no more from_be32/16 macros, other...
+- code splitted into several files
+
+v0.6 (04.09.2003) - final read-only version
+- added support for HashTables, directory scaning should be
+ MUCH faster now
+- added checking of block IDs before reading any data from block
+
+v0.5 (19.07.2003)
+- added simple but effective extent cache - real speed-up
+ in reading large files
+- added read support for symlinks - based on AFFS symlinks
+
+v0.4 (10.07.2003)
+- third code clean-up (thanks to Roman Zippel for advice)
+- now uses generic readpage and readinode routines
+
+v0.3beta (17.06.2003)
+- second code clean-up
+
+v0.2beta2 (15.06.2003)
+- fixed yet another stupid bug - driver can't read root block on little-endian systems
+v0.2beta (15.06.2003)
+- fixed stupid bug - now files have 'file' flag (S_IFREG) set...
+- added mount options to set uid, gid and mode of files and dirs
+- made hidden files & dirs really hidden (= not listed in directories)
+- code clean-up
+
+v0.1beta (11.06.2003)
+- after many kernel crashes, finally got it!
+- first working read-only filesystem driver
diff -ruN linux-source-2.6.24.orig/fs/asfs/dir.c linux-source-2.6.24/fs/asfs/dir.c
--- linux-source-2.6.24.orig/fs/asfs/dir.c 1970-01-01 03:00:00.000000000 +0300
+++ linux-source-2.6.24/fs/asfs/dir.c 2008-12-14 23:05:05.000000000 +0300
@@ -0,0 +1,240 @@
+/*
+ *
+ * Amiga Smart File System, Linux implementation
+ * version: 1.0beta7
+ *
+ * Copyright (C) 2003,2004 Marek 'March' Szyprowski <marek@amiga.pl>
+ *
+ *
+ * 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 "asfs_fs.h"
+
+#include <asm/byteorder.h>
+
+extern struct dentry_operations asfs_dentry_operations;
+
+int asfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+ struct inode *dir = filp->f_path.dentry->d_inode;
+ struct super_block *sb = dir->i_sb;
+ struct nls_table *nls_io = ASFS_SB(sb)->nls_io;
+ struct nls_table *nls_disk = ASFS_SB(sb)->nls_disk;
+ u8 buf[512];
+ unsigned long f_pos;
+ int stored = 0;
+
+ struct buffer_head *bh;
+ struct fsObjectContainer *objcont;
+ struct fsObject *obj;
+ u32 block;
+ int startnode;
+ int add;
+
+ asfs_debug("asfs_readdir:\n");
+
+ if (filp->f_pos == ASFS_SB(sb)->totalblocks)
+ return stored;
+
+ f_pos = filp->f_pos;
+
+ if (f_pos == 0) {
+ filp->private_data = (void *)0;
+ if (filldir(dirent, ".", 1, f_pos, dir->i_ino, DT_DIR) < 0)
+ return 0;
+ filp->f_pos = f_pos = 1;
+ stored++;
+ }
+ if (f_pos == 1) {
+ if (filldir(dirent, "..", 2, f_pos, parent_ino(filp->f_path.dentry), DT_DIR) < 0)
+ return stored;
+ filp->f_pos = f_pos = 2;
+ stored++;
+ }
+
+ if (ASFS_I(dir)->firstblock == 0) { /* empty directory */
+ filp->f_pos = ASFS_SB(sb)->totalblocks;
+ ASFS_I(dir)->modified = 0;
+ return stored;
+ }
+
+ if (f_pos == 2) { /* reading directory from its beginning */
+ block = ASFS_I(dir)->firstblock;
+ add = 1;
+ startnode = 0;
+ } else {
+ startnode = (int)filp->private_data;
+ add = 0;
+ if (ASFS_I(dir)->modified == 0)
+ block = f_pos;
+ else
+ block = ASFS_I(dir)->firstblock;
+ }
+
+ do {
+ if (!(bh = asfs_breadcheck(sb, block, ASFS_OBJECTCONTAINER_ID)))
+ return stored;
+ objcont = (struct fsObjectContainer *) bh->b_data;
+ obj = &(objcont->object[0]);
+
+ while (be32_to_cpu(obj->objectnode) > 0 &&
+ ((char *)obj - (char *)objcont) + sizeof(struct fsObject) + 2 < sb->s_blocksize) {
+
+ if (!add && be32_to_cpu(obj->objectnode) == startnode)
+ add++;
+
+ if (add && !(obj->bits & OTYPE_HIDDEN)) {
+ unsigned int type;
+ asfs_translate(buf, obj->name, nls_io, nls_disk, 512);
+ asfs_debug("ASFS: DirFilling: entry #%d \"%s\" (node %u offset %u), type %x\n", \
+ stored, buf, be32_to_cpu(obj->objectnode), block, obj->bits);
+ filp->f_pos = block;
+
+ if (obj->bits & OTYPE_DIR)
+ type = DT_DIR;
+ else if (obj->bits & OTYPE_LINK && !(obj->bits & OTYPE_HARDLINK))
+ type = DT_LNK;
+ else
+ type = DT_REG;
+
+ if (filldir(dirent, buf, strlen(buf), block, be32_to_cpu(obj->objectnode), type) < 0) {
+ filp->private_data = (void *)be32_to_cpu(obj->objectnode);
+ ASFS_I(dir)->modified = 0;
+ asfs_debug("ASFS: DirFilling: to be continued...\n");
+ asfs_brelse(bh);
+ return stored;
+ }
+ stored++;
+ }
+ obj = asfs_nextobject(obj);
+ }
+ block = be32_to_cpu(objcont->next);
+ asfs_brelse(bh);
+
+ } while (block != 0);
+
+ filp->f_pos = ASFS_SB(sb)->totalblocks;
+ ASFS_I(dir)->modified = 0;
+
+ return stored;
+}
+
+static struct fsObject *asfs_find_obj_by_name_nls(struct super_block *sb, struct fsObjectContainer *objcont, u8 * name)
+{
+ struct fsObject *obj;
+ u8 buf[512];
+
+ obj = &(objcont->object[0]);
+ while (be32_to_cpu(obj->objectnode) > 0 && ((char *) obj - (char *) objcont) + sizeof(struct fsObject) + 2 < sb->s_blocksize) {
+ asfs_translate(buf, obj->name, ASFS_SB(sb)->nls_io, ASFS_SB(sb)->nls_disk, 512);
+ if (asfs_namecmp(buf, name, ASFS_SB(sb)->flags & ASFS_ROOTBITS_CASESENSITIVE, ASFS_SB(sb)->nls_io) == 0) {
+ asfs_debug("Object found! Node %u, Name %s, Type %x, inCont %u\n", be32_to_cpu(obj->objectnode), obj->name, obj->bits, be32_to_cpu(objcont->bheader.ownblock));
+ return obj;
+ }
+ obj = asfs_nextobject(obj);
+ }
+ return NULL;
+}
+
+struct dentry *asfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+{
+ int res = -EACCES; /* placeholder for "no data here" */
+ struct inode *inode;
+ struct super_block *sb = dir->i_sb;
+ u8 *name = (u8 *) dentry->d_name.name;
+ struct buffer_head *bh;
+ struct fsObject *obj;
+ u8 bufname[ASFS_MAXFN_BUF];
+
+ asfs_translate(bufname, name, ASFS_SB(sb)->nls_disk, ASFS_SB(sb)->nls_io, ASFS_MAXFN_BUF);
+
+ asfs_debug("asfs_lookup: (searching \"%s\"...) ", name);
+
+ lock_super(sb);
+
+ if ((!strchr(name, '?')) && (ASFS_I(dir)->hashtable != 0)) { /* hashtable block is available and name can be reverse translated, quick search */
+ struct fsObjectNode *node_p;
+ struct buffer_head *node_bh;
+ u32 node;
+ u16 hash16;
+
+ asfs_debug("(quick search) ");
+
+ if (!(bh = asfs_breadcheck(sb, ASFS_I(dir)->hashtable, ASFS_HASHTABLE_ID))) {
+ unlock_super(sb);
+ return ERR_PTR(res);
+ }
+ hash16 = asfs_hash(bufname, ASFS_SB(sb)->flags & ASFS_ROOTBITS_CASESENSITIVE);
+ node = be32_to_cpu(((struct fsHashTable *) bh->b_data)->hashentry[HASHCHAIN(hash16)]);
+ asfs_brelse(bh);
+
+ while (node != 0) {
+ if (asfs_getnode(sb, node, &node_bh, &node_p) != 0)
+ goto not_found;
+ if (be16_to_cpu(node_p->hash16) == hash16) {
+ if (!(bh = asfs_breadcheck(sb, be32_to_cpu(node_p->node.data), ASFS_OBJECTCONTAINER_ID))) {
+ asfs_brelse(node_bh);
+ unlock_super(sb);
+ return ERR_PTR(res);
+ }
+ if ((obj = asfs_find_obj_by_name(sb, (struct fsObjectContainer *) bh->b_data, bufname)) != NULL) {
+ asfs_brelse(node_bh);
+ goto found_inode;
+ }
+ asfs_brelse(bh);
+ }
+ node = be32_to_cpu(node_p->next);
+ asfs_brelse(node_bh);
+ }
+ } else { /* hashtable not available or name can't be reverse-translated, long search */
+ struct fsObjectContainer *objcont;
+ u32 block;
+
+ asfs_debug("(long search) ");
+ block = ASFS_I(dir)->firstblock;
+ while (block != 0) {
+ if (!(bh = asfs_breadcheck(sb, block, ASFS_OBJECTCONTAINER_ID))) {
+ unlock_super(sb);
+ return ERR_PTR(res);
+ }
+ objcont = (struct fsObjectContainer *) bh->b_data;
+ if ((obj = asfs_find_obj_by_name_nls(sb, objcont, name)) != NULL)
+ goto found_inode;
+ block = be32_to_cpu(objcont->next);
+ asfs_brelse(bh);
+ }
+ }
+
+not_found:
+ unlock_super(sb);
+ inode = NULL;
+ asfs_debug("object not found.\n");
+ if (0) {
+found_inode:
+ unlock_super(sb);
+ if (!(inode = iget_locked(sb, be32_to_cpu(obj->objectnode)))) {
+ asfs_debug("ASFS: Strange - no inode allocated.\n");
+ return ERR_PTR(res);
+ }
+ if (inode->i_state & I_NEW) {
+ asfs_read_locked_inode(inode, obj);
+ unlock_new_inode(inode);
+ }
+ asfs_brelse(bh);
+ }
+ res = 0;
+ dentry->d_op = &asfs_dentry_operations;
+ d_add(dentry, inode);
+ return ERR_PTR(res);
+}
next prev parent reply other threads:[~2009-02-13 6:55 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 ` [PATCH 2/9] " Pavel Fedin
2009-02-13 6:55 ` Pavel Fedin [this message]
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=1039734863.20090213095503@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.