Browse Source

kernel: update yaffs code to the latest version

Use the latest version of the yaffs code. Fetched from the
yaffs2 git tree and it is based on the following commit:

  commit 7e5cf0fa1b694f835cdc184a8395b229fa29f9ae
  Author: Charles Manning <[email protected]>
  Date:   Thu Aug 7 11:25:05 2014 +1200

    yaffs-direct: Basic tests. Add lpthread flag for background gc support

    Signed-off-by: Charles Manning <[email protected]>

Signed-off-by: Gabor Juhos <[email protected]>

SVN-Revision: 45188
Gabor Juhos 10 years ago
parent
commit
82f0308be9
32 changed files with 651 additions and 1298 deletions
  1. 1 1
      target/linux/generic/files/fs/yaffs2/NOTE.openwrt
  2. 12 4
      target/linux/generic/files/fs/yaffs2/yaffs_attribs.c
  3. 198 144
      target/linux/generic/files/fs/yaffs2/yaffs_guts.c
  4. 21 14
      target/linux/generic/files/fs/yaffs2/yaffs_guts.h
  5. 3 1
      target/linux/generic/files/fs/yaffs2/yaffs_mtdif.c
  6. 7 7
      target/linux/generic/files/fs/yaffs2/yaffs_packedtags1.h
  7. 0 1
      target/linux/generic/files/fs/yaffs2/yaffs_summary.c
  8. 191 27
      target/linux/generic/files/fs/yaffs2/yaffs_vfs.c
  9. 5 3
      target/linux/generic/files/fs/yaffs2/yaffs_yaffs2.c
  10. 0 155
      target/linux/generic/patches-3.14/501-yaffs-3.5-convert-to-use-kuid_t-kgid_t.patch
  11. 38 0
      target/linux/generic/patches-3.14/501-yaffs-add-missing-flush-arguments.patch
  12. 0 44
      target/linux/generic/patches-3.14/502-yaffs-3.10-disable-proc-entry.patch
  13. 0 0
      target/linux/generic/patches-3.14/502-yaffs-fix-compat-tags-handling.patch
  14. 0 129
      target/linux/generic/patches-3.14/503-yaffs-3.12-convert-readdir-to-iterate.patch
  15. 8 16
      target/linux/generic/patches-3.14/503-yaffs-add-tags-9bytes-mount-option.patch
  16. 25 0
      target/linux/generic/patches-3.14/504-yaffs-3.16-new-fops.patch
  17. 0 155
      target/linux/generic/patches-3.18/501-yaffs-3.5-convert-to-use-kuid_t-kgid_t.patch
  18. 38 0
      target/linux/generic/patches-3.18/501-yaffs-add-missing-flush-arguments.patch
  19. 0 44
      target/linux/generic/patches-3.18/502-yaffs-3.10-disable-proc-entry.patch
  20. 0 0
      target/linux/generic/patches-3.18/502-yaffs-fix-compat-tags-handling.patch
  21. 0 129
      target/linux/generic/patches-3.18/503-yaffs-3.12-convert-readdir-to-iterate.patch
  22. 8 16
      target/linux/generic/patches-3.18/503-yaffs-add-tags-9bytes-mount-option.patch
  23. 25 0
      target/linux/generic/patches-3.18/504-yaffs-3.16-new-fops.patch
  24. 0 32
      target/linux/generic/patches-3.18/505-yaffs-3.16-new-fops.patch
  25. 0 155
      target/linux/generic/patches-4.0/501-yaffs-3.5-convert-to-use-kuid_t-kgid_t.patch
  26. 38 0
      target/linux/generic/patches-4.0/501-yaffs-add-missing-flush-arguments.patch
  27. 0 44
      target/linux/generic/patches-4.0/502-yaffs-3.10-disable-proc-entry.patch
  28. 0 0
      target/linux/generic/patches-4.0/502-yaffs-fix-compat-tags-handling.patch
  29. 0 129
      target/linux/generic/patches-4.0/503-yaffs-3.12-convert-readdir-to-iterate.patch
  30. 8 16
      target/linux/generic/patches-4.0/503-yaffs-add-tags-9bytes-mount-option.patch
  31. 25 0
      target/linux/generic/patches-4.0/504-yaffs-3.16-new-fops.patch
  32. 0 32
      target/linux/generic/patches-4.0/505-yaffs-3.16-new-fops.patch

+ 1 - 1
target/linux/generic/files/fs/yaffs2/NOTE.openwrt

@@ -1,4 +1,4 @@
 The yaffs2 source has been fetched from the yaffs2 GIT tree.
 The yaffs2 source has been fetched from the yaffs2 GIT tree.
 
 
 URL: git://www.aleph1.co.uk/yaffs2
 URL: git://www.aleph1.co.uk/yaffs2
-Version: bc76682d93955cfb33051beb503ad9f8a5450578 (2013-12-03)
+Version: 7e5cf0fa1b694f835cdc184a8395b229fa29f9ae (2014-08-07)

+ 12 - 4
target/linux/generic/files/fs/yaffs2/yaffs_attribs.c

@@ -14,6 +14,14 @@
 #include "yaffs_guts.h"
 #include "yaffs_guts.h"
 #include "yaffs_attribs.h"
 #include "yaffs_attribs.h"
 
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
+#define IATTR_UID ia_uid
+#define IATTR_GID ia_gid
+#else
+#define IATTR_UID ia_uid.val
+#define IATTR_GID ia_gid.val
+#endif
+
 void yaffs_load_attribs(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh)
 void yaffs_load_attribs(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh)
 {
 {
 	obj->yst_uid = oh->yst_uid;
 	obj->yst_uid = oh->yst_uid;
@@ -77,9 +85,9 @@ int yaffs_set_attribs(struct yaffs_obj *obj, struct iattr *attr)
 	if (valid & ATTR_MODE)
 	if (valid & ATTR_MODE)
 		obj->yst_mode = attr->ia_mode;
 		obj->yst_mode = attr->ia_mode;
 	if (valid & ATTR_UID)
 	if (valid & ATTR_UID)
-		obj->yst_uid = attr->ia_uid;
+		obj->yst_uid = attr->IATTR_UID;
 	if (valid & ATTR_GID)
 	if (valid & ATTR_GID)
-		obj->yst_gid = attr->ia_gid;
+		obj->yst_gid = attr->IATTR_GID;
 
 
 	if (valid & ATTR_ATIME)
 	if (valid & ATTR_ATIME)
 		obj->yst_atime = Y_TIME_CONVERT(attr->ia_atime);
 		obj->yst_atime = Y_TIME_CONVERT(attr->ia_atime);
@@ -103,9 +111,9 @@ int yaffs_get_attribs(struct yaffs_obj *obj, struct iattr *attr)
 
 
 	attr->ia_mode = obj->yst_mode;
 	attr->ia_mode = obj->yst_mode;
 	valid |= ATTR_MODE;
 	valid |= ATTR_MODE;
-	attr->ia_uid = obj->yst_uid;
+	attr->IATTR_UID = obj->yst_uid;
 	valid |= ATTR_UID;
 	valid |= ATTR_UID;
-	attr->ia_gid = obj->yst_gid;
+	attr->IATTR_GID = obj->yst_gid;
 	valid |= ATTR_GID;
 	valid |= ATTR_GID;
 
 
 	Y_TIME_CONVERT(attr->ia_atime) = obj->yst_atime;
 	Y_TIME_CONVERT(attr->ia_atime) = obj->yst_atime;

+ 198 - 144
target/linux/generic/files/fs/yaffs2/yaffs_guts.c

@@ -631,6 +631,78 @@ static void yaffs_retire_block(struct yaffs_dev *dev, int flash_block)
 
 
 /*---------------- Name handling functions ------------*/
 /*---------------- Name handling functions ------------*/
 
 
+static void yaffs_load_name_from_oh(struct yaffs_dev *dev, YCHAR *name,
+				    const YCHAR *oh_name, int buff_size)
+{
+#ifdef CONFIG_YAFFS_AUTO_UNICODE
+	if (dev->param.auto_unicode) {
+		if (*oh_name) {
+			/* It is an ASCII name, do an ASCII to
+			 * unicode conversion */
+			const char *ascii_oh_name = (const char *)oh_name;
+			int n = buff_size - 1;
+			while (n > 0 && *ascii_oh_name) {
+				*name = *ascii_oh_name;
+				name++;
+				ascii_oh_name++;
+				n--;
+			}
+		} else {
+			strncpy(name, oh_name + 1, buff_size - 1);
+		}
+	} else {
+#else
+	(void) dev;
+	{
+#endif
+		strncpy(name, oh_name, buff_size - 1);
+	}
+}
+
+static void yaffs_load_oh_from_name(struct yaffs_dev *dev, YCHAR *oh_name,
+				    const YCHAR *name)
+{
+#ifdef CONFIG_YAFFS_AUTO_UNICODE
+
+	int is_ascii;
+	const YCHAR *w;
+
+	if (dev->param.auto_unicode) {
+
+		is_ascii = 1;
+		w = name;
+
+		/* Figure out if the name will fit in ascii character set */
+		while (is_ascii && *w) {
+			if ((*w) & 0xff00)
+				is_ascii = 0;
+			w++;
+		}
+
+		if (is_ascii) {
+			/* It is an ASCII name, so convert unicode to ascii */
+			char *ascii_oh_name = (char *)oh_name;
+			int n = YAFFS_MAX_NAME_LENGTH - 1;
+			while (n > 0 && *name) {
+				*ascii_oh_name = *name;
+				name++;
+				ascii_oh_name++;
+				n--;
+			}
+		} else {
+			/* Unicode name, so save starting at the second YCHAR */
+			*oh_name = 0;
+			strncpy(oh_name + 1, name, YAFFS_MAX_NAME_LENGTH - 2);
+		}
+	} else {
+#else
+	dev = dev;
+	{
+#endif
+		strncpy(oh_name, name, YAFFS_MAX_NAME_LENGTH - 1);
+	}
+}
+
 static u16 yaffs_calc_name_sum(const YCHAR *name)
 static u16 yaffs_calc_name_sum(const YCHAR *name)
 {
 {
 	u16 sum = 0;
 	u16 sum = 0;
@@ -1377,56 +1449,49 @@ static int yaffs_obj_cache_dirty(struct yaffs_obj *obj)
 	return 0;
 	return 0;
 }
 }
 
 
-static void yaffs_flush_file_cache(struct yaffs_obj *obj)
+static void yaffs_flush_single_cache(struct yaffs_cache *cache, int discard)
+{
+
+	if (!cache || cache->locked)
+		return;
+
+	/* Write it out and free it up  if need be.*/
+	if (cache->dirty) {
+		yaffs_wr_data_obj(cache->object,
+				  cache->chunk_id,
+				  cache->data,
+				  cache->n_bytes,
+				  1);
+
+		cache->dirty = 0;
+	}
+
+	if (discard)
+		cache->object = NULL;
+}
+
+static void yaffs_flush_file_cache(struct yaffs_obj *obj, int discard)
 {
 {
 	struct yaffs_dev *dev = obj->my_dev;
 	struct yaffs_dev *dev = obj->my_dev;
-	int lowest = -99;	/* Stop compiler whining. */
 	int i;
 	int i;
 	struct yaffs_cache *cache;
 	struct yaffs_cache *cache;
-	int chunk_written = 0;
 	int n_caches = obj->my_dev->param.n_caches;
 	int n_caches = obj->my_dev->param.n_caches;
 
 
 	if (n_caches < 1)
 	if (n_caches < 1)
 		return;
 		return;
-	do {
-		cache = NULL;
-
-		/* Find the lowest dirty chunk for this object */
-		for (i = 0; i < n_caches; i++) {
-			if (dev->cache[i].object == obj &&
-			    dev->cache[i].dirty) {
-				if (!cache ||
-				    dev->cache[i].chunk_id < lowest) {
-					cache = &dev->cache[i];
-					lowest = cache->chunk_id;
-				}
-			}
-		}
 
 
-		if (cache && !cache->locked) {
-			/* Write it out and free it up */
-			chunk_written =
-			    yaffs_wr_data_obj(cache->object,
-					      cache->chunk_id,
-					      cache->data,
-					      cache->n_bytes, 1);
-			cache->dirty = 0;
-			cache->object = NULL;
-		}
-	} while (cache && chunk_written > 0);
 
 
-	if (cache)
-		/* Hoosterman, disk full while writing cache out. */
-		yaffs_trace(YAFFS_TRACE_ERROR,
-			"yaffs tragedy: no space during cache write");
+	/* Find the chunks for this object and flush them. */
+	for (i = 0; i < n_caches; i++) {
+		cache = &dev->cache[i];
+		if (cache->object == obj)
+			yaffs_flush_single_cache(cache, discard);
+	}
+
 }
 }
 
 
-/*yaffs_flush_whole_cache(dev)
- *
- *
- */
 
 
-void yaffs_flush_whole_cache(struct yaffs_dev *dev)
+void yaffs_flush_whole_cache(struct yaffs_dev *dev, int discard)
 {
 {
 	struct yaffs_obj *obj;
 	struct yaffs_obj *obj;
 	int n_caches = dev->param.n_caches;
 	int n_caches = dev->param.n_caches;
@@ -1442,12 +1507,12 @@ void yaffs_flush_whole_cache(struct yaffs_dev *dev)
 				obj = dev->cache[i].object;
 				obj = dev->cache[i].object;
 		}
 		}
 		if (obj)
 		if (obj)
-			yaffs_flush_file_cache(obj);
+			yaffs_flush_file_cache(obj, discard);
 	} while (obj);
 	} while (obj);
 
 
 }
 }
 
 
-/* Grab us a cache chunk for use.
+/* Grab us an unused cache chunk for use.
  * First look for an empty one.
  * First look for an empty one.
  * Then look for the least recently used non-dirty one.
  * Then look for the least recently used non-dirty one.
  * Then look for the least recently used dirty one...., flush and look again.
  * Then look for the least recently used dirty one...., flush and look again.
@@ -1462,56 +1527,50 @@ static struct yaffs_cache *yaffs_grab_chunk_worker(struct yaffs_dev *dev)
 				return &dev->cache[i];
 				return &dev->cache[i];
 		}
 		}
 	}
 	}
+
 	return NULL;
 	return NULL;
 }
 }
 
 
 static struct yaffs_cache *yaffs_grab_chunk_cache(struct yaffs_dev *dev)
 static struct yaffs_cache *yaffs_grab_chunk_cache(struct yaffs_dev *dev)
 {
 {
 	struct yaffs_cache *cache;
 	struct yaffs_cache *cache;
-	struct yaffs_obj *the_obj;
 	int usage;
 	int usage;
 	int i;
 	int i;
-	int pushout;
 
 
 	if (dev->param.n_caches < 1)
 	if (dev->param.n_caches < 1)
 		return NULL;
 		return NULL;
 
 
-	/* Try find a non-dirty one... */
+	/* First look for an unused cache */
 
 
 	cache = yaffs_grab_chunk_worker(dev);
 	cache = yaffs_grab_chunk_worker(dev);
 
 
-	if (!cache) {
-		/* They were all dirty, find the LRU object and flush
-		 * its cache, then  find again.
-		 * NB what's here is not very accurate,
-		 * we actually flush the object with the LRU chunk.
-		 */
+	if (cache)
+		return cache;
 
 
-		/* With locking we can't assume we can use entry zero,
-		 * Set the_obj to a valid pointer for Coverity. */
-		the_obj = dev->cache[0].object;
-		usage = -1;
-		cache = NULL;
-		pushout = -1;
+	/*
+	 * Thery were all in use.
+	 * Find the LRU cache and flush it if it is dirty.
+	 */
 
 
-		for (i = 0; i < dev->param.n_caches; i++) {
-			if (dev->cache[i].object &&
-			    !dev->cache[i].locked &&
-			    (dev->cache[i].last_use < usage ||
-			    !cache)) {
+	usage = -1;
+	cache = NULL;
+
+	for (i = 0; i < dev->param.n_caches; i++) {
+		if (dev->cache[i].object &&
+		    !dev->cache[i].locked &&
+		    (dev->cache[i].last_use < usage || !cache)) {
 				usage = dev->cache[i].last_use;
 				usage = dev->cache[i].last_use;
-				the_obj = dev->cache[i].object;
 				cache = &dev->cache[i];
 				cache = &dev->cache[i];
-				pushout = i;
-			}
-		}
-
-		if (!cache || cache->dirty) {
-			/* Flush and try again */
-			yaffs_flush_file_cache(the_obj);
-			cache = yaffs_grab_chunk_worker(dev);
 		}
 		}
 	}
 	}
+
+#if 1
+	yaffs_flush_single_cache(cache, 1);
+#else
+	yaffs_flush_file_cache(cache->object, 1);
+	cache = yaffs_grab_chunk_worker(dev);
+#endif
+
 	return cache;
 	return cache;
 }
 }
 
 
@@ -3189,78 +3248,6 @@ static void yaffs_check_obj_details_loaded(struct yaffs_obj *in)
 	yaffs_release_temp_buffer(dev, buf);
 	yaffs_release_temp_buffer(dev, buf);
 }
 }
 
 
-static void yaffs_load_name_from_oh(struct yaffs_dev *dev, YCHAR *name,
-				    const YCHAR *oh_name, int buff_size)
-{
-#ifdef CONFIG_YAFFS_AUTO_UNICODE
-	if (dev->param.auto_unicode) {
-		if (*oh_name) {
-			/* It is an ASCII name, do an ASCII to
-			 * unicode conversion */
-			const char *ascii_oh_name = (const char *)oh_name;
-			int n = buff_size - 1;
-			while (n > 0 && *ascii_oh_name) {
-				*name = *ascii_oh_name;
-				name++;
-				ascii_oh_name++;
-				n--;
-			}
-		} else {
-			strncpy(name, oh_name + 1, buff_size - 1);
-		}
-	} else {
-#else
-	(void) dev;
-	{
-#endif
-		strncpy(name, oh_name, buff_size - 1);
-	}
-}
-
-static void yaffs_load_oh_from_name(struct yaffs_dev *dev, YCHAR *oh_name,
-				    const YCHAR *name)
-{
-#ifdef CONFIG_YAFFS_AUTO_UNICODE
-
-	int is_ascii;
-	YCHAR *w;
-
-	if (dev->param.auto_unicode) {
-
-		is_ascii = 1;
-		w = name;
-
-		/* Figure out if the name will fit in ascii character set */
-		while (is_ascii && *w) {
-			if ((*w) & 0xff00)
-				is_ascii = 0;
-			w++;
-		}
-
-		if (is_ascii) {
-			/* It is an ASCII name, so convert unicode to ascii */
-			char *ascii_oh_name = (char *)oh_name;
-			int n = YAFFS_MAX_NAME_LENGTH - 1;
-			while (n > 0 && *name) {
-				*ascii_oh_name = *name;
-				name++;
-				ascii_oh_name++;
-				n--;
-			}
-		} else {
-			/* Unicode name, so save starting at the second YCHAR */
-			*oh_name = 0;
-			strncpy(oh_name + 1, name, YAFFS_MAX_NAME_LENGTH - 2);
-		}
-	} else {
-#else
-	dev = dev;
-	{
-#endif
-		strncpy(oh_name, name, YAFFS_MAX_NAME_LENGTH - 1);
-	}
-}
-
 /* UpdateObjectHeader updates the header on NAND for an object.
 /* UpdateObjectHeader updates the header on NAND for an object.
  * If name is not NULL, then that new name is used.
  * If name is not NULL, then that new name is used.
  */
  */
@@ -3765,7 +3752,7 @@ int yaffs_resize_file(struct yaffs_obj *in, loff_t new_size)
 	struct yaffs_dev *dev = in->my_dev;
 	struct yaffs_dev *dev = in->my_dev;
 	loff_t old_size = in->variant.file_variant.file_size;
 	loff_t old_size = in->variant.file_variant.file_size;
 
 
-	yaffs_flush_file_cache(in);
+	yaffs_flush_file_cache(in, 1);
 	yaffs_invalidate_whole_cache(in);
 	yaffs_invalidate_whole_cache(in);
 
 
 	yaffs_check_gc(dev, 0);
 	yaffs_check_gc(dev, 0);
@@ -3798,12 +3785,15 @@ int yaffs_resize_file(struct yaffs_obj *in, loff_t new_size)
 	return YAFFS_OK;
 	return YAFFS_OK;
 }
 }
 
 
-int yaffs_flush_file(struct yaffs_obj *in, int update_time, int data_sync)
+int yaffs_flush_file(struct yaffs_obj *in,
+		     int update_time,
+		     int data_sync,
+		     int discard_cache)
 {
 {
 	if (!in->dirty)
 	if (!in->dirty)
 		return YAFFS_OK;
 		return YAFFS_OK;
 
 
-	yaffs_flush_file_cache(in);
+	yaffs_flush_file_cache(in, discard_cache);
 
 
 	if (data_sync)
 	if (data_sync)
 		return YAFFS_OK;
 		return YAFFS_OK;
@@ -3950,6 +3940,70 @@ int yaffs_del_obj(struct yaffs_obj *obj)
 	return ret_val;
 	return ret_val;
 }
 }
 
 
+
+static void yaffs_empty_dir_to_dir(struct yaffs_obj *from_dir,
+				   struct yaffs_obj *to_dir)
+{
+	struct yaffs_obj *obj;
+	struct list_head *lh;
+	struct list_head *n;
+
+	list_for_each_safe(lh, n, &from_dir->variant.dir_variant.children) {
+		obj = list_entry(lh, struct yaffs_obj, siblings);
+		yaffs_add_obj_to_dir(to_dir, obj);
+	}
+}
+
+struct yaffs_obj *yaffs_retype_obj(struct yaffs_obj *obj,
+				   enum yaffs_obj_type type)
+{
+	/* Tear down the old variant */
+	switch (obj->variant_type) {
+	case YAFFS_OBJECT_TYPE_FILE:
+		/* Nuke file data */
+		yaffs_resize_file(obj, 0);
+		yaffs_free_tnode(obj->my_dev, obj->variant.file_variant.top);
+		obj->variant.file_variant.top = NULL;
+		break;
+	case YAFFS_OBJECT_TYPE_DIRECTORY:
+		/* Put the children in lost and found. */
+		yaffs_empty_dir_to_dir(obj, obj->my_dev->lost_n_found);
+		if (!list_empty(&obj->variant.dir_variant.dirty))
+			list_del_init(&obj->variant.dir_variant.dirty);
+		break;
+	case YAFFS_OBJECT_TYPE_SYMLINK:
+		/* Nuke symplink data */
+		kfree(obj->variant.symlink_variant.alias);
+		obj->variant.symlink_variant.alias = NULL;
+		break;
+	case YAFFS_OBJECT_TYPE_HARDLINK:
+		list_del_init(&obj->hard_links);
+		break;
+	default:
+		break;
+	}
+
+	memset(&obj->variant, 0, sizeof(obj->variant));
+
+	/*Set up new variant if the memset is not enough. */
+	switch (type) {
+	case YAFFS_OBJECT_TYPE_DIRECTORY:
+		INIT_LIST_HEAD(&obj->variant.dir_variant.children);
+		INIT_LIST_HEAD(&obj->variant.dir_variant.dirty);
+		break;
+	case YAFFS_OBJECT_TYPE_FILE:
+	case YAFFS_OBJECT_TYPE_SYMLINK:
+	case YAFFS_OBJECT_TYPE_HARDLINK:
+	default:
+		break;
+	}
+
+	obj->variant_type = type;
+
+	return obj;
+
+}
+
 static int yaffs_unlink_worker(struct yaffs_obj *obj)
 static int yaffs_unlink_worker(struct yaffs_obj *obj)
 {
 {
 	int del_now = 0;
 	int del_now = 0;
@@ -4678,7 +4732,7 @@ int yaffs_guts_ll_init(struct yaffs_dev *dev)
 }
 }
 
 
 
 
-int yaffs_format_dev(struct yaffs_dev *dev)
+int yaffs_guts_format_dev(struct yaffs_dev *dev)
 {
 {
 	int i;
 	int i;
 	enum yaffs_block_state state;
 	enum yaffs_block_state state;

+ 21 - 14
target/linux/generic/files/fs/yaffs2/yaffs_guts.h

@@ -144,12 +144,12 @@ struct yaffs_cache {
  */
  */
 
 
 struct yaffs_tags {
 struct yaffs_tags {
-	unsigned chunk_id:20;
-	unsigned serial_number:2;
-	unsigned n_bytes_lsb:10;
-	unsigned obj_id:18;
-	unsigned ecc:12;
-	unsigned n_bytes_msb:2;
+	u32 chunk_id:20;
+	u32 serial_number:2;
+	u32 n_bytes_lsb:10;
+	u32 obj_id:18;
+	u32 ecc:12;
+	u32 n_bytes_msb:2;
 };
 };
 
 
 union yaffs_tags_union {
 union yaffs_tags_union {
@@ -287,9 +287,9 @@ enum yaffs_block_state {
 
 
 struct yaffs_block_info {
 struct yaffs_block_info {
 
 
-	int soft_del_pages:10;	/* number of soft deleted pages */
-	int pages_in_use:10;	/* number of pages in use */
-	unsigned block_state:4;	/* One of the above block states. */
+	s32 soft_del_pages:10;	/* number of soft deleted pages */
+	s32 pages_in_use:10;	/* number of pages in use */
+	u32 block_state:4;	/* One of the above block states. */
 				/* NB use unsigned because enum is sometimes
 				/* NB use unsigned because enum is sometimes
 				 * an int */
 				 * an int */
 	u32 needs_retiring:1;	/* Data has failed on this block, */
 	u32 needs_retiring:1;	/* Data has failed on this block, */
@@ -688,8 +688,8 @@ struct yaffs_dev {
 	/* Block Info */
 	/* Block Info */
 	struct yaffs_block_info *block_info;
 	struct yaffs_block_info *block_info;
 	u8 *chunk_bits;		/* bitmap of chunks in use */
 	u8 *chunk_bits;		/* bitmap of chunks in use */
-	unsigned block_info_alt:1;	/* allocated using alternative alloc */
-	unsigned chunk_bits_alt:1;	/* allocated using alternative alloc */
+	u8 block_info_alt:1;	/* allocated using alternative alloc */
+	u8 chunk_bits_alt:1;	/* allocated using alternative alloc */
 	int chunk_bit_stride;	/* Number of bytes of chunk_bits per block.
 	int chunk_bit_stride;	/* Number of bytes of chunk_bits per block.
 				 * Must be consistent with chunks_per_block.
 				 * Must be consistent with chunks_per_block.
 				 */
 				 */
@@ -776,6 +776,7 @@ struct yaffs_dev {
 	u32 n_page_writes;
 	u32 n_page_writes;
 	u32 n_page_reads;
 	u32 n_page_reads;
 	u32 n_erasures;
 	u32 n_erasures;
+	u32 n_bad_queries;
 	u32 n_bad_markings;
 	u32 n_bad_markings;
 	u32 n_erase_failures;
 	u32 n_erase_failures;
 	u32 n_gc_copies;
 	u32 n_gc_copies;
@@ -854,6 +855,9 @@ int yaffs_rename_obj(struct yaffs_obj *old_dir, const YCHAR * old_name,
 
 
 int yaffs_unlinker(struct yaffs_obj *dir, const YCHAR * name);
 int yaffs_unlinker(struct yaffs_obj *dir, const YCHAR * name);
 int yaffs_del_obj(struct yaffs_obj *obj);
 int yaffs_del_obj(struct yaffs_obj *obj);
+struct yaffs_obj *yaffs_retype_obj(struct yaffs_obj *obj,
+				   enum yaffs_obj_type type);
+
 
 
 int yaffs_get_obj_name(struct yaffs_obj *obj, YCHAR * name, int buffer_size);
 int yaffs_get_obj_name(struct yaffs_obj *obj, YCHAR * name, int buffer_size);
 loff_t yaffs_get_obj_length(struct yaffs_obj *obj);
 loff_t yaffs_get_obj_length(struct yaffs_obj *obj);
@@ -872,10 +876,13 @@ struct yaffs_obj *yaffs_create_file(struct yaffs_obj *parent,
 				    const YCHAR *name, u32 mode, u32 uid,
 				    const YCHAR *name, u32 mode, u32 uid,
 				    u32 gid);
 				    u32 gid);
 
 
-int yaffs_flush_file(struct yaffs_obj *obj, int update_time, int data_sync);
+int yaffs_flush_file(struct yaffs_obj *in,
+		     int update_time,
+		     int data_sync,
+		     int discard_cache);
 
 
 /* Flushing and checkpointing */
 /* Flushing and checkpointing */
-void yaffs_flush_whole_cache(struct yaffs_dev *dev);
+void yaffs_flush_whole_cache(struct yaffs_dev *dev, int discard);
 
 
 int yaffs_checkpoint_save(struct yaffs_dev *dev);
 int yaffs_checkpoint_save(struct yaffs_dev *dev);
 int yaffs_checkpoint_restore(struct yaffs_dev *dev);
 int yaffs_checkpoint_restore(struct yaffs_dev *dev);
@@ -978,7 +985,7 @@ u32 yaffs_get_group_base(struct yaffs_dev *dev, struct yaffs_tnode *tn,
 
 
 int yaffs_is_non_empty_dir(struct yaffs_obj *obj);
 int yaffs_is_non_empty_dir(struct yaffs_obj *obj);
 
 
-int yaffs_format_dev(struct yaffs_dev *dev);
+int yaffs_guts_format_dev(struct yaffs_dev *dev);
 
 
 void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr,
 void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr,
 				int *chunk_out, u32 *offset_out);
 				int *chunk_out, u32 *offset_out);

+ 3 - 1
target/linux/generic/files/fs/yaffs2/yaffs_mtdif.c

@@ -22,12 +22,14 @@
 #include "linux/kernel.h"
 #include "linux/kernel.h"
 #include "linux/version.h"
 #include "linux/version.h"
 #include "linux/types.h"
 #include "linux/types.h"
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+#include "uapi/linux/major.h"
+#endif
 
 
 #include "yaffs_trace.h"
 #include "yaffs_trace.h"
 #include "yaffs_guts.h"
 #include "yaffs_guts.h"
 #include "yaffs_linux.h"
 #include "yaffs_linux.h"
 
 
-
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
 #define MTD_OPS_AUTO_OOB MTD_OOB_AUTO
 #define MTD_OPS_AUTO_OOB MTD_OOB_AUTO
 #endif
 #endif

+ 7 - 7
target/linux/generic/files/fs/yaffs2/yaffs_packedtags1.h

@@ -21,13 +21,13 @@
 #include "yaffs_guts.h"
 #include "yaffs_guts.h"
 
 
 struct yaffs_packed_tags1 {
 struct yaffs_packed_tags1 {
-	unsigned chunk_id:20;
-	unsigned serial_number:2;
-	unsigned n_bytes:10;
-	unsigned obj_id:18;
-	unsigned ecc:12;
-	unsigned deleted:1;
-	unsigned unused_stuff:1;
+	u32 chunk_id:20;
+	u32 serial_number:2;
+	u32 n_bytes:10;
+	u32 obj_id:18;
+	u32 ecc:12;
+	u32 deleted:1;
+	u32 unused_stuff:1;
 	unsigned should_be_ff;
 	unsigned should_be_ff;
 
 
 };
 };

+ 0 - 1
target/linux/generic/files/fs/yaffs2/yaffs_summary.c

@@ -235,7 +235,6 @@ int yaffs_summary_read(struct yaffs_dev *dev,
 	if (result == YAFFS_OK) {
 	if (result == YAFFS_OK) {
 		/* Verify header */
 		/* Verify header */
 		if (hdr.version != YAFFS_SUMMARY_VERSION ||
 		if (hdr.version != YAFFS_SUMMARY_VERSION ||
-		    hdr.block != blk ||
 		    hdr.seq != bi->seq_number ||
 		    hdr.seq != bi->seq_number ||
 		    hdr.sum != yaffs_summary_sum(dev))
 		    hdr.sum != yaffs_summary_sum(dev))
 			result = YAFFS_FAIL;
 			result = YAFFS_FAIL;

+ 191 - 27
target/linux/generic/files/fs/yaffs2/yaffs_vfs.c

@@ -236,6 +236,15 @@ MODULE_PARM(yaffs_gc_control, "i");
 #define Y_CLEAR_INODE(i) end_writeback(i)
 #define Y_CLEAR_INODE(i) end_writeback(i)
 #endif
 #endif
 
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
+#define YAFFS_USE_DIR_ITERATE
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
+#define YAFFS_NEW_PROCFS
+#include <linux/seq_file.h>
+#endif
+
 
 
 #define update_dir_time(dir) do {\
 #define update_dir_time(dir) do {\
 			(dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \
 			(dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \
@@ -1023,7 +1032,11 @@ static int yaffs_readlink(struct dentry *dentry, char __user * buffer,
 	if (!alias)
 	if (!alias)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)
 	ret = vfs_readlink(dentry, buffer, buflen, alias);
 	ret = vfs_readlink(dentry, buffer, buflen, alias);
+#else
+	ret = readlink_copy(buffer, buflen, alias);
+#endif
 	kfree(alias);
 	kfree(alias);
 	return ret;
 	return ret;
 }
 }
@@ -1206,6 +1219,23 @@ struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
 #define YCRED(x) (x->cred)
 #define YCRED(x) (x->cred)
 #endif
 #endif
 
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)
+#define YPROC_uid(p) (YCRED(p)->fsuid)
+#define YPROC_gid(p) (YCRED(p)->fsgid)
+#define EXTRACT_gid(x) x
+#define EXTRACT_uid(x) x
+#define MAKE_gid(x) x
+#define MAKE_uid(x) x
+#else
+#define YPROC_uid(p) from_kuid(&init_user_ns, YCRED(p)->fsuid)
+#define YPROC_gid(p) from_kgid(&init_user_ns, YCRED(p)->fsgid)
+#define EXTRACT_gid(x) from_kgid(&init_user_ns, x)
+#define EXTRACT_uid(x) from_kuid(&init_user_ns, x)
+#define MAKE_gid(x) make_kgid(&init_user_ns, x)
+#define MAKE_uid(x) make_kuid(&init_user_ns, x)
+#endif
+
+
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
 		       dev_t rdev)
 		       dev_t rdev)
@@ -1225,9 +1255,9 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
 	struct yaffs_obj *parent = yaffs_inode_to_obj(dir);
 	struct yaffs_obj *parent = yaffs_inode_to_obj(dir);
 
 
 	int error = -ENOSPC;
 	int error = -ENOSPC;
-	uid_t uid = YCRED(current)->fsuid;
+	uid_t uid = YPROC_uid(current);
 	gid_t gid =
 	gid_t gid =
-	    (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
+	    (dir->i_mode & S_ISGID) ? EXTRACT_gid(dir->i_gid) : YPROC_gid(current);
 
 
 	if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
 	if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
 		mode |= S_ISGID;
 		mode |= S_ISGID;
@@ -1424,9 +1454,9 @@ static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
 {
 {
 	struct yaffs_obj *obj;
 	struct yaffs_obj *obj;
 	struct yaffs_dev *dev;
 	struct yaffs_dev *dev;
-	uid_t uid = YCRED(current)->fsuid;
+	uid_t uid = YPROC_uid(current);
 	gid_t gid =
 	gid_t gid =
-	    (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
+	    (dir->i_mode & S_ISGID) ? EXTRACT_gid(dir->i_gid) : YPROC_gid(current);
 
 
 	yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
 	yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
 
 
@@ -1674,6 +1704,77 @@ static void yaffs_remove_obj_callback(struct yaffs_obj *obj)
 
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 
 
+#ifdef YAFFS_USE_DIR_ITERATE
+static int yaffs_iterate(struct file *f, struct dir_context *dc)
+{
+	struct yaffs_obj *obj;
+	struct yaffs_dev *dev;
+	struct yaffs_search_context *sc;
+	unsigned long curoffs;
+	struct yaffs_obj *l;
+	int ret_val = 0;
+
+	char name[YAFFS_MAX_NAME_LENGTH + 1];
+
+	obj = yaffs_dentry_to_obj(f->f_dentry);
+	dev = obj->my_dev;
+
+	yaffs_gross_lock(dev);
+
+	yaffs_dev_to_lc(dev)->readdir_process = current;
+
+	sc = yaffs_new_search(obj);
+	if (!sc) {
+		ret_val = -ENOMEM;
+		goto out;
+	}
+
+	if (!dir_emit_dots(f, dc))
+		return 0;
+
+	curoffs = 1;
+
+	while (sc->next_return) {
+		curoffs++;
+		l = sc->next_return;
+		if (curoffs >= dc->pos) {
+			int this_inode = yaffs_get_obj_inode(l);
+			int this_type = yaffs_get_obj_type(l);
+
+			yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
+			yaffs_trace(YAFFS_TRACE_OS,
+				"yaffs_readdir: %s inode %d",
+				name, yaffs_get_obj_inode(l));
+
+			yaffs_gross_unlock(dev);
+
+			if (!dir_emit(dc,
+				      name,
+				      strlen(name),
+				      this_inode,
+				      this_type)) {
+				yaffs_gross_lock(dev);
+				goto out;
+			}
+
+			yaffs_gross_lock(dev);
+
+			dc->pos++;
+			f->f_pos++;
+		}
+		yaffs_search_advance(sc);
+	}
+
+out:
+	yaffs_search_end(sc);
+	yaffs_dev_to_lc(dev)->readdir_process = NULL;
+	yaffs_gross_unlock(dev);
+
+	return ret_val;
+}
+
+#else
+
 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
 {
 {
 	struct yaffs_obj *obj;
 	struct yaffs_obj *obj;
@@ -1781,9 +1882,15 @@ out:
 	return ret_val;
 	return ret_val;
 }
 }
 
 
+#endif
+
 static const struct file_operations yaffs_dir_operations = {
 static const struct file_operations yaffs_dir_operations = {
 	.read = generic_read_dir,
 	.read = generic_read_dir,
+#ifdef YAFFS_USE_DIR_ITERATE
+	.iterate = yaffs_iterate,
+#else
 	.readdir = yaffs_readdir,
 	.readdir = yaffs_readdir,
+#endif
 	.fsync = yaffs_sync_object,
 	.fsync = yaffs_sync_object,
 	.llseek = generic_file_llseek,
 	.llseek = generic_file_llseek,
 };
 };
@@ -1829,8 +1936,8 @@ static void yaffs_fill_inode_from_obj(struct inode *inode,
 
 
 		inode->i_ino = obj->obj_id;
 		inode->i_ino = obj->obj_id;
 		inode->i_mode = obj->yst_mode;
 		inode->i_mode = obj->yst_mode;
-		inode->i_uid = obj->yst_uid;
-		inode->i_gid = obj->yst_gid;
+		inode->i_uid = MAKE_uid(obj->yst_uid);
+		inode->i_gid = MAKE_gid(obj->yst_gid);
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
 		inode->i_blksize = inode->i_sb->s_blocksize;
 		inode->i_blksize = inode->i_sb->s_blocksize;
 #endif
 #endif
@@ -1856,7 +1963,7 @@ static void yaffs_fill_inode_from_obj(struct inode *inode,
 
 
 		yaffs_trace(YAFFS_TRACE_OS,
 		yaffs_trace(YAFFS_TRACE_OS,
 			"yaffs_fill_inode mode %x uid %d gid %d size %lld count %d",
 			"yaffs_fill_inode mode %x uid %d gid %d size %lld count %d",
-			inode->i_mode, inode->i_uid, inode->i_gid,
+			inode->i_mode, obj->yst_uid, obj->yst_gid,
 			inode->i_size, atomic_read(&inode->i_count));
 			inode->i_size, atomic_read(&inode->i_count));
 
 
 		switch (obj->yst_mode & S_IFMT) {
 		switch (obj->yst_mode & S_IFMT) {
@@ -2670,7 +2777,7 @@ static struct super_block *yaffs_internal_read_super(int yaffs_version,
 
 
 	/* Get the device */
 	/* Get the device */
 	mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
 	mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
-	if (!mtd) {
+	if (IS_ERR(mtd)) {
 		yaffs_trace(YAFFS_TRACE_ALWAYS,
 		yaffs_trace(YAFFS_TRACE_ALWAYS,
 			"yaffs: MTD device %u either not valid or unavailable",
 			"yaffs: MTD device %u either not valid or unavailable",
 			MINOR(sb->s_dev));
 			MINOR(sb->s_dev));
@@ -2713,15 +2820,11 @@ static struct super_block *yaffs_internal_read_super(int yaffs_version,
 	context = kmalloc(sizeof(struct yaffs_linux_context), GFP_KERNEL);
 	context = kmalloc(sizeof(struct yaffs_linux_context), GFP_KERNEL);
 
 
 	if (!dev || !context) {
 	if (!dev || !context) {
-		if (dev)
-			kfree(dev);
-		if (context)
-			kfree(context);
+		kfree(dev);
+		kfree(context);
 		dev = NULL;
 		dev = NULL;
 		context = NULL;
 		context = NULL;
-	}
 
 
-	if (!dev) {
 		/* Deep shit could not allocate device structure */
 		/* Deep shit could not allocate device structure */
 		yaffs_trace(YAFFS_TRACE_ALWAYS,
 		yaffs_trace(YAFFS_TRACE_ALWAYS,
 			"yaffs_read_super: Failed trying to allocate struct yaffs_dev."
 			"yaffs_read_super: Failed trying to allocate struct yaffs_dev."
@@ -3188,7 +3291,7 @@ static struct {
 
 
 #define MAX_MASK_NAME_LENGTH 40
 #define MAX_MASK_NAME_LENGTH 40
 static int yaffs_proc_write_trace_options(struct file *file, const char *buf,
 static int yaffs_proc_write_trace_options(struct file *file, const char *buf,
-					  unsigned long count, void *data)
+					  unsigned long count)
 {
 {
 	unsigned rg = 0, mask_bitfield;
 	unsigned rg = 0, mask_bitfield;
 	char *end;
 	char *end;
@@ -3289,7 +3392,7 @@ static int yaffs_proc_write_trace_options(struct file *file, const char *buf,
  */
  */
 
 
 static int yaffs_proc_debug_write(struct file *file, const char *buf,
 static int yaffs_proc_debug_write(struct file *file, const char *buf,
-					  unsigned long count, void *data)
+					  unsigned long count)
 {
 {
 
 
 	char str[100];
 	char str[100];
@@ -3301,7 +3404,7 @@ static int yaffs_proc_debug_write(struct file *file, const char *buf,
 	struct list_head *item;
 	struct list_head *item;
 
 
 	memset(str, 0, sizeof(str));
 	memset(str, 0, sizeof(str));
-	memcpy(str, buf, min(count, sizeof(str) -1));
+	memcpy(str, buf, min((size_t)count, sizeof(str) -1));
 
 
 	cmd = str[1];
 	cmd = str[1];
 
 
@@ -3364,12 +3467,18 @@ static int yaffs_proc_debug_write(struct file *file, const char *buf,
 	return count;
 	return count;
 }
 }
 
 
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
 static int yaffs_proc_write(struct file *file, const char *buf,
 static int yaffs_proc_write(struct file *file, const char *buf,
-			    unsigned long count, void *data)
+			    unsigned long count, void *ppos)
+#else
+static ssize_t yaffs_proc_write(struct file *file, const char __user *buf,
+			    size_t count, loff_t *ppos)
+#endif
 {
 {
 	if (buf[0] == '.')
 	if (buf[0] == '.')
-		return yaffs_proc_debug_write(file, buf, count, data);
-	return yaffs_proc_write_trace_options(file, buf, count, data);
+		return yaffs_proc_debug_write(file, buf, count);
+	return yaffs_proc_write_trace_options(file, buf, count);
 }
 }
 
 
 /* Stuff to handle installation of file systems */
 /* Stuff to handle installation of file systems */
@@ -3384,16 +3493,52 @@ static struct file_system_to_install fs_to_install[] = {
 	{NULL, 0}
 	{NULL, 0}
 };
 };
 
 
-static int __init init_yaffs_fs(void)
+
+#ifdef YAFFS_NEW_PROCFS
+static int yaffs_proc_show(struct seq_file *m, void *v)
 {
 {
-	int error = 0;
-	struct file_system_to_install *fsinst;
+	/* FIXME: Unify in a better way? */
+	char buffer[512];
+	char *start;
+	int len;
 
 
-	yaffs_trace(YAFFS_TRACE_ALWAYS,
-		"yaffs built " __DATE__ " " __TIME__ " Installing.");
+	len = yaffs_proc_read(buffer, &start, 0, sizeof(buffer), NULL, NULL);
+	seq_puts(m, buffer);
+	return 0;
+}
+
+static int yaffs_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, yaffs_proc_show, NULL);
+}
+
+static struct file_operations procfs_ops = {
+	.owner = THIS_MODULE,
+	.open  = yaffs_proc_open,
+	.read  = seq_read,
+	.write = yaffs_proc_write,
+};
+
+static int yaffs_procfs_init(void)
+{
+	/* Install the proc_fs entries */
+	my_proc_entry = proc_create("yaffs",
+				    S_IRUGO | S_IFREG,
+				    YPROC_ROOT,
+				    &procfs_ops);
+
+	if (my_proc_entry) {
+		return 0;
+	} else {
+		return -ENOMEM;
+	}
+}
+
+#else
 
 
-	mutex_init(&yaffs_context_lock);
 
 
+static int yaffs_procfs_init(void)
+{
 	/* Install the proc_fs entries */
 	/* Install the proc_fs entries */
 	my_proc_entry = create_proc_entry("yaffs",
 	my_proc_entry = create_proc_entry("yaffs",
 					  S_IRUGO | S_IFREG, YPROC_ROOT);
 					  S_IRUGO | S_IFREG, YPROC_ROOT);
@@ -3402,9 +3547,28 @@ static int __init init_yaffs_fs(void)
 		my_proc_entry->write_proc = yaffs_proc_write;
 		my_proc_entry->write_proc = yaffs_proc_write;
 		my_proc_entry->read_proc = yaffs_proc_read;
 		my_proc_entry->read_proc = yaffs_proc_read;
 		my_proc_entry->data = NULL;
 		my_proc_entry->data = NULL;
+		return 0;
 	} else {
 	} else {
 		return -ENOMEM;
 		return -ENOMEM;
-        }
+	}
+}
+
+#endif
+
+
+static int __init init_yaffs_fs(void)
+{
+	int error = 0;
+	struct file_system_to_install *fsinst;
+
+	yaffs_trace(YAFFS_TRACE_ALWAYS,
+		"yaffs built " __DATE__ " " __TIME__ " Installing.");
+
+	mutex_init(&yaffs_context_lock);
+
+	error = yaffs_procfs_init();
+	if (error)
+		return error;
 
 
 	/* Now add the file system entries */
 	/* Now add the file system entries */
 
 

+ 5 - 3
target/linux/generic/files/fs/yaffs2/yaffs_yaffs2.c

@@ -1193,12 +1193,14 @@ static inline int yaffs2_scan_chunk(struct yaffs_dev *dev,
 		}
 		}
 
 
 		if (!in->valid && in->variant_type !=
 		if (!in->valid && in->variant_type !=
-		    (oh ? oh->type : tags.extra_obj_type))
+		    (oh ? oh->type : tags.extra_obj_type)) {
 			yaffs_trace(YAFFS_TRACE_ERROR,
 			yaffs_trace(YAFFS_TRACE_ERROR,
-				"yaffs tragedy: Bad object type, %d != %d, for object %d at chunk %d during scan",
+				"yaffs tragedy: Bad type, %d != %d, for object %d at chunk %d during scan",
 				oh ? oh->type : tags.extra_obj_type,
 				oh ? oh->type : tags.extra_obj_type,
 				in->variant_type, tags.obj_id,
 				in->variant_type, tags.obj_id,
 				chunk);
 				chunk);
+			in = yaffs_retype_obj(in, oh ? oh->type : tags.extra_obj_type);
+		}
 
 
 		if (!in->valid &&
 		if (!in->valid &&
 		    (tags.obj_id == YAFFS_OBJECTID_ROOT ||
 		    (tags.obj_id == YAFFS_OBJECTID_ROOT ||
@@ -1439,7 +1441,7 @@ int yaffs2_scan_backwards(struct yaffs_dev *dev)
 		bi++;
 		bi++;
 	}
 	}
 
 
-	yaffs_trace(YAFFS_TRACE_SCAN, "%d blocks to be sorted...", n_to_scan);
+	yaffs_trace(YAFFS_TRACE_ALWAYS, "%d blocks to be sorted...", n_to_scan);
 
 
 	cond_resched();
 	cond_resched();
 
 

+ 0 - 155
target/linux/generic/patches-3.14/501-yaffs-3.5-convert-to-use-kuid_t-kgid_t.patch

@@ -1,155 +0,0 @@
---- a/fs/yaffs2/yaffs_vfs.c
-+++ b/fs/yaffs2/yaffs_vfs.c
-@@ -329,6 +329,33 @@ static int yaffs_readpage(struct file *f
- 	return ret;
- }
- 
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
-+#define YCRED_FSUID()	from_kuid(&init_user_ns, current_fsuid())
-+#define YCRED_FSGID()	from_kgid(&init_user_ns, current_fsgid())
-+#else
-+#define YCRED_FSUID()	YCRED(current)->fsuid
-+#define YCRED_FSGID()	YCRED(current)->fsgid
-+
-+static inline uid_t i_uid_read(const struct inode *inode)
-+{
-+	return inode->i_uid;
-+}
-+
-+static inline gid_t i_gid_read(const struct inode *inode)
-+{
-+	return inode->i_gid;
-+}
-+
-+static inline void i_uid_write(struct inode *inode, uid_t uid)
-+{
-+	inode->i_uid = uid;
-+}
-+
-+static inline void i_gid_write(struct inode *inode, gid_t gid)
-+{
-+	inode->i_gid = gid;
-+}
-+#endif
- 
- static void yaffs_set_super_dirty_val(struct yaffs_dev *dev, int val)
- {
-@@ -1225,9 +1252,9 @@ static int yaffs_mknod(struct inode *dir
- 	struct yaffs_obj *parent = yaffs_inode_to_obj(dir);
- 
- 	int error = -ENOSPC;
--	uid_t uid = YCRED(current)->fsuid;
-+	uid_t uid = YCRED_FSUID();
- 	gid_t gid =
--	    (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
-+	    (dir->i_mode & S_ISGID) ? i_gid_read(dir) : YCRED_FSGID();
- 
- 	if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
- 		mode |= S_ISGID;
-@@ -1424,9 +1451,9 @@ static int yaffs_symlink(struct inode *d
- {
- 	struct yaffs_obj *obj;
- 	struct yaffs_dev *dev;
--	uid_t uid = YCRED(current)->fsuid;
-+	uid_t uid = YCRED_FSUID();
- 	gid_t gid =
--	    (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
-+	    (dir->i_mode & S_ISGID) ? i_gid_read(dir) : YCRED_FSGID();
- 
- 	yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
- 
-@@ -1829,8 +1856,8 @@ static void yaffs_fill_inode_from_obj(st
- 
- 		inode->i_ino = obj->obj_id;
- 		inode->i_mode = obj->yst_mode;
--		inode->i_uid = obj->yst_uid;
--		inode->i_gid = obj->yst_gid;
-+		i_uid_write(inode, obj->yst_uid);
-+		i_gid_write(inode, obj->yst_gid);
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
- 		inode->i_blksize = inode->i_sb->s_blocksize;
- #endif
-@@ -1856,7 +1883,7 @@ static void yaffs_fill_inode_from_obj(st
- 
- 		yaffs_trace(YAFFS_TRACE_OS,
- 			"yaffs_fill_inode mode %x uid %d gid %d size %lld count %d",
--			inode->i_mode, inode->i_uid, inode->i_gid,
-+			inode->i_mode, i_uid_read(inode), i_gid_read(inode),
- 			inode->i_size, atomic_read(&inode->i_count));
- 
- 		switch (obj->yst_mode & S_IFMT) {
---- a/fs/yaffs2/yaffs_attribs.c
-+++ b/fs/yaffs2/yaffs_attribs.c
-@@ -14,6 +14,48 @@
- #include "yaffs_guts.h"
- #include "yaffs_attribs.h"
- 
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
-+static inline uid_t ia_uid_read(const struct iattr *iattr)
-+{
-+	return from_kuid(&init_user_ns, iattr->ia_uid);
-+}
-+
-+static inline gid_t ia_gid_read(const struct iattr *iattr)
-+{
-+	return from_kgid(&init_user_ns, iattr->ia_gid);
-+}
-+
-+static inline void ia_uid_write(struct iattr *iattr, uid_t uid)
-+{
-+	iattr->ia_uid = make_kuid(&init_user_ns, uid);
-+}
-+
-+static inline void ia_gid_write(struct iattr *iattr, gid_t gid)
-+{
-+	iattr->ia_gid = make_kgid(&init_user_ns, gid);
-+}
-+#else
-+static inline uid_t ia_uid_read(const struct iattr *iattr)
-+{
-+	return iattr->ia_uid;
-+}
-+
-+static inline gid_t ia_gid_read(const struct iattr *inode)
-+{
-+	return iattr->ia_gid;
-+}
-+
-+static inline void ia_uid_write(struct iattr *iattr, uid_t uid)
-+{
-+	iattr->ia_uid = uid;
-+}
-+
-+static inline void ia_gid_write(struct iattr *iattr, gid_t gid)
-+{
-+	iattr->ia_gid = gid;
-+}
-+#endif
-+
- void yaffs_load_attribs(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh)
- {
- 	obj->yst_uid = oh->yst_uid;
-@@ -77,9 +119,9 @@ int yaffs_set_attribs(struct yaffs_obj *
- 	if (valid & ATTR_MODE)
- 		obj->yst_mode = attr->ia_mode;
- 	if (valid & ATTR_UID)
--		obj->yst_uid = attr->ia_uid;
-+		obj->yst_uid =  ia_uid_read(attr);
- 	if (valid & ATTR_GID)
--		obj->yst_gid = attr->ia_gid;
-+		obj->yst_gid =  ia_gid_read(attr);
- 
- 	if (valid & ATTR_ATIME)
- 		obj->yst_atime = Y_TIME_CONVERT(attr->ia_atime);
-@@ -103,9 +145,9 @@ int yaffs_get_attribs(struct yaffs_obj *
- 
- 	attr->ia_mode = obj->yst_mode;
- 	valid |= ATTR_MODE;
--	attr->ia_uid = obj->yst_uid;
-+	ia_uid_write(attr, obj->yst_uid);
- 	valid |= ATTR_UID;
--	attr->ia_gid = obj->yst_gid;
-+	ia_gid_write(attr, obj->yst_gid);
- 	valid |= ATTR_GID;
- 
- 	Y_TIME_CONVERT(attr->ia_atime) = obj->yst_atime;

+ 38 - 0
target/linux/generic/patches-3.14/501-yaffs-add-missing-flush-arguments.patch

@@ -0,0 +1,38 @@
+--- a/fs/yaffs2/yaffs_vfs.c
++++ b/fs/yaffs2/yaffs_vfs.c
+@@ -738,7 +738,7 @@ static int yaffs_file_flush(struct file
+ 
+ 	yaffs_gross_lock(dev);
+ 
+-	yaffs_flush_file(obj, 1, 0);
++	yaffs_flush_file(obj, 1, 0, 1);
+ 
+ 	yaffs_gross_unlock(dev);
+ 
+@@ -768,7 +768,7 @@ static int yaffs_sync_object(struct file
+ 	yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC,
+ 		"yaffs_sync_object");
+ 	yaffs_gross_lock(dev);
+-	yaffs_flush_file(obj, 1, datasync);
++	yaffs_flush_file(obj, 1, datasync, 1);
+ 	yaffs_gross_unlock(dev);
+ 	return 0;
+ }
+@@ -2187,7 +2187,7 @@ static void yaffs_flush_inodes(struct su
+ 			yaffs_trace(YAFFS_TRACE_OS,
+ 				"flushing obj %d",
+ 				obj->obj_id);
+-			yaffs_flush_file(obj, 1, 0);
++			yaffs_flush_file(obj, 1, 0, 1);
+ 		}
+ 	}
+ }
+@@ -2200,7 +2200,7 @@ static void yaffs_flush_super(struct sup
+ 
+ 	yaffs_flush_inodes(sb);
+ 	yaffs_update_dirty_dirs(dev);
+-	yaffs_flush_whole_cache(dev);
++	yaffs_flush_whole_cache(dev, 1);
+ 	if (do_checkpoint)
+ 		yaffs_checkpoint_save(dev);
+ }

+ 0 - 44
target/linux/generic/patches-3.14/502-yaffs-3.10-disable-proc-entry.patch

@@ -1,44 +0,0 @@
---- a/fs/yaffs2/yaffs_vfs.c
-+++ b/fs/yaffs2/yaffs_vfs.c
-@@ -3025,6 +3025,7 @@ static DECLARE_FSTYPE(yaffs2_fs_type, "y
- #endif
- 
- 
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
- static struct proc_dir_entry *my_proc_entry;
- 
- static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev)
-@@ -3398,6 +3399,7 @@ static int yaffs_proc_write(struct file
- 		return yaffs_proc_debug_write(file, buf, count, data);
- 	return yaffs_proc_write_trace_options(file, buf, count, data);
- }
-+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)) */
- 
- /* Stuff to handle installation of file systems */
- struct file_system_to_install {
-@@ -3421,6 +3423,7 @@ static int __init init_yaffs_fs(void)
- 
- 	mutex_init(&yaffs_context_lock);
- 
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
- 	/* Install the proc_fs entries */
- 	my_proc_entry = create_proc_entry("yaffs",
- 					  S_IRUGO | S_IFREG, YPROC_ROOT);
-@@ -3432,6 +3435,7 @@ static int __init init_yaffs_fs(void)
- 	} else {
- 		return -ENOMEM;
-         }
-+#endif
- 
- 	/* Now add the file system entries */
- 
-@@ -3468,7 +3472,9 @@ static void __exit exit_yaffs_fs(void)
- 	yaffs_trace(YAFFS_TRACE_ALWAYS,
- 		"yaffs built " __DATE__ " " __TIME__ " removing.");
- 
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
- 	remove_proc_entry("yaffs", YPROC_ROOT);
-+#endif
- 
- 	fsinst = fs_to_install;
- 

+ 0 - 0
target/linux/generic/patches-3.14/504-yaffs-fix-compat-tags-handling.patch → target/linux/generic/patches-3.14/502-yaffs-fix-compat-tags-handling.patch


+ 0 - 129
target/linux/generic/patches-3.14/503-yaffs-3.12-convert-readdir-to-iterate.patch

@@ -1,129 +0,0 @@
---- a/fs/yaffs2/yaffs_vfs.c
-+++ b/fs/yaffs2/yaffs_vfs.c
-@@ -1701,6 +1701,110 @@ static void yaffs_remove_obj_callback(st
- 
- /*-----------------------------------------------------------------*/
- 
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
-+static int yaffs_readdir(struct file *file, struct dir_context *ctx)
-+{
-+	struct yaffs_obj *obj;
-+	struct yaffs_dev *dev;
-+	struct yaffs_search_context *sc;
-+	struct inode *inode = file->f_dentry->d_inode;
-+	unsigned long offset, curoffs;
-+	struct yaffs_obj *l;
-+	int ret_val = 0;
-+
-+	char name[YAFFS_MAX_NAME_LENGTH + 1];
-+
-+	obj = yaffs_dentry_to_obj(file->f_dentry);
-+	dev = obj->my_dev;
-+
-+	yaffs_gross_lock(dev);
-+
-+	yaffs_dev_to_lc(dev)->readdir_process = current;
-+
-+	offset = ctx->pos;
-+
-+	sc = yaffs_new_search(obj);
-+	if (!sc) {
-+		ret_val = -ENOMEM;
-+		goto out;
-+	}
-+
-+	yaffs_trace(YAFFS_TRACE_OS,
-+		"yaffs_readdir: starting at %d", (int)offset);
-+
-+	if (offset == 0) {
-+		yaffs_trace(YAFFS_TRACE_OS,
-+			"yaffs_readdir: entry . ino %d",
-+			(int)inode->i_ino);
-+		yaffs_gross_unlock(dev);
-+		if (!dir_emit_dot(file, ctx)) {
-+			yaffs_gross_lock(dev);
-+			goto out;
-+		}
-+		yaffs_gross_lock(dev);
-+		offset++;
-+		ctx->pos++;
-+	}
-+	if (offset == 1) {
-+		yaffs_trace(YAFFS_TRACE_OS,
-+			"yaffs_readdir: entry .. ino %d",
-+			(int)file->f_dentry->d_parent->d_inode->i_ino);
-+		yaffs_gross_unlock(dev);
-+		if (!dir_emit_dotdot(file, ctx)) {
-+			yaffs_gross_lock(dev);
-+			goto out;
-+		}
-+		yaffs_gross_lock(dev);
-+		offset++;
-+		ctx->pos++;
-+	}
-+
-+	curoffs = 1;
-+
-+	/* If the directory has changed since the open or last call to
-+	   readdir, rewind to after the 2 canned entries. */
-+	if (file->f_version != inode->i_version) {
-+		offset = 2;
-+		ctx->pos = offset;
-+		file->f_version = inode->i_version;
-+	}
-+
-+	while (sc->next_return) {
-+		curoffs++;
-+		l = sc->next_return;
-+		if (curoffs >= offset) {
-+			int this_inode = yaffs_get_obj_inode(l);
-+			int this_type = yaffs_get_obj_type(l);
-+
-+			yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
-+			yaffs_trace(YAFFS_TRACE_OS,
-+				"yaffs_readdir: %s inode %d",
-+				name, yaffs_get_obj_inode(l));
-+
-+			yaffs_gross_unlock(dev);
-+
-+			if (!dir_emit(ctx, name, strlen(name),
-+				      this_inode, this_type) < 0) {
-+				yaffs_gross_lock(dev);
-+				goto out;
-+			}
-+
-+			yaffs_gross_lock(dev);
-+
-+			offset++;
-+			ctx->pos++;
-+		}
-+		yaffs_search_advance(sc);
-+	}
-+
-+out:
-+	yaffs_search_end(sc);
-+	yaffs_dev_to_lc(dev)->readdir_process = NULL;
-+	yaffs_gross_unlock(dev);
-+
-+	return ret_val;
-+}
-+#else
- static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
- {
- 	struct yaffs_obj *obj;
-@@ -1807,10 +1911,15 @@ out:
- 
- 	return ret_val;
- }
-+#endif
- 
- static const struct file_operations yaffs_dir_operations = {
- 	.read = generic_read_dir,
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
-+	.iterate = yaffs_readdir,
-+#else
- 	.readdir = yaffs_readdir,
-+#endif
- 	.fsync = yaffs_sync_object,
- 	.llseek = generic_file_llseek,
- };

+ 8 - 16
target/linux/generic/patches-3.14/503-yaffs-add-tags-9bytes-mount-option.patch

@@ -4,7 +4,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 ---
 ---
 --- a/fs/yaffs2/yaffs_vfs.c
 --- a/fs/yaffs2/yaffs_vfs.c
 +++ b/fs/yaffs2/yaffs_vfs.c
 +++ b/fs/yaffs2/yaffs_vfs.c
-@@ -2634,6 +2634,7 @@ static const struct super_operations yaf
+@@ -2605,6 +2605,7 @@ static const struct super_operations yaf
  
  
  struct yaffs_options {
  struct yaffs_options {
  	int inband_tags;
  	int inband_tags;
@@ -12,7 +12,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  	int skip_checkpoint_read;
  	int skip_checkpoint_read;
  	int skip_checkpoint_write;
  	int skip_checkpoint_write;
  	int no_cache;
  	int no_cache;
-@@ -2673,6 +2674,8 @@ static int yaffs_parse_options(struct ya
+@@ -2644,6 +2645,8 @@ static int yaffs_parse_options(struct ya
  
  
  		if (!strcmp(cur_opt, "inband-tags")) {
  		if (!strcmp(cur_opt, "inband-tags")) {
  			options->inband_tags = 1;
  			options->inband_tags = 1;
@@ -21,7 +21,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  		} else if (!strcmp(cur_opt, "tags-ecc-off")) {
  		} else if (!strcmp(cur_opt, "tags-ecc-off")) {
  			options->tags_ecc_on = 0;
  			options->tags_ecc_on = 0;
  			options->tags_ecc_overridden = 1;
  			options->tags_ecc_overridden = 1;
-@@ -2746,7 +2749,6 @@ static struct super_block *yaffs_interna
+@@ -2717,7 +2720,6 @@ static struct super_block *yaffs_interna
  	struct yaffs_param *param;
  	struct yaffs_param *param;
  
  
  	int read_only = 0;
  	int read_only = 0;
@@ -29,7 +29,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  
  
  	struct yaffs_options options;
  	struct yaffs_options options;
  
  
-@@ -2786,6 +2788,9 @@ static struct super_block *yaffs_interna
+@@ -2757,6 +2759,9 @@ static struct super_block *yaffs_interna
  
  
  	memset(&options, 0, sizeof(options));
  	memset(&options, 0, sizeof(options));
  
  
@@ -39,7 +39,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  	if (yaffs_parse_options(&options, data_str)) {
  	if (yaffs_parse_options(&options, data_str)) {
  		/* Option parsing failed */
  		/* Option parsing failed */
  		return NULL;
  		return NULL;
-@@ -2819,17 +2824,22 @@ static struct super_block *yaffs_interna
+@@ -2790,17 +2795,22 @@ static struct super_block *yaffs_interna
  	}
  	}
  
  
  	/* Added NCB 26/5/2006 for completeness */
  	/* Added NCB 26/5/2006 for completeness */
@@ -68,7 +68,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  		return NULL;
  		return NULL;
  
  
  	/* OK, so if we got here, we have an MTD that's NAND and looks
  	/* OK, so if we got here, we have an MTD that's NAND and looks
-@@ -2890,7 +2900,8 @@ static struct super_block *yaffs_interna
+@@ -2857,7 +2867,8 @@ static struct super_block *yaffs_interna
  
  
  	param->n_reserved_blocks = 5;
  	param->n_reserved_blocks = 5;
  	param->n_caches = (options.no_cache) ? 0 : 10;
  	param->n_caches = (options.no_cache) ? 0 : 10;
@@ -80,15 +80,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  	if (options.lazy_loading_overridden)
  	if (options.lazy_loading_overridden)
 --- a/fs/yaffs2/yaffs_mtdif.c
 --- a/fs/yaffs2/yaffs_mtdif.c
 +++ b/fs/yaffs2/yaffs_mtdif.c
 +++ b/fs/yaffs2/yaffs_mtdif.c
-@@ -16,6 +16,7 @@
- #include "yaffs_mtdif.h"
- 
- #include "linux/mtd/mtd.h"
-+#include "uapi/linux/major.h"
- #include "linux/types.h"
- #include "linux/time.h"
- #include "linux/mtd/nand.h"
-@@ -276,7 +277,8 @@ struct mtd_info * yaffs_get_mtd_device(d
+@@ -278,7 +278,8 @@ struct mtd_info * yaffs_get_mtd_device(d
  	return mtd;
  	return mtd;
  }
  }
  
  
@@ -98,7 +90,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  {
  {
  	if (yaffs_version == 2) {
  	if (yaffs_version == 2) {
  		if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
  		if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
-@@ -295,6 +297,12 @@ int yaffs_verify_mtd(struct mtd_info *mt
+@@ -297,6 +298,12 @@ int yaffs_verify_mtd(struct mtd_info *mt
  			);
  			);
  			return -1;
  			return -1;
  		}
  		}

+ 25 - 0
target/linux/generic/patches-3.14/504-yaffs-3.16-new-fops.patch

@@ -0,0 +1,25 @@
+--- a/fs/yaffs2/yaffs_vfs.c
++++ b/fs/yaffs2/yaffs_vfs.c
+@@ -774,7 +774,21 @@ static int yaffs_sync_object(struct file
+ }
+ 
+ 
+-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
++static const struct file_operations yaffs_file_operations = {
++	.read = new_sync_read,
++	.read_iter = generic_file_read_iter,
++	.write = new_sync_write,
++	.write_iter = generic_file_write_iter,
++	.mmap = generic_file_mmap,
++	.flush = yaffs_file_flush,
++	.fsync = yaffs_sync_object,
++	.splice_read = generic_file_splice_read,
++	.splice_write = iter_file_splice_write,
++	.llseek = generic_file_llseek,
++};
++
++#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
+ static const struct file_operations yaffs_file_operations = {
+ 	.read = do_sync_read,
+ 	.write = do_sync_write,

+ 0 - 155
target/linux/generic/patches-3.18/501-yaffs-3.5-convert-to-use-kuid_t-kgid_t.patch

@@ -1,155 +0,0 @@
---- a/fs/yaffs2/yaffs_vfs.c
-+++ b/fs/yaffs2/yaffs_vfs.c
-@@ -329,6 +329,33 @@ static int yaffs_readpage(struct file *f
- 	return ret;
- }
- 
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
-+#define YCRED_FSUID()	from_kuid(&init_user_ns, current_fsuid())
-+#define YCRED_FSGID()	from_kgid(&init_user_ns, current_fsgid())
-+#else
-+#define YCRED_FSUID()	YCRED(current)->fsuid
-+#define YCRED_FSGID()	YCRED(current)->fsgid
-+
-+static inline uid_t i_uid_read(const struct inode *inode)
-+{
-+	return inode->i_uid;
-+}
-+
-+static inline gid_t i_gid_read(const struct inode *inode)
-+{
-+	return inode->i_gid;
-+}
-+
-+static inline void i_uid_write(struct inode *inode, uid_t uid)
-+{
-+	inode->i_uid = uid;
-+}
-+
-+static inline void i_gid_write(struct inode *inode, gid_t gid)
-+{
-+	inode->i_gid = gid;
-+}
-+#endif
- 
- static void yaffs_set_super_dirty_val(struct yaffs_dev *dev, int val)
- {
-@@ -1225,9 +1252,9 @@ static int yaffs_mknod(struct inode *dir
- 	struct yaffs_obj *parent = yaffs_inode_to_obj(dir);
- 
- 	int error = -ENOSPC;
--	uid_t uid = YCRED(current)->fsuid;
-+	uid_t uid = YCRED_FSUID();
- 	gid_t gid =
--	    (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
-+	    (dir->i_mode & S_ISGID) ? i_gid_read(dir) : YCRED_FSGID();
- 
- 	if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
- 		mode |= S_ISGID;
-@@ -1424,9 +1451,9 @@ static int yaffs_symlink(struct inode *d
- {
- 	struct yaffs_obj *obj;
- 	struct yaffs_dev *dev;
--	uid_t uid = YCRED(current)->fsuid;
-+	uid_t uid = YCRED_FSUID();
- 	gid_t gid =
--	    (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
-+	    (dir->i_mode & S_ISGID) ? i_gid_read(dir) : YCRED_FSGID();
- 
- 	yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
- 
-@@ -1829,8 +1856,8 @@ static void yaffs_fill_inode_from_obj(st
- 
- 		inode->i_ino = obj->obj_id;
- 		inode->i_mode = obj->yst_mode;
--		inode->i_uid = obj->yst_uid;
--		inode->i_gid = obj->yst_gid;
-+		i_uid_write(inode, obj->yst_uid);
-+		i_gid_write(inode, obj->yst_gid);
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
- 		inode->i_blksize = inode->i_sb->s_blocksize;
- #endif
-@@ -1856,7 +1883,7 @@ static void yaffs_fill_inode_from_obj(st
- 
- 		yaffs_trace(YAFFS_TRACE_OS,
- 			"yaffs_fill_inode mode %x uid %d gid %d size %lld count %d",
--			inode->i_mode, inode->i_uid, inode->i_gid,
-+			inode->i_mode, i_uid_read(inode), i_gid_read(inode),
- 			inode->i_size, atomic_read(&inode->i_count));
- 
- 		switch (obj->yst_mode & S_IFMT) {
---- a/fs/yaffs2/yaffs_attribs.c
-+++ b/fs/yaffs2/yaffs_attribs.c
-@@ -14,6 +14,48 @@
- #include "yaffs_guts.h"
- #include "yaffs_attribs.h"
- 
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
-+static inline uid_t ia_uid_read(const struct iattr *iattr)
-+{
-+	return from_kuid(&init_user_ns, iattr->ia_uid);
-+}
-+
-+static inline gid_t ia_gid_read(const struct iattr *iattr)
-+{
-+	return from_kgid(&init_user_ns, iattr->ia_gid);
-+}
-+
-+static inline void ia_uid_write(struct iattr *iattr, uid_t uid)
-+{
-+	iattr->ia_uid = make_kuid(&init_user_ns, uid);
-+}
-+
-+static inline void ia_gid_write(struct iattr *iattr, gid_t gid)
-+{
-+	iattr->ia_gid = make_kgid(&init_user_ns, gid);
-+}
-+#else
-+static inline uid_t ia_uid_read(const struct iattr *iattr)
-+{
-+	return iattr->ia_uid;
-+}
-+
-+static inline gid_t ia_gid_read(const struct iattr *inode)
-+{
-+	return iattr->ia_gid;
-+}
-+
-+static inline void ia_uid_write(struct iattr *iattr, uid_t uid)
-+{
-+	iattr->ia_uid = uid;
-+}
-+
-+static inline void ia_gid_write(struct iattr *iattr, gid_t gid)
-+{
-+	iattr->ia_gid = gid;
-+}
-+#endif
-+
- void yaffs_load_attribs(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh)
- {
- 	obj->yst_uid = oh->yst_uid;
-@@ -77,9 +119,9 @@ int yaffs_set_attribs(struct yaffs_obj *
- 	if (valid & ATTR_MODE)
- 		obj->yst_mode = attr->ia_mode;
- 	if (valid & ATTR_UID)
--		obj->yst_uid = attr->ia_uid;
-+		obj->yst_uid =  ia_uid_read(attr);
- 	if (valid & ATTR_GID)
--		obj->yst_gid = attr->ia_gid;
-+		obj->yst_gid =  ia_gid_read(attr);
- 
- 	if (valid & ATTR_ATIME)
- 		obj->yst_atime = Y_TIME_CONVERT(attr->ia_atime);
-@@ -103,9 +145,9 @@ int yaffs_get_attribs(struct yaffs_obj *
- 
- 	attr->ia_mode = obj->yst_mode;
- 	valid |= ATTR_MODE;
--	attr->ia_uid = obj->yst_uid;
-+	ia_uid_write(attr, obj->yst_uid);
- 	valid |= ATTR_UID;
--	attr->ia_gid = obj->yst_gid;
-+	ia_gid_write(attr, obj->yst_gid);
- 	valid |= ATTR_GID;
- 
- 	Y_TIME_CONVERT(attr->ia_atime) = obj->yst_atime;

+ 38 - 0
target/linux/generic/patches-3.18/501-yaffs-add-missing-flush-arguments.patch

@@ -0,0 +1,38 @@
+--- a/fs/yaffs2/yaffs_vfs.c
++++ b/fs/yaffs2/yaffs_vfs.c
+@@ -738,7 +738,7 @@ static int yaffs_file_flush(struct file
+ 
+ 	yaffs_gross_lock(dev);
+ 
+-	yaffs_flush_file(obj, 1, 0);
++	yaffs_flush_file(obj, 1, 0, 1);
+ 
+ 	yaffs_gross_unlock(dev);
+ 
+@@ -768,7 +768,7 @@ static int yaffs_sync_object(struct file
+ 	yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC,
+ 		"yaffs_sync_object");
+ 	yaffs_gross_lock(dev);
+-	yaffs_flush_file(obj, 1, datasync);
++	yaffs_flush_file(obj, 1, datasync, 1);
+ 	yaffs_gross_unlock(dev);
+ 	return 0;
+ }
+@@ -2187,7 +2187,7 @@ static void yaffs_flush_inodes(struct su
+ 			yaffs_trace(YAFFS_TRACE_OS,
+ 				"flushing obj %d",
+ 				obj->obj_id);
+-			yaffs_flush_file(obj, 1, 0);
++			yaffs_flush_file(obj, 1, 0, 1);
+ 		}
+ 	}
+ }
+@@ -2200,7 +2200,7 @@ static void yaffs_flush_super(struct sup
+ 
+ 	yaffs_flush_inodes(sb);
+ 	yaffs_update_dirty_dirs(dev);
+-	yaffs_flush_whole_cache(dev);
++	yaffs_flush_whole_cache(dev, 1);
+ 	if (do_checkpoint)
+ 		yaffs_checkpoint_save(dev);
+ }

+ 0 - 44
target/linux/generic/patches-3.18/502-yaffs-3.10-disable-proc-entry.patch

@@ -1,44 +0,0 @@
---- a/fs/yaffs2/yaffs_vfs.c
-+++ b/fs/yaffs2/yaffs_vfs.c
-@@ -3025,6 +3025,7 @@ static DECLARE_FSTYPE(yaffs2_fs_type, "y
- #endif
- 
- 
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
- static struct proc_dir_entry *my_proc_entry;
- 
- static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev)
-@@ -3398,6 +3399,7 @@ static int yaffs_proc_write(struct file
- 		return yaffs_proc_debug_write(file, buf, count, data);
- 	return yaffs_proc_write_trace_options(file, buf, count, data);
- }
-+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)) */
- 
- /* Stuff to handle installation of file systems */
- struct file_system_to_install {
-@@ -3421,6 +3423,7 @@ static int __init init_yaffs_fs(void)
- 
- 	mutex_init(&yaffs_context_lock);
- 
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
- 	/* Install the proc_fs entries */
- 	my_proc_entry = create_proc_entry("yaffs",
- 					  S_IRUGO | S_IFREG, YPROC_ROOT);
-@@ -3432,6 +3435,7 @@ static int __init init_yaffs_fs(void)
- 	} else {
- 		return -ENOMEM;
-         }
-+#endif
- 
- 	/* Now add the file system entries */
- 
-@@ -3468,7 +3472,9 @@ static void __exit exit_yaffs_fs(void)
- 	yaffs_trace(YAFFS_TRACE_ALWAYS,
- 		"yaffs built " __DATE__ " " __TIME__ " removing.");
- 
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
- 	remove_proc_entry("yaffs", YPROC_ROOT);
-+#endif
- 
- 	fsinst = fs_to_install;
- 

+ 0 - 0
target/linux/generic/patches-3.18/504-yaffs-fix-compat-tags-handling.patch → target/linux/generic/patches-3.18/502-yaffs-fix-compat-tags-handling.patch


+ 0 - 129
target/linux/generic/patches-3.18/503-yaffs-3.12-convert-readdir-to-iterate.patch

@@ -1,129 +0,0 @@
---- a/fs/yaffs2/yaffs_vfs.c
-+++ b/fs/yaffs2/yaffs_vfs.c
-@@ -1701,6 +1701,110 @@ static void yaffs_remove_obj_callback(st
- 
- /*-----------------------------------------------------------------*/
- 
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
-+static int yaffs_readdir(struct file *file, struct dir_context *ctx)
-+{
-+	struct yaffs_obj *obj;
-+	struct yaffs_dev *dev;
-+	struct yaffs_search_context *sc;
-+	struct inode *inode = file->f_dentry->d_inode;
-+	unsigned long offset, curoffs;
-+	struct yaffs_obj *l;
-+	int ret_val = 0;
-+
-+	char name[YAFFS_MAX_NAME_LENGTH + 1];
-+
-+	obj = yaffs_dentry_to_obj(file->f_dentry);
-+	dev = obj->my_dev;
-+
-+	yaffs_gross_lock(dev);
-+
-+	yaffs_dev_to_lc(dev)->readdir_process = current;
-+
-+	offset = ctx->pos;
-+
-+	sc = yaffs_new_search(obj);
-+	if (!sc) {
-+		ret_val = -ENOMEM;
-+		goto out;
-+	}
-+
-+	yaffs_trace(YAFFS_TRACE_OS,
-+		"yaffs_readdir: starting at %d", (int)offset);
-+
-+	if (offset == 0) {
-+		yaffs_trace(YAFFS_TRACE_OS,
-+			"yaffs_readdir: entry . ino %d",
-+			(int)inode->i_ino);
-+		yaffs_gross_unlock(dev);
-+		if (!dir_emit_dot(file, ctx)) {
-+			yaffs_gross_lock(dev);
-+			goto out;
-+		}
-+		yaffs_gross_lock(dev);
-+		offset++;
-+		ctx->pos++;
-+	}
-+	if (offset == 1) {
-+		yaffs_trace(YAFFS_TRACE_OS,
-+			"yaffs_readdir: entry .. ino %d",
-+			(int)file->f_dentry->d_parent->d_inode->i_ino);
-+		yaffs_gross_unlock(dev);
-+		if (!dir_emit_dotdot(file, ctx)) {
-+			yaffs_gross_lock(dev);
-+			goto out;
-+		}
-+		yaffs_gross_lock(dev);
-+		offset++;
-+		ctx->pos++;
-+	}
-+
-+	curoffs = 1;
-+
-+	/* If the directory has changed since the open or last call to
-+	   readdir, rewind to after the 2 canned entries. */
-+	if (file->f_version != inode->i_version) {
-+		offset = 2;
-+		ctx->pos = offset;
-+		file->f_version = inode->i_version;
-+	}
-+
-+	while (sc->next_return) {
-+		curoffs++;
-+		l = sc->next_return;
-+		if (curoffs >= offset) {
-+			int this_inode = yaffs_get_obj_inode(l);
-+			int this_type = yaffs_get_obj_type(l);
-+
-+			yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
-+			yaffs_trace(YAFFS_TRACE_OS,
-+				"yaffs_readdir: %s inode %d",
-+				name, yaffs_get_obj_inode(l));
-+
-+			yaffs_gross_unlock(dev);
-+
-+			if (!dir_emit(ctx, name, strlen(name),
-+				      this_inode, this_type) < 0) {
-+				yaffs_gross_lock(dev);
-+				goto out;
-+			}
-+
-+			yaffs_gross_lock(dev);
-+
-+			offset++;
-+			ctx->pos++;
-+		}
-+		yaffs_search_advance(sc);
-+	}
-+
-+out:
-+	yaffs_search_end(sc);
-+	yaffs_dev_to_lc(dev)->readdir_process = NULL;
-+	yaffs_gross_unlock(dev);
-+
-+	return ret_val;
-+}
-+#else
- static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
- {
- 	struct yaffs_obj *obj;
-@@ -1807,10 +1911,15 @@ out:
- 
- 	return ret_val;
- }
-+#endif
- 
- static const struct file_operations yaffs_dir_operations = {
- 	.read = generic_read_dir,
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
-+	.iterate = yaffs_readdir,
-+#else
- 	.readdir = yaffs_readdir,
-+#endif
- 	.fsync = yaffs_sync_object,
- 	.llseek = generic_file_llseek,
- };

+ 8 - 16
target/linux/generic/patches-3.18/503-yaffs-add-tags-9bytes-mount-option.patch

@@ -4,7 +4,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 ---
 ---
 --- a/fs/yaffs2/yaffs_vfs.c
 --- a/fs/yaffs2/yaffs_vfs.c
 +++ b/fs/yaffs2/yaffs_vfs.c
 +++ b/fs/yaffs2/yaffs_vfs.c
-@@ -2634,6 +2634,7 @@ static const struct super_operations yaf
+@@ -2605,6 +2605,7 @@ static const struct super_operations yaf
  
  
  struct yaffs_options {
  struct yaffs_options {
  	int inband_tags;
  	int inband_tags;
@@ -12,7 +12,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  	int skip_checkpoint_read;
  	int skip_checkpoint_read;
  	int skip_checkpoint_write;
  	int skip_checkpoint_write;
  	int no_cache;
  	int no_cache;
-@@ -2673,6 +2674,8 @@ static int yaffs_parse_options(struct ya
+@@ -2644,6 +2645,8 @@ static int yaffs_parse_options(struct ya
  
  
  		if (!strcmp(cur_opt, "inband-tags")) {
  		if (!strcmp(cur_opt, "inband-tags")) {
  			options->inband_tags = 1;
  			options->inband_tags = 1;
@@ -21,7 +21,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  		} else if (!strcmp(cur_opt, "tags-ecc-off")) {
  		} else if (!strcmp(cur_opt, "tags-ecc-off")) {
  			options->tags_ecc_on = 0;
  			options->tags_ecc_on = 0;
  			options->tags_ecc_overridden = 1;
  			options->tags_ecc_overridden = 1;
-@@ -2746,7 +2749,6 @@ static struct super_block *yaffs_interna
+@@ -2717,7 +2720,6 @@ static struct super_block *yaffs_interna
  	struct yaffs_param *param;
  	struct yaffs_param *param;
  
  
  	int read_only = 0;
  	int read_only = 0;
@@ -29,7 +29,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  
  
  	struct yaffs_options options;
  	struct yaffs_options options;
  
  
-@@ -2786,6 +2788,9 @@ static struct super_block *yaffs_interna
+@@ -2757,6 +2759,9 @@ static struct super_block *yaffs_interna
  
  
  	memset(&options, 0, sizeof(options));
  	memset(&options, 0, sizeof(options));
  
  
@@ -39,7 +39,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  	if (yaffs_parse_options(&options, data_str)) {
  	if (yaffs_parse_options(&options, data_str)) {
  		/* Option parsing failed */
  		/* Option parsing failed */
  		return NULL;
  		return NULL;
-@@ -2819,17 +2824,22 @@ static struct super_block *yaffs_interna
+@@ -2790,17 +2795,22 @@ static struct super_block *yaffs_interna
  	}
  	}
  
  
  	/* Added NCB 26/5/2006 for completeness */
  	/* Added NCB 26/5/2006 for completeness */
@@ -68,7 +68,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  		return NULL;
  		return NULL;
  
  
  	/* OK, so if we got here, we have an MTD that's NAND and looks
  	/* OK, so if we got here, we have an MTD that's NAND and looks
-@@ -2890,7 +2900,8 @@ static struct super_block *yaffs_interna
+@@ -2857,7 +2867,8 @@ static struct super_block *yaffs_interna
  
  
  	param->n_reserved_blocks = 5;
  	param->n_reserved_blocks = 5;
  	param->n_caches = (options.no_cache) ? 0 : 10;
  	param->n_caches = (options.no_cache) ? 0 : 10;
@@ -80,15 +80,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  	if (options.lazy_loading_overridden)
  	if (options.lazy_loading_overridden)
 --- a/fs/yaffs2/yaffs_mtdif.c
 --- a/fs/yaffs2/yaffs_mtdif.c
 +++ b/fs/yaffs2/yaffs_mtdif.c
 +++ b/fs/yaffs2/yaffs_mtdif.c
-@@ -16,6 +16,7 @@
- #include "yaffs_mtdif.h"
- 
- #include "linux/mtd/mtd.h"
-+#include "uapi/linux/major.h"
- #include "linux/types.h"
- #include "linux/time.h"
- #include "linux/mtd/nand.h"
-@@ -276,7 +277,8 @@ struct mtd_info * yaffs_get_mtd_device(d
+@@ -278,7 +278,8 @@ struct mtd_info * yaffs_get_mtd_device(d
  	return mtd;
  	return mtd;
  }
  }
  
  
@@ -98,7 +90,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  {
  {
  	if (yaffs_version == 2) {
  	if (yaffs_version == 2) {
  		if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
  		if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
-@@ -295,6 +297,12 @@ int yaffs_verify_mtd(struct mtd_info *mt
+@@ -297,6 +298,12 @@ int yaffs_verify_mtd(struct mtd_info *mt
  			);
  			);
  			return -1;
  			return -1;
  		}
  		}

+ 25 - 0
target/linux/generic/patches-3.18/504-yaffs-3.16-new-fops.patch

@@ -0,0 +1,25 @@
+--- a/fs/yaffs2/yaffs_vfs.c
++++ b/fs/yaffs2/yaffs_vfs.c
+@@ -774,7 +774,21 @@ static int yaffs_sync_object(struct file
+ }
+ 
+ 
+-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
++static const struct file_operations yaffs_file_operations = {
++	.read = new_sync_read,
++	.read_iter = generic_file_read_iter,
++	.write = new_sync_write,
++	.write_iter = generic_file_write_iter,
++	.mmap = generic_file_mmap,
++	.flush = yaffs_file_flush,
++	.fsync = yaffs_sync_object,
++	.splice_read = generic_file_splice_read,
++	.splice_write = iter_file_splice_write,
++	.llseek = generic_file_llseek,
++};
++
++#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
+ static const struct file_operations yaffs_file_operations = {
+ 	.read = do_sync_read,
+ 	.write = do_sync_write,

+ 0 - 32
target/linux/generic/patches-3.18/505-yaffs-3.16-new-fops.patch

@@ -1,32 +0,0 @@
---- a/fs/yaffs2/yaffs_vfs.c
-+++ b/fs/yaffs2/yaffs_vfs.c
-@@ -794,15 +794,15 @@ static int yaffs_sync_object(struct file
- 
- #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
- static const struct file_operations yaffs_file_operations = {
--	.read = do_sync_read,
--	.write = do_sync_write,
--	.aio_read = generic_file_aio_read,
--	.aio_write = generic_file_aio_write,
-+	.read = new_sync_read,
-+	.write = new_sync_write,
-+	.read_iter = generic_file_read_iter,
-+	.write_iter = generic_file_write_iter,
- 	.mmap = generic_file_mmap,
- 	.flush = yaffs_file_flush,
- 	.fsync = yaffs_sync_object,
- 	.splice_read = generic_file_splice_read,
--	.splice_write = generic_file_splice_write,
-+	.splice_write = iter_file_splice_write,
- 	.llseek = generic_file_llseek,
- };
- 
-@@ -1050,7 +1050,7 @@ static int yaffs_readlink(struct dentry
- 	if (!alias)
- 		return -ENOMEM;
- 
--	ret = vfs_readlink(dentry, buffer, buflen, alias);
-+	ret = readlink_copy(buffer, buflen, alias);
- 	kfree(alias);
- 	return ret;
- }

+ 0 - 155
target/linux/generic/patches-4.0/501-yaffs-3.5-convert-to-use-kuid_t-kgid_t.patch

@@ -1,155 +0,0 @@
---- a/fs/yaffs2/yaffs_vfs.c
-+++ b/fs/yaffs2/yaffs_vfs.c
-@@ -329,6 +329,33 @@ static int yaffs_readpage(struct file *f
- 	return ret;
- }
- 
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
-+#define YCRED_FSUID()	from_kuid(&init_user_ns, current_fsuid())
-+#define YCRED_FSGID()	from_kgid(&init_user_ns, current_fsgid())
-+#else
-+#define YCRED_FSUID()	YCRED(current)->fsuid
-+#define YCRED_FSGID()	YCRED(current)->fsgid
-+
-+static inline uid_t i_uid_read(const struct inode *inode)
-+{
-+	return inode->i_uid;
-+}
-+
-+static inline gid_t i_gid_read(const struct inode *inode)
-+{
-+	return inode->i_gid;
-+}
-+
-+static inline void i_uid_write(struct inode *inode, uid_t uid)
-+{
-+	inode->i_uid = uid;
-+}
-+
-+static inline void i_gid_write(struct inode *inode, gid_t gid)
-+{
-+	inode->i_gid = gid;
-+}
-+#endif
- 
- static void yaffs_set_super_dirty_val(struct yaffs_dev *dev, int val)
- {
-@@ -1225,9 +1252,9 @@ static int yaffs_mknod(struct inode *dir
- 	struct yaffs_obj *parent = yaffs_inode_to_obj(dir);
- 
- 	int error = -ENOSPC;
--	uid_t uid = YCRED(current)->fsuid;
-+	uid_t uid = YCRED_FSUID();
- 	gid_t gid =
--	    (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
-+	    (dir->i_mode & S_ISGID) ? i_gid_read(dir) : YCRED_FSGID();
- 
- 	if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
- 		mode |= S_ISGID;
-@@ -1424,9 +1451,9 @@ static int yaffs_symlink(struct inode *d
- {
- 	struct yaffs_obj *obj;
- 	struct yaffs_dev *dev;
--	uid_t uid = YCRED(current)->fsuid;
-+	uid_t uid = YCRED_FSUID();
- 	gid_t gid =
--	    (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
-+	    (dir->i_mode & S_ISGID) ? i_gid_read(dir) : YCRED_FSGID();
- 
- 	yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
- 
-@@ -1829,8 +1856,8 @@ static void yaffs_fill_inode_from_obj(st
- 
- 		inode->i_ino = obj->obj_id;
- 		inode->i_mode = obj->yst_mode;
--		inode->i_uid = obj->yst_uid;
--		inode->i_gid = obj->yst_gid;
-+		i_uid_write(inode, obj->yst_uid);
-+		i_gid_write(inode, obj->yst_gid);
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
- 		inode->i_blksize = inode->i_sb->s_blocksize;
- #endif
-@@ -1856,7 +1883,7 @@ static void yaffs_fill_inode_from_obj(st
- 
- 		yaffs_trace(YAFFS_TRACE_OS,
- 			"yaffs_fill_inode mode %x uid %d gid %d size %lld count %d",
--			inode->i_mode, inode->i_uid, inode->i_gid,
-+			inode->i_mode, i_uid_read(inode), i_gid_read(inode),
- 			inode->i_size, atomic_read(&inode->i_count));
- 
- 		switch (obj->yst_mode & S_IFMT) {
---- a/fs/yaffs2/yaffs_attribs.c
-+++ b/fs/yaffs2/yaffs_attribs.c
-@@ -14,6 +14,48 @@
- #include "yaffs_guts.h"
- #include "yaffs_attribs.h"
- 
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
-+static inline uid_t ia_uid_read(const struct iattr *iattr)
-+{
-+	return from_kuid(&init_user_ns, iattr->ia_uid);
-+}
-+
-+static inline gid_t ia_gid_read(const struct iattr *iattr)
-+{
-+	return from_kgid(&init_user_ns, iattr->ia_gid);
-+}
-+
-+static inline void ia_uid_write(struct iattr *iattr, uid_t uid)
-+{
-+	iattr->ia_uid = make_kuid(&init_user_ns, uid);
-+}
-+
-+static inline void ia_gid_write(struct iattr *iattr, gid_t gid)
-+{
-+	iattr->ia_gid = make_kgid(&init_user_ns, gid);
-+}
-+#else
-+static inline uid_t ia_uid_read(const struct iattr *iattr)
-+{
-+	return iattr->ia_uid;
-+}
-+
-+static inline gid_t ia_gid_read(const struct iattr *inode)
-+{
-+	return iattr->ia_gid;
-+}
-+
-+static inline void ia_uid_write(struct iattr *iattr, uid_t uid)
-+{
-+	iattr->ia_uid = uid;
-+}
-+
-+static inline void ia_gid_write(struct iattr *iattr, gid_t gid)
-+{
-+	iattr->ia_gid = gid;
-+}
-+#endif
-+
- void yaffs_load_attribs(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh)
- {
- 	obj->yst_uid = oh->yst_uid;
-@@ -77,9 +119,9 @@ int yaffs_set_attribs(struct yaffs_obj *
- 	if (valid & ATTR_MODE)
- 		obj->yst_mode = attr->ia_mode;
- 	if (valid & ATTR_UID)
--		obj->yst_uid = attr->ia_uid;
-+		obj->yst_uid =  ia_uid_read(attr);
- 	if (valid & ATTR_GID)
--		obj->yst_gid = attr->ia_gid;
-+		obj->yst_gid =  ia_gid_read(attr);
- 
- 	if (valid & ATTR_ATIME)
- 		obj->yst_atime = Y_TIME_CONVERT(attr->ia_atime);
-@@ -103,9 +145,9 @@ int yaffs_get_attribs(struct yaffs_obj *
- 
- 	attr->ia_mode = obj->yst_mode;
- 	valid |= ATTR_MODE;
--	attr->ia_uid = obj->yst_uid;
-+	ia_uid_write(attr, obj->yst_uid);
- 	valid |= ATTR_UID;
--	attr->ia_gid = obj->yst_gid;
-+	ia_gid_write(attr, obj->yst_gid);
- 	valid |= ATTR_GID;
- 
- 	Y_TIME_CONVERT(attr->ia_atime) = obj->yst_atime;

+ 38 - 0
target/linux/generic/patches-4.0/501-yaffs-add-missing-flush-arguments.patch

@@ -0,0 +1,38 @@
+--- a/fs/yaffs2/yaffs_vfs.c
++++ b/fs/yaffs2/yaffs_vfs.c
+@@ -738,7 +738,7 @@ static int yaffs_file_flush(struct file
+ 
+ 	yaffs_gross_lock(dev);
+ 
+-	yaffs_flush_file(obj, 1, 0);
++	yaffs_flush_file(obj, 1, 0, 1);
+ 
+ 	yaffs_gross_unlock(dev);
+ 
+@@ -768,7 +768,7 @@ static int yaffs_sync_object(struct file
+ 	yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC,
+ 		"yaffs_sync_object");
+ 	yaffs_gross_lock(dev);
+-	yaffs_flush_file(obj, 1, datasync);
++	yaffs_flush_file(obj, 1, datasync, 1);
+ 	yaffs_gross_unlock(dev);
+ 	return 0;
+ }
+@@ -2187,7 +2187,7 @@ static void yaffs_flush_inodes(struct su
+ 			yaffs_trace(YAFFS_TRACE_OS,
+ 				"flushing obj %d",
+ 				obj->obj_id);
+-			yaffs_flush_file(obj, 1, 0);
++			yaffs_flush_file(obj, 1, 0, 1);
+ 		}
+ 	}
+ }
+@@ -2200,7 +2200,7 @@ static void yaffs_flush_super(struct sup
+ 
+ 	yaffs_flush_inodes(sb);
+ 	yaffs_update_dirty_dirs(dev);
+-	yaffs_flush_whole_cache(dev);
++	yaffs_flush_whole_cache(dev, 1);
+ 	if (do_checkpoint)
+ 		yaffs_checkpoint_save(dev);
+ }

+ 0 - 44
target/linux/generic/patches-4.0/502-yaffs-3.10-disable-proc-entry.patch

@@ -1,44 +0,0 @@
---- a/fs/yaffs2/yaffs_vfs.c
-+++ b/fs/yaffs2/yaffs_vfs.c
-@@ -3025,6 +3025,7 @@ static DECLARE_FSTYPE(yaffs2_fs_type, "y
- #endif
- 
- 
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
- static struct proc_dir_entry *my_proc_entry;
- 
- static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev)
-@@ -3398,6 +3399,7 @@ static int yaffs_proc_write(struct file
- 		return yaffs_proc_debug_write(file, buf, count, data);
- 	return yaffs_proc_write_trace_options(file, buf, count, data);
- }
-+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)) */
- 
- /* Stuff to handle installation of file systems */
- struct file_system_to_install {
-@@ -3421,6 +3423,7 @@ static int __init init_yaffs_fs(void)
- 
- 	mutex_init(&yaffs_context_lock);
- 
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
- 	/* Install the proc_fs entries */
- 	my_proc_entry = create_proc_entry("yaffs",
- 					  S_IRUGO | S_IFREG, YPROC_ROOT);
-@@ -3432,6 +3435,7 @@ static int __init init_yaffs_fs(void)
- 	} else {
- 		return -ENOMEM;
-         }
-+#endif
- 
- 	/* Now add the file system entries */
- 
-@@ -3468,7 +3472,9 @@ static void __exit exit_yaffs_fs(void)
- 	yaffs_trace(YAFFS_TRACE_ALWAYS,
- 		"yaffs built " __DATE__ " " __TIME__ " removing.");
- 
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
- 	remove_proc_entry("yaffs", YPROC_ROOT);
-+#endif
- 
- 	fsinst = fs_to_install;
- 

+ 0 - 0
target/linux/generic/patches-4.0/504-yaffs-fix-compat-tags-handling.patch → target/linux/generic/patches-4.0/502-yaffs-fix-compat-tags-handling.patch


+ 0 - 129
target/linux/generic/patches-4.0/503-yaffs-3.12-convert-readdir-to-iterate.patch

@@ -1,129 +0,0 @@
---- a/fs/yaffs2/yaffs_vfs.c
-+++ b/fs/yaffs2/yaffs_vfs.c
-@@ -1701,6 +1701,110 @@ static void yaffs_remove_obj_callback(st
- 
- /*-----------------------------------------------------------------*/
- 
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
-+static int yaffs_readdir(struct file *file, struct dir_context *ctx)
-+{
-+	struct yaffs_obj *obj;
-+	struct yaffs_dev *dev;
-+	struct yaffs_search_context *sc;
-+	struct inode *inode = file->f_dentry->d_inode;
-+	unsigned long offset, curoffs;
-+	struct yaffs_obj *l;
-+	int ret_val = 0;
-+
-+	char name[YAFFS_MAX_NAME_LENGTH + 1];
-+
-+	obj = yaffs_dentry_to_obj(file->f_dentry);
-+	dev = obj->my_dev;
-+
-+	yaffs_gross_lock(dev);
-+
-+	yaffs_dev_to_lc(dev)->readdir_process = current;
-+
-+	offset = ctx->pos;
-+
-+	sc = yaffs_new_search(obj);
-+	if (!sc) {
-+		ret_val = -ENOMEM;
-+		goto out;
-+	}
-+
-+	yaffs_trace(YAFFS_TRACE_OS,
-+		"yaffs_readdir: starting at %d", (int)offset);
-+
-+	if (offset == 0) {
-+		yaffs_trace(YAFFS_TRACE_OS,
-+			"yaffs_readdir: entry . ino %d",
-+			(int)inode->i_ino);
-+		yaffs_gross_unlock(dev);
-+		if (!dir_emit_dot(file, ctx)) {
-+			yaffs_gross_lock(dev);
-+			goto out;
-+		}
-+		yaffs_gross_lock(dev);
-+		offset++;
-+		ctx->pos++;
-+	}
-+	if (offset == 1) {
-+		yaffs_trace(YAFFS_TRACE_OS,
-+			"yaffs_readdir: entry .. ino %d",
-+			(int)file->f_dentry->d_parent->d_inode->i_ino);
-+		yaffs_gross_unlock(dev);
-+		if (!dir_emit_dotdot(file, ctx)) {
-+			yaffs_gross_lock(dev);
-+			goto out;
-+		}
-+		yaffs_gross_lock(dev);
-+		offset++;
-+		ctx->pos++;
-+	}
-+
-+	curoffs = 1;
-+
-+	/* If the directory has changed since the open or last call to
-+	   readdir, rewind to after the 2 canned entries. */
-+	if (file->f_version != inode->i_version) {
-+		offset = 2;
-+		ctx->pos = offset;
-+		file->f_version = inode->i_version;
-+	}
-+
-+	while (sc->next_return) {
-+		curoffs++;
-+		l = sc->next_return;
-+		if (curoffs >= offset) {
-+			int this_inode = yaffs_get_obj_inode(l);
-+			int this_type = yaffs_get_obj_type(l);
-+
-+			yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1);
-+			yaffs_trace(YAFFS_TRACE_OS,
-+				"yaffs_readdir: %s inode %d",
-+				name, yaffs_get_obj_inode(l));
-+
-+			yaffs_gross_unlock(dev);
-+
-+			if (!dir_emit(ctx, name, strlen(name),
-+				      this_inode, this_type) < 0) {
-+				yaffs_gross_lock(dev);
-+				goto out;
-+			}
-+
-+			yaffs_gross_lock(dev);
-+
-+			offset++;
-+			ctx->pos++;
-+		}
-+		yaffs_search_advance(sc);
-+	}
-+
-+out:
-+	yaffs_search_end(sc);
-+	yaffs_dev_to_lc(dev)->readdir_process = NULL;
-+	yaffs_gross_unlock(dev);
-+
-+	return ret_val;
-+}
-+#else
- static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
- {
- 	struct yaffs_obj *obj;
-@@ -1807,10 +1911,15 @@ out:
- 
- 	return ret_val;
- }
-+#endif
- 
- static const struct file_operations yaffs_dir_operations = {
- 	.read = generic_read_dir,
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
-+	.iterate = yaffs_readdir,
-+#else
- 	.readdir = yaffs_readdir,
-+#endif
- 	.fsync = yaffs_sync_object,
- 	.llseek = generic_file_llseek,
- };

+ 8 - 16
target/linux/generic/patches-4.0/503-yaffs-add-tags-9bytes-mount-option.patch

@@ -4,7 +4,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
 ---
 ---
 --- a/fs/yaffs2/yaffs_vfs.c
 --- a/fs/yaffs2/yaffs_vfs.c
 +++ b/fs/yaffs2/yaffs_vfs.c
 +++ b/fs/yaffs2/yaffs_vfs.c
-@@ -2634,6 +2634,7 @@ static const struct super_operations yaf
+@@ -2605,6 +2605,7 @@ static const struct super_operations yaf
  
  
  struct yaffs_options {
  struct yaffs_options {
  	int inband_tags;
  	int inband_tags;
@@ -12,7 +12,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  	int skip_checkpoint_read;
  	int skip_checkpoint_read;
  	int skip_checkpoint_write;
  	int skip_checkpoint_write;
  	int no_cache;
  	int no_cache;
-@@ -2673,6 +2674,8 @@ static int yaffs_parse_options(struct ya
+@@ -2644,6 +2645,8 @@ static int yaffs_parse_options(struct ya
  
  
  		if (!strcmp(cur_opt, "inband-tags")) {
  		if (!strcmp(cur_opt, "inband-tags")) {
  			options->inband_tags = 1;
  			options->inband_tags = 1;
@@ -21,7 +21,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  		} else if (!strcmp(cur_opt, "tags-ecc-off")) {
  		} else if (!strcmp(cur_opt, "tags-ecc-off")) {
  			options->tags_ecc_on = 0;
  			options->tags_ecc_on = 0;
  			options->tags_ecc_overridden = 1;
  			options->tags_ecc_overridden = 1;
-@@ -2746,7 +2749,6 @@ static struct super_block *yaffs_interna
+@@ -2717,7 +2720,6 @@ static struct super_block *yaffs_interna
  	struct yaffs_param *param;
  	struct yaffs_param *param;
  
  
  	int read_only = 0;
  	int read_only = 0;
@@ -29,7 +29,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  
  
  	struct yaffs_options options;
  	struct yaffs_options options;
  
  
-@@ -2786,6 +2788,9 @@ static struct super_block *yaffs_interna
+@@ -2757,6 +2759,9 @@ static struct super_block *yaffs_interna
  
  
  	memset(&options, 0, sizeof(options));
  	memset(&options, 0, sizeof(options));
  
  
@@ -39,7 +39,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  	if (yaffs_parse_options(&options, data_str)) {
  	if (yaffs_parse_options(&options, data_str)) {
  		/* Option parsing failed */
  		/* Option parsing failed */
  		return NULL;
  		return NULL;
-@@ -2819,17 +2824,22 @@ static struct super_block *yaffs_interna
+@@ -2790,17 +2795,22 @@ static struct super_block *yaffs_interna
  	}
  	}
  
  
  	/* Added NCB 26/5/2006 for completeness */
  	/* Added NCB 26/5/2006 for completeness */
@@ -68,7 +68,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  		return NULL;
  		return NULL;
  
  
  	/* OK, so if we got here, we have an MTD that's NAND and looks
  	/* OK, so if we got here, we have an MTD that's NAND and looks
-@@ -2890,7 +2900,8 @@ static struct super_block *yaffs_interna
+@@ -2857,7 +2867,8 @@ static struct super_block *yaffs_interna
  
  
  	param->n_reserved_blocks = 5;
  	param->n_reserved_blocks = 5;
  	param->n_caches = (options.no_cache) ? 0 : 10;
  	param->n_caches = (options.no_cache) ? 0 : 10;
@@ -80,15 +80,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  	if (options.lazy_loading_overridden)
  	if (options.lazy_loading_overridden)
 --- a/fs/yaffs2/yaffs_mtdif.c
 --- a/fs/yaffs2/yaffs_mtdif.c
 +++ b/fs/yaffs2/yaffs_mtdif.c
 +++ b/fs/yaffs2/yaffs_mtdif.c
-@@ -16,6 +16,7 @@
- #include "yaffs_mtdif.h"
- 
- #include "linux/mtd/mtd.h"
-+#include "uapi/linux/major.h"
- #include "linux/types.h"
- #include "linux/time.h"
- #include "linux/mtd/nand.h"
-@@ -276,7 +277,8 @@ struct mtd_info * yaffs_get_mtd_device(d
+@@ -278,7 +278,8 @@ struct mtd_info * yaffs_get_mtd_device(d
  	return mtd;
  	return mtd;
  }
  }
  
  
@@ -98,7 +90,7 @@ Signed-off-by: Gabor Juhos <[email protected]>
  {
  {
  	if (yaffs_version == 2) {
  	if (yaffs_version == 2) {
  		if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
  		if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
-@@ -295,6 +297,12 @@ int yaffs_verify_mtd(struct mtd_info *mt
+@@ -297,6 +298,12 @@ int yaffs_verify_mtd(struct mtd_info *mt
  			);
  			);
  			return -1;
  			return -1;
  		}
  		}

+ 25 - 0
target/linux/generic/patches-4.0/504-yaffs-3.16-new-fops.patch

@@ -0,0 +1,25 @@
+--- a/fs/yaffs2/yaffs_vfs.c
++++ b/fs/yaffs2/yaffs_vfs.c
+@@ -774,7 +774,21 @@ static int yaffs_sync_object(struct file
+ }
+ 
+ 
+-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
++static const struct file_operations yaffs_file_operations = {
++	.read = new_sync_read,
++	.read_iter = generic_file_read_iter,
++	.write = new_sync_write,
++	.write_iter = generic_file_write_iter,
++	.mmap = generic_file_mmap,
++	.flush = yaffs_file_flush,
++	.fsync = yaffs_sync_object,
++	.splice_read = generic_file_splice_read,
++	.splice_write = iter_file_splice_write,
++	.llseek = generic_file_llseek,
++};
++
++#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
+ static const struct file_operations yaffs_file_operations = {
+ 	.read = do_sync_read,
+ 	.write = do_sync_write,

+ 0 - 32
target/linux/generic/patches-4.0/505-yaffs-3.16-new-fops.patch

@@ -1,32 +0,0 @@
---- a/fs/yaffs2/yaffs_vfs.c
-+++ b/fs/yaffs2/yaffs_vfs.c
-@@ -794,15 +794,15 @@ static int yaffs_sync_object(struct file
- 
- #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
- static const struct file_operations yaffs_file_operations = {
--	.read = do_sync_read,
--	.write = do_sync_write,
--	.aio_read = generic_file_aio_read,
--	.aio_write = generic_file_aio_write,
-+	.read = new_sync_read,
-+	.write = new_sync_write,
-+	.read_iter = generic_file_read_iter,
-+	.write_iter = generic_file_write_iter,
- 	.mmap = generic_file_mmap,
- 	.flush = yaffs_file_flush,
- 	.fsync = yaffs_sync_object,
- 	.splice_read = generic_file_splice_read,
--	.splice_write = generic_file_splice_write,
-+	.splice_write = iter_file_splice_write,
- 	.llseek = generic_file_llseek,
- };
- 
-@@ -1050,7 +1050,7 @@ static int yaffs_readlink(struct dentry
- 	if (!alias)
- 		return -ENOMEM;
- 
--	ret = vfs_readlink(dentry, buffer, buflen, alias);
-+	ret = readlink_copy(buffer, buflen, alias);
- 	kfree(alias);
- 	return ret;
- }