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 <cdhmanning@gmail.com>
  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 <cdhmanning@gmail.com>

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@45188 3c298f89-4303-0410-b956-a3cf2f4a3e73
master
Gabor Juhos 2015-03-31 15:31:57 +00:00
parent a42b37dd86
commit 472f5abe11
32 changed files with 654 additions and 1301 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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) { /* Find the chunks for this object and flush them. */
/* Write it out and free it up */ for (i = 0; i < n_caches; i++) {
chunk_written = cache = &dev->cache[i];
yaffs_wr_data_obj(cache->object, if (cache->object == obj)
cache->chunk_id, yaffs_flush_single_cache(cache, discard);
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");
} }
/*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) { if (cache)
/* They were all dirty, find the LRU object and flush return cache;
* its cache, then find again.
* NB what's here is not very accurate,
* we actually flush the object with the LRU chunk.
*/
/* With locking we can't assume we can use entry zero, /*
* Set the_obj to a valid pointer for Coverity. */ * Thery were all in use.
the_obj = dev->cache[0].object; * Find the LRU cache and flush it if it is dirty.
usage = -1; */
cache = NULL;
pushout = -1;
for (i = 0; i < dev->param.n_caches; i++) { usage = -1;
if (dev->cache[i].object && cache = NULL;
!dev->cache[i].locked &&
(dev->cache[i].last_use < usage || for (i = 0; i < dev->param.n_caches; i++) {
!cache)) { 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;

View File

@ -144,12 +144,12 @@ struct yaffs_cache {
*/ */
struct yaffs_tags { struct yaffs_tags {
unsigned chunk_id:20; u32 chunk_id:20;
unsigned serial_number:2; u32 serial_number:2;
unsigned n_bytes_lsb:10; u32 n_bytes_lsb:10;
unsigned obj_id:18; u32 obj_id:18;
unsigned ecc:12; u32 ecc:12;
unsigned n_bytes_msb:2; 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 */ s32 soft_del_pages:10; /* number of soft deleted pages */
int pages_in_use:10; /* number of pages in use */ s32 pages_in_use:10; /* number of pages in use */
unsigned block_state:4; /* One of the above block states. */ 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 */ u8 block_info_alt:1; /* allocated using alternative alloc */
unsigned chunk_bits_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);

View File

@ -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

View File

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

View File

@ -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;

View File

@ -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_uid = MAKE_uid(obj->yst_uid);
inode->i_gid = obj->yst_gid; 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);
kfree(dev); kfree(context);
if (context)
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_debug_write(file, buf, count);
return yaffs_proc_write_trace_options(file, buf, count, data); return yaffs_proc_write_trace_options(file, buf, count);
} }
/* Stuff to handle installation of file systems */ /* Stuff to handle installation of file systems */
@ -3384,6 +3493,69 @@ static struct file_system_to_install fs_to_install[] = {
{NULL, 0} {NULL, 0}
}; };
#ifdef YAFFS_NEW_PROCFS
static int yaffs_proc_show(struct seq_file *m, void *v)
{
/* FIXME: Unify in a better way? */
char buffer[512];
char *start;
int len;
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
static int yaffs_procfs_init(void)
{
/* Install the proc_fs entries */
my_proc_entry = create_proc_entry("yaffs",
S_IRUGO | S_IFREG, YPROC_ROOT);
if (my_proc_entry) {
my_proc_entry->write_proc = yaffs_proc_write;
my_proc_entry->read_proc = yaffs_proc_read;
my_proc_entry->data = NULL;
return 0;
} else {
return -ENOMEM;
}
}
#endif
static int __init init_yaffs_fs(void) static int __init init_yaffs_fs(void)
{ {
int error = 0; int error = 0;
@ -3394,17 +3566,9 @@ static int __init init_yaffs_fs(void)
mutex_init(&yaffs_context_lock); mutex_init(&yaffs_context_lock);
/* Install the proc_fs entries */ error = yaffs_procfs_init();
my_proc_entry = create_proc_entry("yaffs", if (error)
S_IRUGO | S_IFREG, YPROC_ROOT); return error;
if (my_proc_entry) {
my_proc_entry->write_proc = yaffs_proc_write;
my_proc_entry->read_proc = yaffs_proc_read;
my_proc_entry->data = NULL;
} else {
return -ENOMEM;
}
/* Now add the file system entries */ /* Now add the file system entries */

View File

@ -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();

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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,
};

View File

@ -4,7 +4,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- ---
--- 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 <juhosg@openwrt.org>
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 <juhosg@openwrt.org>
} 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 <juhosg@openwrt.org>
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 <juhosg@openwrt.org>
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 <juhosg@openwrt.org>
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 <juhosg@openwrt.org>
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 @@ @@ -278,7 +278,8 @@ struct mtd_info * yaffs_get_mtd_device(d
#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
return mtd; return mtd;
} }
@ -98,7 +90,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
{ {
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;
} }

View File

@ -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,

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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,
};

View File

@ -4,7 +4,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- ---
--- 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 <juhosg@openwrt.org>
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 <juhosg@openwrt.org>
} 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 <juhosg@openwrt.org>
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 <juhosg@openwrt.org>
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 <juhosg@openwrt.org>
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 <juhosg@openwrt.org>
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 @@ @@ -278,7 +278,8 @@ struct mtd_info * yaffs_get_mtd_device(d
#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
return mtd; return mtd;
} }
@ -98,7 +90,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
{ {
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;
} }

View File

@ -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,

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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,
};

View File

@ -4,7 +4,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- ---
--- 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 <juhosg@openwrt.org>
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 <juhosg@openwrt.org>
} 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 <juhosg@openwrt.org>
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 <juhosg@openwrt.org>
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 <juhosg@openwrt.org>
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 <juhosg@openwrt.org>
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 @@ @@ -278,7 +278,8 @@ struct mtd_info * yaffs_get_mtd_device(d
#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
return mtd; return mtd;
} }
@ -98,7 +90,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
{ {
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;
} }

View File

@ -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,

View File

@ -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;
}