• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE Article PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
2
3<Article>
4
5<ArtHeader>
6
7<Title>The extended-2 filesystem overview</Title>
8<AUTHOR
9>
10<FirstName>Gadi Oxman, tgud@tochnapc2.technion.ac.il</FirstName>
11</AUTHOR
12>
13<PubDate>v0.1, August 3 1995</PubDate>
14
15</ArtHeader>
16
17<Sect1>
18<Title>Preface</Title>
19
20<Para>
21This document attempts to present an overview of the internal structure of
22the ext2 filesystem. It was written in summer 95, while I was working on the
23<Literal remap="tt">ext2 filesystem editor project (EXT2ED)</Literal>.
24</Para>
25
26<Para>
27In the process of constructing EXT2ED, I acquired knowledge of the various
28design aspects of the the ext2 filesystem. This document is a result of an
29effort to document this knowledge.
30</Para>
31
32<Para>
33This is only the initial version of this document. It is obviously neither
34error-prone nor complete, but at least it provides a starting point.
35</Para>
36
37<Para>
38In the process of learning the subject, I have used the following sources /
39tools:
40
41<ItemizedList>
42<ListItem>
43
44<Para>
45	Experimenting with EXT2ED, as it was developed.
46</Para>
47</ListItem>
48<ListItem>
49
50<Para>
51	The ext2 kernel sources:
52
53<ItemizedList>
54<ListItem>
55
56<Para>
57	The main ext2 include file,
58<FILENAME>/usr/include/linux/ext2&lowbar;fs.h</FILENAME>
59</Para>
60</ListItem>
61<ListItem>
62
63<Para>
64	The contents of the directory <FILENAME>/usr/src/linux/fs/ext2</FILENAME>.
65</Para>
66</ListItem>
67<ListItem>
68
69<Para>
70	The VFS layer sources (only a bit).
71</Para>
72</ListItem>
73
74</ItemizedList>
75
76</Para>
77</ListItem>
78<ListItem>
79
80<Para>
81	The slides: The Second Extended File System, Current State, Future
82Development, by <personname><firstname>Remy</firstname> <surname>Card</surname></personname>.
83</Para>
84</ListItem>
85<ListItem>
86
87<Para>
88	The slides: Optimisation in File Systems, by <personname><firstname>Stephen</firstname> <surname>Tweedie</surname></personname>.
89</Para>
90</ListItem>
91<ListItem>
92
93<Para>
94	The various ext2 utilities.
95</Para>
96</ListItem>
97
98</ItemizedList>
99
100</Para>
101
102</Sect1>
103
104<Sect1>
105<Title>Introduction</Title>
106
107<Para>
108The <Literal remap="tt">Second Extended File System (Ext2fs)</Literal> is very popular among Linux
109users. If you use Linux, chances are that you are using the ext2 filesystem.
110</Para>
111
112<Para>
113Ext2fs was designed by <personname><firstname>Remy</firstname> <surname>Card</surname></personname> and <personname><firstname>Wayne</firstname> <surname>Davison</surname></personname>. It was
114implemented by <personname><firstname>Remy</firstname> <surname>Card</surname></personname> and was further enhanced by <personname><firstname>Stephen</firstname>
115<surname>Tweedie</surname></personname> and <personname><firstname>Theodore</firstname> <surname>Ts'o</surname></personname>.
116</Para>
117
118<Para>
119The ext2 filesystem is still under development. I will document here
120version 0.5a, which is distributed along with Linux 1.2.x. At this time of
121writing, the most recent version of Linux is 1.3.13, and the version of the
122ext2 kernel source is 0.5b. A lot of fancy enhancements are planned for the
123ext2 filesystem in Linux 1.3, so stay tuned.
124</Para>
125
126</Sect1>
127
128<Sect1>
129<Title>A filesystem - Why do we need it?</Title>
130
131<Para>
132I thought that before we dive into the various small details, I'll reserve a
133few minutes for the discussion of filesystems from a general point of view.
134</Para>
135
136<Para>
137A <Literal remap="tt">filesystem</Literal> consists of two word - <Literal remap="tt">file</Literal> and <Literal remap="tt">system</Literal>.
138</Para>
139
140<Para>
141Everyone knows the meaning of the word <Literal remap="tt">file</Literal> - A bunch of data put
142somewhere. where? This is an important question. I, for example, usually
143throw almost everything into a single drawer, and have difficulties finding
144something later.
145</Para>
146
147<Para>
148This is where the <Literal remap="tt">system</Literal> comes in - Instead of just throwing the data
149to the device, we generalize and construct a <Literal remap="tt">system</Literal> which will
150virtualize for us a nice and ordered structure in which we could arrange our
151data in much the same way as books are arranged in a library. The purpose of
152the filesystem, as I understand it, is to make it easy for us to update and
153maintain our data.
154</Para>
155
156<Para>
157Normally, by <Literal remap="tt">mounting</Literal> filesystems, we just use the nice and logical
158virtual structure. However, the disk knows nothing about that - The device
159driver views the disk as a large continuous paper in which we can write notes
160wherever we wish. It is the task of the filesystem management code to store
161bookkeeping information which will serve the kernel for showing us the nice
162and ordered virtual structure.
163</Para>
164
165<Para>
166In this document, we consider one particular administrative structure - The
167Second Extended Filesystem.
168</Para>
169
170</Sect1>
171
172<Sect1>
173<Title>The Linux VFS layer</Title>
174
175<Para>
176When Linux was first developed, it supported only one filesystem - The
177<Literal remap="tt">Minix</Literal> filesystem. Today, Linux has the ability to support several
178filesystems concurrently. This was done by the introduction of another layer
179between the kernel and the filesystem code - The Virtual File System (VFS).
180</Para>
181
182<Para>
183The kernel "speaks" with the VFS layer. The VFS layer passes the kernel's
184request to the proper filesystem management code. I haven't learned much of
185the VFS layer as I didn't need it for the construction of EXT2ED so that I
186can't elaborate on it. Just be aware that it exists.
187</Para>
188
189</Sect1>
190
191<Sect1>
192<Title>About blocks and block groups</Title>
193
194<Para>
195In order to ease management, the ext2 filesystem logically divides the disk
196into small units called <Literal remap="tt">blocks</Literal>. A block is the smallest unit which
197can be allocated. Each block in the filesystem can be <Literal remap="tt">allocated</Literal> or
198<Literal remap="tt">free</Literal>.
199<FOOTNOTE>
200
201<Para>
202The Ext2fs source code refers to the concept of <Literal remap="tt">fragments</Literal>, which I
203believe are supposed to be sub-block allocations. As far as I know,
204fragments are currently unsupported in Ext2fs.
205</Para>
206
207</FOOTNOTE>
208
209The block size can be selected to be 1024, 2048 or 4096 bytes when creating
210the filesystem.
211</Para>
212
213<Para>
214Ext2fs groups together a fixed number of sequential blocks into a <Literal remap="tt">group
215block</Literal>. The resulting situation is that the filesystem is managed as a
216series of group blocks. This is done in order to keep related information
217physically close on the disk and to ease the management task. As a result,
218much of the filesystem management reduces to management of a single blocks
219group.
220</Para>
221
222</Sect1>
223
224<Sect1>
225<Title>The view of inodes from the point of view of a blocks group</Title>
226
227<Para>
228Each file in the filesystem is reserved a special <Literal remap="tt">inode</Literal>. I don't want
229to explain inodes now. Rather, I would like to treat it as another resource,
230much like a <Literal remap="tt">block</Literal> - Each blocks group contains a limited number of
231inode, while any specific inode can be <Literal remap="tt">allocated</Literal> or
232<Literal remap="tt">unallocated</Literal>.
233</Para>
234
235</Sect1>
236
237<Sect1>
238<Title>The group descriptors</Title>
239
240<Para>
241Each blocks group is accompanied by a <Literal remap="tt">group descriptor</Literal>. The group
242descriptor summarizes some necessary information about the specific group
243block. Follows the definition of the group descriptor, as defined in
244<FILENAME>/usr/include/linux/ext2&lowbar;fs.h</FILENAME>:
245</Para>
246
247<Para>
248
249<ProgramListing>
250struct ext2_group_desc
251{
252	__u32	bg_block_bitmap;	/* Blocks bitmap block */
253	__u32	bg_inode_bitmap;	/* Inodes bitmap block */
254	__u32	bg_inode_table;		/* Inodes table block */
255	__u16	bg_free_blocks_count;	/* Free blocks count */
256	__u16	bg_free_inodes_count;	/* Free inodes count */
257	__u16	bg_used_dirs_count;	/* Directories count */
258	__u16	bg_pad;
259	__u32	bg_reserved[3];
260};
261</ProgramListing>
262
263</Para>
264
265<Para>
266The last three variables: <Literal remap="tt">bg&lowbar;free&lowbar;blocks&lowbar;count, bg&lowbar;free&lowbar;inodes&lowbar;count and bg&lowbar;used&lowbar;dirs&lowbar;count</Literal> provide statistics about the use of the three
267resources in a blocks group - The <Literal remap="tt">blocks</Literal>, the <Literal remap="tt">inodes</Literal> and the
268<Literal remap="tt">directories</Literal>. I believe that they are used by the kernel for balancing
269the load between the various blocks groups.
270</Para>
271
272<Para>
273<Literal remap="tt">bg&lowbar;block&lowbar;bitmap</Literal> contains the block number of the <Literal remap="tt">block allocation
274bitmap block</Literal>. This is used to allocate / deallocate each block in the
275specific blocks group.
276</Para>
277
278<Para>
279<Literal remap="tt">bg&lowbar;inode&lowbar;bitmap</Literal> is fully analogous to the previous variable - It
280contains the block number of the <Literal remap="tt">inode allocation bitmap block</Literal>, which
281is used to allocate / deallocate each specific inode in the filesystem.
282</Para>
283
284<Para>
285<Literal remap="tt">bg&lowbar;inode&lowbar;table</Literal> contains the block number of the start of the
286<Literal remap="tt">inode table of the current blocks group</Literal>. The <Literal remap="tt">inode table</Literal> is
287just the actual inodes which are reserved for the current block.
288</Para>
289
290<Para>
291The block bitmap block, inode bitmap block and the inode table are created
292when the filesystem is created.
293</Para>
294
295<Para>
296The group descriptors are placed one after the other. Together they make the
297<Literal remap="tt">group descriptors table</Literal>.
298</Para>
299
300<Para>
301Each blocks group contains the entire table of group descriptors in its
302second block, right after the superblock. However, only the first copy (in
303group 0) is actually used by the kernel. The other copies are there for
304backup purposes and can be of use if the main copy gets corrupted.
305</Para>
306
307</Sect1>
308
309<Sect1>
310<Title>The block bitmap allocation block</Title>
311
312<Para>
313Each blocks group contains one special block which is actually a map of the
314entire blocks in the group, with respect to their allocation status. Each
315<Literal remap="tt">bit</Literal> in the block bitmap indicated whether a specific block in the
316group is used or free.
317</Para>
318
319<Para>
320The format is actually quite simple - Just view the entire block as a series
321of bits. For example,
322</Para>
323
324<Para>
325Suppose the block size is 1024 bytes. As such, there is a place for
3261024*8=8192 blocks in a group block. This number is one of the fields in the
327filesystem's <Literal remap="tt">superblock</Literal>, which will be explained later.
328</Para>
329
330<Para>
331
332<ItemizedList>
333<ListItem>
334
335<Para>
336	Block 0 in the blocks group is managed by bit 0 of byte 0 in the bitmap
337block.
338</Para>
339</ListItem>
340<ListItem>
341
342<Para>
343	Block 7 in the blocks group is managed by bit 7 of byte 0 in the bitmap
344block.
345</Para>
346</ListItem>
347<ListItem>
348
349<Para>
350	Block 8 in the blocks group is managed by bit 0 of byte 1 in the bitmap
351block.
352</Para>
353</ListItem>
354<ListItem>
355
356<Para>
357	Block 8191 in the blocks group is managed by bit 7 of byte 1023 in the
358bitmap 	block.
359</Para>
360</ListItem>
361
362</ItemizedList>
363
364</Para>
365
366<Para>
367A value of "<Literal remap="tt">1</Literal>" in the appropriate bit signals that the block is
368allocated, while a value of "<Literal remap="tt">0</Literal>" signals that the block is
369unallocated.
370</Para>
371
372<Para>
373You will probably notice that typically, all the bits in a byte contain the
374same value, making the byte's value <Literal remap="tt">0</Literal> or <Literal remap="tt">0ffh</Literal>. This is done by
375the kernel on purpose in order to group related data in physically close
376blocks, since the physical device is usually optimized to handle such a close
377relationship.
378</Para>
379
380</Sect1>
381
382<Sect1>
383<Title>The inode allocation bitmap</Title>
384
385<Para>
386The format of the inode allocation bitmap block is exactly like the format of
387the block allocation bitmap block. The explanation above is valid here, with
388the work <Literal remap="tt">block</Literal> replaced by <Literal remap="tt">inode</Literal>. Typically, there are much less
389inodes then blocks in a blocks group and thus only part of the inode bitmap
390block is used. The number of inodes in a blocks group is another variable
391which is listed in the <Literal remap="tt">superblock</Literal>.
392</Para>
393
394</Sect1>
395
396<Sect1>
397<Title>On the inode and the inode tables</Title>
398
399<Para>
400An inode is a main resource in the ext2 filesystem. It is used for various
401purposes, but the main two are:
402
403<ItemizedList>
404<ListItem>
405
406<Para>
407	Support of files
408</Para>
409</ListItem>
410<ListItem>
411
412<Para>
413	Support of directories
414</Para>
415</ListItem>
416
417</ItemizedList>
418
419</Para>
420
421<Para>
422Each file, for example, will allocate one inode from the filesystem
423resources.
424</Para>
425
426<Para>
427An ext2 filesystem has a total number of available inodes which is determined
428while creating the filesystem. When all the inodes are used, for example, you
429will not be able to create an additional file even though there will still
430be free blocks on the filesystem.
431</Para>
432
433<Para>
434Each inode takes up 128 bytes in the filesystem. By default, <Literal remap="tt">mke2fs</Literal>
435reserves an inode for each 4096 bytes of the filesystem space.
436</Para>
437
438<Para>
439The inodes are placed in several tables, each of which contains the same
440number of inodes and is placed at a different blocks group. The goal is to
441place inodes and their related files in the same blocks group because of
442locality arguments.
443</Para>
444
445<Para>
446The number of inodes in a blocks group is available in the superblock variable
447<Literal remap="tt">s&lowbar;inodes&lowbar;per&lowbar;group</Literal>. For example, if there are 2000 inodes per group,
448group 0 will contain the inodes 1-2000, group 2 will contain the inodes
4492001-4000, and so on.
450</Para>
451
452<Para>
453Each inode table is accessed from the group descriptor of the specific
454blocks group which contains the table.
455</Para>
456
457<Para>
458Follows the structure of an inode in Ext2fs:
459</Para>
460
461<Para>
462
463<ProgramListing>
464struct ext2_inode {
465	__u16	i_mode;		/* File mode */
466	__u16	i_uid;		/* Owner Uid */
467	__u32	i_size;		/* Size in bytes */
468	__u32	i_atime;	/* Access time */
469	__u32	i_ctime;	/* Creation time */
470	__u32	i_mtime;	/* Modification time */
471	__u32	i_dtime;	/* Deletion Time */
472	__u16	i_gid;		/* Group Id */
473	__u16	i_links_count;	/* Links count */
474	__u32	i_blocks;	/* Blocks count */
475	__u32	i_flags;	/* File flags */
476	union {
477		struct {
478			__u32  l_i_reserved1;
479		} linux1;
480		struct {
481			__u32  h_i_translator;
482		} hurd1;
483		struct {
484			__u32  m_i_reserved1;
485		} masix1;
486	} osd1;				/* OS dependent 1 */
487	__u32	i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
488	__u32	i_version;	/* File version (for NFS) */
489	__u32	i_file_acl;	/* File ACL */
490	__u32	i_size_high;	/* High 32bits of size */
491	__u32	i_faddr;	/* Fragment address */
492	union {
493		struct {
494			__u8	l_i_frag;	/* Fragment number */
495			__u8	l_i_fsize;	/* Fragment size */
496			__u16	i_pad1;
497			__u32	l_i_reserved2[2];
498		} linux2;
499		struct {
500			__u8	h_i_frag;	/* Fragment number */
501			__u8	h_i_fsize;	/* Fragment size */
502			__u16	h_i_mode_high;
503			__u16	h_i_uid_high;
504			__u16	h_i_gid_high;
505			__u32	h_i_author;
506		} hurd2;
507		struct {
508			__u8	m_i_frag;	/* Fragment number */
509			__u8	m_i_fsize;	/* Fragment size */
510			__u16	m_pad1;
511			__u32	m_i_reserved2[2];
512		} masix2;
513	} osd2;				/* OS dependent 2 */
514};
515</ProgramListing>
516
517</Para>
518
519<Sect2>
520<Title>The allocated blocks</Title>
521
522<Para>
523The basic functionality of an inode is to group together a series of
524allocated blocks. There is no limitation on the allocated blocks - Each
525block can be allocated to each inode. Nevertheless, block allocation will
526usually be done in series to take advantage of the locality principle.
527</Para>
528
529<Para>
530The inode is not always used in that way. I will now explain the allocation
531of blocks, assuming that the current inode type indeed refers to a list of
532allocated blocks.
533</Para>
534
535<Para>
536It was found experimentally that many of the files in the filesystem are
537actually quite small. To take advantage of this effect, the kernel provides
538storage of up to 12 block numbers in the inode itself. Those blocks are
539called <Literal remap="tt">direct blocks</Literal>. The advantage is that once the kernel has the
540inode, it can directly access the file's blocks, without an additional disk
541access. Those 12 blocks are directly specified in the variables
542<Literal remap="tt">i&lowbar;block[0] to i&lowbar;block[11]</Literal>.
543</Para>
544
545<Para>
546<Literal remap="tt">i&lowbar;block[12]</Literal> is the <Literal remap="tt">indirect block</Literal> - The block pointed by
547i&lowbar;block&lsqb;12] will <Literal remap="tt">not</Literal> be a data block. Rather, it will just contain a
548list of direct blocks. For example, if the block size is 1024 bytes, since
549each block number is 4 bytes long, there will be place for 256 indirect
550blocks. That is, block 13 till block 268 in the file will be accessed by the
551<Literal remap="tt">indirect block</Literal> method. The penalty in this case, compared to the
552direct blocks case, is that an additional access to the device is needed -
553We need <Literal remap="tt">two</Literal> accesses to reach the required data block.
554</Para>
555
556<Para>
557In much the same way, <Literal remap="tt">i&lowbar;block[13]</Literal> is the <Literal remap="tt">double indirect block</Literal>
558and <Literal remap="tt">i&lowbar;block[14]</Literal> is the <Literal remap="tt">triple indirect block</Literal>.
559</Para>
560
561<Para>
562<Literal remap="tt">i&lowbar;block[13]</Literal> points to a block which contains pointers to indirect
563blocks. Each one of them is handled in the way described above.
564</Para>
565
566<Para>
567In much the same way, the triple indirect block is just an additional level
568of indirection - It will point to a list of double indirect blocks.
569</Para>
570
571</Sect2>
572
573<Sect2>
574<Title>The i&lowbar;mode variable</Title>
575
576<Para>
577The i&lowbar;mode variable is used to determine the <Literal remap="tt">inode type</Literal> and the
578associated <Literal remap="tt">permissions</Literal>. It is best described by representing it as an
579octal number. Since it is a 16 bit variable, there will be 6 octal digits.
580Those are divided into two parts - The rightmost 4 digits and the leftmost 2
581digits.
582</Para>
583
584<Sect3>
585<Title>The rightmost 4 octal digits</Title>
586
587<Para>
588The rightmost 4 digits are <Literal remap="tt">bit options</Literal> - Each bit has its own
589purpose.
590</Para>
591
592<Para>
593The last 3 digits (Octal digits 0,1 and 2) are just the usual permissions,
594in the known form <Literal remap="tt">rwxrwxrwx</Literal>. Digit 2 refers to the user, digit 1 to
595the group and digit 2 to everyone else. They are used by the kernel to grant
596or deny access to the object presented by this inode.
597<FOOTNOTE>
598
599<Para>
600A <Literal remap="tt">smarter</Literal> permissions control is one of the enhancements planned for
601Linux 1.3 - The ACL (Access Control Lists). Actually, from browsing of the
602kernel source, some of the ACL handling is already done.
603</Para>
604
605</FOOTNOTE>
606
607</Para>
608
609<Para>
610Bit number 9 signals that the file (I'll refer to the object presented by
611the inode as file even though it can be a special device, for example) is
612<Literal remap="tt">set VTX</Literal>. I still don't know what is the meaning of "VTX".
613</Para>
614
615<Para>
616Bit number 10 signals that the file is <Literal remap="tt">set group id</Literal> - I don't know
617exactly the meaning of the above either.
618</Para>
619
620<Para>
621Bit number 11 signals that the file is <Literal remap="tt">set user id</Literal>, which means that
622the file will run with an effective user id root.
623</Para>
624
625</Sect3>
626
627<Sect3>
628<Title>The leftmost two octal digits</Title>
629
630<Para>
631Note the the leftmost octal digit can only be 0 or 1, since the total number
632of bits is 16.
633</Para>
634
635<Para>
636Those digits, as opposed to the rightmost 4 digits, are not bit mapped
637options. They determine the type of the "file" to which the inode belongs:
638
639<ItemizedList>
640<ListItem>
641
642<Para>
643	<Literal remap="tt">01</Literal> - The file is a <Literal remap="tt">FIFO</Literal>.
644</Para>
645</ListItem>
646<ListItem>
647
648<Para>
649	<Literal remap="tt">02</Literal> - The file is a <Literal remap="tt">character device</Literal>.
650</Para>
651</ListItem>
652<ListItem>
653
654<Para>
655	<Literal remap="tt">04</Literal> - The file is a <Literal remap="tt">directory</Literal>.
656</Para>
657</ListItem>
658<ListItem>
659
660<Para>
661	<Literal remap="tt">06</Literal> - The file is a <Literal remap="tt">block device</Literal>.
662</Para>
663</ListItem>
664<ListItem>
665
666<Para>
667	<Literal remap="tt">10</Literal> - The file is a <Literal remap="tt">regular file</Literal>.
668</Para>
669</ListItem>
670<ListItem>
671
672<Para>
673	<Literal remap="tt">12</Literal> - The file is a <Literal remap="tt">symbolic link</Literal>.
674</Para>
675</ListItem>
676<ListItem>
677
678<Para>
679	<Literal remap="tt">14</Literal> - The file is a <Literal remap="tt">socket</Literal>.
680</Para>
681</ListItem>
682
683</ItemizedList>
684
685</Para>
686
687</Sect3>
688
689</Sect2>
690
691<Sect2>
692<Title>Time and date</Title>
693
694<Para>
695Linux records the last time in which various operations occurred with the
696file. The time and date are saved in the standard C library format - The
697number of seconds which passed since 00:00:00 GMT, January 1, 1970. The
698following times are recorded:
699
700<ItemizedList>
701<ListItem>
702
703<Para>
704	<Literal remap="tt">i&lowbar;ctime</Literal> - The time in which the inode was last allocated. In
705other words, the time in which the file was created.
706</Para>
707</ListItem>
708<ListItem>
709
710<Para>
711	<Literal remap="tt">i&lowbar;mtime</Literal> - The time in which the file was last modified.
712</Para>
713</ListItem>
714<ListItem>
715
716<Para>
717	<Literal remap="tt">i&lowbar;atime</Literal> - The time in which the file was last accessed.
718</Para>
719</ListItem>
720<ListItem>
721
722<Para>
723	<Literal remap="tt">i&lowbar;dtime</Literal> - The time in which the inode was deallocated. In
724other words, the time in which the file was deleted.
725</Para>
726</ListItem>
727
728</ItemizedList>
729
730</Para>
731
732</Sect2>
733
734<Sect2>
735<Title>i&lowbar;size</Title>
736
737<Para>
738<Literal remap="tt">i&lowbar;size</Literal> contains information about the size of the object presented by
739the inode. If the inode corresponds to a regular file, this is just the size
740of the file in bytes. In other cases, the interpretation of the variable is
741different.
742</Para>
743
744</Sect2>
745
746<Sect2>
747<Title>User and group id</Title>
748
749<Para>
750The user and group id of the file are just saved in the variables
751<Literal remap="tt">i&lowbar;uid</Literal> and <Literal remap="tt">i&lowbar;gid</Literal>.
752</Para>
753
754</Sect2>
755
756<Sect2>
757<Title>Hard links</Title>
758
759<Para>
760Later, when we'll discuss the implementation of directories, it will be
761explained that each <Literal remap="tt">directory entry</Literal> points to an inode. It is quite
762possible that a <Literal remap="tt">single inode</Literal> will be pointed to from <Literal remap="tt">several</Literal>
763directories. In that case, we say that there exist <Literal remap="tt">hard links</Literal> to the
764file - The file can be accessed from each of the directories.
765</Para>
766
767<Para>
768The kernel keeps track of the number of hard links in the variable
769<Literal remap="tt">i&lowbar;links&lowbar;count</Literal>. The variable is set to "1" when first allocating the
770inode, and is incremented with each additional link. Deletion of a file will
771delete the current directory entry and will decrement the number of links.
772Only when this number reaches zero, the inode will be actually deallocated.
773</Para>
774
775<Para>
776The name <Literal remap="tt">hard link</Literal> is used to distinguish between the alias method
777described above, to another alias method called <Literal remap="tt">symbolic linking</Literal>,
778which will be described later.
779</Para>
780
781</Sect2>
782
783<Sect2>
784<Title>The Ext2fs extended flags</Title>
785
786<Para>
787The ext2 filesystem associates additional flags with an inode. The extended
788attributes are stored in the variable <Literal remap="tt">i&lowbar;flags</Literal>. <Literal remap="tt">i&lowbar;flags</Literal> is a 32
789bit variable. Only the 7 rightmost bits are defined. Of them, only 5 bits
790are used in version 0.5a of the filesystem. Specifically, the
791<Literal remap="tt">undelete</Literal> and the <Literal remap="tt">compress</Literal> features are not implemented, and
792are to be introduced in Linux 1.3 development.
793</Para>
794
795<Para>
796The currently available flags are:
797
798<ItemizedList>
799<ListItem>
800
801<Para>
802	bit 0 - Secure deletion.
803
804When this bit is on, the file's blocks are zeroed when the file is
805deleted. With this bit off, they will just be left with their
806original data when the inode is deallocated.
807</Para>
808</ListItem>
809<ListItem>
810
811<Para>
812	bit 1 - Undelete.
813
814This bit is not supported yet. It will be used to provide an
815<Literal remap="tt">undelete</Literal> feature in future Ext2fs developments.
816</Para>
817</ListItem>
818<ListItem>
819
820<Para>
821	bit 2 - Compress file.
822
823This bit is also not supported. The plan is to offer "compression on
824the fly" in future releases.
825</Para>
826</ListItem>
827<ListItem>
828
829<Para>
830	bit 3 - Synchronous updates.
831
832With this bit on, the meta-data will be written synchronously to the
833disk, as if the filesystem was mounted with the "sync" mount option.
834</Para>
835</ListItem>
836<ListItem>
837
838<Para>
839	bit 4 - Immutable file.
840
841When this bit is on, the file will stay as it is - Can not be
842changed, deleted, renamed, no hard links, etc, before the bit is
843cleared.
844</Para>
845</ListItem>
846<ListItem>
847
848<Para>
849	bit 5 - Append only file.
850
851With this option active, data will only be appended to the file.
852</Para>
853</ListItem>
854<ListItem>
855
856<Para>
857	bit 6 - Do not dump this file.
858
859I think that this bit is used by the port of dump to linux (ported by
860<Literal remap="tt">Remy Card</Literal>) to check if the file should not be dumped.
861</Para>
862</ListItem>
863
864</ItemizedList>
865
866</Para>
867
868</Sect2>
869
870<Sect2>
871<Title>Symbolic links</Title>
872
873<Para>
874The <Literal remap="tt">hard links</Literal> presented above are just another pointers to the same
875inode. The important aspect is that the inode number is <Literal remap="tt">fixed</Literal> when
876the link is created. This means that the implementation details of the
877filesystem are visible to the user - In a pure abstract usage of the
878filesystem, the user should not care about inodes.
879</Para>
880
881<Para>
882The above causes several limitations:
883
884<ItemizedList>
885<ListItem>
886
887<Para>
888	Hard links can be done only in the same filesystem. This is obvious,
889since a hard link is just an inode number in some directory entry,
890and the above elements are filesystem specific.
891</Para>
892</ListItem>
893<ListItem>
894
895<Para>
896	You can not "replace" the file which is pointed to by the hard link
897after the link creation. "Replacing" the file in one directory will
898still leave the original file in the other directory - The
899"replacement" will not deallocate the original inode, but rather
900allocate another inode for the new version, and the directory entry
901at the other place will just point to the old inode number.
902</Para>
903</ListItem>
904
905</ItemizedList>
906
907</Para>
908
909<Para>
910<Literal remap="tt">Symbolic link</Literal>, on the other hand, is analyzed at <Literal remap="tt">run time</Literal>. A
911symbolic link is just a <Literal remap="tt">pathname</Literal> which is accessible from an inode.
912As such, it "speaks" in the language of the abstract filesystem. When the
913kernel reaches a symbolic link, it will <Literal remap="tt">follow it in run time</Literal> using
914its normal way of reaching directories.
915</Para>
916
917<Para>
918As such, symbolic link can be made <Literal remap="tt">across different filesystems</Literal> and a
919replacement of a file with a new version will automatically be active on all
920its symbolic links.
921</Para>
922
923<Para>
924The disadvantage is that hard link doesn't consume space except to a small
925directory entry. Symbolic link, on the other hand, consumes at least an
926inode, and can also consume one block.
927</Para>
928
929<Para>
930When the inode is identified as a symbolic link, the kernel needs to find
931the path to which it points.
932</Para>
933
934<Sect3>
935<Title>Fast symbolic links</Title>
936
937<Para>
938When the pathname contains up to 64 bytes, it can be saved directly in the
939inode, on the <Literal remap="tt">i&lowbar;block[0] - i&lowbar;block[15]</Literal> variables, since those are not
940needed in that case. This is called <Literal remap="tt">fast</Literal> symbolic link. It is fast
941because the pathname resolution can be done using the inode itself, without
942accessing additional blocks. It is also economical, since it allocates only
943an inode. The length of the pathname is stored in the <Literal remap="tt">i&lowbar;size</Literal>
944variable.
945</Para>
946
947</Sect3>
948
949<Sect3>
950<Title>Slow symbolic links</Title>
951
952<Para>
953Starting from 65 bytes, additional block is allocated (by the use of
954<Literal remap="tt">i&lowbar;block[0]</Literal>) and the pathname is stored in it. It is called slow
955because the kernel needs to read additional block to resolve the pathname.
956The length is again saved in <Literal remap="tt">i&lowbar;size</Literal>.
957</Para>
958
959</Sect3>
960
961</Sect2>
962
963<Sect2>
964<Title>i&lowbar;version</Title>
965
966<Para>
967<Literal remap="tt">i&lowbar;version</Literal> is used with regard to Network File System. I don't know
968its exact use.
969</Para>
970
971</Sect2>
972
973<Sect2>
974<Title>Reserved variables</Title>
975
976<Para>
977As far as I know, the variables which are connected to ACL and fragments
978are not currently used. They will be supported in future versions.
979</Para>
980
981<Para>
982Ext2fs is being ported to other operating systems. As far as I know,
983at least in linux, the os dependent variables are also not used.
984</Para>
985
986</Sect2>
987
988<Sect2>
989<Title>Special reserved inodes</Title>
990
991<Para>
992The first ten inodes on the filesystem are special inodes:
993
994<ItemizedList>
995<ListItem>
996
997<Para>
998	Inode 1 is the <Literal remap="tt">bad blocks inode</Literal> - I believe that its data
999blocks contain a list of the bad blocks in the filesystem, which
1000should not be allocated.
1001</Para>
1002</ListItem>
1003<ListItem>
1004
1005<Para>
1006	Inode 2 is the <Literal remap="tt">root inode</Literal> - The inode of the root directory.
1007It is the starting point for reaching a known path in the filesystem.
1008</Para>
1009</ListItem>
1010<ListItem>
1011
1012<Para>
1013	Inode 3 is the <Literal remap="tt">acl index inode</Literal>. Access control lists are
1014currently not supported by the ext2 filesystem, so I believe this
1015inode is not used.
1016</Para>
1017</ListItem>
1018<ListItem>
1019
1020<Para>
1021	Inode 4 is the <Literal remap="tt">acl data inode</Literal>. Of course, the above applies
1022here too.
1023</Para>
1024</ListItem>
1025<ListItem>
1026
1027<Para>
1028	Inode 5 is the <Literal remap="tt">boot loader inode</Literal>. I don't know its
1029usage.
1030</Para>
1031</ListItem>
1032<ListItem>
1033
1034<Para>
1035	Inode 6 is the <Literal remap="tt">undelete directory inode</Literal>. It is also a
1036foundation for future enhancements, and is currently not used.
1037</Para>
1038</ListItem>
1039<ListItem>
1040
1041<Para>
1042	Inodes 7-10 are <Literal remap="tt">reserved</Literal> and currently not used.
1043</Para>
1044</ListItem>
1045
1046</ItemizedList>
1047
1048</Para>
1049
1050</Sect2>
1051
1052</Sect1>
1053
1054<Sect1>
1055<Title>Directories</Title>
1056
1057<Para>
1058A directory is implemented in the same way as files are implemented (with
1059the direct blocks, indirect blocks, etc) - It is just a file which is
1060formatted with a special format - A list of directory entries.
1061</Para>
1062
1063<Para>
1064Follows the definition of a directory entry:
1065</Para>
1066
1067<Para>
1068
1069<ProgramListing>
1070struct ext2_dir_entry {
1071	__u32	inode;			/* Inode number */
1072	__u16	rec_len;		/* Directory entry length */
1073	__u16	name_len;		/* Name length */
1074	char	name[EXT2_NAME_LEN];	/* File name */
1075};
1076</ProgramListing>
1077
1078</Para>
1079
1080<Para>
1081Ext2fs supports file names of varying lengths, up to 255 bytes. The
1082<Literal remap="tt">name</Literal> field above just contains the file name. Note that it is
1083<Literal remap="tt">not zero terminated</Literal>; Instead, the variable <Literal remap="tt">name&lowbar;len</Literal> contains
1084the length of the file name.
1085</Para>
1086
1087<Para>
1088The variable <Literal remap="tt">rec&lowbar;len</Literal> is provided because the directory entries are
1089padded with zeroes so that the next entry will be in an offset which is
1090a multiplication of 4. The resulting directory entry size is stored in
1091<Literal remap="tt">rec&lowbar;len</Literal>. If the directory entry is the last in the block, it is
1092padded with zeroes till the end of the block, and rec&lowbar;len is updated
1093accordingly.
1094</Para>
1095
1096<Para>
1097The <Literal remap="tt">inode</Literal> variable points to the inode of the above file.
1098</Para>
1099
1100<Para>
1101Deletion of directory entries is done by appending of the deleted entry
1102space to the previous (or next, I am not sure) entry.
1103</Para>
1104
1105</Sect1>
1106
1107<Sect1>
1108<Title>The superblock</Title>
1109
1110<Para>
1111The <Literal remap="tt">superblock</Literal> is a block which contains information which describes
1112the state of the internal filesystem.
1113</Para>
1114
1115<Para>
1116The superblock is located at the <Literal remap="tt">fixed offset 1024</Literal> in the device. Its
1117length is 1024 bytes also.
1118</Para>
1119
1120<Para>
1121The superblock, like the group descriptors, is copied on each blocks group
1122boundary for backup purposes. However, only the main copy is used by the
1123kernel.
1124</Para>
1125
1126<Para>
1127The superblock contain three types of information:
1128
1129<ItemizedList>
1130<ListItem>
1131
1132<Para>
1133	Filesystem parameters which are fixed and which were determined when
1134this specific filesystem was created. Some of those parameters can
1135be different in different installations of the ext2 filesystem, but
1136can not be changed once the filesystem was created.
1137</Para>
1138</ListItem>
1139<ListItem>
1140
1141<Para>
1142	Filesystem parameters which are tunable - Can always be changed.
1143</Para>
1144</ListItem>
1145<ListItem>
1146
1147<Para>
1148	Information about the current filesystem state.
1149</Para>
1150</ListItem>
1151
1152</ItemizedList>
1153
1154</Para>
1155
1156<Para>
1157Follows the superblock definition:
1158</Para>
1159
1160<Para>
1161
1162<ProgramListing>
1163struct ext2_super_block {
1164	__u32	s_inodes_count;		/* Inodes count */
1165	__u32	s_blocks_count;		/* Blocks count */
1166	__u32	s_r_blocks_count;	/* Reserved blocks count */
1167	__u32	s_free_blocks_count;	/* Free blocks count */
1168	__u32	s_free_inodes_count;	/* Free inodes count */
1169	__u32	s_first_data_block;	/* First Data Block */
1170	__u32	s_log_block_size;	/* Block size */
1171	__s32	s_log_frag_size;	/* Fragment size */
1172	__u32	s_blocks_per_group;	/* # Blocks per group */
1173	__u32	s_frags_per_group;	/* # Fragments per group */
1174	__u32	s_inodes_per_group;	/* # Inodes per group */
1175	__u32	s_mtime;		/* Mount time */
1176	__u32	s_wtime;		/* Write time */
1177	__u16	s_mnt_count;		/* Mount count */
1178	__s16	s_max_mnt_count;	/* Maximal mount count */
1179	__u16	s_magic;		/* Magic signature */
1180	__u16	s_state;		/* File system state */
1181	__u16	s_errors;		/* Behaviour when detecting errors */
1182	__u16	s_pad;
1183	__u32	s_lastcheck;		/* time of last check */
1184	__u32	s_checkinterval;	/* max. time between checks */
1185	__u32	s_creator_os;		/* OS */
1186	__u32	s_rev_level;		/* Revision level */
1187	__u16	s_def_resuid;		/* Default uid for reserved blocks */
1188	__u16	s_def_resgid;		/* Default gid for reserved blocks */
1189	__u32	s_reserved[235];	/* Padding to the end of the block */
1190};
1191</ProgramListing>
1192
1193</Para>
1194
1195<Sect2>
1196<Title>superblock identification</Title>
1197
1198<Para>
1199The ext2 filesystem's superblock is identified by the <Literal remap="tt">s&lowbar;magic</Literal> field.
1200The current ext2 magic number is 0xEF53. I presume that "EF" means "Extended
1201Filesystem". In versions of the ext2 filesystem prior to 0.2B, the magic
1202number was 0xEF51. Those filesystems are not compatible with the current
1203versions; Specifically, the group descriptors definition is different. I
1204doubt if there still exists such a installation.
1205</Para>
1206
1207</Sect2>
1208
1209<Sect2>
1210<Title>Filesystem fixed parameters</Title>
1211
1212<Para>
1213By using the word <Literal remap="tt">fixed</Literal>, I mean fixed with respect to a particular
1214installation. Those variables are usually not fixed with respect to
1215different installations.
1216</Para>
1217
1218<Para>
1219The <Literal remap="tt">block size</Literal> is determined by using the <Literal remap="tt">s&lowbar;log&lowbar;block&lowbar;size</Literal>
1220variable. The block size is 1024*pow (2,s&lowbar;log&lowbar;block&lowbar;size) and should be
1221between 1024 and 4096. The available options are 1024, 2048 and 4096.
1222</Para>
1223
1224<Para>
1225<Literal remap="tt">s&lowbar;inodes&lowbar;count</Literal> contains the total number of available inodes.
1226</Para>
1227
1228<Para>
1229<Literal remap="tt">s&lowbar;blocks&lowbar;count</Literal> contains the total number of available blocks.
1230</Para>
1231
1232<Para>
1233<Literal remap="tt">s&lowbar;first&lowbar;data&lowbar;block</Literal> specifies in which of the <Literal remap="tt">device block</Literal> the
1234<Literal remap="tt">superblock</Literal> is present. The superblock is always present at the fixed
1235offset 1024, but the device block numbering can differ. For example, if the
1236block size is 1024, the superblock will be at <Literal remap="tt">block 1</Literal> with respect to
1237the device. However, if the block size is 4096, offset 1024 is included in
1238<Literal remap="tt">block 0</Literal> of the device, and in that case <Literal remap="tt">s&lowbar;first&lowbar;data&lowbar;block</Literal>
1239will contain 0. At least this is how I understood this variable.
1240</Para>
1241
1242<Para>
1243<Literal remap="tt">s&lowbar;blocks&lowbar;per&lowbar;group</Literal> contains the number of blocks which are grouped
1244together as a blocks group.
1245</Para>
1246
1247<Para>
1248<Literal remap="tt">s&lowbar;inodes&lowbar;per&lowbar;group</Literal> contains the number of inodes available in a group
1249block. I think that this is always the total number of inodes divided by the
1250number of blocks groups.
1251</Para>
1252
1253<Para>
1254<Literal remap="tt">s&lowbar;creator&lowbar;os</Literal> contains a code number which specifies the operating
1255system which created this specific filesystem:
1256
1257<ItemizedList>
1258<ListItem>
1259
1260<Para>
1261	<Literal remap="tt">Linux</Literal> :-) is specified by the value <Literal remap="tt">0</Literal>.
1262</Para>
1263</ListItem>
1264<ListItem>
1265
1266<Para>
1267	<Literal remap="tt">Hurd</Literal> is specified by the value <Literal remap="tt">1</Literal>.
1268</Para>
1269</ListItem>
1270<ListItem>
1271
1272<Para>
1273	<Literal remap="tt">Masix</Literal> is specified by the value <Literal remap="tt">2</Literal>.
1274</Para>
1275</ListItem>
1276
1277</ItemizedList>
1278
1279</Para>
1280
1281<Para>
1282<Literal remap="tt">s&lowbar;rev&lowbar;level</Literal> contains the major version of the ext2 filesystem.
1283Currently this is always <Literal remap="tt">0</Literal>, as the most recent version is 0.5B. It
1284will probably take some time until we reach version 1.0.
1285</Para>
1286
1287<Para>
1288As far as I know, fragments (sub-block allocations) are currently not
1289supported and hence a block is equal to a fragment. As a result,
1290<Literal remap="tt">s&lowbar;log&lowbar;frag&lowbar;size</Literal> and <Literal remap="tt">s&lowbar;frags&lowbar;per&lowbar;group</Literal> are always equal to
1291<Literal remap="tt">s&lowbar;log&lowbar;block&lowbar;size</Literal> and <Literal remap="tt">s&lowbar;blocks&lowbar;per&lowbar;group</Literal>, respectively.
1292</Para>
1293
1294</Sect2>
1295
1296<Sect2>
1297<Title>Ext2fs error handling</Title>
1298
1299<Para>
1300The ext2 filesystem error handling is based on the following philosophy:
1301
1302<OrderedList>
1303<ListItem>
1304
1305<Para>
1306	Identification of problems is done by the kernel code.
1307</Para>
1308</ListItem>
1309<ListItem>
1310
1311<Para>
1312	The correction task is left to an external utility, such as
1313<Literal remap="tt">e2fsck by Theodore Ts'o</Literal> for <Literal remap="tt">automatic</Literal> analysis and
1314correction, or perhaps <Literal remap="tt">debugfs by Theodore Ts'o</Literal> and
1315<Literal remap="tt">EXT2ED by myself</Literal>, for <Literal remap="tt">hand</Literal> analysis and correction.
1316</Para>
1317</ListItem>
1318
1319</OrderedList>
1320
1321</Para>
1322
1323<Para>
1324The <Literal remap="tt">s&lowbar;state</Literal> variable is used by the kernel to pass the identification
1325result to third party utilities:
1326
1327<ItemizedList>
1328<ListItem>
1329
1330<Para>
1331	<Literal remap="tt">bit 0</Literal> of s&lowbar;state is reset when the partition is mounted and
1332set when the partition is unmounted. Thus, a value of 0 on an
1333unmounted filesystem means that the filesystem was not unmounted
1334properly - The filesystem is not "clean" and probably contains
1335errors.
1336</Para>
1337</ListItem>
1338<ListItem>
1339
1340<Para>
1341	<Literal remap="tt">bit 1</Literal> of s&lowbar;state is set by the kernel when it detects an
1342error in the filesystem. A value of 0 doesn't mean that there isn't
1343an error in the filesystem, just that the kernel didn't find any.
1344</Para>
1345</ListItem>
1346
1347</ItemizedList>
1348
1349</Para>
1350
1351<Para>
1352The kernel behavior when an error is found is determined by the user tunable
1353parameter <Literal remap="tt">s&lowbar;errors</Literal>:
1354
1355<ItemizedList>
1356<ListItem>
1357
1358<Para>
1359	The kernel will ignore the error and continue if <Literal remap="tt">s&lowbar;errors=1</Literal>.
1360</Para>
1361</ListItem>
1362<ListItem>
1363
1364<Para>
1365	The kernel will remount the filesystem in read-only mode if
1366<Literal remap="tt">s&lowbar;errors=2</Literal>.
1367</Para>
1368</ListItem>
1369<ListItem>
1370
1371<Para>
1372	A kernel panic will be issued if <Literal remap="tt">s&lowbar;errors=3</Literal>.
1373</Para>
1374</ListItem>
1375
1376</ItemizedList>
1377
1378</Para>
1379
1380<Para>
1381The default behavior is to ignore the error.
1382</Para>
1383
1384</Sect2>
1385
1386<Sect2>
1387<Title>Additional parameters used by e2fsck</Title>
1388
1389<Para>
1390Of-course, <Literal remap="tt">e2fsck</Literal> will check the filesystem if errors were detected
1391or if the filesystem is not clean.
1392</Para>
1393
1394<Para>
1395In addition, each time the filesystem is mounted, <Literal remap="tt">s&lowbar;mnt&lowbar;count</Literal> is
1396incremented. When s&lowbar;mnt&lowbar;count reaches <Literal remap="tt">s&lowbar;max&lowbar;mnt&lowbar;count</Literal>, <Literal remap="tt">e2fsck</Literal>
1397will force a check on the filesystem even though it may be clean. It will
1398then zero s&lowbar;mnt&lowbar;count. <Literal remap="tt">s&lowbar;max&lowbar;mnt&lowbar;count</Literal> is a tunable parameter.
1399</Para>
1400
1401<Para>
1402E2fsck also records the last time in which the file system was checked in
1403the <Literal remap="tt">s&lowbar;lastcheck</Literal> variable. The user tunable parameter
1404<Literal remap="tt">s&lowbar;checkinterval</Literal> will contain the number of seconds which are allowed
1405to pass since <Literal remap="tt">s&lowbar;lastcheck</Literal> until a check is forced. A value of
1406<Literal remap="tt">0</Literal> disables time-based check.
1407</Para>
1408
1409</Sect2>
1410
1411<Sect2>
1412<Title>Additional user tunable parameters</Title>
1413
1414<Para>
1415<Literal remap="tt">s&lowbar;r&lowbar;blocks&lowbar;count</Literal> contains the number of disk blocks which are
1416reserved for root, the user whose id number is <Literal remap="tt">s&lowbar;def&lowbar;resuid</Literal> and the
1417group whose id number is <Literal remap="tt">s&lowbar;deg&lowbar;resgid</Literal>. The kernel will refuse to
1418allocate those last <Literal remap="tt">s&lowbar;r&lowbar;blocks&lowbar;count</Literal> if the user is not one of the
1419above. This is done so that the filesystem will usually not be 100&percnt; full,
1420since 100&percnt; full filesystems can affect various aspects of operation.
1421</Para>
1422
1423<Para>
1424<Literal remap="tt">s&lowbar;def&lowbar;resuid</Literal> and <Literal remap="tt">s&lowbar;def&lowbar;resgid</Literal> contain the id of the user and
1425of the group who can use the reserved blocks in addition to root.
1426</Para>
1427
1428</Sect2>
1429
1430<Sect2>
1431<Title>Filesystem current state</Title>
1432
1433<Para>
1434<Literal remap="tt">s&lowbar;free&lowbar;blocks&lowbar;count</Literal> contains the current number of free blocks
1435in the filesystem.
1436</Para>
1437
1438<Para>
1439<Literal remap="tt">s&lowbar;free&lowbar;inodes&lowbar;count</Literal> contains the current number of free inodes in the
1440filesystem.
1441</Para>
1442
1443<Para>
1444<Literal remap="tt">s&lowbar;mtime</Literal> contains the time at which the system was last mounted.
1445</Para>
1446
1447<Para>
1448<Literal remap="tt">s&lowbar;wtime</Literal> contains the last time at which something was changed in the
1449filesystem.
1450</Para>
1451
1452</Sect2>
1453
1454</Sect1>
1455
1456<Sect1>
1457<Title>Copyright</Title>
1458
1459<Para>
1460This document contains source code which was taken from the Linux ext2
1461kernel source code, mainly from <FILENAME>/usr/include/linux/ext2&lowbar;fs.h</FILENAME>. Follows
1462the original copyright:
1463</Para>
1464
1465<Para>
1466
1467<ProgramListing>
1468/*
1469 *  linux/include/linux/ext2_fs.h
1470 *
1471 * Copyright (C) 1992, 1993, 1994, 1995
1472 * Remy Card (card@masi.ibp.fr)
1473 * Laboratoire MASI - Institut Blaise Pascal
1474 * Universite Pierre et Marie Curie (Paris VI)
1475 *
1476 *  from
1477 *
1478 *  linux/include/linux/minix_fs.h
1479 *
1480 *  Copyright (C) 1991, 1992  Linus Torvalds
1481 */
1482
1483</ProgramListing>
1484
1485</Para>
1486
1487</Sect1>
1488
1489<Sect1>
1490<Title>Acknowledgments</Title>
1491
1492<Para>
1493I would like to thank the following people, who were involved in the
1494design and implementation of the ext2 filesystem kernel code and support
1495utilities:
1496
1497<ItemizedList>
1498<ListItem>
1499
1500<Para>
1501	<Literal remap="tt">Remy Card</Literal>
1502
1503Who designed, implemented and maintains the ext2 filesystem kernel
1504code, and some of the ext2 utilities. <Literal remap="tt">Remy Card</Literal> is also the
1505author 	of several helpful slides concerning the ext2 filesystem.
1506Specifically, he is the author of <Literal remap="tt">File Management in the Linux
1507Kernel</Literal> and of <Literal remap="tt">The Second Extended File System - Current
1508State, Future Development</Literal>.
1509
1510</Para>
1511</ListItem>
1512<ListItem>
1513
1514<Para>
1515	<Literal remap="tt">Wayne Davison</Literal>
1516
1517Who designed the ext2 filesystem.
1518</Para>
1519</ListItem>
1520<ListItem>
1521
1522<Para>
1523	<Literal remap="tt">Stephen Tweedie</Literal>
1524
1525Who helped designing the ext2 filesystem kernel code and wrote the
1526slides <Literal remap="tt">Optimizations in File Systems</Literal>.
1527</Para>
1528</ListItem>
1529<ListItem>
1530
1531<Para>
1532	<Literal remap="tt">Theodore Ts'o</Literal>
1533
1534Who is the author of several ext2 utilities and of the ext2 library
1535<Literal remap="tt">libext2fs</Literal> (which I didn't use, simply because I didn't know
1536it exists when I started to work on my project).
1537</Para>
1538</ListItem>
1539
1540</ItemizedList>
1541
1542</Para>
1543
1544<Para>
1545Lastly, I would like to thank, of-course, <Literal remap="tt">Linus Torvalds</Literal> and the
1546<Literal remap="tt">Linux community</Literal> for providing all of us with such a great operating
1547system.
1548</Para>
1549
1550<Para>
1551Please contact me in a case of an error report, suggestions, or just about
1552anything concerning this document.
1553</Para>
1554
1555<Para>
1556Enjoy,
1557</Para>
1558
1559<Para>
1560Gadi Oxman &lt;tgud@tochnapc2.technion.ac.il&gt;
1561</Para>
1562
1563<Para>
1564Haifa, August 95
1565</Para>
1566
1567</Sect1>
1568
1569</Article>
1570