X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_vfs_multi.c;h=3cf6dde1717c394487c3780189da83801fddcb52;hp=8f6e4b5fb9b198459d0048a82f1c1af6fdbbaf0a;hb=87b33ecd1898c99b9aa2b0abcbb3e6002d6b3532;hpb=a7ae50c6ee8de56afbdae3176a355da54f45b21a diff --git a/yaffs_vfs_multi.c b/yaffs_vfs_multi.c index 8f6e4b5..3cf6dde 100644 --- a/yaffs_vfs_multi.c +++ b/yaffs_vfs_multi.c @@ -148,6 +148,12 @@ #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) { @@ -170,8 +176,6 @@ static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size) #include "yaffs_linux.h" #include "yaffs_mtdif.h" -#include "yaffs_mtdif1.h" -#include "yaffs_mtdif2.h" unsigned int yaffs_trace_mask = YAFFS_TRACE_BAD_BLOCKS | YAFFS_TRACE_ALWAYS; unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS; @@ -971,7 +975,6 @@ static int yaffs_readpage_nolock(struct file *f, struct page *pg) unsigned char *pg_buf; int ret; loff_t pos = ((loff_t) pg->index) << PAGE_CACHE_SHIFT; - struct yaffs_dev *dev; yaffs_trace(YAFFS_TRACE_OS, @@ -1325,7 +1328,7 @@ static void yaffs_fill_inode_from_obj(struct inode *inode, 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 %lld count %d", @@ -1740,10 +1743,9 @@ static int yaffs_unlink(struct inode *dir, struct dentry *dentry) 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); - mark_inode_dirty(dentry->d_inode); update_dir_time(dir); return 0; } @@ -1775,7 +1777,7 @@ static int yaffs_link(struct dentry *old_dentry, struct inode *dir, obj); if (link) { - 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, @@ -1805,6 +1807,14 @@ static int yaffs_symlink(struct inode *dir, struct dentry *dentry, 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, @@ -1893,10 +1903,8 @@ static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry, 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) @@ -2465,8 +2473,10 @@ struct mutex yaffs_context_lock; static void yaffs_put_super(struct super_block *sb) { struct yaffs_dev *dev = yaffs_super_to_dev(sb); + struct mtd_info *mtd = yaffs_dev_to_mtd(dev); - yaffs_trace(YAFFS_TRACE_OS, "yaffs_put_super"); + yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS, + "yaffs_put_super"); yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND, "Shutting down yaffs background thread"); @@ -2478,9 +2488,6 @@ static void yaffs_put_super(struct super_block *sb) yaffs_flush_super(sb, 1); - if (yaffs_dev_to_lc(dev)->put_super_fn) - yaffs_dev_to_lc(dev)->put_super_fn(sb); - yaffs_deinitialise(dev); yaffs_gross_unlock(dev); @@ -2495,18 +2502,18 @@ static void yaffs_put_super(struct super_block *sb) } kfree(dev); -} - -static void yaffs_mtd_put_super(struct super_block *sb) -{ - struct mtd_info *mtd = yaffs_dev_to_mtd(yaffs_super_to_dev(sb)); - if (mtd->sync) + if (mtd && mtd->sync) mtd->sync(mtd); - put_mtd_device(mtd); + if(mtd) + put_mtd_device(mtd); + + yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS, + "yaffs_put_super done"); } + static void yaffs_touch_super(struct yaffs_dev *dev) { struct super_block *sb = yaffs_dev_to_lc(dev)->super; @@ -2821,14 +2828,7 @@ static struct super_block *yaffs_internal_read_super(int yaffs_version, /* Set up the memory size parameters.... */ - n_blocks = - YCALCBLOCKS(mtd->size, - (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK)); - param->start_block = 0; - param->end_block = n_blocks - 1; - param->chunks_per_block = YAFFS_CHUNKS_PER_BLOCK; - param->total_bytes_per_chunk = YAFFS_BYTES_PER_CHUNK; param->n_reserved_blocks = 5; param->n_caches = (options.no_cache) ? 0 : 10; param->inband_tags = options.inband_tags; @@ -2851,12 +2851,6 @@ static struct super_block *yaffs_internal_read_super(int yaffs_version, /* ... and the functions. */ if (yaffs_version == 2) { - param->write_chunk_tags_fn = nandmtd2_write_chunk_tags; - param->read_chunk_tags_fn = nandmtd2_read_chunk_tags; - param->bad_block_fn = nandmtd2_mark_block_bad; - param->query_block_fn = nandmtd2_query_block; - yaffs_dev_to_lc(dev)->spare_buffer = - kmalloc(mtd->oobsize, GFP_NOFS); param->is_yaffs2 = 1; #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) param->total_bytes_per_chunk = mtd->writesize; @@ -2870,26 +2864,21 @@ static struct super_block *yaffs_internal_read_super(int yaffs_version, param->start_block = 0; param->end_block = n_blocks - 1; } else { -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) - /* use the MTD interface in yaffs_mtdif1.c */ - param->write_chunk_tags_fn = nandmtd1_write_chunk_tags; - param->read_chunk_tags_fn = nandmtd1_read_chunk_tags; - param->bad_block_fn = nandmtd1_mark_block_bad; - param->query_block_fn = nandmtd1_query_block; -#else - param->write_chunk_fn = nandmtd_write_chunk; - param->read_chunk_fn = nandmtd_read_chunk; -#endif param->is_yaffs2 = 0; + n_blocks = YCALCBLOCKS(mtd->size, + YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK); + + param->chunks_per_block = YAFFS_CHUNKS_PER_BLOCK; + param->total_bytes_per_chunk = YAFFS_BYTES_PER_CHUNK; } - /* ... and common functions */ - param->erase_fn = nandmtd_erase_block; - param->initialise_flash_fn = nandmtd_initialise; - yaffs_dev_to_lc(dev)->put_super_fn = yaffs_mtd_put_super; + param->start_block = 0; + param->end_block = n_blocks - 1; + + yaffs_mtd_drv_install(dev); param->sb_dirty_fn = yaffs_touch_super; - param->gc_control = yaffs_gc_control_callback; + param->gc_control_fn = yaffs_gc_control_callback; yaffs_dev_to_lc(dev)->super = sb;