[PATCH 5/9] Amiga SmartFileSystem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



diff -ruN linux-source-2.6.24.orig/fs/asfs/file.c linux-source-2.6.24/fs/asfs/file.c
--- linux-source-2.6.24.orig/fs/asfs/file.c     1970-01-01 03:00:00.000000000 +0300
+++ linux-source-2.6.24/fs/asfs/file.c  2008-12-14 23:33:00.000000000 +0300
@@ -0,0 +1,255 @@
+/*
+ *
+ * Amiga Smart File System, Linux implementation
+ * version: 1.0beta7
+ *  
+ * Copyright (C) 2003,2004  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/pagemap.h>
+#include <linux/buffer_head.h>
+#include <linux/vfs.h>
+#include "asfs_fs.h"
+
+#include <asm/byteorder.h>
+
+static int
+asfs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create)
+{
+       struct buffer_head *ebn_bh;
+       struct fsExtentBNode extent, *ebn_p;
+       u32 filedata;
+       unsigned long pos;
+       struct super_block *sb = inode->i_sb;
+#ifdef CONFIG_ASFS_RW
+       int error;
+       struct buffer_head *bh;
+       struct fsObject *obj;
+#endif
+
+       asfs_debug("ASFS: get_block(%lu, %ld, %d)\n", inode->i_ino, block, create);
+
+       if (block < 0) {
+               printk(KERN_ERR "ASFS: asfsget_block: requested block (%ld) < 0!\n", block);
+               return -EIO;
+       } else if (block >= inode->i_blocks && !create) {
+               printk(KERN_ERR "ASFS: asfsget_block: strange block request %ld!\n", block);
+               return -EIO;
+       } 
+
+       if (create)
+#ifdef CONFIG_ASFS_RW
+               ASFS_I(inode)->modified = TRUE;
+#else
+               return -EROFS;
+#endif
+
+       if (block < inode->i_blocks)
+               create = 0;
+
+       lock_super(sb);
+
+#ifdef CONFIG_ASFS_RW
+       if (create) {
+               int blockstoadd;
+               u32 newspace, addedblocks;
+
+               blockstoadd = block - inode->i_blocks + 1;
+
+               if (blockstoadd < ASFS_BLOCKCHUNKS)
+                       blockstoadd = ASFS_BLOCKCHUNKS;
+ 
+               asfs_debug("ASFS get_block: Trying to add %d blocks to file\n", blockstoadd);
+               
+               if ((error = asfs_readobject(sb, inode->i_ino, &bh, &obj)) != 0) {
+                       unlock_super(sb);
+                       return error;
+               }
+
+               if ((error = asfs_addblockstofile(sb, bh, obj, blockstoadd, &newspace, &addedblocks)) != 0) {
+                       asfs_brelse(bh);
+                       unlock_super(sb);
+                       return error;
+               }
+               ASFS_I(inode)->mmu_private += addedblocks * sb->s_blocksize;
+               inode->i_blocks += addedblocks;
+               ASFS_I(inode)->ext_cache.key = 0;
+               ASFS_I(inode)->firstblock = be32_to_cpu(obj->object.file.data);
+               asfs_brelse(bh);
+       }
+#endif
+
+       if (ASFS_I(inode)->ext_cache.key > 0 && ASFS_I(inode)->ext_cache.startblock <= block) {
+               extent.key = ASFS_I(inode)->ext_cache.key;
+               extent.next = ASFS_I(inode)->ext_cache.next;
+               extent.blocks = ASFS_I(inode)->ext_cache.blocks;
+               pos = ASFS_I(inode)->ext_cache.startblock;
+       } else {
+               if (asfs_getextent(inode->i_sb, ASFS_I(inode)->firstblock, &ebn_bh, &ebn_p) != 0) {
+                       unlock_super(sb);
+                       return -EIO;
+               }
+               extent.key = be32_to_cpu(ebn_p->key);
+               extent.next = be32_to_cpu(ebn_p->next);
+               extent.blocks = be16_to_cpu(ebn_p->blocks);
+               pos = 0;
+               asfs_brelse(ebn_bh);
+       }
+       ebn_p = &extent;
+       filedata = ebn_p->next;
+
+       while (pos + ebn_p->blocks <= block && ebn_p->next != 0 && pos < inode->i_blocks) {
+               pos += ebn_p->blocks;
+               if (asfs_getextent(inode->i_sb, filedata, &ebn_bh, &ebn_p) != 0) {
+                       unlock_super(sb);
+                       return -EIO;
+               }
+               extent.key = be32_to_cpu(ebn_p->key);
+               extent.next = be32_to_cpu(ebn_p->next);
+               extent.blocks = be16_to_cpu(ebn_p->blocks);
+               ebn_p = &extent;        
+               filedata = ebn_p->next;
+               asfs_brelse(ebn_bh);
+       }
+
+       unlock_super(sb);
+
+       map_bh(bh_result, inode->i_sb, (sector_t) (ebn_p->key + block - pos));
+
+       if (create)
+               set_buffer_new(bh_result);
+
+       asfs_debug("ASFS: get_block - mapped block %lu\n", ebn_p->key + block - pos);
+
+       ASFS_I(inode)->ext_cache.startblock = pos;
+       ASFS_I(inode)->ext_cache.key = ebn_p->key;
+       ASFS_I(inode)->ext_cache.next = ebn_p->next;
+       ASFS_I(inode)->ext_cache.blocks = ebn_p->blocks;
+
+       return 0;
+}
+
+int asfs_readpage(struct file *file, struct page *page)
+{
+       asfs_debug("ASFS: %s\n", __FUNCTION__);
+       return block_read_full_page(page, asfs_get_block);
+}
+
+sector_t asfs_bmap(struct address_space *mapping, sector_t block)
+{
+       asfs_debug("ASFS: %s\n", __FUNCTION__);
+       return generic_block_bmap(mapping,block,asfs_get_block);
+}
+
+#ifdef CONFIG_ASFS_RW
+
+int asfs_writepage(struct page *page, struct writeback_control *wbc)
+{
+       asfs_debug("ASFS: %s\n", __FUNCTION__);
+       return block_write_full_page(page, asfs_get_block, wbc);
+}
+
+int asfs_write_begin(struct file *file, struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned flags,
+                       struct page **pagep, void **fsdata)
+{
+       *pagep = NULL;
+       return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+                               asfs_get_block,
+                               &ASFS_I(mapping->host)->mmu_private);
+}
+
+void asfs_truncate(struct inode *inode)
+{
+       struct super_block *sb = inode->i_sb;
+       struct buffer_head *bh;
+       struct fsObject *obj;
+
+       asfs_debug("AFFS: truncate(inode=%d, oldsize=%u, newsize=%u)\n",
+                (u32)inode->i_ino, (u32)ASFS_I(inode)->mmu_private, (u32)inode->i_size);
+
+       if (inode->i_size > ASFS_I(inode)->mmu_private) {
+               printk("ASFS: enlarging file is not supported yet\n");
+               return;
+       }
+
+       lock_super(sb);
+
+       if ((asfs_readobject(sb, inode->i_ino, &bh, &obj)) != 0) {
+               unlock_super(sb);
+               return;
+       }
+
+       if (asfs_truncateblocksinfile(sb, bh, obj, inode->i_size) != 0) {
+               asfs_brelse(bh);
+               unlock_super(sb);
+               return;
+       }
+               
+       obj->object.file.size = cpu_to_be32(inode->i_size);
+       ASFS_I(inode)->mmu_private = inode->i_size;
+       ASFS_I(inode)->modified = TRUE;
+       inode->i_blocks = (be32_to_cpu(obj->object.file.size) + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
+       asfs_bstore(sb, bh);
+       asfs_brelse(bh);
+
+       unlock_super(sb);
+}
+
+int asfs_file_open(struct inode *inode, struct file *filp)
+{
+       if (atomic_read(&filp->f_count) != 1)
+               return 0;
+       asfs_debug("ASFS: file open (node %d)\n", (int)inode->i_ino);
+       return 0;
+}
+
+int asfs_file_release(struct inode *inode, struct file *filp)
+{
+       int error = 0;
+
+       asfs_debug("ASFS: file release (node %d oc %d)\n", (int)inode->i_ino, atomic_read(&filp->f_count));
+
+       if (atomic_read(&filp->f_count) != 0)
+               return 0;
+
+       if (ASFS_I(inode)->modified == TRUE) {
+               struct buffer_head *bh;
+               struct fsObject *obj;
+               lock_super(inode->i_sb);
+
+               if ((error = asfs_readobject(inode->i_sb, inode->i_ino, &bh, &obj)) != 0) {
+                       unlock_super(inode->i_sb);
+                       return error;
+               }
+
+               obj->datemodified = cpu_to_be32(inode->i_mtime.tv_sec - (365*8+2)*24*60*60);
+               if (inode->i_mode & S_IFREG) {
+                       error = asfs_truncateblocksinfile(inode->i_sb, bh, obj, (u32)inode->i_size);
+                       obj->object.file.size = cpu_to_be32(inode->i_size);
+                       ASFS_I(inode)->mmu_private = inode->i_size;
+                       inode->i_blocks = (be32_to_cpu(obj->object.file.size) + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
+               }
+               asfs_bstore(inode->i_sb, bh);
+
+               unlock_super(inode->i_sb);
+
+               asfs_brelse(bh);
+       }
+       ASFS_I(inode)->modified = FALSE;
+
+       return error;
+}
+
+#endif
diff -ruN linux-source-2.6.24.orig/fs/asfs/inode.c linux-source-2.6.24/fs/asfs/inode.c
--- linux-source-2.6.24.orig/fs/asfs/inode.c    1970-01-01 03:00:00.000000000 +0300
+++ linux-source-2.6.24/fs/asfs/inode.c 2008-12-14 23:31:39.000000000 +0300
@@ -0,0 +1,437 @@
+/*
+ *
+ * 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/smp_lock.h>
+#include <linux/time.h>
+#include <linux/buffer_head.h>
+#include <linux/vfs.h>
+#include <linux/dirent.h>
+#include "asfs_fs.h"
+
+#include <asm/byteorder.h>
+
+#ifdef CONFIG_ASFS_RW
+static int asfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd);
+static int asfs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
+static int asfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
+static int asfs_rmdir(struct inode *dir, struct dentry *dentry);
+static int asfs_unlink(struct inode *dir, struct dentry *dentry);
+static int asfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+               struct inode *new_dir, struct dentry *new_dentry);
+/*static int asfs_notify_change(struct dentry *dentry, struct iattr *attr);*/
+#endif
+
+/* Mapping from our types to the kernel */
+
+static struct address_space_operations asfs_aops = {
+       .readpage       = asfs_readpage,
+       .sync_page      = block_sync_page,
+       .bmap           = asfs_bmap,
+#ifdef CONFIG_ASFS_RW
+       .writepage      = asfs_writepage,
+       .write_begin    = asfs_write_begin,
+       .write_end      = generic_write_end,
+#endif
+};
+
+static struct file_operations asfs_file_operations = {
+       .llseek         = generic_file_llseek,
+       .aio_read               = generic_file_aio_read,
+       .mmap           = generic_file_mmap,
+#ifdef CONFIG_ASFS_RW
+       .aio_write              = generic_file_aio_write,
+       .open           = asfs_file_open,
+       .release        = asfs_file_release,
+       .fsync          = file_fsync,
+#endif
+};
+
+static struct file_operations asfs_dir_operations = {
+       .read           = generic_read_dir,
+       .readdir        = asfs_readdir,
+};
+
+static struct inode_operations asfs_dir_inode_operations = {
+       .lookup         = asfs_lookup,
+#ifdef CONFIG_ASFS_RW
+       .create         = asfs_create,
+       .unlink         = asfs_unlink,
+       .symlink        = asfs_symlink,
+       .mkdir          = asfs_mkdir,
+       .rmdir          = asfs_rmdir,
+       .rename         = asfs_rename,
+/*     .setattr        = asfs_notify_change,*/
+#endif
+};
+
+static struct inode_operations asfs_file_inode_operations = {
+#ifdef CONFIG_ASFS_RW
+       .truncate       = asfs_truncate,
+/*     .setattr                = asfs_notify_change,*/
+#endif
+};
+
+static struct address_space_operations asfs_symlink_aops = {
+       .readpage       = asfs_symlink_readpage,
+};
+
+static struct inode_operations asfs_symlink_inode_operations = {
+       .readlink       = generic_readlink,
+       .follow_link    = page_follow_link_light,
+       .put_link       = page_put_link,
+#ifdef CONFIG_ASFS_RW
+/*     .setattr        = asfs_notify_change,*/
+#endif
+};
+
+void asfs_read_locked_inode(struct inode *inode, void *arg)
+{
+       struct super_block *sb = inode->i_sb;
+       struct fsObject *obj = arg;
+
+       inode->i_mode = ASFS_SB(sb)->mode;
+       inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = be32_to_cpu(obj->datemodified) + (365*8+2)*24*60*60;  
+       /* Linux: seconds since 01-01-1970, AmigaSFS: seconds since 01-01-1978 */
+       inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_atime.tv_nsec = 0;
+       inode->i_uid = ASFS_SB(sb)->uid;
+       inode->i_gid = ASFS_SB(sb)->gid;
+
+       asfs_debug("asfs_read_inode2: Setting-up node %lu... ", inode->i_ino);
+
+       if (obj->bits & OTYPE_DIR) {
+               asfs_debug("dir (FirstdirBlock: %u, HashTable %u)\n", \
+                          be32_to_cpu(obj->object.dir.firstdirblock), be32_to_cpu(obj->object.dir.hashtable));
+
+               inode->i_size = 0;
+               inode->i_op = &asfs_dir_inode_operations;
+               inode->i_fop = &asfs_dir_operations;
+               inode->i_mode |= S_IFDIR | ((inode->i_mode & 0400) ? 0100 : 0) | 
+                             ((inode->i_mode & 0040) ? 0010 : 0) | ((inode->i_mode & 0004) ? 0001 : 0);
+               ASFS_I(inode)->firstblock = be32_to_cpu(obj->object.dir.firstdirblock);
+               ASFS_I(inode)->hashtable = be32_to_cpu(obj->object.dir.hashtable);
+               ASFS_I(inode)->modified = 0;
+       } else if (obj->bits & OTYPE_LINK && !(obj->bits & OTYPE_HARDLINK)) {
+               asfs_debug("symlink\n");
+               inode->i_size = 0;
+               inode->i_op = &asfs_symlink_inode_operations;
+               inode->i_data.a_ops = &asfs_symlink_aops;
+               inode->i_mode |= S_IFLNK | S_IRWXUGO;
+               ASFS_I(inode)->firstblock = be32_to_cpu(obj->object.file.data);
+       } else {
+               asfs_debug("file (Size: %u, FirstBlock: %u)\n", be32_to_cpu(obj->object.file.size), be32_to_cpu(obj->object.file.data));
+               inode->i_size = be32_to_cpu(obj->object.file.size);
+               inode->i_blocks = (be32_to_cpu(obj->object.file.size) + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
+               inode->i_op = &asfs_file_inode_operations;
+               inode->i_fop = &asfs_file_operations;
+               inode->i_mapping->a_ops = &asfs_aops;
+               inode->i_mode |= S_IFREG;
+               ASFS_I(inode)->firstblock = be32_to_cpu(obj->object.file.data);
+               ASFS_I(inode)->ext_cache.startblock = 0;
+               ASFS_I(inode)->ext_cache.key = 0;
+               ASFS_I(inode)->mmu_private = inode->i_size;
+       }
+       return; 
+}
+
+struct inode *asfs_get_root_inode(struct super_block *sb)
+{
+       struct inode *result = NULL;
+       struct fsObject *obj;
+       struct buffer_head *bh;
+
+       asfs_debug("asfs_get_root_inode\n");
+
+       if ((bh = asfs_breadcheck(sb, ASFS_SB(sb)->rootobjectcontainer, ASFS_OBJECTCONTAINER_ID))) {
+               obj = &(((struct fsObjectContainer *)bh->b_data)->object[0]);
+               if (be32_to_cpu(obj->objectnode) > 0)
+                       result = iget_locked(sb, be32_to_cpu(obj->objectnode));
+
+               if (result != NULL && result->i_state & I_NEW) {
+                       asfs_read_locked_inode(result, obj);
+                       unlock_new_inode(result);
+               }
+               asfs_brelse(bh);
+       }
+       return result;
+}
+
+#ifdef CONFIG_ASFS_RW
+
+static void asfs_sync_dir_inode(struct inode *dir, struct fsObject *obj)
+{
+       ASFS_I(dir)->firstblock = be32_to_cpu(obj->object.dir.firstdirblock);
+       ASFS_I(dir)->modified = 1;
+       dir->i_mtime = dir->i_atime = dir->i_ctime = CURRENT_TIME;
+       obj->datemodified = cpu_to_be32(dir->i_mtime.tv_sec - (365*8+2)*24*60*60);
+}
+
+enum { it_file, it_dir, it_link };
+
+static int asfs_create_object(struct inode *dir, struct dentry *dentry, int mode, int type, const char *symname)
+{
+       int error;
+       struct super_block *sb = dir->i_sb;
+       struct inode *inode;
+       struct buffer_head *bh, *dir_bh;
+       struct fsObject obj_data, *dir_obj, *obj;
+       u8 *name = (u8 *) dentry->d_name.name;
+       u8 bufname[ASFS_MAXFN_BUF];
+
+       asfs_debug("asfs_create_obj %s in dir node %d\n", name, (int)dir->i_ino);
+
+       asfs_translate(bufname, name, ASFS_SB(sb)->nls_disk, ASFS_SB(sb)->nls_io, ASFS_MAXFN_BUF);
+       if ((error = asfs_check_name(bufname, strlen(bufname))) != 0)
+               return error;
+
+       sb = dir->i_sb;
+       inode = new_inode(sb);
+       if (!inode)
+               return -ENOMEM;
+
+       memset(&obj_data, 0, sizeof(struct fsObject));
+
+       obj_data.protection = cpu_to_be32(FIBF_READ|FIBF_WRITE|FIBF_EXECUTE|FIBF_DELETE);
+       obj_data.datemodified = cpu_to_be32(inode->i_mtime.tv_sec - (365*8+2)*24*60*60);
+       switch (type) {
+       case it_dir:
+               obj_data.bits = OTYPE_DIR;
+               break;
+       case it_link:
+               obj_data.bits = OTYPE_LINK;
+               break;
+       default:
+               break;
+       }
+
+       lock_super(sb);
+
+       if ((error = asfs_readobject(sb, dir->i_ino, &dir_bh, &dir_obj)) != 0) {
+               dec_count(inode);
+               unlock_super(sb);
+               return error;
+       }
+
+       bh = dir_bh;
+       obj = dir_obj;
+
+       if ((error = asfs_createobject(sb, &bh, &obj, &obj_data, bufname, FALSE)) != 0) {
+               asfs_brelse(dir_bh);
+               dec_count(inode);
+               unlock_super(sb);
+               return error;
+       }
+
+       inode->i_ino = be32_to_cpu(obj->objectnode);
+       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+       inode->i_size = inode->i_blocks = 0;
+       inode->i_uid = dir->i_uid;
+       inode->i_gid = dir->i_gid;
+       inode->i_mode = mode | ASFS_SB(sb)->mode;
+
+       switch (type) {
+       case it_dir:
+               inode->i_mode |= S_IFDIR;
+               inode->i_op = &asfs_dir_inode_operations;
+               inode->i_fop = &asfs_dir_operations;
+               ASFS_I(inode)->firstblock = be32_to_cpu(obj->object.dir.firstdirblock);
+               ASFS_I(inode)->hashtable = be32_to_cpu(obj->object.dir.hashtable);
+               ASFS_I(inode)->modified = 0;
+               break;
+       case it_file:
+               inode->i_mode |= S_IFREG;
+               inode->i_op = &asfs_file_inode_operations;
+               inode->i_fop = &asfs_file_operations;
+               inode->i_mapping->a_ops = &asfs_aops;
+               ASFS_I(inode)->firstblock = be32_to_cpu(obj->object.file.data);
+               ASFS_I(inode)->ext_cache.startblock = 0;
+               ASFS_I(inode)->ext_cache.key = 0;
+               ASFS_I(inode)->mmu_private = inode->i_size;
+               break;
+       case it_link:
+               inode->i_mode = S_IFLNK | S_IRWXUGO;
+               inode->i_op = &page_symlink_inode_operations;
+               inode->i_mapping->a_ops = &asfs_symlink_aops;
+               ASFS_I(inode)->firstblock = be32_to_cpu(obj->object.file.data);
+               error = asfs_write_symlink(inode, symname);
+               break;
+       default:
+               break;
+       }
+
+       asfs_bstore(sb, bh);
+       insert_inode_hash(inode);
+       mark_inode_dirty(inode);
+       d_instantiate(dentry, inode);
+       asfs_sync_dir_inode(dir, dir_obj);
+       asfs_bstore(sb, dir_bh); 
+
+       unlock_super(sb);
+       asfs_brelse(bh);
+       asfs_brelse(dir_bh);
+       
+       return error;
+}
+
+static int asfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
+{
+       return asfs_create_object(dir, dentry, mode, it_file, NULL);
+}
+
+static int asfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+       return asfs_create_object(dir, dentry, mode, it_dir, NULL);
+}
+
+static int asfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+{
+       return asfs_create_object(dir, dentry, 0, it_link, symname);
+}
+
+static int asfs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+       asfs_debug("ASFS: %s\n", __FUNCTION__);
+
+       if (ASFS_I(dentry->d_inode)->firstblock != 0)
+               return -ENOTEMPTY;
+       
+       return asfs_unlink(dir, dentry);
+}
+
+static int asfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+       struct inode *inode = dentry->d_inode;
+       int error;
+       struct super_block *sb = dir->i_sb;
+       struct buffer_head *bh, *dir_bh;
+       struct fsObject *dir_obj, *obj;
+
+       asfs_debug("ASFS: %s\n", __FUNCTION__);
+
+       lock_super(sb);
+
+       if ((error = asfs_readobject(sb, inode->i_ino, &bh, &obj)) != 0) {
+               unlock_super(sb);
+               return error;
+       }
+       if ((error = asfs_deleteobject(sb, bh, obj)) != 0) {
+               asfs_brelse(bh);
+               unlock_super(sb);
+               return error;
+       }
+       asfs_brelse(bh);
+
+       /* directory data could change after removing the object */
+       if ((error = asfs_readobject(sb, dir->i_ino, &dir_bh, &dir_obj)) != 0) {
+               unlock_super(sb);
+               return error;
+       }
+
+       asfs_sync_dir_inode(dir, dir_obj);
+       asfs_bstore(sb, dir_bh); 
+
+       dec_count(inode);
+       unlock_super(sb);
+       asfs_brelse(dir_bh);
+
+       return 0;
+}
+
+static int asfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
+{
+       struct super_block *sb = old_dir->i_sb;
+       struct buffer_head *src_bh, *old_bh, *new_bh;
+       int error;
+       struct fsObject *src_obj, *old_obj, *new_obj;
+       u8 bufname[ASFS_MAXFN_BUF];
+
+       asfs_debug("ASFS: rename (old=%u,\"%*s\" to new=%u,\"%*s\")\n",
+                (u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name,
+                (u32)new_dir->i_ino, (int)new_dentry->d_name.len, new_dentry->d_name.name);
+
+       asfs_translate(bufname, (u8 *) new_dentry->d_name.name, ASFS_SB(sb)->nls_disk, ASFS_SB(sb)->nls_io, ASFS_MAXFN_BUF);
+       if ((error = asfs_check_name(bufname, strlen(bufname))) != 0)
+               return error;
+
+
+       /* Unlink destination if it already exists */
+       if (new_dentry->d_inode) 
+               if ((error = asfs_unlink(new_dir, new_dentry)) != 0)
+                       return error;
+
+       lock_super(sb);
+
+       if ((error = asfs_readobject(sb, old_dentry->d_inode->i_ino, &src_bh, &src_obj)) != 0) {
+               unlock_super(sb);
+               return error;
+       }
+       if ((error = asfs_readobject(sb, new_dir->i_ino, &new_bh, &new_obj)) != 0) {
+               asfs_brelse(src_bh);
+               unlock_super(sb);
+               return error;
+       }
+
+       if ((error = asfs_renameobject(sb, src_bh, src_obj, new_bh, new_obj, bufname)) != 0) {
+               asfs_brelse(src_bh);
+               asfs_brelse(new_bh);
+               unlock_super(sb);
+               return error;
+       }
+       asfs_brelse(src_bh);
+       asfs_brelse(new_bh);
+
+       if ((error = asfs_readobject(sb, old_dir->i_ino, &old_bh, &old_obj)) != 0) {
+               unlock_super(sb);
+               return error;
+       }
+       if ((error = asfs_readobject(sb, new_dir->i_ino, &new_bh, &new_obj)) != 0) {
+               asfs_brelse(old_bh);
+               unlock_super(sb);
+               return error;
+       }
+
+       asfs_sync_dir_inode(old_dir, old_obj);
+       asfs_sync_dir_inode(new_dir, new_obj);
+
+       asfs_bstore(sb, new_bh);        
+       asfs_bstore(sb, old_bh);
+
+       unlock_super(sb);
+       asfs_brelse(old_bh);
+       asfs_brelse(new_bh);
+
+       mark_inode_dirty(old_dir);
+       mark_inode_dirty(new_dir);
+
+       return 0;
+}
+
+/*
+int asfs_notify_change(struct dentry *dentry, struct iattr *attr)
+{
+       struct inode *inode = dentry->d_inode;
+       int error = 0;
+
+       asfs_debug("ASFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid);
+
+       error = inode_change_ok(inode,attr);
+
+       return error;
+}
+*/
+#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

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux