Also rolled in some suggestions for the multi-version code.
Signed-off-by: Charles Manning <cdhmanning@gmail.com>
+/Module.symvers
+/.tmp_versions
+
+#
+# cscope files
+#
+cscope.*
ifdef YAFFS_CURRENT
YAFFS_O := yaffs2.o
ifdef YAFFS_CURRENT
YAFFS_O := yaffs2.o
+ EXTRA_CFLAGS += -DYAFFS_CURRENT
else
YAFFS_O := yaffs2multi.o
endif
else
YAFFS_O := yaffs2multi.o
endif
#include "linux/types.h"
#include "linux/mtd/mtd.h"
#include "linux/types.h"
#include "linux/mtd/mtd.h"
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
+#define MTD_OPS_AUTO_OOB MTD_OOB_AUTO
+#endif
+
+
/* Don't compile this module if we don't have MTD's mtd_oob_ops interface */
#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
/* Don't compile this module if we don't have MTD's mtd_oob_ops interface */
#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
}
memset(&ops, 0, sizeof(ops));
}
memset(&ops, 0, sizeof(ops));
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.len = (data) ? chunk_bytes : 0;
ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
ops.datbuf = (u8 *) data;
ops.len = (data) ? chunk_bytes : 0;
ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
ops.datbuf = (u8 *) data;
int deleted;
memset(&ops, 0, sizeof(ops));
int deleted;
memset(&ops, 0, sizeof(ops));
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.len = (data) ? chunk_bytes : 0;
ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
ops.datbuf = data;
ops.len = (data) ? chunk_bytes : 0;
ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
ops.datbuf = data;
}
memset(&ops, 0, sizeof(ops));
}
memset(&ops, 0, sizeof(ops));
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.len = (data) ? chunk_bytes : 0;
ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
ops.datbuf = (u8 *) data;
ops.len = (data) ? chunk_bytes : 0;
ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
ops.datbuf = (u8 *) data;
int deleted;
memset(&ops, 0, sizeof(ops));
int deleted;
memset(&ops, 0, sizeof(ops));
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.len = (data) ? chunk_bytes : 0;
ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
ops.datbuf = data;
ops.len = (data) ? chunk_bytes : 0;
ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
ops.datbuf = data;
*
* Returns YAFFS_OK or YAFFS_FAIL.
*/
*
* Returns YAFFS_OK or YAFFS_FAIL.
*/
-static int nandmtd1_test_prerequists(struct mtd_info *mtd)
+static int nandmtd1_test_prerequists(struct yaffs_dev *dev, struct mtd_info *mtd)
{
/* 2.6.18 has mtd->ecclayout->oobavail */
/* 2.6.21 has mtd->ecclayout->oobavail and mtd->oobavail */
{
/* 2.6.18 has mtd->ecclayout->oobavail */
/* 2.6.21 has mtd->ecclayout->oobavail and mtd->oobavail */
if (oobavail < (dev->param.tags_9bytes ? 9 : 8)) {
yaffs_trace(YAFFS_TRACE_ERROR,
"mtd device has only %d bytes for tags, need %d",
if (oobavail < (dev->param.tags_9bytes ? 9 : 8)) {
yaffs_trace(YAFFS_TRACE_ERROR,
"mtd device has only %d bytes for tags, need %d",
- oobavail, (dev->param.tags_9bytes ? 9 : 8);
+ oobavail, (dev->param.tags_9bytes ? 9 : 8));
return YAFFS_FAIL;
}
return YAFFS_OK;
return YAFFS_FAIL;
}
return YAFFS_OK;
/* We don't yet have a good place to test for MTD config prerequists.
* Do it here as we are called during the initial scan.
*/
/* We don't yet have a good place to test for MTD config prerequists.
* Do it here as we are called during the initial scan.
*/
- if (nandmtd1_test_prerequists(mtd) != YAFFS_OK)
+ if (nandmtd1_test_prerequists(dev, mtd) != YAFFS_OK)
return YAFFS_FAIL;
retval = nandmtd1_read_chunk_tags(dev, chunk_num, NULL, &etags);
return YAFFS_FAIL;
retval = nandmtd1_read_chunk_tags(dev, chunk_num, NULL, &etags);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
+#define MTD_OPS_AUTO_OOB MTD_OOB_AUTO
+#endif
+
+
+
/* NB For use with inband tags....
* We assume that the data buffer is of size total_bytes_per_chunk so
* that we can also use it to load the tags.
/* NB For use with inband tags....
* We assume that the data buffer is of size total_bytes_per_chunk so
* that we can also use it to load the tags.
}
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
}
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
ops.len = dev->param.total_bytes_per_chunk;
ops.ooboffs = 0;
ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
ops.len = dev->param.total_bytes_per_chunk;
ops.ooboffs = 0;
retval = mtd->read(mtd, addr, dev->param.total_bytes_per_chunk,
&dummy, data);
else if (tags) {
retval = mtd->read(mtd, addr, dev->param.total_bytes_per_chunk,
&dummy, data);
else if (tags) {
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.ooblen = packed_tags_size;
ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
ops.ooboffs = 0;
ops.ooblen = packed_tags_size;
ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
ops.ooboffs = 0;
#include "linux/mtd/mtd.h"
#include "linux/types.h"
#include "linux/time.h"
#include "linux/mtd/mtd.h"
#include "linux/types.h"
#include "linux/time.h"
+#include "mtd/mtd-abi.h"
/* NB For use with inband tags....
/* NB For use with inband tags....
yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
}
yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
}
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
ops.len = dev->param.total_bytes_per_chunk;
ops.ooboffs = 0;
ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
ops.len = dev->param.total_bytes_per_chunk;
ops.ooboffs = 0;
retval = mtd->read(mtd, addr, dev->param.total_bytes_per_chunk,
&dummy, data);
} else if (tags) {
retval = mtd->read(mtd, addr, dev->param.total_bytes_per_chunk,
&dummy, data);
} else if (tags) {
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.ooblen = packed_tags_size;
ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
ops.ooboffs = 0;
ops.ooblen = packed_tags_size;
ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
ops.ooboffs = 0;
#define YAFFS_USE_WRITE_BEGIN_END 0
#endif
#define YAFFS_USE_WRITE_BEGIN_END 0
#endif
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
+#define set_nlink(inode, count) do { (inode)->i_nlink = (count); } while(0)
+#endif
+
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28))
static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
{
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28))
static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
{
inode->i_size = yaffs_get_obj_length(obj);
inode->i_blocks = (inode->i_size + 511) >> 9;
inode->i_size = yaffs_get_obj_length(obj);
inode->i_blocks = (inode->i_size + 511) >> 9;
- inode->i_nlink = yaffs_get_obj_link_count(obj);
+ set_nlink(inode, yaffs_get_obj_link_count(obj));
yaffs_trace(YAFFS_TRACE_OS,
"yaffs_fill_inode mode %x uid %d gid %d size %d count %d",
yaffs_trace(YAFFS_TRACE_OS,
"yaffs_fill_inode mode %x uid %d gid %d size %d count %d",
ret_val = yaffs_unlinker(obj, dentry->d_name.name);
if (ret_val == YAFFS_OK) {
ret_val = yaffs_unlinker(obj, dentry->d_name.name);
if (ret_val == YAFFS_OK) {
- dentry->d_inode->i_nlink--;
+ inode_dec_link_count(dentry->d_inode);
dir->i_version++;
yaffs_gross_unlock(dev);
dir->i_version++;
yaffs_gross_unlock(dev);
- mark_inode_dirty(dentry->d_inode);
update_dir_time(dir);
return 0;
}
update_dir_time(dir);
return 0;
}
- old_dentry->d_inode->i_nlink = yaffs_get_obj_link_count(obj);
+ set_nlink(old_dentry->d_inode, yaffs_get_obj_link_count(obj));
d_instantiate(dentry, old_dentry->d_inode);
atomic_inc(&old_dentry->d_inode->i_count);
yaffs_trace(YAFFS_TRACE_OS,
d_instantiate(dentry, old_dentry->d_inode);
atomic_inc(&old_dentry->d_inode->i_count);
yaffs_trace(YAFFS_TRACE_OS,
yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
+ if (strnlen(dentry->d_name.name, YAFFS_MAX_NAME_LENGTH + 1) >
+ YAFFS_MAX_NAME_LENGTH)
+ return -ENAMETOOLONG;
+
+ if (strnlen(symname, YAFFS_MAX_ALIAS_LENGTH + 1) >
+ YAFFS_MAX_ALIAS_LENGTH)
+ return -ENAMETOOLONG;
+
dev = yaffs_inode_to_obj(dir)->my_dev;
yaffs_gross_lock(dev);
obj = yaffs_create_symlink(yaffs_inode_to_obj(dir), dentry->d_name.name,
dev = yaffs_inode_to_obj(dir)->my_dev;
yaffs_gross_lock(dev);
obj = yaffs_create_symlink(yaffs_inode_to_obj(dir), dentry->d_name.name,
yaffs_gross_unlock(dev);
if (ret_val == YAFFS_OK) {
yaffs_gross_unlock(dev);
if (ret_val == YAFFS_OK) {
- if (target) {
- new_dentry->d_inode->i_nlink--;
- mark_inode_dirty(new_dentry->d_inode);
- }
+ if (target)
+ inode_dec_link_count(new_dentry->d_inode);
update_dir_time(old_dir);
if (old_dir != new_dir)
update_dir_time(old_dir);
if (old_dir != new_dir)
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
#include <linux/pagemap.h>
#include <linux/mtd/mtd.h>
#include <linux/interrupt.h>
#include <linux/pagemap.h>
#include <linux/mtd/mtd.h>
#include <linux/interrupt.h>
- old_dentry->d_inode->i_nlink = yaffs_get_obj_link_count(obj);
+ set_nlink(old_dentry->d_inode, yaffs_get_obj_link_count(obj));
d_instantiate(dentry, old_dentry->d_inode);
atomic_inc(&old_dentry->d_inode->i_count);
yaffs_trace(YAFFS_TRACE_OS,
d_instantiate(dentry, old_dentry->d_inode);
atomic_inc(&old_dentry->d_inode->i_count);
yaffs_trace(YAFFS_TRACE_OS,
yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
+ if (strnlen(dentry->d_name.name, YAFFS_MAX_NAME_LENGTH + 1) >
+ YAFFS_MAX_NAME_LENGTH)
+ return -ENAMETOOLONG;
+
+ if (strnlen(symname, YAFFS_MAX_ALIAS_LENGTH + 1) >
+ YAFFS_MAX_ALIAS_LENGTH)
+ return -ENAMETOOLONG;
+
dev = yaffs_inode_to_obj(dir)->my_dev;
yaffs_gross_lock(dev);
obj = yaffs_create_symlink(yaffs_inode_to_obj(dir), dentry->d_name.name,
dev = yaffs_inode_to_obj(dir)->my_dev;
yaffs_gross_lock(dev);
obj = yaffs_create_symlink(yaffs_inode_to_obj(dir), dentry->d_name.name,
ret_val = yaffs_unlinker(obj, dentry->d_name.name);
if (ret_val == YAFFS_OK) {
ret_val = yaffs_unlinker(obj, dentry->d_name.name);
if (ret_val == YAFFS_OK) {
- dentry->d_inode->i_nlink--;
+ inode_dec_link_count(dentry->d_inode);
dir->i_version++;
yaffs_gross_unlock(dev);
dir->i_version++;
yaffs_gross_unlock(dev);
- mark_inode_dirty(dentry->d_inode);
update_dir_time(dir);
return 0;
}
update_dir_time(dir);
return 0;
}
-static int yaffs_sync_object(struct file *file, int datasync)
+static int yaffs_sync_object(struct file *file, loff_t start, loff_t end, int datasync)
yaffs_gross_unlock(dev);
if (ret_val == YAFFS_OK) {
yaffs_gross_unlock(dev);
if (ret_val == YAFFS_OK) {
- if (target) {
- new_dentry->d_inode->i_nlink--;
- mark_inode_dirty(new_dentry->d_inode);
- }
+ if (target)
+ inode_dec_link_count(new_dentry->d_inode);
update_dir_time(old_dir);
if (old_dir != new_dir)
update_dir_time(old_dir);
if (old_dir != new_dir)
inode->i_ctime.tv_nsec = 0;
inode->i_size = yaffs_get_obj_length(obj);
inode->i_blocks = (inode->i_size + 511) >> 9;
inode->i_ctime.tv_nsec = 0;
inode->i_size = yaffs_get_obj_length(obj);
inode->i_blocks = (inode->i_size + 511) >> 9;
- inode->i_nlink = yaffs_get_obj_link_count(obj);
+ set_nlink(inode, yaffs_get_obj_link_count(obj));
yaffs_trace(YAFFS_TRACE_OS,
"yaffs_fill_inode mode %x uid %d gid %d size %d count %d",
inode->i_mode, inode->i_uid, inode->i_gid,
yaffs_trace(YAFFS_TRACE_OS,
"yaffs_fill_inode mode %x uid %d gid %d size %d count %d",
inode->i_mode, inode->i_uid, inode->i_gid,
return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
}
return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
}
-static int yaffs_read_super(struct file_system_type *fs,
+static struct dentry *yaffs_mount(struct file_system_type *fs,
int flags, const char *dev_name,
int flags, const char *dev_name,
- void *data, struct vfsmount *mnt)
-
- return get_sb_bdev(fs, flags, dev_name, data,
- yaffs_internal_read_super_mtd, mnt);
+ return mount_bdev(fs, flags, dev_name, data,
+ yaffs_internal_read_super_mtd);
}
static struct file_system_type yaffs_fs_type = {
.owner = THIS_MODULE,
.name = "yaffs",
}
static struct file_system_type yaffs_fs_type = {
.owner = THIS_MODULE,
.name = "yaffs",
- .get_sb = yaffs_read_super,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
}
return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
}
-static int yaffs2_read_super(struct file_system_type *fs,
- int flags, const char *dev_name, void *data,
- struct vfsmount *mnt)
+static struct dentry *yaffs2_mount(struct file_system_type *fs,
+ int flags, const char *dev_name, void *data)
- return get_sb_bdev(fs, flags, dev_name, data,
- yaffs2_internal_read_super_mtd, mnt);
+ return mount_bdev(fs, flags, dev_name, data,
+ yaffs2_internal_read_super_mtd);
}
static struct file_system_type yaffs2_fs_type = {
.owner = THIS_MODULE,
.name = "yaffs2",
}
static struct file_system_type yaffs2_fs_type = {
.owner = THIS_MODULE,
.name = "yaffs2",
- .get_sb = yaffs2_read_super,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
--- /dev/null
+/*
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ * for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * Created by Waldemar Rymarkiewicz <waldemar.rymarkiewicz@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ */
+
+#ifdef YAFFS_CURRENT
+ #include "yportenv_single.h"
+#else
+ #include "yportenv_multi.h"
+#endif