From: Charles Manning Date: Mon, 16 Aug 2010 05:35:36 +0000 (+1200) Subject: yaffs: Compile with Linux 2.6.36 X-Git-Tag: pre-name-change~20 X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=commitdiff_plain;h=af1e66bdb6be00b49d8500d01813cb207b930282 yaffs: Compile with Linux 2.6.36 There have been some changes with how setattr works and changing clear/delete inode to the new evict_inode. Signed-off-by: Charles Manning --- diff --git a/yaffs_fs.c b/yaffs_fs.c index 8e39ce2..c3f11f4 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -41,6 +41,13 @@ #define YAFFS_COMPILE_EXPORTFS #endif +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)) +#define YAFFS_USE_SETATTR_COPY +#endif +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)) +#define YAFFS_HAS_EVICT_INODE +#endif + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) #define YAFFS_NEW_FOLLOW_LINK 1 #else @@ -267,8 +274,12 @@ static int yaffs_statfs(struct super_block *sb, struct statfs *buf); static void yaffs_put_inode(struct inode *inode); #endif +#ifdef YAFFS_HAS_EVICT_INODE +static void yaffs_evict_inode(struct inode *); +#else static void yaffs_delete_inode(struct inode *); static void yaffs_clear_inode(struct inode *); +#endif static int yaffs_readpage(struct file *file, struct page *page); #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) @@ -315,6 +326,9 @@ static void yaffs_MarkSuperBlockDirty(yaffs_Device *dev); static loff_t yaffs_dir_llseek(struct file *file, loff_t offset, int origin); +static int yaffs_vfs_setattr(struct inode *, struct iattr *); + + static struct address_space_operations yaffs_file_address_operations = { .readpage = yaffs_readpage, .writepage = yaffs_writepage, @@ -327,6 +341,7 @@ static struct address_space_operations yaffs_file_address_operations = { #endif }; + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22)) static const struct file_operations yaffs_file_operations = { .read = do_sync_read, @@ -440,12 +455,28 @@ static const struct super_operations yaffs_super_ops = { .put_inode = yaffs_put_inode, #endif .put_super = yaffs_put_super, +#ifdef YAFFS_HAS_EVICT_INODE + .evict_inode = yaffs_evict_inode, +#else .delete_inode = yaffs_delete_inode, .clear_inode = yaffs_clear_inode, +#endif .sync_fs = yaffs_sync_fs, .write_super = yaffs_write_super, }; + +static int yaffs_vfs_setattr(struct inode *inode, struct iattr *attr) +{ +#ifdef YAFFS_USE_SETATTR_COPY + setattr_copy(inode,attr); + return 0; +#else + return inode_setattr(inode, attr); +#endif + +} + static unsigned yaffs_gc_control_callback(yaffs_Device *dev) { return yaffs_gc_control; @@ -788,36 +819,85 @@ static void yaffs_put_inode(struct inode *inode) } #endif -/* clear is called to tell the fs to release any per-inode data it holds */ -static void yaffs_clear_inode(struct inode *inode) + +static void yaffs_UnstitchObject(struct inode *inode, yaffs_Object *obj) +{ + /* Clear the association between the inode and + * the yaffs_Object. + */ + obj->myInode = NULL; + yaffs_InodeToObjectLV(inode) = NULL; + + /* If the object freeing was deferred, then the real + * free happens now. + * This should fix the inode inconsistency problem. + */ + yaffs_HandleDeferedFree(obj); +} + +#ifdef YAFFS_HAS_EVICT_INODE +/* yaffs_evict_inode combines into one operation what was previously done in + * yaffs_clear_inode() and yaffs_delete_inode() + * + */ +static void yaffs_evict_inode( struct inode *inode) { yaffs_Object *obj; yaffs_Device *dev; + int deleteme = 0; obj = yaffs_InodeToObject(inode); T(YAFFS_TRACE_OS, - (TSTR("yaffs_clear_inode: ino %d, count %d %s\n"), (int)inode->i_ino, + (TSTR("yaffs_evict_inode: ino %d, count %d %s\n"), (int)inode->i_ino, atomic_read(&inode->i_count), obj ? "object exists" : "null object")); + if (!inode->i_nlink && !is_bad_inode(inode)) + deleteme = 1; + truncate_inode_pages(&inode->i_data,0); + + if(deleteme && obj){ + dev = obj->myDev; + yaffs_GrossLock(dev); + yaffs_DeleteObject(obj); + yaffs_GrossUnlock(dev); + } + end_writeback(inode); if (obj) { dev = obj->myDev; yaffs_GrossLock(dev); + yaffs_UnstitchObject(inode,obj); + yaffs_GrossUnlock(dev); + } + + +} +#else + +/* clear is called to tell the fs to release any per-inode data it holds. + * The object might still exist on disk and is just being thrown out of the cache + * or else the object has actually been deleted and we're being called via + * the chain + * yaffs_delete_inode() -> clear_inode()->yaffs_clear_inode() + */ - /* Clear the association between the inode and - * the yaffs_Object. - */ - obj->myInode = NULL; - yaffs_InodeToObjectLV(inode) = NULL; +static void yaffs_clear_inode(struct inode *inode) +{ + yaffs_Object *obj; + yaffs_Device *dev; - /* If the object freeing was deferred, then the real - * free happens now. - * This should fix the inode inconsistency problem. - */ + obj = yaffs_InodeToObject(inode); - yaffs_HandleDeferedFree(obj); + T(YAFFS_TRACE_OS, + (TSTR("yaffs_clear_inode: ino %d, count %d %s\n"), (int)inode->i_ino, + atomic_read(&inode->i_count), + obj ? "object exists" : "null object")); + if (obj) { + dev = obj->myDev; + yaffs_GrossLock(dev); + yaffs_UnstitchObject(inode,obj); yaffs_GrossUnlock(dev); } @@ -849,6 +929,8 @@ static void yaffs_delete_inode(struct inode *inode) #endif clear_inode(inode); } +#endif + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) static int yaffs_file_flush(struct file *file, fl_owner_t id) @@ -1881,7 +1963,7 @@ static int yaffs_setattr(struct dentry *dentry, struct iattr *attr) if (error == 0) { int result; if (!error){ - error = inode_setattr(inode, attr); + error = yaffs_vfs_setattr(inode, attr); T(YAFFS_TRACE_OS,(TSTR("inode_setattr called\n"))); if (attr->ia_valid & ATTR_SIZE) truncate_inode_pages(&inode->i_data,attr->ia_size);