转载请注明出处lingdxuyan.blog.chinaunix.net
最新内核linux-3.14.6 yaffs2移植修复记录
原文地址http://blog.chinaunix.net/uid-23089249-id-4296123.html
1、yaffs源码没有跟上linux内核源码变化,所以在移植yaffs2到linux3.14内核时,会遇到好像编译问题
1)kuid_t、kgid_t类型
3.14移除以下定义
typedef uid_t kuid_t;
typedef gid_t kgid_t;
只剩下如下定义
typedef struct {
uid_t val;
} kuid_t;
typedef struct {
gid_t val;
} kgid_t;
所以我们需要修改以下kgid_t、kuid_t的使用
2)file_operations.readdir接口
linux从3.11内核开始移除了file_operations.readdir接口,我们需要改用file_operations.iterate来替代
这部分修复参考了
503-yaffs-3.12-convert-readdir-to-iterate.patch
3)create_proc_entry接口
linux从3.10内核开始移除了create_proc_entry、proc_dir_entry.write_proc、proc_dir_entry.read_proc等接口,我们需要改用proc_create和file_operations来替代
4)MTD_BLOCK_MAJOR宏
linux从3.13内核开始将MTD_BLOCK_MAJOR宏定义从linux/mtd/mtd.h搬到include/uapi/linux/major.h头文件中
2、yaffs2编译问题修复
1)fs/yaffs2/yaffs_vfs.c编译问题修复
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_mknod':
fs/yaffs2/yaffs_vfs.c:1228: error: incompatible types when initializing type 'uid_t' using type 'kuid_t'
fs/yaffs2/yaffs_vfs.c:1230: error: incompatible types when initializing type 'gid_t' using type 'const struct
'
/************** lingd20140511 *************/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
uid_t uid = YCRED(current)->fsuid;
gid_t gid =
(dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
#else
uid_t uid = YCRED(current)->fsuid.val;
gid_t gid =
(dir->i_mode & S_ISGID) ? dir->i_gid.val : YCRED(current)->fsgid.val;
#endif
/************** lingd20140511 *************/
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_symlink':
fs/yaffs2/yaffs_vfs.c:1427: error: incompatible types when initializing type 'uid_t' using type 'kuid_t'
fs/yaffs2/yaffs_vfs.c:1429: error: incompatible types when initializing type 'gid_t' using type 'const struct '
/************** lingd20140511 *************/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
uid_t uid = YCRED(current)->fsuid;
gid_t gid =
(dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
#else
uid_t uid = YCRED(current)->fsuid.val;
gid_t gid =
(dir->i_mode & S_ISGID) ? dir->i_gid.val : YCRED(current)->fsgid.val;
#endif
/************** lingd20140511 *************/
fs/yaffs2/yaffs_vfs.c: At top level:
fs/yaffs2/yaffs_vfs.c:1786: error: unknown field 'readdir' specified in initializer
fs/yaffs2/yaffs_vfs.c:1786: warning: initialization from incompatible pointer type
/************** lingd20140511 *************/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
static int yaffs_iterate(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
/************** lingd20140511 *************/
static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
{
struct yaffs_obj *obj;
struct yaffs_dev *dev;
struct yaffs_search_context *sc;
struct inode *inode = f->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(f->f_dentry);
dev = obj->my_dev;
yaffs_gross_lock(dev);
yaffs_dev_to_lc(dev)->readdir_process = current;
offset = f->f_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 (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0) {
yaffs_gross_lock(dev);
goto out;
}
yaffs_gross_lock(dev);
offset++;
f->f_pos++;
}
if (offset == 1) {
yaffs_trace(YAFFS_TRACE_OS,
"yaffs_readdir: entry .. ino %d",
(int)f->f_dentry->d_parent->d_inode->i_ino);
yaffs_gross_unlock(dev);
if (filldir(dirent, "..", 2, offset,
f->f_dentry->d_parent->d_inode->i_ino,
DT_DIR) < 0) {
yaffs_gross_lock(dev);
goto out;
}
yaffs_gross_lock(dev);
offset++;
f->f_pos++;
}
curoffs = 1;
/* If the directory has changed since the open or last call to
readdir, rewind to after the 2 canned entries. */
if (f->f_version != inode->i_version) {
offset = 2;
f->f_pos = offset;
f->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 (filldir(dirent,
name,
strlen(name),
offset, this_inode, this_type) < 0) {
yaffs_gross_lock(dev);
goto out;
}
yaffs_gross_lock(dev);
offset++;
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;
}
/************** lingd20140511 *************/
#endif
/************** lingd20140511 *************/
static const struct file_operations yaffs_dir_operations = {
.read = generic_read_dir,
/************** lingd20140511 *************/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
.iterate = yaffs_iterate,
#else
/************** lingd20140511 *************/
.readdir = yaffs_readdir,
/************** lingd20140511 *************/
#endif
/************** lingd20140511 *************/
.fsync = yaffs_sync_object,
.llseek = generic_file_llseek,
};
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_fill_inode_from_obj':
fs/yaffs2/yaffs_vfs.c:1832: error: incompatible types when assigning to type 'kuid_t' from type 'u32'
fs/yaffs2/yaffs_vfs.c:1833: error: incompatible types when assigning to type 'kgid_t' from type 'u32'
/************** lingd20140511 *************/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
inode->i_uid = obj->yst_uid;
inode->i_gid = obj->yst_gid;
#else
inode->i_uid.val = obj->yst_uid;
inode->i_gid.val = obj->yst_gid;
#endif
/************** lingd20140511 *************/
fs/yaffs2/yaffs_vfs.c:1857: warning: format '%d' expects type 'int', but argument 3 has type 'kuid_t'
fs/yaffs2/yaffs_vfs.c:1857: warning: format '%d' expects type 'int', but argument 4 has type 'kgid_t'
/************** lingd20140511 *************/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
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_size, atomic_read(&inode->i_count));
#else
yaffs_trace(YAFFS_TRACE_OS,
"yaffs_fill_inode mode %x uid %d gid %d size %lld count %d",
inode->i_mode, inode->i_uid.val, inode->i_gid.val,
inode->i_size, atomic_read(&inode->i_count));
#endif
/************** lingd20140511 *************/
fs/yaffs2/yaffs_vfs.c: In function 'yaffs_proc_debug_write':
fs/yaffs2/yaffs_vfs.c:3300: warning: comparison of distinct pointer types lacks a cast
/************** lingd20140511 *************/
// memcpy(str, buf, min(count, sizeof(str) -1));
memcpy(str, buf, min(count, (unsigned long)(sizeof(str) -1)));
/************** lingd20140511 *************/
fs/yaffs2/yaffs_vfs.c: In function 'init_yaffs_fs':
fs/yaffs2/yaffs_vfs.c:3394: error: implicit declaration of function 'create_proc_entry'
fs/yaffs2/yaffs_vfs.c:3395: warning: assignment makes pointer from integer without a cast
fs/yaffs2/yaffs_vfs.c:3398: error: dereferencing pointer to incomplete type
fs/yaffs2/yaffs_vfs.c:3399: error: dereferencing pointer to incomplete type
fs/yaffs2/yaffs_vfs.c:3400: error: dereferencing pointer to incomplete type
/************** lingd20140511 *************/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
#include
#endif
/************** lingd20140511 *************/
/************** lingd20140511 *************/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
/************** lingd20140511 *************/
static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev)
{
struct yaffs_param *param = &dev->param;
int bs[10];
yaffs_count_blocks_by_state(dev,bs);
buf += sprintf(buf, "start_block.......... %d\n", param->start_block);
buf += sprintf(buf, "end_block............ %d\n", param->end_block);
buf += sprintf(buf, "total_bytes_per_chunk %d\n",
param->total_bytes_per_chunk);
buf += sprintf(buf, "use_nand_ecc......... %d\n", param->use_nand_ecc);
buf += sprintf(buf, "no_tags_ecc.......... %d\n", param->no_tags_ecc);
buf += sprintf(buf, "is_yaffs2............ %d\n", param->is_yaffs2);
buf += sprintf(buf, "inband_tags.......... %d\n", param->inband_tags);
buf += sprintf(buf, "empty_lost_n_found... %d\n",
param->empty_lost_n_found);
buf += sprintf(buf, "disable_lazy_load.... %d\n",
param->disable_lazy_load);
buf += sprintf(buf, "disable_bad_block_mrk %d\n",
param->disable_bad_block_marking);
buf += sprintf(buf, "refresh_period....... %d\n",
param->refresh_period);
buf += sprintf(buf, "n_caches............. %d\n", param->n_caches);
buf += sprintf(buf, "n_reserved_blocks.... %d\n",
param->n_reserved_blocks);
buf += sprintf(buf, "always_check_erased.. %d\n",
param->always_check_erased);
buf += sprintf(buf, "\n");
buf += sprintf(buf, "block count by state\n");
buf += sprintf(buf, "0:%d 1:%d 2:%d 3:%d 4:%d\n",
bs[0], bs[1], bs[2], bs[3], bs[4]);
buf += sprintf(buf, "5:%d 6:%d 7:%d 8:%d 9:%d\n",
bs[5], bs[6], bs[7], bs[8], bs[9]);
return buf;
}
static char *yaffs_dump_dev_part1(char *buf, struct yaffs_dev *dev)
{
buf += sprintf(buf, "max file size....... %lld\n",
(long long) yaffs_max_file_size(dev));
buf += sprintf(buf, "data_bytes_per_chunk. %d\n",
dev->data_bytes_per_chunk);
buf += sprintf(buf, "chunk_grp_bits....... %d\n", dev->chunk_grp_bits);
buf += sprintf(buf, "chunk_grp_size....... %d\n", dev->chunk_grp_size);
buf += sprintf(buf, "n_erased_blocks...... %d\n", dev->n_erased_blocks);
buf += sprintf(buf, "blocks_in_checkpt.... %d\n",
dev->blocks_in_checkpt);
buf += sprintf(buf, "\n");
buf += sprintf(buf, "n_tnodes............. %d\n", dev->n_tnodes);
buf += sprintf(buf, "n_obj................ %d\n", dev->n_obj);
buf += sprintf(buf, "n_free_chunks........ %d\n", dev->n_free_chunks);
buf += sprintf(buf, "\n");
buf += sprintf(buf, "n_page_writes........ %u\n", dev->n_page_writes);
buf += sprintf(buf, "n_page_reads......... %u\n", dev->n_page_reads);
buf += sprintf(buf, "n_erasures........... %u\n", dev->n_erasures);
buf += sprintf(buf, "n_gc_copies.......... %u\n", dev->n_gc_copies);
buf += sprintf(buf, "all_gcs.............. %u\n", dev->all_gcs);
buf += sprintf(buf, "passive_gc_count..... %u\n",
dev->passive_gc_count);
buf += sprintf(buf, "oldest_dirty_gc_count %u\n",
dev->oldest_dirty_gc_count);
buf += sprintf(buf, "n_gc_blocks.......... %u\n", dev->n_gc_blocks);
buf += sprintf(buf, "bg_gcs............... %u\n", dev->bg_gcs);
buf += sprintf(buf, "n_retried_writes..... %u\n",
dev->n_retried_writes);
buf += sprintf(buf, "n_retired_blocks..... %u\n",
dev->n_retired_blocks);
buf += sprintf(buf, "n_ecc_fixed.......... %u\n", dev->n_ecc_fixed);
buf += sprintf(buf, "n_ecc_unfixed........ %u\n", dev->n_ecc_unfixed);
buf += sprintf(buf, "n_tags_ecc_fixed..... %u\n",
dev->n_tags_ecc_fixed);
buf += sprintf(buf, "n_tags_ecc_unfixed... %u\n",
dev->n_tags_ecc_unfixed);
buf += sprintf(buf, "cache_hits........... %u\n", dev->cache_hits);
buf += sprintf(buf, "n_deleted_files...... %u\n", dev->n_deleted_files);
buf += sprintf(buf, "n_unlinked_files..... %u\n",
dev->n_unlinked_files);
buf += sprintf(buf, "refresh_count........ %u\n", dev->refresh_count);
buf += sprintf(buf, "n_bg_deletions....... %u\n", dev->n_bg_deletions);
buf += sprintf(buf, "tags_used............ %u\n", dev->tags_used);
buf += sprintf(buf, "summary_used......... %u\n", dev->summary_used);
return buf;
}
static int yaffs_proc_read(char *page,
char **start,
off_t offset, int count, int *eof, void *data)
{
struct list_head *item;
char *buf = page;
int step = offset;
int n = 0;
/* Get proc_file_read() to step 'offset' by one on each sucessive call.
* We use 'offset' (*ppos) to indicate where we are in dev_list.
* This also assumes the user has posted a read buffer large
* enough to hold the complete output; but that's life in /proc.
*/
*(int *)start = 1;
/* Print header first */
if (step == 0)
buf +=
sprintf(buf,
"Multi-version YAFFS built:" __DATE__ " " __TIME__
"\n");
else if (step == 1)
buf += sprintf(buf, "\n");
else {
step -= 2;
mutex_lock(&yaffs_context_lock);
/* Locate and print the Nth entry. Order N-squared but N is small. */
list_for_each(item, &yaffs_context_list) {
struct yaffs_linux_context *dc =
list_entry(item, struct yaffs_linux_context,
context_list);
struct yaffs_dev *dev = dc->dev;
if (n < (step & ~1)) {
n += 2;
continue;
}
if ((step & 1) == 0) {
buf +=
sprintf(buf, "\nDevice %d \"%s\"\n", n,
dev->param.name);
buf = yaffs_dump_dev_part0(buf, dev);
} else {
buf = yaffs_dump_dev_part1(buf, dev);
}
break;
}
mutex_unlock(&yaffs_context_lock);
}
return buf - page < count ? buf - page : count;
}
/************** lingd20140511 *************/
#endif
/************** lingd20140511 *************/
/************** lingd20140511 *************/
/************** lingd20140511 *************/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
/************** lingd20140511 *************/
static int yaffs_proc_write(struct file *file, const char *buf,
unsigned long count, void *data)
{
if (buf[0] == '.')
return yaffs_proc_debug_write(file, buf, count, data);
return yaffs_proc_write_trace_options(file, buf, count, data);
}
/************** lingd20140511 *************/
#else
static int yaffs_proc_show(struct seq_file *m, void *v)
{
struct list_head *item;
struct yaffs_param *param;
int n = 0;
int bs[10];
seq_printf(m, "Multi-version YAFFS built:" __DATE__ " " __TIME__ "\n\n");
mutex_lock(&yaffs_context_lock);
/* Locate and print the Nth entry. Order N-squared but N is small. */
list_for_each(item, &yaffs_context_list) {
struct yaffs_linux_context *dc =
list_entry(item, struct yaffs_linux_context,
context_list);
struct yaffs_dev *dev = dc->dev;
seq_printf(m, "\nDevice %d \"%s\"\n", n++,
dev->param.name);
param = &dev->param;
yaffs_count_blocks_by_state(dev, bs);
seq_printf(m, "start_block.......... %d\n", param->start_block);
seq_printf(m, "end_block............ %d\n", param->end_block);
seq_printf(m, "total_bytes_per_chunk %d\n",
param->total_bytes_per_chunk);
seq_printf(m, "use_nand_ecc......... %d\n", param->use_nand_ecc);
seq_printf(m, "no_tags_ecc.......... %d\n", param->no_tags_ecc);
seq_printf(m, "is_yaffs2............ %d\n", param->is_yaffs2);
seq_printf(m, "inband_tags.......... %d\n", param->inband_tags);
seq_printf(m, "empty_lost_n_found... %d\n",
param->empty_lost_n_found);
seq_printf(m, "disable_lazy_load.... %d\n",
param->disable_lazy_load);
seq_printf(m, "disable_bad_block_mrk %d\n",
param->disable_bad_block_marking);
seq_printf(m, "refresh_period....... %d\n",
param->refresh_period);
seq_printf(m, "n_caches............. %d\n", param->n_caches);
seq_printf(m, "n_reserved_blocks.... %d\n",
param->n_reserved_blocks);
seq_printf(m, "always_check_erased.. %d\n",
param->always_check_erased);
seq_printf(m, "\n");
seq_printf(m, "block count by state\n");
seq_printf(m, "0:%d 1:%d 2:%d 3:%d 4:%d\n",
bs[0], bs[1], bs[2], bs[3], bs[4]);
seq_printf(m, "5:%d 6:%d 7:%d 8:%d 9:%d\n",
bs[5], bs[6], bs[7], bs[8], bs[9]);
seq_printf(m, "max file size....... %lld\n",
(long long) yaffs_max_file_size(dev));
seq_printf(m, "data_bytes_per_chunk. %d\n",
dev->data_bytes_per_chunk);
seq_printf(m, "chunk_grp_bits....... %d\n", dev->chunk_grp_bits);
seq_printf(m, "chunk_grp_size....... %d\n", dev->chunk_grp_size);
seq_printf(m, "n_erased_blocks...... %d\n", dev->n_erased_blocks);
seq_printf(m, "blocks_in_checkpt.... %d\n",
dev->blocks_in_checkpt);
seq_printf(m, "\n");
seq_printf(m, "n_tnodes............. %d\n", dev->n_tnodes);
seq_printf(m, "n_obj................ %d\n", dev->n_obj);
seq_printf(m, "n_free_chunks........ %d\n", dev->n_free_chunks);
seq_printf(m, "\n");
seq_printf(m, "n_page_writes........ %u\n", dev->n_page_writes);
seq_printf(m, "n_page_reads......... %u\n", dev->n_page_reads);
seq_printf(m, "n_erasures........... %u\n", dev->n_erasures);
seq_printf(m, "n_gc_copies.......... %u\n", dev->n_gc_copies);
seq_printf(m, "all_gcs.............. %u\n", dev->all_gcs);
seq_printf(m, "passive_gc_count..... %u\n",
dev->passive_gc_count);
seq_printf(m, "oldest_dirty_gc_count %u\n",
dev->oldest_dirty_gc_count);
seq_printf(m, "n_gc_blocks.......... %u\n", dev->n_gc_blocks);
seq_printf(m, "bg_gcs............... %u\n", dev->bg_gcs);
seq_printf(m, "n_retried_writes..... %u\n",
dev->n_retried_writes);
seq_printf(m, "n_retired_blocks..... %u\n",
dev->n_retired_blocks);
seq_printf(m, "n_ecc_fixed.......... %u\n", dev->n_ecc_fixed);
seq_printf(m, "n_ecc_unfixed........ %u\n", dev->n_ecc_unfixed);
seq_printf(m, "n_tags_ecc_fixed..... %u\n",
dev->n_tags_ecc_fixed);
seq_printf(m, "n_tags_ecc_unfixed... %u\n",
dev->n_tags_ecc_unfixed);
seq_printf(m, "cache_hits........... %u\n", dev->cache_hits);
seq_printf(m, "n_deleted_files...... %u\n", dev->n_deleted_files);
seq_printf(m, "n_unlinked_files..... %u\n",
dev->n_unlinked_files);
seq_printf(m, "refresh_count........ %u\n", dev->refresh_count);
seq_printf(m, "n_bg_deletions....... %u\n", dev->n_bg_deletions);
seq_printf(m, "tags_used............ %u\n", dev->tags_used);
seq_printf(m, "summary_used......... %u\n", dev->summary_used);
}
mutex_unlock(&yaffs_context_lock);
return 0;
}
static int yaffs_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, yaffs_proc_show, NULL);
}
static ssize_t yaffs_proc_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
{
if (buf[0] == '.')
return yaffs_proc_debug_write(file, buf, count, NULL);
return yaffs_proc_write_trace_options(file, buf, count, NULL);
}
static const struct file_operations yaffs_proc_fops = {
.owner = THIS_MODULE,
.open = yaffs_proc_open,
.write = yaffs_proc_write,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
#endif
/************** lingd20140511 *************/
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);
/* Install the proc_fs entries */
/************** lingd20140511 *************/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
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;
} else {
return -ENOMEM;
}
#else
my_proc_entry = proc_create("yaffs",
S_IRUGO | S_IFREG, YPROC_ROOT, &yaffs_proc_fops);
if (!my_proc_entry)
return -ENOMEM;
#endif
/************** lingd20140511 *************/
/* Now add the file system entries */
fsinst = fs_to_install;
while (fsinst->fst && !error) {
error = register_filesystem(fsinst->fst);
if (!error)
fsinst->installed = 1;
fsinst++;
}
/* Any errors? uninstall */
if (error) {
fsinst = fs_to_install;
while (fsinst->fst) {
if (fsinst->installed) {
unregister_filesystem(fsinst->fst);
fsinst->installed = 0;
}
fsinst++;
}
}
return error;
}
2)修改fs/yaffs2/yaffs_mtdif.c
fs/yaffs2/yaffs_mtdif.c: In function 'yaffs_get_mtd_device':
fs/yaffs2/yaffs_mtdif.c:256: error: 'MTD_BLOCK_MAJOR' undeclared (first use in this function)
fs/yaffs2/yaffs_mtdif.c:256: error: (Each undeclared identifier is reported only once
fs/yaffs2/yaffs_mtdif.c:256: error: for each function it appears in.)
/************** lingd20140511 *************/
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
#include "uapi/linux/major.h"
#endif
/************** lingd20140511 *************/
3)修改fs/yaffs2/yaffs_attribs.c
fs/yaffs2/yaffs_attribs.c: In function 'yaffs_set_attribs':
fs/yaffs2/yaffs_attribs.c:80: error: incompatible types when assigning to type 'u32' from type 'kuid_t'
fs/yaffs2/yaffs_attribs.c:82: error: incompatible types when assigning to type 'u32' from type 'kgid_t'
/************** lingd20140511 *************/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
if (valid & ATTR_UID)
obj->yst_uid = attr->ia_uid;
if (valid & ATTR_GID)
obj->yst_gid = attr->ia_gid;
#else
if (valid & ATTR_UID)
obj->yst_uid = attr->ia_uid.val;
if (valid & ATTR_GID)
obj->yst_gid = attr->ia_gid.val;
#endif
/************** lingd20140511 *************/
fs/yaffs2/yaffs_attribs.c: In function 'yaffs_get_attribs':
fs/yaffs2/yaffs_attribs.c:106: error: incompatible types when assigning to type 'kuid_t' from type 'u32'
fs/yaffs2/yaffs_attribs.c:108: error: incompatible types when assigning to type 'kgid_t' from type 'u32'
/************** lingd20140511 *************/
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
attr->ia_uid = obj->yst_uid;
valid |= ATTR_UID;
attr->ia_gid = obj->yst_gid;
#else
attr->ia_uid.val = obj->yst_uid;
valid |= ATTR_UID;
attr->ia_gid.val = obj->yst_gid;
#endif
/************** lingd20140511 *************/
3、yaffs2补丁
yaffs2-linux-3.14.patch
我已经将上面的修复做成补丁,直接通过以下方法即可修复:
3.1 获取yaffs源码
lingd@ubuntu14:~/arm$ git clone git://
3.2 为yaffs2打补丁
lingd@ubuntu14:~/arm$ cd yaffs2/
lingd@ubuntu14:~/arm/yaffs2$ patch -p1 < ../yaffs2-linux-3.14.patch
patching file yaffs_attribs.c
patching file yaffs_mtdif_multi.c
patching file yaffs_vfs_multi.c
3.3 为内核打yaffs2补丁
lingd@ubuntu14:~/arm/yaffs2$ ./patch-ker.sh l m /home/lingd/arm/linux-3.14.6
Updating /home/lingd/arm/linux-3.14.6/fs/Kconfig
Updating /home/lingd/arm/linux-3.14.6/fs/Makefile
转载请注明出处lingdxuyan.blog.chinaunix.net
最新内核linux-3.14.6 yaffs2移植修复记录
原文地址http://blog.chinaunix.net/uid-23089249-id-4296123.html
阅读(7468) | 评论(0) | 转发(1) |