jffs2 파일 시스템 관련 질문

loveteaeun의 이미지

jffs2 파일 시스템에 큰 파일이 들어와서
연속적으로 저장 되지 못한다면 분명 크기 만큼 짤려서 저장 되게 될것인데
만약 데이터를 read 한다면 어떤식으로 찾아 가게 될까요?

kgykingdom의 이미지

제가 알기로는 블럭단위로 저장될때 앞쪽에 있는 아이노드에 다음 블럭을 지정하는 포인터가 있습니다. 그걸 보고 찾아 가는거죠.
기억이 가물가물하니. jffs2 코드를 함 보시면 이해가 되실 겁니다. ㅎㅎ

loveteaeun의 이미지

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

혹시 블록 앞에 무엇인가 들어 간다면 다른 구조체 인가요?

kgykingdom의 이미지

본지 좀 되나서 헷갈렸네요.
jffs2 는 노드 단위로 데이터를 저장하게 되는데, nodelist.h 에 보시면 그에 대한 설명이 나와 있습니다. 가령 물리적으로 다음노드를 가리킨다던지.. 파일내에서 현재 노드에서 다음노드는 어디인지.. nodelist.h 하고 슈퍼 블럭쪽 한번 참고 해보세요..

loveteaeun의 이미지

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을 위해서 버전별로 저장 하는데 그 버전을 나타 내는것으로 알고 있습니다.

죄송 합니다 자꾸 질문을 올려서 ^^;;; 생각보다 분석하는게 너무 어렵네요 길을 좀 제시 해주시면 감사 하겠습니다.
어떤식으로 찾아 가는지..

kgykingdom의 이미지

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 };
loveteaeun의 이미지

저는 커널 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 번호는 같고 버전 정보는 다른 것을 나타 내는게 아닌가요?
아님 잘려진 파일을 나타 내는 것인가요?? 저는 버전으로 알고 있는데 잘못 알고 있는 것인가요?
^^;; 죄송 합니다. 저의 무지함이 ..참..ㅎㅎㅎ

kgykingdom의 이미지

질문에 의도를 잘 파악하지 못하겠지만.. wear leveling 을 위해서 inode 를 버전별로 저장하고 있는건 잘 모르겠습니다. 일반적으로 wear leveling 을 위한 동작은 가비지 콜렉터에서 수행합니다.

그리고 파일이 여러 개의 노드로 잘렸다고 이해하시면 될거 같습니다. 그래서 jffs2 는 데이터 노드와 디렉토리 노드로 나눠서 이걸 관리하는 걸로 알고 있습니다.

이게 딱 맞다는 내용은 아니니 코드 참고하시고요.

loveteaeun의 이미지

제가 드리고 싶은 질문은 파일이 크기가 커지면 연속적으로 저장 하지 못하는데
만약 나누어서 저장 한다면 어떤 자료 구조에 의해서 Read 명령이 왔을때 파일을 하나로 합쳐주는가 입니다.
파일에 대한 read 명령이 오면 나누어져있던 파일의 데이터를 하나로 합쳐야 하지 않나요?
그걸 해주는 부분이 next_in_ino; 이라고 말씀 하시는거 같은데요
제가 알고 있기로는 한부분에 파일을 읽고 쓰고 하면 플래시 메모리 특징상 100000만번 이상은 사용 못한다고 하더라구요
그래서 JFF2는 변경 사항이 생기면 새로운 노드를 하나 만들고 버전 정보를 올리고 저장 하는 것으로 알고 있습니다.
next_in_ino는 다음번 버전을 나타 내는걸로 알고 있구요

죄송 합니다. 많은 가르침 부탁 드립니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.