15
#include <linux/kernel.h>
16
#include <linux/pagemap.h>
17
#include <linux/crc32.h>
30
#include <fs/fs_driver.h>
31
#include <fs/super_block.h>
32
#include <fs/dir_context.h>
33
#include <fs/inode_operation.h>
36
#include <fs/hlpr_path.h>
37
#include <fs/file_desc.h>
39
#include <lib/libds/array.h>
41
#include <embox/unit.h>
43
#include <mem/misc/pool.h>
44
#include <mem/phymem.h>
45
#include <mem/sysmalloc.h>
47
#include <drivers/block_dev.h>
48
#include <drivers/flash/flash.h>
49
#include <drivers/flash/emulator.h>
51
#define FS_NAME "jffs2"
54
POOL_DEF(jffs2_fs_pool, struct jffs2_fs_info,
55
OPTION_GET(NUMBER,jffs2_descriptor_quantity));
58
POOL_DEF(jffs2_file_pool, struct jffs2_file_info,
59
OPTION_GET(NUMBER,inode_quantity));
61
static int jffs2fs_iterate(struct inode *next, char *name, struct inode *parent, struct dir_ctx *dir_ctx);
63
static int jffs2_free_fs(struct super_block *sb);
64
static int jffs2_read_inode (struct _inode *inode);
65
static void jffs2_clear_inode (struct _inode *inode);
67
static int jffs2_truncate_file (struct _inode *inode);
68
static unsigned char gc_buffer[PAGE_CACHE_SIZE];
73
struct jffs2_dirsearch {
75
const unsigned char *path;
77
const unsigned char *name;
82
typedef struct jffs2_dirsearch jffs2_dirsearch_t;
92
static void icache_evict(struct _inode *root_i, struct _inode *i) {
93
struct _inode *this = root_i, *next;
94
struct _inode *parent;
97
D2(printf("icache_evict\n"));
103
next = this->i_cache_next;
104
if (this != i && this->i_count == 0) {
105
parent = this->i_parent;
106
if (this->i_cache_next) {
107
this->i_cache_next->i_cache_prev = this->i_cache_prev;
109
if (this->i_cache_prev) {
110
this->i_cache_prev->i_cache_next = this->i_cache_next;
112
jffs2_clear_inode(this);
113
memset(this, 0x5a, sizeof(*this));
115
if (parent && parent != this) {
132
static void init_dirsearch(jffs2_dirsearch_t * ds,
133
struct _inode *dir, const unsigned char *name) {
134
D2(printf("init_dirsearch name = %s\n", name));
135
D2(printf("init_dirsearch dir = %#x\n",(unsigned int) dir));
150
static int find_entry(jffs2_dirsearch_t * ds) {
151
struct _inode *dir = ds->dir;
152
const unsigned char *name = ds->path;
153
const unsigned char *n = name;
157
D2(printf("find_entry\n"));
160
if (!S_ISDIR(dir->i_mode)) {
164
while (*n != '\0' && *n != '/') {
177
ds->namelen = namelen;
179
if (name[0] == '.') {
190
D2(printf("find_entry found ..\n"));
192
ds->node = ds->dir->i_parent;
197
D2(printf("find_entry found .\n"));
207
D2(printf("find_entry for name = %s\n", ds->path));
208
d = jffs2_lookup(dir, name, namelen);
209
D2(printf("find_entry got dir = %#x\n",(unsigned int) d));
219
if (S_ISDIR(d->i_mode) && !d->i_parent) {
236
static int jffs2_find(jffs2_dirsearch_t * d) {
239
D2(printf("jffs2_find for path =%s\n", d->path));
242
if (*(d->path) == '\0') {
247
while (*(d->path) == '/') {
268
d->path += d->namelen;
269
while (*(d->path) == '/') {
279
static int jffs2_read_super(struct jffs2_super_block *sb) {
280
struct jffs2_sb_info *c;
283
D1(printk( "jffs2: read_super\n"));
287
c->flash_size = sb->bdev->size < 4096 ? 4096 : sb->bdev->size;
288
c->sector_size = sb->bdev->block_size < 4096 ? 4096 : sb->bdev->size;
297
c->cleanmarker_size = sizeof(struct jffs2_unknown_node);
299
err = jffs2_do_mount_fs(c);
303
D1(printk( "jffs2_read_super(): Getting root inode\n"));
304
sb->s_root = jffs2_iget(sb, 1);
305
if (IS_ERR(sb->s_root)) {
306
D1(printk(KERN_WARNING "get root inode failed\n"));
307
err = PTR_ERR(sb->s_root);
315
jffs2_free_ino_caches(c);
316
jffs2_free_raw_node_refs(c);
322
static int jffs2_mount(struct inode *dir_node) {
323
struct jffs2_super_block *jffs2_sb;
324
struct jffs2_sb_info *c;
327
struct jffs2_fs_info *fsi;
329
fsi = dir_node->i_sb->sb_data;
331
jffs2_sb = &fsi->jffs2_sb;
333
if (jffs2_sb == NULL) {
337
c = &jffs2_sb->jffs2_sb;
338
memset(jffs2_sb, 0, sizeof (struct jffs2_super_block));
340
jffs2_sb->bdev = dir_node->i_sb->bdev;
342
c->inocache_list = sysmalloc(sizeof(struct jffs2_inode_cache *) * INOCACHE_HASHSIZE);
343
if (!c->inocache_list) {
346
memset(c->inocache_list, 0, sizeof(struct jffs2_inode_cache *) * INOCACHE_HASHSIZE);
348
spin_init(&c->inocache_lock, __SPIN_UNLOCKED);
349
spin_init(&c->erase_completion_lock, __SPIN_UNLOCKED);
351
jffs2_compressors_init();
353
err = jffs2_read_super(jffs2_sb);
356
jffs2_compressors_exit();
358
sysfree(c->inocache_list);
362
jffs2_sb->s_root->i_parent = jffs2_sb->s_root;
363
jffs2_sb->s_root->i_cache_prev = NULL;
364
jffs2_sb->s_root->i_cache_next = NULL;
365
jffs2_sb->s_root->i_count = 1;
367
D2(printf("jffs2_mount erasing pending blocks\n"));
368
jffs2_erase_pending_blocks(c, 0);
370
#ifdef CYGOPT_FS_JFFS2_GCTHREAD
371
jffs2_start_garbage_collect_thread(c);
374
D2(printf("jffs2_mounted superblock"));
382
static int jffs2_clean_sb(struct super_block *sb) {
384
struct jffs2_super_block *jffs2_sb;
385
struct jffs2_fs_info *fsi;
386
struct jffs2_sb_info *c;
387
struct jffs2_full_dirent *fd, *next;
390
jffs2_sb = &fsi->jffs2_sb;
391
root = jffs2_sb->s_root;
392
c = &jffs2_sb->jffs2_sb;
394
D2(printf("jffs2_umount\n"));
397
icache_evict(root, NULL);
399
if (root->i_count != 1) {
400
printf("Ino #1 has use count %d\n", root->i_count);
403
#ifdef CYGOPT_FS_JFFS2_GCTHREAD
404
jffs2_stop_garbage_collect_thread(c);
409
for (fd = root->jffs2_i.dents; fd; fd = next) {
411
jffs2_free_full_dirent(fd);
417
jffs2_free_ino_caches(c);
418
jffs2_free_raw_node_refs(c);
420
sysfree(c->inocache_list);
422
D2(printf("jffs2_umount No current mounts\n"));
424
jffs2_compressors_exit();
428
pool_free(&jffs2_file_pool, inode_priv(sb->sb_root));
436
static int jffs2_open(struct _inode *dir_ino, const char *name, int mode) {
437
jffs2_dirsearch_t ds;
438
struct _inode *node = NULL;
441
D2(printf("jffs2_open\n"));
447
init_dirsearch(&ds, (struct _inode *) dir_ino,
448
(const unsigned char *) name);
450
err = jffs2_find(&ds);
453
if (ds.last && (mode & O_CREAT)) {
458
err = jffs2_create(ds.dir, ds.name,
459
S_IRUGO|S_IXUGO|S_IWUSR|S_IFREG, &node);
467
} else if (err == ENOERR) {
472
if ((mode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) {
487
if (S_ISDIR(node->i_mode)) {
492
if (mode & O_TRUNC) {
493
err = jffs2_truncate_file(node);
505
static int jffs2_ops_unlink(struct _inode * dir, const char *name) {
506
struct jffs2_dirsearch ds;
509
D2(printf("jffs2_ops_unlink\n"));
511
init_dirsearch(&ds, (struct _inode *) dir,
512
(const unsigned char *)name);
514
err = jffs2_find(&ds);
522
if (S_ISDIR(ds.node->i_mode)) {
529
err = jffs2_unlink(ds.dir, ds.node, ds.name);
539
static int jffs2_ops_mkdir(struct _inode *dir, const char *name, mode_t mode) {
540
jffs2_dirsearch_t ds;
543
D2(printf("jffs2_ops_mkdir\n"));
545
init_dirsearch(&ds, (struct _inode *) dir,
546
(const unsigned char *)name);
548
err = jffs2_find(&ds);
555
err = -jffs2_mkdir(ds.dir, ds.name, mode);
576
static int jffs2_ops_rmdir(struct _inode * dir, const char *name) {
577
struct jffs2_dirsearch ds;
580
D2(printf("jffs2_ops_rmdir\n"));
582
init_dirsearch(&ds, (struct _inode *) dir,
583
(const unsigned char *)name);
585
err = jffs2_find(&ds);
593
if (!S_ISDIR(ds.node->i_mode)) {
599
err = jffs2_rmdir(ds.dir, ds.node, ds.name);
708
static int jffs2_extend_file (struct _inode *inode,
709
struct jffs2_raw_inode *ri, unsigned long offset) {
710
struct jffs2_sb_info *c;
711
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
712
struct jffs2_full_dnode *fn;
713
uint32_t phys_ofs, alloc_len;
716
c = &inode->i_sb->jffs2_sb;
719
D1(printk( "Writing new hole frag %#x-%#x between current EOF and new page\n",
720
(unsigned int)inode->i_size, (unsigned int)offset));
722
ret = jffs2_reserve_space(c, sizeof(*ri),
723
&phys_ofs, &alloc_len, ALLOC_NORMAL);
729
ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
730
ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
731
ri->totlen = cpu_to_je32(sizeof(*ri));
732
ri->hdr_crc = cpu_to_je32(crc32(0, ri,
733
sizeof(struct jffs2_unknown_node)-4));
735
ri->version = cpu_to_je32(++f->highest_version);
736
ri->isize = cpu_to_je32(max((uint32_t)inode->i_size, offset));
738
ri->offset = cpu_to_je32(inode->i_size);
739
ri->dsize = cpu_to_je32(offset - inode->i_size);
740
ri->csize = cpu_to_je32(0);
741
ri->compr = JFFS2_COMPR_ZERO;
742
ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
743
ri->data_crc = cpu_to_je32(0);
745
fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
746
jffs2_complete_reservation(c);
752
ret = jffs2_add_full_dnode_to_inode(c, f, fn);
754
jffs2_mark_node_obsolete(c, f->metadata->raw);
755
jffs2_free_full_dnode(f->metadata);
759
D1(printk( "Eep. add_full_dnode_to_inode() failed in prepare_write, returned %d\n", ret));
760
jffs2_mark_node_obsolete(c, fn->raw);
761
jffs2_free_full_dnode(fn);
765
inode->i_size = offset;
773
static int jffs2_truncate_file (struct _inode *inode) {
774
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
775
struct jffs2_sb_info *c;
776
struct jffs2_full_dnode *new_metadata, * old_metadata;
777
struct jffs2_raw_inode *ri;
778
uint32_t phys_ofs, alloclen;
781
ri = jffs2_alloc_raw_inode();
785
c = &inode->i_sb->jffs2_sb;
786
err = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
789
jffs2_free_raw_inode(ri);
793
ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
794
ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
795
ri->totlen = cpu_to_je32(sizeof(*ri));
796
ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
798
ri->ino = cpu_to_je32(inode->i_ino);
799
ri->version = cpu_to_je32(++f->highest_version);
801
ri->uid = cpu_to_je16(inode->i_uid);
802
ri->gid = cpu_to_je16(inode->i_gid);
803
ri->mode = cpu_to_jemode(inode->i_mode);
804
ri->isize = cpu_to_je32(0);
805
ri->atime = cpu_to_je32(inode->i_atime);
806
ri->mtime = cpu_to_je32(timestamp());
807
ri->offset = cpu_to_je32(0);
808
ri->csize = ri->dsize = cpu_to_je32(0);
809
ri->compr = JFFS2_COMPR_NONE;
810
ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
811
ri->data_crc = cpu_to_je32(0);
812
new_metadata = jffs2_write_dnode(c, f, ri, NULL, 0,
813
phys_ofs, ALLOC_NORMAL);
814
if (IS_ERR(new_metadata)) {
815
jffs2_complete_reservation(c);
816
jffs2_free_raw_inode(ri);
818
return PTR_ERR(new_metadata);
822
inode->i_mtime = timestamp();
824
old_metadata = f->metadata;
825
jffs2_truncate_fragtree (c, &f->fragtree, 0);
826
f->metadata = new_metadata;
828
jffs2_mark_node_obsolete(c, old_metadata->raw);
829
jffs2_free_full_dnode(old_metadata);
831
jffs2_free_raw_inode(ri);
834
jffs2_complete_reservation(c);
839
static int jffs2_fo_write(struct file_desc *desc, char *buf, ssize_t size) {
840
struct _inode *inode;
841
off_t pos = file_get_pos(desc);
842
ssize_t resid = size;
843
struct jffs2_raw_inode ri;
844
struct jffs2_inode_info *f;
845
struct jffs2_sb_info *c;
846
struct jffs2_file_info *fi;
852
fi = inode_priv(desc->f_inode);
855
f = JFFS2_INODE_INFO(inode);
856
c = &inode->i_sb->jffs2_sb;
863
memset(&ri, 0, sizeof(ri));
865
ri.ino = cpu_to_je32(f->inocache->ino);
866
ri.mode = cpu_to_jemode(inode->i_mode);
867
ri.uid = cpu_to_je16(inode->i_uid);
868
ri.gid = cpu_to_je16(inode->i_gid);
869
ri.atime = ri.ctime = ri.mtime = cpu_to_je32(timestamp());
871
if (pos > inode->i_size) {
872
ri.version = cpu_to_je32(++f->highest_version);
873
err = jffs2_extend_file(inode, &ri, pos);
880
ri.isize = cpu_to_je32(inode->i_size);
884
D2(printf("jffs2_fo_write page_start_pos %d\n", pos));
885
D2(printf("jffs2_fo_write transfer size %d\n", len));
887
err = jffs2_write_inode_range(c, f, &ri, (unsigned char *)buf,
888
pos, len, &writtenlen);
895
if (writtenlen != len) {
907
inode->i_mtime = inode->i_ctime = je32_to_cpu(ri.mtime);
908
if (pos > inode->i_size) {
919
static int jffs2_fo_close(struct _inode *node) {
920
D2(printf("jffs2_fo_close\n"));
927
unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
928
struct jffs2_inode_info *f, unsigned long offset, unsigned long *priv) {
932
ret = jffs2_read_inode_range(c, f, gc_buffer,
933
offset & ~(PAGE_CACHE_SIZE-1), PAGE_CACHE_SIZE);
941
void jffs2_gc_release_page(struct jffs2_sb_info *c,
942
unsigned char *ptr, unsigned long *priv) {
946
static struct _inode *new_inode(struct jffs2_super_block *sb) {
950
struct _inode *inode;
951
struct _inode *cached_inode;
953
inode = sysmalloc(sizeof (struct _inode));
959
("malloc new_inode %x ####################################\n",
960
(unsigned int)inode));
962
memset(inode, 0, sizeof (struct _inode));
969
inode->i_cache_next = NULL;
972
for (cached_inode = sb->s_root; cached_inode != NULL;
973
cached_inode = cached_inode->i_cache_next) {
974
if (cached_inode->i_cache_next == NULL) {
975
cached_inode->i_cache_next = inode;
976
inode->i_cache_prev = cached_inode;
983
static struct _inode *ilookup(struct jffs2_super_block *sb, uint32_t ino)
985
struct _inode *inode = NULL;
987
D2(printf("ilookup\n"));
989
for (inode = sb->s_root; inode != NULL; inode = inode->i_cache_next) {
990
if (inode->i_ino == ino) {
998
struct _inode *jffs2_iget(struct jffs2_super_block *sb, uint32_t ino) {
1002
struct _inode *inode;
1005
D2(printf("jffs2_iget\n"));
1007
inode = ilookup(sb, ino);
1013
inode = new_inode(sb);
1014
if (inode == NULL) {
1015
return ERR_PTR(-ENOMEM);
1020
err = jffs2_read_inode(inode);
1022
printf("jffs2_read_inode() failed\n");
1026
return ERR_PTR(err);
1035
void jffs2_iput(struct _inode *i) {
1036
struct _inode *parent;
1040
printf("jffs2_iput() called with NULL inode\n");
1046
if (i->i_count < 0) {
1056
if (i->i_cache_prev) {
1057
i->i_cache_prev->i_cache_next = i->i_cache_next;
1059
if (i->i_cache_next) {
1060
i->i_cache_next->i_cache_prev = i->i_cache_prev;
1063
parent = i->i_parent;
1064
jffs2_clear_inode(i);
1065
memset(i, 0x5a, sizeof(*i));
1068
if (parent && parent != i) {
1077
icache_evict(i->i_sb->s_root, i);
1081
static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) {
1082
memset(f, 0, sizeof(*f));
1083
init_MUTEX_LOCKED(&f->sem);
1086
static void jffs2_clear_inode (struct _inode *inode) {
1090
struct jffs2_sb_info *c;
1091
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
1093
c = &inode->i_sb->jffs2_sb;
1095
D1(printk( "jffs2_clear_inode(): ino #%u mode %o\n", inode->i_ino, inode->i_mode));
1097
jffs2_do_clear_inode(c, f);
1105
struct _inode *jffs2_new_inode (struct _inode *dir_i,
1106
int mode, struct jffs2_raw_inode *ri) {
1107
struct _inode *inode;
1108
struct jffs2_super_block *sb = dir_i->i_sb;
1109
struct jffs2_sb_info *c;
1110
struct jffs2_inode_info *f;
1113
D1(printk( "jffs2_new_inode(): dir_i %d, mode 0x%x\n", dir_i->i_ino, i_mode));
1117
inode = new_inode(sb);
1120
return ERR_PTR(-ENOMEM);
1123
f = JFFS2_INODE_INFO(inode);
1124
jffs2_init_inode_info(f);
1126
memset(ri, 0, sizeof(*ri));
1128
ri->uid = ri->gid = cpu_to_je16(0);
1129
ri->mode = cpu_to_jemode(mode);
1130
ret = jffs2_do_new_inode (c, f, mode, ri);
1135
if (inode->i_cache_prev) {
1136
inode->i_cache_prev->i_cache_next = inode->i_cache_next;
1138
if (inode->i_cache_next) {
1139
inode->i_cache_next->i_cache_prev = inode->i_cache_prev;
1142
jffs2_clear_inode(inode);
1143
memset(inode, 0x6a, sizeof(*inode));
1145
return ERR_PTR(ret);
1148
inode->i_ino = je32_to_cpu(ri->ino);
1149
inode->i_mode = jemode_to_cpu(ri->mode);
1150
inode->i_gid = je16_to_cpu(ri->gid);
1151
inode->i_uid = je16_to_cpu(ri->uid);
1152
inode->i_atime = inode->i_ctime = inode->i_mtime = timestamp();
1153
ri->atime = ri->mtime = ri->ctime = cpu_to_je32(inode->i_mtime);
1161
static int jffs2_read_inode (struct _inode *inode) {
1162
struct jffs2_inode_info *f;
1163
struct jffs2_sb_info *c;
1164
struct jffs2_raw_inode latest_node;
1167
D1(printk( "jffs2_read_inode(): inode->i_ino == %d\n", inode->i_ino));
1169
f = JFFS2_INODE_INFO(inode);
1170
c = &inode->i_sb->jffs2_sb;
1172
jffs2_init_inode_info(f);
1174
ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
1180
inode->i_mode = jemode_to_cpu(latest_node.mode);
1181
inode->i_uid = je16_to_cpu(latest_node.uid);
1182
inode->i_gid = je16_to_cpu(latest_node.gid);
1183
inode->i_size = je32_to_cpu(latest_node.isize);
1184
inode->i_atime = je32_to_cpu(latest_node.atime);
1185
inode->i_mtime = je32_to_cpu(latest_node.mtime);
1186
inode->i_ctime = je32_to_cpu(latest_node.ctime);
1188
inode->i_nlink = f->inocache->nlink;
1191
D1(printk( "jffs2_read_inode() returning\n"));
1196
void jffs2_gc_release_inode(struct jffs2_sb_info *c,
1197
struct jffs2_inode_info *f) {
1198
jffs2_iput(OFNI_EDONI_2SFFJ(f));
1201
struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
1202
int inum, int nlink) {
1203
struct _inode *inode;
1204
struct jffs2_inode_cache *ic;
1205
struct jffs2_super_block *sb;
1207
sb = member_cast_out(c, struct jffs2_super_block, jffs2_sb);
1224
inode = ilookup(sb, inum);
1226
D1(printk( "ilookup() failed for ino #%u; inode is probably deleted.\n",
1229
spin_lock(&c->inocache_lock);
1230
ic = jffs2_get_ino_cache(c, inum);
1232
D1(printk( "Inode cache for ino #%u is gone.\n", inum));
1233
spin_unlock(&c->inocache_lock);
1236
if (ic->state != INO_STATE_CHECKEDABSENT) {
1238
D1(printk( "Waiting for ino #%u in state %d\n",
1239
ic->ino, ic->state));
1240
sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
1242
spin_unlock(&c->inocache_lock);
1252
inode = jffs2_iget(sb, inum);
1253
if (IS_ERR(inode)) {
1254
return (void *)inode;
1258
return JFFS2_INODE_INFO(inode);
1261
uint32_t jffs2_from_os_mode(uint32_t osmode) {
1262
uint32_t jmode = ((osmode & S_IRUSR)?00400:0) |
1263
((osmode & S_IWUSR)?00200:0) |
1264
((osmode & S_IXUSR)?00100:0) |
1265
((osmode & S_IRGRP)?00040:0) |
1266
((osmode & S_IWGRP)?00020:0) |
1267
((osmode & S_IXGRP)?00010:0) |
1268
((osmode & S_IROTH)?00004:0) |
1269
((osmode & S_IWOTH)?00002:0) |
1270
((osmode & S_IXOTH)?00001:0);
1272
switch (osmode & S_IFMT) {
1274
return jmode | 0140000;
1276
return jmode | 0120000;
1278
return jmode | 0100000;
1280
return jmode | 0060000;
1282
return jmode | 0040000;
1284
return jmode | 0020000;
1286
return jmode | 0010000;
1288
return jmode | 0004000;
1290
return jmode | 0002000;
1293
return jmode | 0001000;
1296
printf("os_to_jffs2_mode() cannot convert 0x%x\n", osmode);
1301
uint32_t jffs2_to_os_mode (uint32_t jmode) {
1302
uint32_t osmode = ((jmode & 00400)?S_IRUSR:0) |
1303
((jmode & 00200)?S_IWUSR:0) |
1304
((jmode & 00100)?S_IXUSR:0) |
1305
((jmode & 00040)?S_IRGRP:0) |
1306
((jmode & 00020)?S_IWGRP:0) |
1307
((jmode & 00010)?S_IXGRP:0) |
1308
((jmode & 00004)?S_IROTH:0) |
1309
((jmode & 00002)?S_IWOTH:0) |
1310
((jmode & 00001)?S_IXOTH:0);
1312
switch(jmode & 00170000) {
1314
return osmode | S_IFSOCK;
1316
return osmode | S_IFLNK;
1318
return osmode | S_IFREG;
1320
return osmode | S_IFBLK;
1322
return osmode | S_IFDIR;
1324
return osmode | S_IFCHR;
1326
return osmode | S_IFIFO;
1328
return osmode | S_ISUID;
1330
return osmode | S_ISGID;
1333
return osmode | S_ISVTX;
1336
printf("jffs2_to_os_mode() cannot convert 0x%x\n", osmode);
1341
static struct idesc *jffs2fs_open(struct inode *node, struct idesc *idesc, int __oflag);
1342
static int jffs2fs_close(struct file_desc *desc);
1343
static size_t jffs2fs_read(struct file_desc *desc, void *buf, size_t size);
1344
static size_t jffs2fs_write(struct file_desc *desc, void *buf, size_t size);
1346
static struct file_operations jffs2_fop = {
1347
.open = jffs2fs_open,
1348
.close = jffs2fs_close,
1349
.read = jffs2fs_read,
1350
.write = jffs2fs_write,
1356
static struct idesc *jffs2fs_open(struct inode *node, struct idesc *idesc, int __oflag) {
1357
struct jffs2_file_info *fi;
1358
struct jffs2_fs_info *fsi;
1359
char path[PATH_MAX];
1362
fi = inode_priv(node);
1363
fsi = node->i_sb->sb_data;
1365
file_set_size(file_desc_from_idesc(idesc), fi->_inode->i_size);
1367
vfs_get_relative_path(node, path, PATH_MAX);
1369
res = jffs2_open(fsi->jffs2_sb.s_root, path, idesc->idesc_flags);
1371
return err2ptr(-res);
1376
static int jffs2fs_close(struct file_desc *desc) {
1377
struct jffs2_file_info *fi;
1382
fi = inode_priv(desc->f_inode);
1383
file_set_size(desc, fi->_inode->i_size);
1385
return jffs2_fo_close(fi->_inode);
1388
static size_t jffs2fs_read(struct file_desc *desc, void *buff, size_t size) {
1390
struct jffs2_file_info *fi;
1391
struct jffs2_inode_info *f;
1392
struct jffs2_sb_info *c;
1396
pos = file_get_pos(desc);
1398
fi = inode_priv(desc->f_inode);
1400
f = JFFS2_INODE_INFO(fi->_inode);
1401
c = &fi->_inode->i_sb->jffs2_sb;
1403
len = min(size, fi->_inode->i_size - pos);
1405
if (0 != (rc = jffs2_read_inode_range(c, f,
1406
(unsigned char *) buff, pos, len))) {
1414
static size_t jffs2fs_write(struct file_desc *desc, void *buff, size_t size) {
1416
struct jffs2_file_info *fi;
1418
fi = inode_priv(desc->f_inode);
1420
bytecount = jffs2_fo_write(desc, buff, size);
1422
file_set_size(desc, fi->_inode->i_size);
1427
static int jffs2_free_fs(struct super_block *sb) {
1428
struct jffs2_fs_info *fsi = sb->sb_data;
1431
pool_free(&jffs2_fs_pool, fsi);
1437
static int jffs2fs_format(struct block_dev *bdev, void *priv);
1438
static int jffs2fs_create(struct inode *i_new, struct inode *parent_node, int mode);
1440
static int jffs2fs_truncate(struct inode *node, off_t length);
1441
static int jffs2_fill_sb(struct super_block *sb, const char *source);
1443
static struct fs_driver jffs2fs_driver = {
1445
.format = jffs2fs_format,
1446
.fill_sb = jffs2_fill_sb,
1447
.clean_sb = jffs2_clean_sb,
1450
static jffs2_file_info_t *jffs2_fi_alloc(struct inode *i_new, void *fs) {
1451
jffs2_file_info_t *fi;
1453
fi = pool_alloc(&jffs2_file_pool);
1455
memset(fi, 0, sizeof(struct jffs2_file_info));
1456
inode_priv_set(i_new, fi);
1457
inode_size_set(i_new, 0);
1463
static int mount_vfs_dir_enty(struct inode *dir_node) {
1464
struct jffs2_inode_info *dir_f;
1465
struct jffs2_full_dirent *fd_list;
1466
struct _inode *inode = NULL;
1468
struct inode *vfs_node;
1469
struct _inode *dir_i;
1470
struct jffs2_file_info *fi;
1472
fi = inode_priv(dir_node);
1475
dir_f = JFFS2_INODE_INFO(dir_i);
1477
for (fd_list = dir_f->dents; NULL != fd_list; fd_list = fd_list->next) {
1481
inode = jffs2_iget(dir_i->i_sb, ino);
1482
if(NULL == (vfs_node = vfs_subtree_lookup(dir_node,
1483
(const char *) fd_list->name))) {
1484
vfs_node = vfs_subtree_create(dir_node,
1485
(const char *) fd_list->name, inode->i_mode);
1486
if(NULL == vfs_node) {
1491
if (NULL == inode_priv(vfs_node)) {
1492
if (NULL == (fi = jffs2_fi_alloc(vfs_node, dir_node->i_sb))) {
1493
inode_priv_set(vfs_node, fi);
1499
if(S_ISDIR(vfs_node->i_mode)) {
1500
mount_vfs_dir_enty(vfs_node);
1509
static int jffs2fs_create(struct inode *i_new, struct inode *parent_node, int mode) {
1511
struct jffs2_file_info *fi, *parents_fi;
1513
parents_fi = inode_priv(parent_node);
1515
if (S_ISDIR(i_new->i_mode)) {
1516
i_new->i_mode |= S_IRUGO|S_IXUGO|S_IWUSR;
1517
if (0 != (rc = jffs2_ops_mkdir(parents_fi->_inode,
1518
(const char *) inode_name(i_new), i_new->i_mode))) {
1522
if (0 != (rc = mount_vfs_dir_enty(parent_node))) {
1526
if (NULL == (fi = jffs2_fi_alloc(i_new, parent_node->i_sb))) {
1527
inode_priv_set(i_new, fi);
1530
if (0 != (rc = jffs2_create(parents_fi->_inode,
1531
(const unsigned char *) inode_name(i_new),
1532
i_new->i_mode, &fi->_inode))) {
1539
static int jffs2fs_delete(struct inode *dir, struct inode *node) {
1541
struct jffs2_file_info *par_fi, *fi;
1543
struct inode *parent;
1545
if (NULL == (parent = vfs_subtree_get_parent(node))) {
1550
par_fi = inode_priv(dir);
1551
fi = inode_priv(node);
1552
if (S_ISDIR(node->i_mode)) {
1553
if (0 != (rc = jffs2_ops_rmdir(par_fi->_inode,
1554
(const char *) inode_name(node)))) {
1558
if (0 != (rc = jffs2_ops_unlink(par_fi->_inode,
1559
(const char *) inode_name(node)))) {
1564
if(NULL != (fi = inode_priv(node))) {
1565
pool_free(&jffs2_file_pool, fi);
1571
static int jffs2fs_format(struct block_dev *bdev, void *priv) {
1572
char flash_node_name[PATH_MAX];
1574
snprintf(flash_node_name, PATH_MAX, "%s_flash", block_dev_name(bdev));
1576
return flash_emu_dev_create(flash_node_name, 16 * 1024, 1024);
1579
static int jffs2fs_destroy_inode(struct inode *inode) {
1583
static struct super_block_operations jffs2fs_sbops = {
1585
.destroy_inode = jffs2fs_destroy_inode,
1588
struct inode_operations jffs2fs_iops = {
1589
.ino_create = jffs2fs_create,
1590
.ino_remove = jffs2fs_delete,
1591
.ino_iterate = jffs2fs_iterate,
1592
.ino_truncate = jffs2fs_truncate,
1595
struct inode *jffs2fs_lookup(char const *name, struct inode const *dir) {
1599
static int jffs2fs_iterate(struct inode *next, char *next_name, struct inode *parent, struct dir_ctx *dir_ctx) {
1600
struct jffs2_inode_info *dir_f;
1601
struct jffs2_full_dirent *fd_list;
1602
struct _inode *inode = NULL;
1604
struct _inode *dir_i;
1605
struct jffs2_file_info *fi;
1608
fi = inode_priv(parent);
1611
dir_f = JFFS2_INODE_INFO(dir_i);
1613
for (fd_list = dir_f->dents; NULL != fd_list; fd_list = fd_list->next) {
1617
inode = jffs2_iget(dir_i->i_sb, ino);
1619
if (idx++ < (int)(uintptr_t)dir_ctx->fs_ctx) {
1622
if (NULL == (fi = jffs2_fi_alloc(next, parent->i_sb))) {
1625
inode_priv_set(next, fi);
1628
next->i_mode = inode->i_mode;
1630
next->i_owner_id = inode->i_uid;
1631
next->i_group_id = inode->i_gid;
1632
inode_size_set(next, inode->i_size);
1634
strncpy(next_name, (const char *)fd_list->name, NAME_MAX - 1);
1635
next_name[NAME_MAX - 1] = '\0';
1637
dir_ctx->fs_ctx = (void *)(uintptr_t)idx;
1648
static int jffs2fs_create_root(struct super_block *sb, struct inode *dest) {
1650
struct jffs2_file_info *fi;
1651
struct jffs2_fs_info *fsi;
1653
if (NULL == (fi = pool_alloc(&jffs2_file_pool))) {
1654
inode_priv_set(dest, fi);
1658
memset(fi, 0, sizeof(struct jffs2_file_info));
1660
if (0 != (rc = jffs2_mount(dest))) {
1664
inode_priv_set(dest, fi);
1666
fi->_inode = fsi->jffs2_sb.s_root;
1676
static int jffs2_fill_sb(struct super_block *sb, const char *source) {
1677
struct block_dev *bdev;
1678
struct jffs2_fs_info *fsi;
1680
bdev = bdev_by_path(source);
1688
if (NULL == (fsi = pool_alloc(&jffs2_fs_pool))) {
1691
memset(fsi, 0, sizeof(struct jffs2_fs_info));
1693
sb->sb_ops = &jffs2fs_sbops;
1694
sb->sb_iops = &jffs2fs_iops;
1695
sb->sb_fops = &jffs2_fop;
1697
jffs2fs_create_root(sb, sb->sb_root);
1702
static int jffs2fs_truncate (struct inode *node, off_t length) {
1703
struct jffs2_file_info *fi;
1705
inode_size_set(node, length);
1707
fi = inode_priv(node);
1708
jffs2_truncate_file(fi->_inode);
1713
DECLARE_FILE_SYSTEM_DRIVER(jffs2fs_driver);