Merge branch 'master' of ssh://www.aleph1.co.uk/home/aleph1/git/yaffs2
[yaffs2.git] / yaffs_fs.c
index a372ddfcbd75ebbce1715a6596daf1e391239f16..ecf2bbe4d48bc458fff4396e663b8b1bc8a3e781 100644 (file)
@@ -43,6 +43,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
@@ -164,6 +165,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))
@@ -171,6 +173,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");
@@ -483,6 +486,17 @@ 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
+       return simple_setsize(inode, newsize);
+#endif
+
+}
+
 static unsigned yaffs_gc_control_callback(yaffs_Device *dev)
 {
        return yaffs_gc_control;
@@ -862,6 +876,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;
@@ -869,7 +884,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);
@@ -1971,8 +1985,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){
@@ -2038,9 +2054,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;
@@ -2320,12 +2335,12 @@ static int yaffs_BackgroundThread(void *data)
 
                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);