From: Pavel Fedin <sonic.amiga@gmail.com>
To: Phillip Lougher <phillip@lougher.demon.co.uk>
Cc: linux-fsdevel@vger.kernel.org
Subject: [PATCH 6/9] Amiga SmartFileSystem, revision 2
Date: Fri, 13 Feb 2009 09:56:31 +0300 [thread overview]
Message-ID: <1605486592.20090213095631@gmail.com> (raw)
In-Reply-To: <4994506C.1000209@lougher.demon.co.uk>
diff -ruN linux-source-2.6.24.orig/fs/asfs/Makefile linux-source-2.6.24/fs/asfs/Makefile
--- linux-source-2.6.24.orig/fs/asfs/Makefile 1970-01-01 03:00:00.000000000 +0300
+++ linux-source-2.6.24/fs/asfs/Makefile 2008-12-14 23:05:05.000000000 +0300
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux asfs filesystem routines.
+#
+
+obj-$(CONFIG_ASFS_FS) += asfs.o
+
+asfs-y += dir.o extents.o file.o inode.o namei.o nodes.o objects.o super.o symlink.o
+asfs-$(CONFIG_ASFS_RW) += adminspace.o bitfuncs.o
diff -ruN linux-source-2.6.24.orig/fs/asfs/namei.c linux-source-2.6.24/fs/asfs/namei.c
--- linux-source-2.6.24.orig/fs/asfs/namei.c 1970-01-01 03:00:00.000000000 +0300
+++ linux-source-2.6.24/fs/asfs/namei.c 2008-12-14 23:05:05.000000000 +0300
@@ -0,0 +1,197 @@
+/*
+ *
+ * Amiga Smart File System, Linux implementation
+ * version: 1.0beta10
+ *
+ * Copyright (C) 2003,2004,2005 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/string.h>
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/vfs.h>
+#include <linux/string.h>
+#include <linux/nls.h>
+#include "asfs_fs.h"
+
+static inline u8 asfs_upperchar(u8 c)
+{
+ if ((c >= 224 && c <= 254 && c != 247) || (c >= 'a' && c <= 'z'))
+ c -= 32;
+ return (c);
+}
+
+u8 asfs_lowerchar(u8 c)
+{
+ if ((c >= 192 && c <= 222 && c != 215) || (c >= 'A' && c <= 'Z'))
+ c += 32;
+ return (c);
+}
+
+static inline u8 asfs_nls_upperchar(u8 c, struct nls_table *t)
+{
+ if (t) {
+ u8 nc = t->charset2upper[c];
+ return nc ? nc : c;
+ } else
+ return asfs_upperchar(c);
+}
+
+/* Check if the name is valid for a asfs object. */
+
+inline int asfs_check_name(const u8 *name, int len)
+{
+ int i;
+
+ if (len > ASFS_MAXFN)
+ return -ENAMETOOLONG;
+
+ for (i = 0; i < len; i++)
+ if (name[i] < ' ' || name[i] == ':' || (name[i] > 0x7e && name[i] < 0xa0))
+ return -EINVAL;
+
+ return 0;
+}
+
+/* Note: the dentry argument is the parent dentry. */
+
+static int asfs_hash_dentry(struct dentry *dentry, struct qstr *qstr)
+{
+ struct super_block *sb = dentry->d_inode->i_sb;
+ const u8 *name = qstr->name;
+ unsigned long hash;
+ int i;
+ struct nls_table *nls_io = ASFS_SB(sb)->nls_io;
+
+ i = asfs_check_name(qstr->name,qstr->len);
+ if (i)
+ return i;
+
+ hash = init_name_hash();
+
+ if (ASFS_SB(sb)->flags & ASFS_ROOTBITS_CASESENSITIVE)
+ for (i=qstr->len; i > 0; name++, i--)
+ hash = partial_name_hash(*name, hash);
+ else
+ for (i=qstr->len; i > 0; name++, i--)
+ hash = partial_name_hash(asfs_nls_upperchar(*name, nls_io), hash);
+
+ qstr->hash = end_name_hash(hash);
+
+ return 0;
+}
+
+static int asfs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
+{
+ struct super_block *sb = dentry->d_inode->i_sb;
+ const u8 *aname = a->name;
+ const u8 *bname = b->name;
+ int len;
+ struct nls_table *nls_io = ASFS_SB(sb)->nls_io;
+
+ /* 'a' is the qstr of an already existing dentry, so the name
+ * must be valid. 'b' must be validated first.
+ */
+
+ if (asfs_check_name(b->name,b->len))
+ return 1;
+
+ if (a->len != b->len)
+ return 1;
+
+ if (ASFS_SB(sb)->flags & ASFS_ROOTBITS_CASESENSITIVE) {
+ for (len=a->len; len > 0; len--)
+ if (*aname++ != *bname++)
+ return 1;
+ } else {
+ for (len=a->len; len > 0; len--)
+ if (asfs_nls_upperchar(*aname++, nls_io) != asfs_nls_upperchar(*bname++, nls_io))
+ return 1;
+ }
+
+ return 0;
+}
+
+struct dentry_operations asfs_dentry_operations = {
+ d_hash: asfs_hash_dentry,
+ d_compare: asfs_compare_dentry,
+};
+
+int asfs_namecmp(u8 *s, u8 *ct, int casesensitive, struct nls_table *t)
+{
+ if (casesensitive) {
+ while (*s == *ct && *ct != '\0' && *ct != '/') {
+ s++;
+ ct++;
+ }
+ } else {
+ while (asfs_nls_upperchar(*s, t) == asfs_nls_upperchar(*ct, t) && *ct != '\0'
+ && *ct != '/') {
+ s++;
+ ct++;
+ }
+ }
+ return (*s == '\0' && (*ct == '\0' || *ct == '/')) ? 0 : *ct - *s;
+}
+
+u16 asfs_hash(u8 *name, int casesensitive)
+{
+ u16 hashval = 0;
+ while (name[hashval] != 0 && name[hashval] != '/')
+ hashval++;
+ if (casesensitive) {
+ u8 c = *name;
+ while (c != 0 && c != '/') {
+ hashval = hashval * 13 + c;
+ c = *++name;
+ }
+ } else {
+ u8 c = *name;
+ while (c != 0 && c != '/') {
+ hashval = hashval * 13 + asfs_upperchar(c);
+ c = *++name;
+ }
+ }
+ return hashval;
+}
+
+void asfs_translate(u8 *to, u8 *from, struct nls_table *nls_to, struct nls_table *nls_from, int limit)
+{
+ wchar_t uni;
+ int i, len;
+ int from_len, to_len = limit;
+
+ if (nls_to) {
+ from_len = strlen(from);
+ for (i=0; i < from_len && to_len > 1; ) {
+ len = nls_from->char2uni(&from[i], from_len-i, &uni);
+ if (len > 0) {
+ i += len;
+ len = nls_to->uni2char(uni, to, to_len);
+ if (len > 0) {
+ to += len;
+ to_len -= len;
+ }
+ } else
+ i++;
+ if (len < 0) {
+ *to++ = '?';
+ to_len--;
+ }
+ }
+ *to = '\0';
+ } else {
+ strncpy (to, from, limit);
+ to[limit-1] = '\0';
+ }
+}
diff -ruN linux-source-2.6.24.orig/fs/asfs/nodes.c linux-source-2.6.24/fs/asfs/nodes.c
--- linux-source-2.6.24.orig/fs/asfs/nodes.c 1970-01-01 03:00:00.000000000 +0300
+++ linux-source-2.6.24/fs/asfs/nodes.c 2008-12-14 23:05:05.000000000 +0300
@@ -0,0 +1,455 @@
+/*
+ *
+ * Amiga Smart File System, Linux implementation
+ * version: 1.0beta7
+ *
+ * This file contains some parts of the original amiga version of
+ * SmartFilesystem source code.
+ *
+ * SmartFilesystem is copyrighted (C) 2003 by: John Hendrikx,
+ * Ralph Schmidt, Emmanuel Lesueur, David Gerber and Marcin Kurek
+ *
+ * Adapted and modified by Marek 'March' Szyprowski <marek@amiga.pl>
+ *
+ */
+
+#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>
+
+/* Finds a specific node by number. */
+int asfs_getnode(struct super_block *sb, u32 nodeno, struct buffer_head **ret_bh, struct fsObjectNode **ret_node)
+{
+ struct buffer_head *bh;
+ struct fsNodeContainer *nodecont;
+ u32 nodeindex = ASFS_SB(sb)->objectnoderoot;
+
+ while ((bh = asfs_breadcheck(sb, nodeindex, ASFS_NODECONTAINER_ID))) {
+ nodecont = (struct fsNodeContainer *) bh->b_data;
+
+ if (be32_to_cpu(nodecont->nodes) == 1) {
+ *ret_node = (struct fsObjectNode *) ((u8 *) nodecont->node + NODE_STRUCT_SIZE * (nodeno - be32_to_cpu(nodecont->nodenumber)));
+ *ret_bh = bh;
+ return 0;
+ } else {
+ u16 containerentry = (nodeno - be32_to_cpu(nodecont->nodenumber)) / be32_to_cpu(nodecont->nodes);
+ nodeindex = be32_to_cpu(nodecont->node[containerentry]) >> (sb->s_blocksize_bits - ASFS_BLCKFACCURACY);
+ }
+ asfs_brelse(bh);
+ }
+ if (bh == NULL)
+ return -EIO;
+ return -ENOENT;
+}
+
+#ifdef CONFIG_ASFS_RW
+
+ /* Looks for the parent of the passed-in buffer_head (fsNodeContainer)
+ starting from the root. It returns an error if any error occured.
+ If error is 0 and io_bh is NULL as well, then there was no parent (ie,
+ you asked parent of the root). Otherwise io_bh should contain the
+ parent of the passed-in NodeContainer. */
+
+static int parentnodecontainer(struct super_block *sb, struct buffer_head **io_bh)
+{
+ u32 noderoot = ASFS_SB(sb)->objectnoderoot;
+ u32 childblock = be32_to_cpu(((struct fsBlockHeader *) (*io_bh)->b_data)->ownblock);
+ u32 nodenumber = be32_to_cpu(((struct fsNodeContainer *) (*io_bh)->b_data)->nodenumber);
+ int errorcode = 0;
+
+ if (noderoot == childblock) {
+ *io_bh = NULL;
+ return 0;
+ }
+
+ while ((*io_bh = asfs_breadcheck(sb, noderoot, ASFS_NODECONTAINER_ID))) {
+ struct fsNodeContainer *nc = (void *) (*io_bh)->b_data;
+
+ if (be32_to_cpu(nc->nodes) == 1) {
+ /* We've descended the tree to a leaf NodeContainer, something
+ which should never happen if the passed-in io_bh had
+ contained a valid fsNodeContainer. */
+ printk("ASFS: Failed to locate the parent NodeContainer - node tree is corrupted!\n");
+ *io_bh = NULL;
+ return -EIO;
+ } else {
+ u16 containerentry = (nodenumber - be32_to_cpu(nc->nodenumber)) / be32_to_cpu(nc->nodes);
+ noderoot = be32_to_cpu(nc->node[containerentry]) >> (sb->s_blocksize_bits - ASFS_BLCKFACCURACY);
+ }
+
+ if (noderoot == childblock)
+ break;
+
+ asfs_brelse(*io_bh);
+ }
+
+ if (*io_bh == NULL)
+ return -EIO;
+
+ return errorcode;
+}
+
+
+static int isfull(struct super_block *sb, struct fsNodeContainer *nc)
+{
+ u32 *p = nc->node;
+ s16 n = NODECONT_BLOCK_COUNT;
+
+ while (--n >= 0) {
+ if (*p == 0 || (be32_to_cpu(*p) & 0x00000001) == 0) {
+ break;
+ }
+ p++;
+ }
+
+ return n < 0;
+}
+
+static int markparentfull(struct super_block *sb, struct buffer_head *bh)
+{
+ u32 nodenumber = be32_to_cpu(((struct fsNodeContainer *) (bh->b_data))->nodenumber);
+ int errorcode;
+
+ if ((errorcode = parentnodecontainer(sb, &bh)) == 0 && bh != 0) {
+ struct fsNodeContainer *nc = (void *) bh->b_data;
+ u16 containerentry = (nodenumber - be32_to_cpu(nc->nodenumber)) / be32_to_cpu(nc->nodes);
+
+ nc->node[containerentry] = cpu_to_be32(be32_to_cpu(nc->node[containerentry]) | 0x00000001);
+
+ asfs_bstore(sb, bh);
+
+ if (isfull(sb, nc)) { /* This container now is full as well! Mark the next higher up container too then! */
+ return markparentfull(sb, bh);
+ }
+ asfs_brelse(bh);
+ }
+
+ return errorcode;
+}
+
+static int addnewnodelevel(struct super_block *sb, u16 nodesize)
+{
+ struct buffer_head *bh;
+ u32 noderoot = ASFS_SB(sb)->objectnoderoot;
+ int errorcode;
+
+ /* Adds a new level to the Node tree. */
+
+ asfs_debug("addnewnodelevel: Entry\n");
+
+ if ((bh = asfs_breadcheck(sb, noderoot, ASFS_NODECONTAINER_ID))) {
+ struct buffer_head *newbh;
+ u32 newblock;
+
+ if ((errorcode = asfs_allocadminspace(sb, &newblock)) == 0 && (newbh = asfs_getzeroblk(sb, newblock))) {
+ struct fsNodeContainer *nc = (void *) bh->b_data;
+ struct fsNodeContainer *newnc = (void *) newbh->b_data;
+
+ /* The newly allocated block will become a copy of the current root. */
+
+ newnc->bheader.id = cpu_to_be32(ASFS_NODECONTAINER_ID);
+ newnc->bheader.ownblock = cpu_to_be32(newblock);
+ newnc->nodenumber = nc->nodenumber;
+ newnc->nodes = nc->nodes;
+ memcpy(newnc->node, nc->node, sb->s_blocksize - sizeof(struct fsNodeContainer));
+
+ asfs_bstore(sb, newbh);
+ asfs_brelse(newbh);
+
+ /* The current root will now be transformed into a new root. */
+
+ if (be32_to_cpu(nc->nodes) == 1)
+ nc->nodes = cpu_to_be32((sb->s_blocksize - sizeof(struct fsNodeContainer)) / nodesize);
+ else
+ nc->nodes = cpu_to_be32(be32_to_cpu(nc->nodes) * NODECONT_BLOCK_COUNT);
+
+ nc->node[0] = cpu_to_be32((newblock << (sb->s_blocksize_bits - ASFS_BLCKFACCURACY)) + 1); /* Tree is full from that point! */
+ memset(&nc->node[1], 0, sb->s_blocksize - sizeof(struct fsNodeContainer) - 4);
+
+ asfs_bstore(sb, bh);
+ }
+ asfs_brelse(bh);
+ } else
+ errorcode = -EIO;
+
+ return errorcode;
+}
+
+static int createnodecontainer(struct super_block *sb, u32 nodenumber, u32 nodes, u32 * returned_block)
+{
+ struct buffer_head *bh;
+ int errorcode;
+ u32 newblock;
+
+ asfs_debug("createnodecontainer: nodenumber = %u, nodes = %u\n", nodenumber, nodes);
+
+ if ((errorcode = asfs_allocadminspace(sb, &newblock)) == 0 && (bh = asfs_getzeroblk(sb, newblock))) {
+ struct fsNodeContainer *nc = (void *) bh->b_data;
+
+ nc->bheader.id = cpu_to_be32(ASFS_NODECONTAINER_ID);
+ nc->bheader.ownblock = cpu_to_be32(newblock);
+
+ nc->nodenumber = cpu_to_be32(nodenumber);
+ nc->nodes = cpu_to_be32(nodes);
+
+ asfs_bstore(sb, bh);
+ asfs_brelse(bh);
+ *returned_block = newblock;
+ }
+
+ return errorcode;
+}
+
+ /* This function creates a new fsNode structure in a fsNodeContainer. If needed
+ it will create a new fsNodeContainers and a new fsNodeIndexContainer. */
+
+int asfs_createnode(struct super_block *sb, struct buffer_head **returned_bh, struct fsNode **returned_node, u32 * returned_nodeno)
+{
+ u16 nodecount = (sb->s_blocksize - sizeof(struct fsNodeContainer)) / NODE_STRUCT_SIZE;
+ u32 noderoot = ASFS_SB(sb)->objectnoderoot;
+ u32 nodeindex = noderoot;
+ int errorcode = 0;
+
+ while ((*returned_bh = asfs_breadcheck(sb, nodeindex, ASFS_NODECONTAINER_ID))) {
+ struct fsNodeContainer *nc = (void *) (*returned_bh)->b_data;
+
+ if (be32_to_cpu(nc->nodes) == 1) { /* Is it a leaf-container? */
+ struct fsNode *n;
+ s16 i = nodecount;
+
+ n = (struct fsNode *) nc->node;
+
+ while (i-- > 0) {
+ if (n->data == 0)
+ break;
+
+ n = (struct fsNode *) ((u8 *) n + NODE_STRUCT_SIZE);
+ }
+
+ if (i >= 0) {
+ /* Found an empty fsNode structure! */
+ *returned_node = n;
+ *returned_nodeno = be32_to_cpu(nc->nodenumber) + ((u8 *) n - (u8 *) nc->node) / NODE_STRUCT_SIZE;
+
+ asfs_debug("createnode: Created Node %d\n", *returned_nodeno);
+
+ /* Below we continue to look through the NodeContainer block. We skip the entry
+ we found to be unused, and see if there are any more unused entries. If we
+ do not find any more unused entries then this container is now full. */
+
+ n = (struct fsNode *) ((u8 *) n + NODE_STRUCT_SIZE);
+
+ while (i-- > 0) {
+ if (n->data == 0)
+ break;
+
+ n = (struct fsNode *) ((u8 *) n + NODE_STRUCT_SIZE);
+ }
+
+ if (i < 0) {
+ /* No more empty fsNode structures in this block. Mark parent full. */
+ errorcode = markparentfull(sb, *returned_bh);
+ }
+
+ return errorcode;
+ } else {
+ /* What happened now is that we found a leaf-container which was
+ completely filled. In practice this should only happen when there
+ is only a single NodeContainer (only this container), or when there
+ was an error in one of the full-bits in a higher level container. */
+
+ if (noderoot != nodeindex) {
+ /*** Hmmm... it looks like there was a damaged full-bit or something.
+ In this case we'd probably better call markcontainerfull. */
+
+ printk("ASFS: Couldn't find empty Node in NodeContainer while NodeIndexContainer indicated there should be one!\n");
+
+ errorcode = -ENOSPC;
+ break;
+ } else {
+ /* Container is completely filled. */
+
+ if ((errorcode = addnewnodelevel(sb, NODE_STRUCT_SIZE)) != 0)
+ return errorcode;
+
+ nodeindex = noderoot;
+ }
+ }
+ } else { /* This isn't a leaf container */
+ u32 *p = nc->node;
+ s16 i = NODECONT_BLOCK_COUNT;
+
+ /* We've read a normal container */
+
+ while (i-- > 0) {
+ if (*p != 0 && (be32_to_cpu(*p) & 0x00000001) == 0)
+ break;
+
+ p++;
+ }
+
+ if (i >= 0) {
+ /* Found a not completely filled Container */
+
+ nodeindex = be32_to_cpu(*p) >> (sb->s_blocksize_bits - ASFS_BLCKFACCURACY);
+ } else {
+ /* Everything in the NodeIndexContainer was completely filled. There possibly
+ are some unused pointers in this block however. */
+
+ asfs_debug("createnode: NodeContainer at block has no empty Nodes.\n");
+
+ p = nc->node;
+ i = NODECONT_BLOCK_COUNT;
+
+ while (i-- > 0) {
+ if (*p == 0)
+ break;
+
+ p++;
+ }
+
+ if (i >= 0) {
+ u32 newblock;
+ u32 nodes;
+
+ /* Found an unused Container pointer */
+
+ if (be32_to_cpu(nc->nodes) == (sb->s_blocksize - sizeof(struct fsNodeContainer)) / NODE_STRUCT_SIZE) {
+ nodes = 1;
+ } else {
+ nodes = be32_to_cpu(nc->nodes) / NODECONT_BLOCK_COUNT;
+ }
+
+ if ((errorcode = createnodecontainer(sb, be32_to_cpu(nc->nodenumber) + (p - nc->node) * be32_to_cpu(nc->nodes), nodes, &newblock)) != 0) {
+ break;
+ }
+
+ *p = cpu_to_be32(newblock << (sb->s_blocksize_bits - ASFS_BLCKFACCURACY));
+
+ asfs_bstore(sb, *returned_bh);
+ } else {
+ /* Container is completely filled. This must be the top-level NodeIndex container
+ as otherwise the full-bit would have been wrong! */
+
+ if ((errorcode = addnewnodelevel(sb, NODE_STRUCT_SIZE)) != 0)
+ break;
+
+ nodeindex = noderoot;
+ }
+ }
+ }
+ asfs_brelse(*returned_bh);
+ }
+
+ if (*returned_bh == NULL)
+ return -EIO;
+
+ return (errorcode);
+}
+
+static int markparentempty(struct super_block *sb, struct buffer_head *bh)
+{
+ u32 nodenumber = be32_to_cpu(((struct fsNodeContainer *) bh->b_data)->nodenumber);
+ int errorcode;
+
+ if ((errorcode = parentnodecontainer(sb, &bh)) == 0 && bh != 0) {
+ struct fsNodeContainer *nc = (void *) bh->b_data;
+ int wasfull;
+ u16 containerentry = (nodenumber - be32_to_cpu(nc->nodenumber)) / be32_to_cpu(nc->nodes);
+
+ wasfull = isfull(sb, nc);
+
+ nc->node[containerentry] = cpu_to_be32(be32_to_cpu(nc->node[containerentry]) & ~0x00000001);
+
+ asfs_bstore(sb, bh);
+
+ if (wasfull) {
+ /* This container was completely full before! Mark the next higher up container too then! */
+ return markparentempty(sb, bh);
+ }
+ asfs_brelse(bh);
+ }
+
+ return errorcode;
+}
+
+static int freecontainer(struct super_block *sb, struct buffer_head *bh)
+{
+ u32 nodenumber = be32_to_cpu(((struct fsNodeContainer *) bh->b_data)->nodenumber);
+ int errorcode;
+
+ if ((errorcode = parentnodecontainer(sb, &bh)) == 0 && bh != NULL) { /* This line also prevents the freeing of the noderoot. */
+ struct fsNodeContainer *nc = (void *) bh->b_data;
+ u16 containerindex = (nodenumber - be32_to_cpu(nc->nodenumber)) / be32_to_cpu(nc->nodes);
+
+ if ((errorcode = asfs_freeadminspace(sb, be32_to_cpu(nc->node[containerindex]) >> (sb->s_blocksize_bits - ASFS_BLCKFACCURACY))) == 0) {
+ u32 *p = nc->node;
+ s16 n = NODECONT_BLOCK_COUNT;
+
+ nc->node[containerindex] = 0;
+ asfs_bstore(sb, bh);
+
+ while (n-- > 0)
+ if (*p++ != 0)
+ break;
+
+ if (n < 0) { /* This container is now completely empty! Free this NodeIndexContainer too then! */
+ return freecontainer(sb, bh);
+ }
+ }
+ asfs_brelse(bh);
+ }
+
+ return errorcode;
+}
+
+static int internaldeletenode(struct super_block *sb, struct buffer_head *bh, struct fsNode *n)
+{
+ struct fsNodeContainer *nc = (void *) bh->b_data;
+ u16 nodecount = (sb->s_blocksize - sizeof(struct fsNodeContainer)) / NODE_STRUCT_SIZE;
+ s16 i = nodecount;
+ s16 empty = 0;
+ int errorcode = 0;
+
+ n->data = 0;
+ n = (struct fsNode *) nc->node;
+
+ while (i-- > 0) {
+ if (n->data == 0)
+ empty++;
+
+ n = (struct fsNode *) ((u8 *) n + NODE_STRUCT_SIZE);
+ }
+
+ asfs_bstore(sb, bh);
+
+ if (empty == 1) /* NodeContainer was completely full before, so we need to mark it empty now. */
+ errorcode = markparentempty(sb, bh);
+ else if (empty == nodecount) /* NodeContainer is now completely empty! Free it! */
+ errorcode = freecontainer(sb, bh);
+
+ return (errorcode);
+}
+
+int asfs_deletenode(struct super_block *sb, u32 objectnode)
+{
+ struct buffer_head *bh;
+ struct fsObjectNode *on;
+ int errorcode;
+
+ asfs_debug("deletenode: Deleting Node %d\n", objectnode);
+
+ if ((errorcode = asfs_getnode(sb, objectnode, &bh, &on)) == 0)
+ errorcode = internaldeletenode(sb, bh, (struct fsNode *) on);
+
+ asfs_brelse(bh);
+ return (errorcode);
+}
+
+#endif
next prev parent reply other threads:[~2009-02-13 6:56 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 ` [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 ` Pavel Fedin [this message]
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=1605486592.20090213095631@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.