<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>9tutorials - The best collection of tutorials &#187; Linux</title>
	<atom:link href="http://9tutorials.com/category/linux/feed" rel="self" type="application/rss+xml" />
	<link>http://9tutorials.com</link>
	<description>Photoshop tutorials , Flash tutorials, PHP tutorials and much more</description>
	<lastBuildDate>Sat, 20 Feb 2010 20:24:02 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Tuning Ubuntu on a Macintosh</title>
		<link>http://9tutorials.com/2007/11/01/tuning-ubuntu-on-a-macintosh.html</link>
		<comments>http://9tutorials.com/2007/11/01/tuning-ubuntu-on-a-macintosh.html#comments</comments>
		<pubDate>Thu, 01 Nov 2007 10:06:39 +0000</pubDate>
		<dc:creator>dangtruong</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://9tutorials.com/2007/11/01/tuning-ubuntu-on-a-macintosh.html</guid>
		<description><![CDATA[Tuning Ubuntu on a 
Macintosh Many versions 
of Linux have been ported 
to the Macintosh, but were 
not initially developed for 
the Mac. Ubuntu falls into 
this category. There are 
some PC features that do 
not exist on the Mac, and 
some Mac features that 
lack support under Ubuntu. 
Using a One-Button Mouse 
in a Three-Button World 
The biggest issue with 
using Ubuntu on a Mac is 
the lack of a three-button 
mouse. Under Ubuntu, the 
left mouse button performs 
actions, such as selecting 
icons and moving windows. 
The right button brings up 
menus, and the middle 
button is used for pasting 
from the clipboard. Tip 
There are many different
]]></description>
			<content:encoded><![CDATA[<div class="spost"><p>Many versions of Linux have been ported to the Macintosh, but were not initially developed for the Mac. Ubuntu falls into this category. There are some PC features that do not exist on the Mac, and some Mac features that lack support under Ubuntu.</p>
<p><span id="more-3466"></span></p>
<p><strong>Using a One-Button Mouse in a Three-Button World</strong></p>
<p>The biggest issue with using Ubuntu on a Mac is the lack of a three-button mouse. Under Ubuntu, the left mouse button performs actions, such as selecting icons and moving windows. The right button brings up menus, and the middle button is used for pasting from the clipboard.</p>
<p><strong><u>Tip:</u></strong> There are many different types of PC mice. Some only have two-buttons. The middle button can be emulated by clicking both the right and left buttons at the same time. Others have a scroll wheel that can be pushed in for use as the third button.</p>
<p>Most Macs include a one-button mouse. If you swap the one-button mouse for a three-button model, it will work fine with Ubuntu, but if you do not want to swap hardware then how do you use the other buttons?</p>
<p>By default, Ubuntu on the Mac (PowerPC platform) maps the F11 and F12 keys to the middle and right mouse buttons. This is configured in the <font face="Courier New" size="2">/etc/sysctl.conf</font> file. On the PowerPC installation, this file contains the following additional lines:</p>
<p><font face="Courier New" size="2"># Emulate the middle mouse button with F11 and the right with F12.</font></p>
<p><font face="Courier New" size="2">dev/mac_hid/mouse_button_emulation = 1</font></p>
<p><font face="Courier New" size="2">dev/mac_hid/mouse_button2_keycode = 87</font></p>
<p><font face="Courier New" size="2">dev/mac_hid/mouse_button3_keycode = 88</font></p>
<p>On a Mac, keycode 87 is F11 and keycode 88 is F12. One easy way to see the keycodes is to use the X Event Tester (<font face="Courier New" size="2">xev</font> ). This tool opens a window and displays all X-Windows events. If you type in the window, it displays the keycodes.</p>
<p><img src="http://9tutorials.com/wp-content/uploads/2007/11/ubuntu-mac-01.jpg" alt="ubuntu_mac_01" align="top" border="0" height="190" hspace="8" width="350" /><br />
<em> The xev application, showing keycodes</em></p>
<p><strong>Missing Keys and Functionality</strong></p>
<p>PC keyboards usually do not look like Mac keyboards. The standard 104-key PC keyboard contains many extra keys that are not found on a Mac. Some of the missing keys include:</p>
<ul type="square">
<li><strong>Two Alt keys</strong> -Every Mac keyboard has a left Alt key (Alt_L), but the right Alt key (Alt_R) is not always present.</li>
<li><strong>Two Ctrl keys</strong> -While Control_L always exists, Control_R may be missing on some Mac keyboards.</li>
<li><strong>System keys</strong> -The Print Screen, System Request, Scroll Lock, Pause, and Break keys are missing. With Ubuntu on a PC, the Print Screen button is mapped to the screen capture application. Without this button, you will need to remap the functionality to another key combination.</li>
<li><strong>Edit keys</strong> -Most PC keyboards have a set of keys for Insert, Delete, Home, End, Page Up, and Page Down. Although Mac keyboards do have Page Up and Page Down, they are not in the same location as a PC keyboard. Different Mac keyboards can have very different keys. For example, the Mac iBook G4 has Home/End while the older iMac G3 keyboard has Home and Help (where Help generates the same keycode as Insert).</li>
<li><strong>Windows keys</strong> -The Windows keys do not exist on the Mac keyboard (for obvious reasons). Similarly, the Menu key does not exist.</li>
<li><strong>Numeric keyboard</strong> -Although they are usually not labeled on the Mac, the numeric keyboard does have the same arrows (KP_Up, KP_Down, KP_Left, and KP_Right) and navigation keys as a standard PC keyboard.</li>
</ul>
<p><strong>Keys Please</strong></p>
<p>Under X-Windows, there are two types of keyboard values: keycodes and keysyms. Keycodes are the actual numeric representation sent by the keyboard when a key or button is pressed. Keysyms are the values assigned to the keycodes. For example, when you press the A key on the keyboard, it generates keycode 73. Keycode 73 is mapped to the keyboard symbol 0&#215;61 (the letter a). The command <font face="Courier New" size="2">xmodmap -pk</font>  prints the key table, showing the keycode to keysym mapping. For example, hereâ€™s a section of output from the key table:</p>
<p><font face="Courier New" size="2">    55 0xff6a (Help) 0xff6a (Help)</font></p>
<p><font face="Courier New" size="2">    56 0&#215;0030 (0) 0&#215;0029 (parenright)</font></p>
<p><font face="Courier New" size="2">    57 0&#215;0031 (1) 0&#215;0021 (exclam)</font></p>
<p><font face="Courier New" size="2">    58 0&#215;0032 (2) 0&#215;0040 (at)</font></p>
<p><font face="Courier New" size="2">    59 0&#215;0033 (3) 0&#215;0023 (numbersign)</font></p>
<p>This key table shows that keycode 56 is mapped to the number zero, and when shifted, maps to a right parenthesis.</p>
<p>It is important to realize that not every keyboard can generate every keycode, and not every keycode is mapped to a keysym. Other input devices also generate key- codes. For example, the mouse buttons are keycodes 1, 2, and 3 (for left, middle, and right). Using <font face="Courier New" size="2">xmodmap</font> , you can change the key table, swapping keyboard keys or mouse buttons. For example, the command <font face="Courier New" size="2">xmodmap -e &#8220;pointer = 3 2 1&#8243;</font>  flips the mouse buttons for a left-handed mouse.</p>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td style="padding: 0in" valign="top">Warning</td>
<td style="padding: 0in" valign="top">Many Mac keyboards do not have an indicator light to show when NumLock is enabled, so switching between keypad navigation and numeric entry can be confusing.</td>
</tr>
</table>
<p>There are also some keys that exist on the Mac but not on the PC. By default, these are not mapped to anything but can be mapped to other keys.</p>
<ul type="square">
<li><strong>Command keys</strong> -On a Macintosh keyboard, there is at least one and possibly two Command keys. These are located on either side of the spacebar and are labeled with a flower pattern. Mac users call this the Apple or Command key. Under Linux, it is called the Super key. The left one (Super_L) is mapped to keycode 115 and the right key (Super_R) is keycode 116.</li>
<li><strong>Keypad Equal (=)</strong> -On a standard PC keyboard, there is no equal sign on the numeric keypad, but there is one on the Mac. This key is mapped to keycode 157 but is not mapped to any keyboard value.</li>
</ul>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td style="padding: 0in" valign="top">Note</td>
<td style="padding: 0in" valign="top">Specialized keyboards may have additional keys, such as volume up/down, power, and even buttons labeled for e-mail or the Web. Each generates a distinct keycode. Use <font face="Courier New" size="2">xev</font> to see the codes. This way, you can map the keys to functions.</td>
</tr>
</table>
<p><strong>Changing Keyboard Layouts</strong></p>
<p>By default, Ubuntu configures itself for a generic 104 key PC keyboard. This is not the same layout as a Macintosh. You can change the configuration to match your keyboard by choosing System -&gt; Preferences -&gt; Keyboard. This brings up the keyboard configuration applet. From here, you can change the keyboard model to match your Mac keyboard . Changing the keyboard layout changes the keycode to keysym map.</p>
<p><img src="http://9tutorials.com/wp-content/uploads/2007/11/ubuntu-mac-02.jpg" alt="ubuntu_mac_02" align="top" border="0" height="181" hspace="8" width="350" /><br />
<em> The Keyboard Preferences applet for changing keyboard models.</em></p>
<p><strong>Remapping the Command and Alt Keys</strong></p>
<p>One of the biggest distinctions for Mac users is the use of the Command key. Under Mac OS, this key modifier is used for most shortcuts. For example, Command+W closes the window and Command+Q quits an application. Under Ubuntu and on most PC operating systems, the Ctrl key has the same usage (for example, Ctrl+W instead of Command+W). Adding to the confusion, a PC keyboard has Alt next to the spacebar whereas a Mac has the Command keys in that location. What this means is that a Mac user running Ubuntu will need to relearn how to use the Alt key instead of the Command key, or you can just remap the keys.</p>
<p>To remap the Command keys to act as Alt keys, use the <font face="Courier New" size="2">xmodmap</font> program. This program maintains a list of keycode mappings (<font face="Courier New" size="2">xmodmap -pke</font> ) and special key modifiers such as Shift and Control (<font face="Courier New" size="2">xmodmap -pm</font> ). The easiest way to remap the Command keys is to simply change the modifiers. First, remove the control and command keys, then add the Ctrl keys again.</p>
<p><font face="Courier New" size="2">xmodmap -e &#8220;remove control = Control_L Control_R&#8221; # unmap control</font></p>
<p><font face="Courier New" size="2">xmodmap -e &#8220;remove mod4 = Super_L Super_R&#8221; # unmap old Super keys</font></p>
<p><font face="Courier New" size="2">xmodmap -e &#8220;add control = Super_L Super_R&#8221; # map Super to Ctrl</font></p>
<p>Alternately, you could actually re-map the Command and Ctrl keys.</p>
<p><font face="Courier New" size="2">xmodmap -e &#8220;remove control = Control_L Control_R&#8221; # unmap Ctrl</font></p>
<p><font face="Courier New" size="2">xmodmap -e &#8220;remove mod4 = Super_L Super_R&#8221; # unmap super</font></p>
<p><font face="Courier New" size="2">xmodmap -e &#8220;keycode 115 = Control_L Control_L&#8221; # map Command to Alt</font></p>
<p><font face="Courier New" size="2">xmodmap -e &#8220;keycode 116 = Control_R Control_R&#8221; # map Command to Alt</font></p>
<p><font face="Courier New" size="2">xmodmap -e &#8220;keycode 64 = Super_L Super_L&#8221; # map Alt to Command</font></p>
<p><font face="Courier New" size="2">xmodmap -e &#8220;keycode 113 = Super_R Super_R&#8221; # map Alt to Command</font></p>
<p><font face="Courier New" size="2">xmodmap -e &#8220;add control = Control_L Control_R&#8221; # map new Ctrl to Ctrl</font></p>
<p>Mapping the keyboard using <font face="Courier New" size="2">xmodmap</font> only creates a temporary change. If you reboot the computer or restart the X-server, the changes will be lost. To make the changes permanent, you can put the changes in <font face="Courier New" size="2">Ëœ/.Xmodmap</font> or <font face="Courier New" size="2">/usr/X11/xinit/Xmodmap</font> -depending on whether you want the changes to be per user or system wide:</p>
<p><font face="Courier New" size="2">remove control = Control_L Control_R</font></p>
<p><font face="Courier New" size="2">keycode 115 = Super_L Super_L</font></p>
<p><font face="Courier New" size="2">keycode 116 = Super_R Super_R</font></p>
<p><font face="Courier New" size="2">remove mod4 = Super_L</font></p>
<p><font face="Courier New" size="2">add control = Super_L Super_R</font></p>
<p><strong><u>Tip:</u></strong>  After creating .xmodmap, you can test it using the command xmodmap .xmodmap. Be sure to correct any errors, otherwise the configuration will not load.</p>
<p><strong><u>Note:</u></strong>  Under the default Dapper installation, Super_R is not defined, so you will need to map it to key- code 116 before using it. Also, Super_L is part of the mod4 modifiers. Use xmodmap -pm to display the modifier list.</p>
<p>Instead of adding the mappings to the <font face="Courier New" size="2">.xmodmap</font> file, you can add the <font face="Courier New" size="2">xmodmap</font> commands to <font face="Courier New" size="2">Ëœ/.xinitrc</font> or <font face="Courier New" size="2">/etc/X11/xinit/xinirrc</font> . You might want to do this anyway since Gnome will prompt you about using a new <font face="Courier New" size="2">.xmodmap</font> file each time you log in.</p>
<p><strong>Shasâ€™t Nos Funny!</strong></p>
<p>Thereâ€™s an old practical joke where people pry the keys off a keyboard and replace them out of order. A user who is not a touch typist can get really confused when they look for the right letters. The <font face="Courier New" size="2">xmodmap</font> command can be used for an excellent alternative to this prank. For example, you can add the following commands into the victimâ€™s <font face="Courier New" size="2">.bashrc</font> file:</p>
<p><font face="Courier New" size="2">    xmodmap -e â€™keycode 91 = t Tâ€™</font></p>
<p><font face="Courier New" size="2">    xmodmap -e â€™keycode 92 = s Sâ€™</font></p>
<p>This prank swaps the s and t keys on the keyboard without requiring any physical keyboard modifications. Alternately, if you can pry up and replace the keys on the keyboard, follow it up by remapping the keyboard so it actually works correctly! Your coworkers should get a big laugh out of it!</p>
]]></content:encoded>
			<wfw:commentRss>http://9tutorials.com/2007/11/01/tuning-ubuntu-on-a-macintosh.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Linux Virtual File System</title>
		<link>http://9tutorials.com/2007/05/21/the-linux-virtual-file-system.html</link>
		<comments>http://9tutorials.com/2007/05/21/the-linux-virtual-file-system.html#comments</comments>
		<pubDate>Mon, 21 May 2007 09:04:34 +0000</pubDate>
		<dc:creator>dangtruong</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[basic]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://9tutorials.com/2007/05/21/the-linux-virtual-file-system.html</guid>
		<description><![CDATA[â€œEverything is a file in Linuxâ€? is an oft repeated statement. What this basically implies is that all the devices (Hard disks,CD ROMs, Floppy Disks, USB Sticks,etc) are all treated as files.

Just to explain this a bit more ,let us consider the C function write(f,&#38;buf,len) . You must have used this function to write len [...]]]></description>
			<content:encoded><![CDATA[<div class="spost"><p>â€œEverything is a file in Linuxâ€? is an oft repeated statement. What this basically implies is that all the devices (Hard disks,CD ROMs, Floppy Disks, USB Sticks,etc) are all treated as files.<br />
<span id="more-338"></span><br />
Just to explain this a bit more ,let us consider the C function write(f,&amp;buf,len) . You must have used this function to write len bytes of data contained in buf to a file whose File Descriptor is given by f. Linux allows you to use the same function to write to a floppy (in the simplest of cases) as well. This is because everything capable of input and output is treated as a file in Linux. This is one of the two major abstractions in Linux, the other being a Process.</p>
<p>A filesystem is the methods and data structures that an operating system uses to keep track of files on a disk or partition; that is, the way the files are organized on the disk. The word is also used to refer to a partition or disk that is used to store the files or the type of the filesystem. Thus, one might say I have two filesystems meaning one has two partitions on which one stores files, or that one is using the extended filesystem, meaning the type of the filesystem.</p>
<h2>Linux Filesystems</h2>
<p>One of the most important features of Linux is its support for many different file systems. This makes it very flexible and well able to coexist with many other operating systems. ext2fs, ext3fs, ReiserFS, vfat, minix are among the major supported file systems. You can have have multiple filesystems on each partition of your hard disk and make them co-ordinate beautifully. For example you could install the Linux system in your ext3 partition and store all your data in a vfat partition.<br />
<!--adsense#inside--><br />
Now to support the multiple filesystems relevant support should be built into the Linux kernel to recognize them. This again implies that the we must be having different mechanisms to write to a hard disk file and to a floppy disk file as they are having different filesystems. However we just mentioned in the beginning that we can use the same function to achieve the objective. Does this mean that we are having different implementations of the function for each filesystem? Fortunately, No. This would otherwise make the kernel bigger and decrease the extensibility of the kernel to support newer file systems. There is only a single implementation of the function and hence the same function may be used to write data to files stored on different filesystems. This is possible by the use of The Vitual Filesystem.</p>
<h2>The Virtual Filesystem</h2>
<p>The Virtual Filesystem henceforth referred to as VFS, is the subsytem of the Linux kernel which implementats the filesystem related interfaces provided to user space programs. The interoperability of the filesystems is made possible by the VFS.</p>
<p><img src="http://9tutorials.com/wp-content/uploads/2007/05/file.gif" alt="File" align="bottom" border="0" height="261" hspace="0" width="350" /></p>
<p><em>Figure 1 </em><br />
As is apparent from the figure (Figure 1) , the requests from the user space application layer programs are received by the VFS which then interacts with the low level filesystems such as ext2,ext3,etc. Thus the VFS provides a layer of abstraction around the low-level filesystem interface. This is possible because the VFS provides a common file model that is capable of representing any conceivable filesystemâ€™s general features and behavior.</p>
<h2>Implementation of the VFS</h2>
<p>The VFS is object-oriented. Well this might actually surprise you as it did me. The Linux kernel is programmed in C, so how come the VFS is object-oriented? This does not mean the VFS is coded using classes , objects and other OOPS features. VFS is object oriented in the sense that the whole implementation is built around the concept of objects. Since C does not support OOPS constructs such as classes therefore the data structures which are used to implemented object oriented C code are represented as C structures.<br />
The four primary object types of the VFS are:</p>
<ul>
<li>The superblock object which represents a specific mounted filesystem</li>
<li>The inode object which represents a specific file</li>
<li>The dentry object which represents a directory entry, a single component of a path</li>
<li>The file object which represents an open file as associated with a process</li>
</ul>
<p>An operations object is contained within each of this primary objects and they define the operations that the kernel invokes on each of these objects. Specifically these are:</p>
<ul>
<li>The super_operations object is a structure which is used by the kernel to read and write inodes, write superblock information back to disk and collect file system statistics as required by the system calls like fstatfs and statfs</li>
<li>The inode_operations object contains methods which the kernel can invoke on a specific file such as create( ) and link( )</li>
<li>The dentry_operations object contains the methods that the kernel can invoke on a specific directory entry, such as d_compare( ) and d_delete( )</li>
<li>The file object contains the operations that a process can invoke an open file such as read( ) and write( )</li>
</ul>
<h2>The Superblock Object and Superblock Operations</h2>
<p>The superblock object represents a specific mounted file system. It usually corresponds to the file system superblock or file system control block on disk. A superblock is created and initialized when filesystem is mounted.</p>
<p>The superblock object is represented by struct super_block and defined in</p>
<linux>. The important fields are reproduced here (Listing 1)</linux>Listing 1<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
struct super_block{<br />
â€¦<br />
unsigned long s_blocksize; /* blocksize in bytes */<br />
unsigned long long s_maxbytes; /* max file size */<br />
struct file_system_type s_type; /* file system type */<br />
struct super_operations s_op; /* superblock methods */<br />
struct dentry *s_root; /* directory mount point */<br />
struct list_head *s_dirty; /* list of dirty inodes */<br />
struct list_head *s_files; /* list of assigned files */<br />
void *s_fs_info; /* filesystem-specific info */<br />
â€¦<br />
};&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>As you can see above, there is a field struct super_operations s_op. This field defines a interface to the struct super_operations defined in &lt; linux / fs.h &gt;. This structure represents the superblock operations table. Listing 2 reproduces the important fields of the table:</p>
<p>Listing 2<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
struct super_block{<br />
&#8230;..<br />
struct inode *(*alloc_inode)(struct super_block sb); /* Create and initialize a new inode object */<br />
void (*read_inode) (struct inode inode); /* Read a inode from disk */<br />
void (*dirty_inode) (struct inode inode); /*Invoked by the VFS when the inode is dirtied / modified*/<br />
void (*write_inode) (struct inode inode, int wait); /* write the given inode to disk */<br />
int (*sync_fs) (struct super_block sb, int wait); /* Synchronizes filesystem metadata with ondisk meta data */<br />
int (*statfs) (struct super_block sb, struct statfs statfs); /* statfs( ) system call */<br />
int (*remount_fs) (struct super_block sb, int flags, char data); / * called by VFS when filesystem is remounted*/<br />
â€¦<br />
};<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Each item in the above structure is a pointer to a function that operates on a superblock object.</p>
<h2>The Inode Object and Inode Operations</h2>
<p>The inode object represents all the information needed by the kernel to manipulate a file or directory. Inode stores the metadata about the files and directories on the disk.<br />
It is represented by struct inode defined in &lt; linux / fs.h &gt;. The important fields are reproduced below.(Listing 3)<br />
Listing 3<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
struct inode{<br />
â€¦<br />
unsigned long i_ino; /* inode number */<br />
umode_t i_mode; /* access permissions */<br />
unsigned int i_nlink; /* number of hard links */<br />
uid_t i_uid; /* user id of owner */<br />
loff_t i_size; /* file size in bytes */<br />
struct inode_operations *i_op; /* inode operations table */<br />
struct file_operations *f_op; /* file operations */<br />
struct super_block *i_sb; /* associated superblock */<br />
union{ void *generic_ip;} u; /* fs-specific info */<br />
â€¦<br />
struct list_head i_devices; /* list of block Devices */<br />
struct pipe_inode_info i_pipe; / * pipe information */<br />
struct block_device i_bdev; / * Block Device Driver */<br />
struct cdev i_cdev; /* Character Devcie Driver*/<br />
&#8230;<br />
};<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
An inode represents information about each file on a filesystem and are created in memory as the files are accessed. Also it is worthwhile to note in the above listing the last few lines. Recall that even devices and pipes are represented as files and so they must be having the corresponding inode entries. This is what is achieved by the following entries : (Table 1)</p>
<p>Table 1</p>
<table cellpadding="0" cellspacing="0">
<tr>
<th scope="col" valign="top" width="200">
<p class="TableHeading"><span style="font-family: Nimbus Roman No9 L">Inode entry </span></p>
</th>
<th scope="col" valign="top" width="200">
<p class="TableHeading"><span style="font-family: Nimbus Roman No9 L">Special Files </span></p>
</th>
</tr>
<tr>
<td valign="top" width="200">
<p class="TableContents"><span style="font-size: 10pt; color: black">struct pipe_inode_info *i_pipe; </span></p>
</td>
<td valign="top" width="200">
<p class="TableContents"><span style="font-family: Nimbus Roman No9 L">Pipe </span></p>
</td>
</tr>
<tr>
<td valign="top" width="200">
<p class="TableContents"><span style="font-size: 10pt; color: black">struct block_device *i_bdev; </span></p>
</td>
<td valign="top" width="200">
<p class="TableContents"><span style="font-family: Nimbus Roman No9 L">Block device driver </span></p>
</td>
</tr>
<tr>
<td valign="top" width="200">
<p class="TableContents"><span style="font-size: 10pt; color: black">struct cdev *i_cdev; </span></p>
</td>
<td valign="top" width="200">
<p class="TableContents"><span style="font-family: Nimbus Roman No9 L">Character device driver </span></p>
</td>
</tr>
</table>
<p>The inode operations are defined in struct inode_operations in &lt; linux/fs.h &gt;. The common fields are reproduced below. (Listing 5)<br />
Listing 4<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
struct inode_operations{<br />
â€¦<br />
int (*create) (struct inode dir, struct dentry dentry, int mode); /* Create a new inode corresponding to a creat( ) or open ( ) system call */<br />
struct dentry (*lookup) (struct inode dir, struct dentry dentry); /* Search for an inode */<br />
int (*link) (struct dentry old_dentry, struct inode dir, struct dentry dentry); /* called by the link ( ) system call*/<br />
int (*unlink) (struct inode dir, struct dentry dentry); /* called from unlink( ) system call */<br />
int (*mkdir) (struct inode ,struct dentry ,int); /* called by the mkdir( ) system call */<br />
int (*rmdir) (struct inode *,struct dentry *); /* called by the rmdir( ) system call */<br />
int (*mknod) (struct inode *,struct dentry *,int,dev_t); /* called by the mknod( ) system call */<br />
â€¦<br />
};<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<h2>The Dentry Object and Dentry Operations</h2>
<p>A dentry object represents a specific component in a path and usually corresponds to some inode. It is created on-the-fly from a string representation of a path name and does not correspond to any on-disk data structure and is created/used in directory-specific operations such as path name lookup<br />
Listing 5<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
struct dentry{<br />
â€¦<br />
struct inode *d_inode; /* associated inode */<br />
struct list_head d_subdirs; /* subdirectories */<br />
struct dentry_operations *d_op; /* dentry operations table */<br />
struct super_block *d_sb; /*superblock of file */<br />
void *d_fsdata; /* fs-specific data */<br />
struct dentry *d_parent; /* dentry of parent dir */<br />
struct qstr d_name; /* dentry name */<br />
â€¦<br />
};</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
The dentry operations are declared in struct dentry_operations( Listing 6)</p>
<p><strong>Listing 6 </strong><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
struct dentry_operations{<br />
â€¦<br />
int (*d_revalidate) (struct dentry *, int);<br />
int (*d_hash) (struct dentry *, struct qstr *);<br />
int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);<br />
â€¦<br />
};</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<h2>The File object and File operations</h2>
<p>Finally, we reach the highest level of abstraction, the file. Every file that is opened by a process has a corresponding entry of the file object. It is defined as struct file in &lt;linux/fs.h&gt; .The important fields are reproduced here. (Listing 6)<br />
Listing 7<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
struct file{<br />
â€¦<br />
struct dentry *f_dentry; /* associated dentry object */<br />
struct file_operations *f_op; /* file operations table */<br />
unsigned int f_flags; /* flags specified on open */<br />
loff_t f_pos; /* file offset(file pointer)*/<br />
void *private_data;<br />
â€¦<br />
};<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
When a file is opened using the open( ) system call a new file object is created and destroyed when close ( ) is called. These operations are specified in struct file_operations in &lt; linux /fs.h &gt; (Listing 7)<br />
Listing 8<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
struct file_operations{<br />
â€¦<br />
loff_t (*llseek) (struct file , loff_t int); / * llseek( ) system call */<br />
ssize_t (*read) (struct file *, char *, size_t *, loff_t *); /* read( ) system call */<br />
ssize_t (*write) (struct file *, const char *, size_t, loff_t *); /* write( ) system call */<br />
int (*open) (struct inode *, struct file *); /* open( ) system call */<br />
int (*readdir) (struct file , void dirent, filldir_t); / * readdir() system call */<br />
â€¦<br />
};<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
As is apparent , the most common file operation system calls are defined here.<br />
After this short tour of the VFS let us now seek an understanding how a filesystem is mounted</p>
<p><strong>Mounting a filesystem </strong></p>
<p>Note : Portions of this section has been cited from the doc available at http://www.tldp.org/LDP/tlk/fs/filesystem.html as the licence allows this<br />
When the user attempts to mount a file system, the Linux kernel must first validate the arguments passed in the system call. Although mount does some basic checking, it does not know which file systems this kernel has been built to support or that the proposed mount point actually exists. Consider the following mount command:<br />
$ mount -t vfat /dev/hda5 /mnt/winc<br />
Once this command is given, the first task of the VFS is to find the type of filesystem to be mounted (vfat in this example). The VFS achieves this by browsing through the list of known file systems by looking at each file_system_type (see below) data structure in the list of supported filesystems . If a match is found it knows that this file system type is supported by this kernel and it has the address of the file system specific routine for reading this file systemâ€™s superblock. If it cannot find a matching file system name, a request is passed to the kernel daemon to load the appropriate module. (This is possible only if the kernel supports module loading).<br />
The next task is to find the VFS inode of the directory (/mnt/winc) which is to be the new file systemâ€™s mount point. Once the inode has been found (either in the inode cache or a block device) it is checked to see that it is a directory and that there is not already some other file system mounted there.<br />
At this point a VFS superblock must be allocated and pass the mount information to the superblock read routine for this file system. All of the systemâ€™s VFS superblocks are kept in the super_blocks vector of super_block data structures and one must be allocated for this mount. The superblock read routine must fill out the VFS superblock fields based on information that it reads from the physical device. Note that not all the fields of the superblock are used by all filesystems, some filesystems may just leave certain unused fields as NULL.<br />
Each mounted file system is described by a vfsmount data structure( defined as struct vfsmount in linux/mount.h, Listing 9). These are queued on a list pointed at by vfsmntlist (defined in &lt; fs/super.c &gt;).</p>
<p>Listing 9<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
struct vfsmount {<br />
struct list_head mnt_hash;<br />
struct vfsmount *mnt_parent; /* fs we are mounted on */<br />
struct dentry *mnt_mountpoint; /* dentry of mountpoint */<br />
struct dentry *mnt_root; /* root of the mounted tree */<br />
struct super_block *mnt_sb; /* pointer to superblock */<br />
struct list_head mnt_mounts; /* list of children, anchored here */<br />
struct list_head mnt_child; /* and going through their mnt_child */<br />
atomic_t mnt_count;<br />
int mnt_flags;<br />
int mnt_expiry_mark; /* true if marked for expiry */<br />
char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */<br />
struct list_head mnt_list;<br />
struct list_head mnt_expire; /* link in fs-specific expiry list */<br />
struct list_head mnt_share; /* circular list of shared mounts */<br />
struct list_head mnt_slave_list; /* list of slave mounts */<br />
struct list_head mnt_slave; /* slave list entry */<br />
struct vfsmount *mnt_master; /* slave is on master-&gt;mnt_slave_list */<br />
struct namespace *mnt_namespace; /* containing namespace */<br />
int mnt_pinned;<br />
};</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Another pointer, vfsmnttail ( fs/super,c&gt;) points at the last entry in the list and the mru_vfsmnt (&lt;fs/super.c &gt;) pointer points at the most recently used file system. Each vfsmount structure contains the device number of the block device holding the file system, the directory where this file system is mounted and a pointer to the VFS superblock allocated when this file system was mounted. In turn the VFS superblock points at the file_system_type (See Below) data structure for this sort of file system and to the root inode for this file system. This inode is kept resident in the VFS inode cache all of the time that this file system is loaded.</p>
<p><strong>The file_system_type structure </strong></p>
<p>Each filesystem is represented by a struct file_system_type structure defined in &lt;linux /fs.h&gt; (Listing 10)<br />
Listing 10<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
struct file_system_type {<br />
const char name; /* filesystemâ€™s name */<br />
int fs_flags; /* filesystem type flags */<br />
struct super_block *(*get_sb) (struct file_system_type *, int, const char *, void *);<br />
/* read the superblock off the disk*/<br />
void (*kill_sb) (struct super_block *); /* terminate access to the superblock*/<br />
struct module owner; /* module ownning the filesystem */<br />
struct file_system_type * next; /* next filesystem in list*/<br />
struct list_head fs_supers; /* list of superblock objects */<br />
};</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;CODE&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<h2>Footnotes</h2>
<p>So that was a whirlwind tour of the Linux VFS wounding up with the internals of the mounting of filesystems. Implementation of a filesystem and how data lands up in the disks are unexplored territories which we will explore later. Till then happy hacking!<br />
All code samples in this article are as in Linux kernel 2.6.15.4<br />
References<br />
â€¢ Linux Kernel Development, Robert Love<br />
â€¢ Linux Kernel Source Code</p>
<p><em>Copyright @ Amit Kumar Saha</em></p>
<p><em>The author is a 3rd year Computer engineering undergraduate student at Haldia Institute of Technology, Haldia, India. His interests include Operating systems, Network protocols, Network security, Mobile computing.He is passionate about programming and Python is the most recent addition to the kitty of languages<br />
Homepage: http://amitsaha.in.googlepages.com </em></p>
<p><strong>Attached Files:</strong></p>
<ul>
<li> <a href="http://9tutorials.com/wp-content/uploads/2007/05/website-mockup-tips1.zip" target="_blank"><em>website-mockup-tips1.zip (403 KB)</em></a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://9tutorials.com/2007/05/21/the-linux-virtual-file-system.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
