X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_fs.c;h=dc00bd5abc8ef12ffd6e76b705c858b6a41afeaa;hp=c3f11f4b81b9bd06ebb0e2c1f605471eb0098c91;hb=5d36331d84025fe263395a341cba3369b4ba5fed;hpb=af1e66bdb6be00b49d8500d01813cb207b930282 diff --git a/yaffs_fs.c b/yaffs_fs.c index c3f11f4..dc00bd5 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -35,6 +35,9 @@ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)) #define YAFFS_COMPILE_BACKGROUND +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6, 23)) +#define YAFFS_COMPILE_FREEZER +#endif #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) @@ -43,6 +46,7 @@ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)) #define YAFFS_USE_SETATTR_COPY +#define YAFFS_USE_TRUNCATE_SETSIZE #endif #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)) #define YAFFS_HAS_EVICT_INODE @@ -82,6 +86,8 @@ #ifdef YAFFS_COMPILE_BACKGROUND #include #include +#endif +#ifdef YAFFS_COMPILE_FREEZER #include #endif @@ -116,6 +122,12 @@ #define YPROC_ROOT NULL #endif +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) +#define Y_INIT_TIMER(a) init_timer(a) +#else +#define Y_INIT_TIMER(a) init_timer_on_stack(a) +#endif + #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) #define WRITE_SIZE_STR "writesize" #define WRITE_SIZE(mtd) ((mtd)->writesize) @@ -158,6 +170,7 @@ unsigned int yaffs_traceMask = YAFFS_TRACE_BAD_BLOCKS | YAFFS_TRACE_ALWAYS; unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS; unsigned int yaffs_auto_checkpoint = 1; unsigned int yaffs_gc_control = 1; +unsigned int yaffs_bg_enable = 1; /* Module Parameters */ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)) @@ -165,6 +178,7 @@ module_param(yaffs_traceMask, uint, 0644); module_param(yaffs_wr_attempts, uint, 0644); module_param(yaffs_auto_checkpoint, uint, 0644); module_param(yaffs_gc_control, uint, 0644); +module_param(yaffs_bg_enable, uint, 0644); #else MODULE_PARM(yaffs_traceMask, "i"); MODULE_PARM(yaffs_wr_attempts, "i"); @@ -477,6 +491,18 @@ static int yaffs_vfs_setattr(struct inode *inode, struct iattr *attr) } +static int yaffs_vfs_setsize(struct inode *inode, loff_t newsize) +{ +#ifdef YAFFS_USE_TRUNCATE_SETSIZE + truncate_setsize(inode,newsize); + return 0; +#else + truncate_inode_pages(&inode->i_data,newsize); + return 0; +#endif + +} + static unsigned yaffs_gc_control_callback(yaffs_Device *dev) { return yaffs_gc_control; @@ -856,6 +882,7 @@ static void yaffs_evict_inode( struct inode *inode) if (!inode->i_nlink && !is_bad_inode(inode)) deleteme = 1; truncate_inode_pages(&inode->i_data,0); + end_writeback(inode); if(deleteme && obj){ dev = obj->myDev; @@ -863,7 +890,6 @@ static void yaffs_evict_inode( struct inode *inode) yaffs_DeleteObject(obj); yaffs_GrossUnlock(dev); } - end_writeback(inode); if (obj) { dev = obj->myDev; yaffs_GrossLock(dev); @@ -1965,8 +1991,10 @@ static int yaffs_setattr(struct dentry *dentry, struct iattr *attr) if (!error){ 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); + if (attr->ia_valid & ATTR_SIZE){ + yaffs_vfs_setsize(inode,attr->ia_size); + inode->i_blocks = (inode->i_size + 511) >> 9; + } } dev = yaffs_InodeToObject(inode)->myDev; if (attr->ia_valid & ATTR_SIZE){ @@ -2032,9 +2060,8 @@ ssize_t yaffs_getxattr(struct dentry *dentry, const char *name, void *buff, yaffs_Object *obj = yaffs_InodeToObject(inode); T(YAFFS_TRACE_OS, - (TSTR("yaffs_getxattr of object %d\n"), - obj->objectId)); - + (TSTR("yaffs_getxattr \"%s\" from object %d\n"), + name, obj->objectId)); if (error == 0) { dev = obj->myDev; @@ -2298,8 +2325,9 @@ static int yaffs_BackgroundThread(void *data) (TSTR("yaffs_background starting for dev %p\n"), (void *)dev)); +#ifdef YAFFS_COMPILE_FREEZER set_freezable(); - +#endif while(context->bgRunning){ T(YAFFS_TRACE_BACKGROUND, (TSTR("yaffs_background\n"))); @@ -2307,19 +2335,20 @@ static int yaffs_BackgroundThread(void *data) if(kthread_should_stop()) break; +#ifdef YAFFS_COMPILE_FREEZER if(try_to_freeze()) continue; - +#endif yaffs_GrossLock(dev); now = jiffies; - if(time_after(now, next_dir_update)){ + if(time_after(now, next_dir_update) && yaffs_bg_enable){ yaffs_UpdateDirtyDirectories(dev); next_dir_update = now + HZ; } - if(time_after(now,next_gc)){ + if(time_after(now,next_gc) && yaffs_bg_enable){ if(!dev->isCheckpointed){ urgency = yaffs_bg_gc_urgency(dev); gcResult = yaffs_BackgroundGarbageCollect(dev, urgency); @@ -2343,7 +2372,7 @@ static int yaffs_BackgroundThread(void *data) if(time_before(expires,now)) expires = now + HZ; - init_timer_on_stack(&timer); + Y_INIT_TIMER(&timer); timer.expires = expires+1; timer.data = (unsigned long) current; timer.function = yaffs_background_waker; @@ -3188,6 +3217,7 @@ static char *yaffs_dump_dev_part1(char *buf, yaffs_Device * dev) buf += sprintf(buf, "allGCs............. %u\n", dev->allGCs); buf += sprintf(buf, "passiveGCs......... %u\n", dev->passiveGCs); buf += sprintf(buf, "oldestDirtyGCs..... %u\n", dev->oldestDirtyGCs); + buf += sprintf(buf, "nGCBlocks.......... %u\n", dev->nGCBlocks); buf += sprintf(buf, "backgroundGCs...... %u\n", dev->backgroundGCs); buf += sprintf(buf, "nRetriedWrites..... %u\n", dev->nRetriedWrites); buf += sprintf(buf, "nRetireBlocks...... %u\n", dev->nRetiredBlocks);