본지 좀 되나서 헷갈렸네요.
jffs2 는 노드 단위로 데이터를 저장하게 되는데, nodelist.h 에 보시면 그에 대한 설명이 나와 있습니다. 가령 물리적으로 다음노드를 가리킨다던지.. 파일내에서 현재 노드에서 다음노드는 어디인지.. nodelist.h 하고 슈퍼 블럭쪽 한번 참고 해보세요..
Red Black 트리에 저장 되어지는 정보들을 말씀 하시는 것인가요?
아니면
struct jffs2_raw_node_ref
{
struct jffs2_raw_node_ref *next_in_ino; /* Points to the next raw_node_ref
for this object. If this _is_ the last, it points to the inode_cache,
xattr_ref or xattr_datum instead. The common part of those structures
has NULL in the first word. See jffs2_raw_ref_to_ic() below */
uint32_t flash_offset;
#define TEST_TOTLEN
#ifdef TEST_TOTLEN
uint32_t __totlen; /* This may die; use ref_totlen(c, jeb, ) below */
#endif
};
이부분에서 next_in_ino는 다음 버전의 노드를 가지는걸로 알고 있는데 틀린건가요?
Wear leveling을 위해서 버전별로 저장 하는데 그 버전을 나타 내는것으로 알고 있습니다.
죄송 합니다 자꾸 질문을 올려서 ^^;;; 생각보다 분석하는게 너무 어렵네요 길을 좀 제시 해주시면 감사 하겠습니다.
어떤식으로 찾아 가는지..
2.6.17 커널에 포함된 jffs2 코드에 주요 구조체가 아래와 같습니다.
좀 기네요.. jffs2_sb_info 먼저 보시고 jffs2 가 가지는 구조를 한번 그려보시면 이해가 좀 되실듯 싶습니다. 간단히 설명 드리자면 eraseblock = flash 에서 사용하는 sector 와 같은 개념으로 하나의 eraseblock 내에는 구조체를 보시면 여러개의 노드가 있습니다. 해당 eraseblock 에 처음노드와 마지막노드, 가비지 콜렉션을 수행할 노드의 포인터, 그외에 정보 등등.. 그리고 노드 구조체에서는 flash 에서의 자신의 오프셋, 노드의 길이, 다음 ino, 물리적으로 다음에 위치한 노드.. 제가 알기로는 그렇습니다. 참고만 하세요. ^^;;
26 struct jffs2_sb_info {
27 struct mtd_info *mtd;
28
29 uint32_t highest_ino;
30 uint32_t checked_ino;
31
32 unsigned int flags;
33
34 struct task_struct *gc_task; /* GC task struct */
35 struct completion gc_thread_start; /* GC thread start completion */
36 struct completion gc_thread_exit; /* GC thread exit completion port */
37
38 struct semaphore alloc_sem; /* Used to protect all the following
39 fields, and also to protect against
40 out-of-order writing of nodes. And GC. */
41 uint32_t cleanmarker_size; /* Size of an _inline_ CLEANMARKER
42 (i.e. zero for OOB CLEANMARKER */
43
44 uint32_t flash_size;
45 uint32_t used_size;
46 uint32_t dirty_size;
47 uint32_t wasted_size;
48 uint32_t free_size;
49 uint32_t erasing_size;
50 uint32_t bad_size;
51 uint32_t sector_size;
52 uint32_t unchecked_size;
53
54 uint32_t nr_free_blocks;
55 uint32_t nr_erasing_blocks;
56
57 /* Number of free blocks there must be before we... */
58 uint8_t resv_blocks_write; /* ... allow a normal filesystem write */
59 uint8_t resv_blocks_deletion; /* ... allow a normal filesystem deletion */
60 uint8_t resv_blocks_gctrigger; /* ... wake up the GC thread */
61 uint8_t resv_blocks_gcbad; /* ... pick a block from the bad_list to GC */
62 uint8_t resv_blocks_gcmerge; /* ... merge pages when garbage collecting */
63
64 uint32_t nospc_dirty_size;
65
66 uint32_t nr_blocks;
67 struct jffs2_eraseblock *blocks; /* The whole array of blocks. Used for getting blocks
68 * from the offset (blocks[ofs / sector_size]) */
69 struct jffs2_eraseblock *nextblock; /* The block we're currently filling */
70
71 struct jffs2_eraseblock *gcblock; /* The block we're currently garbage-collecting */
72
73 struct list_head clean_list; /* Blocks 100% full of clean data */
74 struct list_head very_dirty_list; /* Blocks with lots of dirty space */
75 struct list_head dirty_list; /* Blocks with some dirty space */
76 struct list_head erasable_list; /* Blocks which are completely dirty, and need erasing */
77 struct list_head erasable_pending_wbuf_list; /* Blocks which need erasing but only after the current wbuf is flushed */
78 struct list_head erasing_list; /* Blocks which are currently erasing */
79 struct list_head erase_pending_list; /* Blocks which need erasing now */
80 struct list_head erase_complete_list; /* Blocks which are erased and need the clean marker written to them */
81 struct list_head free_list; /* Blocks which are free and ready to be used */
82 struct list_head bad_list; /* Bad blocks. */
83 struct list_head bad_used_list; /* Bad blocks with valid data in. */
84
85 spinlock_t erase_completion_lock; /* Protect free_list and erasing_list
86 against erase completion handler */
87 wait_queue_head_t erase_wait; /* For waiting for erases to complete */
88
89 wait_queue_head_t inocache_wq;
90 struct jffs2_inode_cache **inocache_list;
91 spinlock_t inocache_lock;
92
93 /* Sem to allow jffs2_garbage_collect_deletion_dirent to
94 drop the erase_completion_lock while it's holding a pointer
95 to an obsoleted node. I don't like this. Alternatives welcomed. */
96 struct semaphore erase_free_sem;
97
98 uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */
99
100 #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
101 /* Write-behind buffer for NAND flash */
102 unsigned char *wbuf;
103 uint32_t wbuf_ofs;
104 uint32_t wbuf_len;
105 struct jffs2_inodirty *wbuf_inodes;
106
107 struct rw_semaphore wbuf_sem; /* Protects the write buffer */
108
109 /* Information about out-of-band area usage... */
110 struct nand_oobinfo *oobinfo;
111 uint32_t badblock_pos;
112 uint32_t fsdata_pos;
113 uint32_t fsdata_len;
114 #endif
115
116 struct jffs2_summary *summary; /* Summary information */
117
118 /* OS-private pointer for getting back to master superblock info */
119 void *os_priv;
120 };
75 struct jffs2_raw_node_ref
76 {
77 struct jffs2_raw_node_ref *next_in_ino; /* Points to the next raw_node_ref
78 for this inode. If this is the last, it points to the inode_cache
79 for this inode instead. The inode_cache will have NULL in the first
80 word so you know when you've got there :) */
81 struct jffs2_raw_node_ref *next_phys;
82 uint32_t flash_offset;
83 uint32_t __totlen; /* This may die; use ref_totlen(c, jeb, ) below */
84 };
183 struct jffs2_eraseblock
184 {
185 struct list_head list;
186 int bad_count;
187 uint32_t offset; /* of this block in the MTD */
188
189 uint32_t unchecked_size;
190 uint32_t used_size;
191 uint32_t dirty_size;
192 uint32_t wasted_size;
193 uint32_t free_size; /* Note that sector_size - free_size
194 is the address of the first free space */
195 struct jffs2_raw_node_ref *first_node;
196 struct jffs2_raw_node_ref *last_node;
197
198 struct jffs2_raw_node_ref *gc_node; /* Next node to be garbage collected */
199 };
[/code]75 struct jffs2_raw_node_ref
76 {
77 struct jffs2_raw_node_ref *next_in_ino; /* Points to the next raw_node_ref
78 for this inode. If this is the last, it points to the inode_cache
79 for this inode instead. The inode_cache will have NULL in the first
80 word so you know when you've got there :) */
81 struct jffs2_raw_node_ref *next_phys;
82 uint32_t flash_offset;
83 uint32_t __totlen; /* This may die; use ref_totlen(c, jeb, ) below */
84 };
next_in_ino는 JFFS2는 Wear leveling을 위해 inode를 버전별로 저장 되는데 그 다음번 버전 inode 번호는 같고 버전 정보는 다른 것을 나타 내는게 아닌가요?
아님 잘려진 파일을 나타 내는 것인가요?? 저는 버전으로 알고 있는데 잘못 알고 있는 것인가요?
^^;; 죄송 합니다. 저의 무지함이 ..참..ㅎㅎㅎ
제가 드리고 싶은 질문은 파일이 크기가 커지면 연속적으로 저장 하지 못하는데
만약 나누어서 저장 한다면 어떤 자료 구조에 의해서 Read 명령이 왔을때 파일을 하나로 합쳐주는가 입니다.
파일에 대한 read 명령이 오면 나누어져있던 파일의 데이터를 하나로 합쳐야 하지 않나요?
그걸 해주는 부분이 next_in_ino; 이라고 말씀 하시는거 같은데요
제가 알고 있기로는 한부분에 파일을 읽고 쓰고 하면 플래시 메모리 특징상 100000만번 이상은 사용 못한다고 하더라구요
그래서 JFF2는 변경 사항이 생기면 새로운 노드를 하나 만들고 버전 정보를 올리고 저장 하는 것으로 알고 있습니다.
next_in_ino는 다음번 버전을 나타 내는걸로 알고 있구요
그건 말이죠..
제가 알기로는 블럭단위로 저장될때 앞쪽에 있는 아이노드에 다음 블럭을 지정하는 포인터가 있습니다. 그걸 보고 찾아 가는거죠.
기억이 가물가물하니. jffs2 코드를 함 보시면 이해가 되실 겁니다. ㅎㅎ
이구조체가 저장 될텐데 이 구조체에는 정보가 없네요
struct jffs2_raw_inode
{
jint16_t magic; /* A constant magic number. */
jint16_t nodetype; /* == JFFS_NODETYPE_INODE */
jint32_t totlen; /* Total length of this node (inc data, etc.) */
jint32_t hdr_crc; /* Crc checksum */
jint32_t ino; /* Inode number. */
jint32_t version; /* Version number. */
jmode_t mode; /* The file's type or mode. */
jint16_t uid; /* The file's owner. */
jint16_t gid; /* The file's group. */
jint32_t isize; /* Total resultant size of this inode (used for truncations) */
jint32_t atime; /* Last access time. */
jint32_t mtime; /* Last modification time. */
jint32_t ctime; /* Change time. */
jint32_t offset; /* Where to begin to write. */
jint32_t csize; /* (Compressed) data size */
jint32_t dsize; /* Size of the node's data. (after decompression) */
uint8_t compr; /* Compression algorithm used */
uint8_t usercompr; /* Compression algorithm requested by the user */
jint16_t flags; /* See JFFS2_INO_FLAG_* */
jint32_t data_crc; /* CRC for the (compressed) data. */
jint32_t node_crc; /* CRC for the raw inode (excluding data) */
uint8_t data[0];
};
혹시 블록 앞에 무엇인가 들어 간다면 다른 구조체 인가요?
아.. 제가 설명을 좀 잘못 드린듯 하네요
본지 좀 되나서 헷갈렸네요.
jffs2 는 노드 단위로 데이터를 저장하게 되는데, nodelist.h 에 보시면 그에 대한 설명이 나와 있습니다. 가령 물리적으로 다음노드를 가리킨다던지.. 파일내에서 현재 노드에서 다음노드는 어디인지.. nodelist.h 하고 슈퍼 블럭쪽 한번 참고 해보세요..
죄송 합니다. 못찾겠어서 다시 글 올리네요
Red Black 트리에 저장 되어지는 정보들을 말씀 하시는 것인가요?
아니면
struct jffs2_raw_node_ref
{
struct jffs2_raw_node_ref *next_in_ino; /* Points to the next raw_node_ref
for this object. If this _is_ the last, it points to the inode_cache,
xattr_ref or xattr_datum instead. The common part of those structures
has NULL in the first word. See jffs2_raw_ref_to_ic() below */
uint32_t flash_offset;
#define TEST_TOTLEN
#ifdef TEST_TOTLEN
uint32_t __totlen; /* This may die; use ref_totlen(c, jeb, ) below */
#endif
};
이부분에서 next_in_ino는 다음 버전의 노드를 가지는걸로 알고 있는데 틀린건가요?
Wear leveling을 위해서 버전별로 저장 하는데 그 버전을 나타 내는것으로 알고 있습니다.
죄송 합니다 자꾸 질문을 올려서 ^^;;; 생각보다 분석하는게 너무 어렵네요 길을 좀 제시 해주시면 감사 하겠습니다.
어떤식으로 찾아 가는지..
jffs2 어떤 버전을 보시는지..
2.6.17 커널에 포함된 jffs2 코드에 주요 구조체가 아래와 같습니다.
좀 기네요.. jffs2_sb_info 먼저 보시고 jffs2 가 가지는 구조를 한번 그려보시면 이해가 좀 되실듯 싶습니다. 간단히 설명 드리자면 eraseblock = flash 에서 사용하는 sector 와 같은 개념으로 하나의 eraseblock 내에는 구조체를 보시면 여러개의 노드가 있습니다. 해당 eraseblock 에 처음노드와 마지막노드, 가비지 콜렉션을 수행할 노드의 포인터, 그외에 정보 등등.. 그리고 노드 구조체에서는 flash 에서의 자신의 오프셋, 노드의 길이, 다음 ino, 물리적으로 다음에 위치한 노드.. 제가 알기로는 그렇습니다. 참고만 하세요. ^^;;
저는 커널 2.6.18을
저는 커널 2.6.18을 보고 있는데요
[/code]75 struct jffs2_raw_node_ref
76 {
77 struct jffs2_raw_node_ref *next_in_ino; /* Points to the next raw_node_ref
78 for this inode. If this is the last, it points to the inode_cache
79 for this inode instead. The inode_cache will have NULL in the first
80 word so you know when you've got there :) */
81 struct jffs2_raw_node_ref *next_phys;
82 uint32_t flash_offset;
83 uint32_t __totlen; /* This may die; use ref_totlen(c, jeb, ) below */
84 };
next_in_ino는 JFFS2는 Wear leveling을 위해 inode를 버전별로 저장 되는데 그 다음번 버전 inode 번호는 같고 버전 정보는 다른 것을 나타 내는게 아닌가요?
아님 잘려진 파일을 나타 내는 것인가요?? 저는 버전으로 알고 있는데 잘못 알고 있는 것인가요?
^^;; 죄송 합니다. 저의 무지함이 ..참..ㅎㅎㅎ
제가 알기로는
질문에 의도를 잘 파악하지 못하겠지만.. wear leveling 을 위해서 inode 를 버전별로 저장하고 있는건 잘 모르겠습니다. 일반적으로 wear leveling 을 위한 동작은 가비지 콜렉터에서 수행합니다.
그리고 파일이 여러 개의 노드로 잘렸다고 이해하시면 될거 같습니다. 그래서 jffs2 는 데이터 노드와 디렉토리 노드로 나눠서 이걸 관리하는 걸로 알고 있습니다.
이게 딱 맞다는 내용은 아니니 코드 참고하시고요.
질문은 ..
제가 드리고 싶은 질문은 파일이 크기가 커지면 연속적으로 저장 하지 못하는데
만약 나누어서 저장 한다면 어떤 자료 구조에 의해서 Read 명령이 왔을때 파일을 하나로 합쳐주는가 입니다.
파일에 대한 read 명령이 오면 나누어져있던 파일의 데이터를 하나로 합쳐야 하지 않나요?
그걸 해주는 부분이 next_in_ino; 이라고 말씀 하시는거 같은데요
제가 알고 있기로는 한부분에 파일을 읽고 쓰고 하면 플래시 메모리 특징상 100000만번 이상은 사용 못한다고 하더라구요
그래서 JFF2는 변경 사항이 생기면 새로운 노드를 하나 만들고 버전 정보를 올리고 저장 하는 것으로 알고 있습니다.
next_in_ino는 다음번 버전을 나타 내는걸로 알고 있구요
죄송 합니다. 많은 가르침 부탁 드립니다.
댓글 달기