mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-31 14:04:26 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			181 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| --- a/fs/yaffs2/yaffs_vfs_glue.c
 | |
| +++ b/fs/yaffs2/yaffs_vfs_glue.c
 | |
| @@ -393,6 +393,84 @@ static void yaffs_touch_super(yaffs_dev_
 | |
|  static int yaffs_vfs_setattr(struct inode *, struct iattr *);
 | |
|  
 | |
|  
 | |
| +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 | |
| +
 | |
| +#define yaffs_super_to_dev(sb)    ((struct yaffs_dev_s *)sb->s_fs_info)
 | |
| +
 | |
| +static inline struct yaffs_LinuxContext *
 | |
| +yaffs_sb_to_ylc(struct super_block *sb)
 | |
| +{
 | |
| +	struct yaffs_dev_s *ydev;
 | |
| +	struct yaffs_LinuxContext *ylc;
 | |
| +
 | |
| +	ydev = yaffs_super_to_dev(sb);
 | |
| +	ylc = yaffs_dev_to_lc(ydev);
 | |
| +	return ylc;
 | |
| +}
 | |
| +
 | |
| +static inline struct super_block *yaffs_work_to_sb(struct work_struct *work)
 | |
| +{
 | |
| +	struct delayed_work *dwork;
 | |
| +	struct yaffs_LinuxContext *ylc;
 | |
| +
 | |
| +	dwork = container_of(work, struct delayed_work, work);
 | |
| +	ylc = container_of(dwork, struct yaffs_LinuxContext, sb_sync_dwork);
 | |
| +	return ylc->superBlock;
 | |
| +}
 | |
| +
 | |
| +static void yaffs_sb_sync_dwork_func(struct work_struct *work)
 | |
| +{
 | |
| +	struct super_block *sb = yaffs_work_to_sb(work);
 | |
| +
 | |
| +	yaffs_write_super(sb);
 | |
| +}
 | |
| +
 | |
| +static void yaffs_init_sb_sync_dwork(struct yaffs_LinuxContext *ylc)
 | |
| +{
 | |
| +	INIT_DELAYED_WORK(&ylc->sb_sync_dwork, yaffs_sb_sync_dwork_func);
 | |
| +}
 | |
| +
 | |
| +static void yaffs_cancel_sb_sync_dwork(struct super_block *sb)
 | |
| +{
 | |
| +	struct yaffs_LinuxContext *ylc = yaffs_sb_to_ylc(sb);
 | |
| +
 | |
| +	cancel_delayed_work_sync(&ylc->sb_sync_dwork);
 | |
| +}
 | |
| +
 | |
| +static inline bool yaffs_sb_is_dirty(struct super_block *sb)
 | |
| +{
 | |
| +	struct yaffs_LinuxContext *ylc = yaffs_sb_to_ylc(sb);
 | |
| +
 | |
| +	return !!ylc->sb_dirty;
 | |
| +}
 | |
| +
 | |
| +static inline void yaffs_sb_set_dirty(struct super_block *sb, int dirty)
 | |
| +{
 | |
| +	struct yaffs_LinuxContext *ylc = yaffs_sb_to_ylc(sb);
 | |
| +
 | |
| +	if (ylc->sb_dirty == dirty)
 | |
| +		return;
 | |
| +
 | |
| +	ylc->sb_dirty = dirty;
 | |
| +	if (dirty)
 | |
| +		queue_delayed_work(system_long_wq, &ylc->sb_sync_dwork,
 | |
| +				   msecs_to_jiffies(5000));
 | |
| +}
 | |
| +#else
 | |
| +static inline bool yaffs_sb_is_dirty(struct super_block *sb)
 | |
| +{
 | |
| +	return !!sb->s_dirt;
 | |
| +}
 | |
| +
 | |
| +static inline void yaffs_sb_set_dirty(struct super_block *sb, int dirty)
 | |
| +{
 | |
| +	sb->s_dirt = dirty;
 | |
| +}
 | |
| +
 | |
| +static inline void yaffs_init_sb_sync_dwork(struct yaffs_LinuxContext *ylc) {}
 | |
| +static inline void yaffs_cancel_sb_sync_dwork(struct super_block *sb) {}
 | |
| +#endif /* >= 3.6.0 */
 | |
| +
 | |
|  static struct address_space_operations yaffs_file_address_operations = {
 | |
|  	.readpage = yaffs_readpage,
 | |
|  	.writepage = yaffs_writepage,
 | |
| @@ -553,7 +631,9 @@ static const struct super_operations yaf
 | |
|  	.clear_inode = yaffs_clear_inode,
 | |
|  #endif
 | |
|  	.sync_fs = yaffs_sync_fs,
 | |
| +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
 | |
|  	.write_super = yaffs_write_super,
 | |
| +#endif
 | |
|  };
 | |
|  
 | |
|  
 | |
| @@ -2340,7 +2420,7 @@ static int yaffs_do_sync_fs(struct super
 | |
|  	T(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND,
 | |
|  		(TSTR("yaffs_do_sync_fs: gc-urgency %d %s %s%s\n"),
 | |
|  		gc_urgent,
 | |
| -		sb->s_dirt ? "dirty" : "clean",
 | |
| +		yaffs_sb_is_dirty(sb) ? "dirty" : "clean",
 | |
|  		request_checkpoint ? "checkpoint requested" : "no checkpoint",
 | |
|  		oneshot_checkpoint ? " one-shot" : "" ));
 | |
|  
 | |
| @@ -2349,9 +2429,9 @@ static int yaffs_do_sync_fs(struct super
 | |
|  			oneshot_checkpoint) &&
 | |
|  			!dev->is_checkpointed;
 | |
|  
 | |
| -	if (sb->s_dirt || do_checkpoint) {
 | |
| +	if (yaffs_sb_is_dirty(sb) || do_checkpoint) {
 | |
|  		yaffs_flush_super(sb, !dev->is_checkpointed && do_checkpoint);
 | |
| -		sb->s_dirt = 0;
 | |
| +		yaffs_sb_set_dirty(sb, 0);
 | |
|  		if(oneshot_checkpoint)
 | |
|  			yaffs_auto_checkpoint &= ~4;
 | |
|  	}
 | |
| @@ -2627,6 +2707,8 @@ static void yaffs_put_super(struct super
 | |
|  
 | |
|  	yaffs_flush_super(sb,1);
 | |
|  
 | |
| +	yaffs_cancel_sb_sync_dwork(sb);
 | |
| +
 | |
|  	if (yaffs_dev_to_lc(dev)->putSuperFunc)
 | |
|  		yaffs_dev_to_lc(dev)->putSuperFunc(sb);
 | |
|  
 | |
| @@ -2665,7 +2747,7 @@ static void yaffs_touch_super(yaffs_dev_
 | |
|  
 | |
|  	T(YAFFS_TRACE_OS, (TSTR("yaffs_touch_super() sb = %p\n"), sb));
 | |
|  	if (sb)
 | |
| -		sb->s_dirt = 1;
 | |
| +		yaffs_sb_set_dirty(sb, 1);
 | |
|  }
 | |
|  
 | |
|  typedef struct {
 | |
| @@ -2991,6 +3073,8 @@ static struct super_block *yaffs_interna
 | |
|  	context->dev = dev;
 | |
|  	context->superBlock = sb;
 | |
|  
 | |
| +	yaffs_init_sb_sync_dwork(context);
 | |
| +
 | |
|  	dev->read_only = read_only;
 | |
|  
 | |
|  #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
 | |
| @@ -3177,7 +3261,7 @@ static struct super_block *yaffs_interna
 | |
|  		return NULL;
 | |
|  	}
 | |
|  	sb->s_root = root;
 | |
| -	sb->s_dirt = !dev->is_checkpointed;
 | |
| +	yaffs_sb_set_dirty(sb, !dev->is_checkpointed);
 | |
|  	T(YAFFS_TRACE_ALWAYS,
 | |
|  		(TSTR("yaffs_read_super: is_checkpointed %d\n"),
 | |
|  		dev->is_checkpointed));
 | |
| --- a/fs/yaffs2/yaffs_linux.h
 | |
| +++ b/fs/yaffs2/yaffs_linux.h
 | |
| @@ -34,6 +34,11 @@ struct yaffs_LinuxContext {
 | |
|  
 | |
|  	struct task_struct *readdirProcess;
 | |
|  	unsigned mount_id;
 | |
| +
 | |
| +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 | |
| +	struct delayed_work sb_sync_dwork;	/* superblock write-out work */
 | |
| +	int sb_dirty;				/* superblock is dirty */
 | |
| +#endif
 | |
|  };
 | |
|  
 | |
|  #define yaffs_dev_to_lc(dev) ((struct yaffs_LinuxContext *)((dev)->os_context))
 | |
| --- a/fs/yaffs2/yportenv.h
 | |
| +++ b/fs/yaffs2/yportenv.h
 | |
| @@ -49,6 +49,9 @@
 | |
|  #include <linux/slab.h>
 | |
|  #include <linux/vmalloc.h>
 | |
|  #include <linux/xattr.h>
 | |
| +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
 | |
| +#include <linux/workqueue.h>
 | |
| +#endif
 | |
|  
 | |
|  #define YCHAR char
 | |
|  #define YUCHAR unsigned char
 |