Difference between pages "Funtoo Filesystem Guide, Part 2" and "Funtoo Filesystem Guide, Part 3"

(Difference between pages)
 
 
Line 1: Line 1:
 
{{Article
 
{{Article
 
|Author=Drobbins
 
|Author=Drobbins
|Previous in Series=Funtoo Filesystem Guide, Part 1
+
|Previous in Series=Funtoo Filesystem Guide, Part 2
|Next in Series=Funtoo Filesystem Guide, Part 3
+
|Next in Series=Funtoo Filesystem Guide, Part 4
 
}}
 
}}
== Using ReiserFS and Linux ==
+
== Introduction ==
 +
In my previous articles in this series, I introduced the benefits of journaling and the ReiserFS and showed how to set up a rock-solid ReiserFS system. In this article, we're going to tackle a couple of semi-offbeat topics. First, we'll take a look at tmpfs, also known as the virtual memory (VM) filesystem. Tmpfs is probably the best RAM disk-like system available for Linux right now, and was introduced with Linux kernel 2.4. Then, we'll take a look at another capability introduced with Linux kernel 2.4 called "bind mounts", which allow a great deal of flexibilit
 +
y when it comes to mounting (and remounting) filesystems.
  
=== Introduction ===
+
== Introducing Tmpfs ==
In this article, I'll show you how to get ReiserFS running under a typical Linux distribution. I'll also share lots of technical information on a variety of topics, such as performance considerations and more. Since I'll be covering installation first, I recommend that you read this article in its entirety before following the installation instructions. That way, you'll have all the technical notes in the back of your head as you start getting ReiserFS running on your systems, allowing you to make any necessary adjustments along the way.
+
If I had to explain tmpfs in one breath, I'd say that tmpfs is like a ramdisk, but different. Like a ramdisk, tmpfs can use your RAM, but it can also use your swap devices for storage. And while a traditional ramdisk is a block device and requires a mkfs command of some kind before you can actually use it, tmpfs is a filesystem, not a block device; you just mount it, and it's there.  
 +
All in all, this makes tmpfs the niftiest RAM-based filesystem I've had the opportunity to meet.
  
=== The Search For A Good Kernel ===
+
== Tmpfs and VM ==
To enable ReiserFS on your system, you'll first need to find a suitable kernel. At the time this article was orginally written (way back in 2001,) finding a suitable kernel for running ReiserFS required some effort, as ReiserFS was still an experimental filesystem. However, these days ReiserFS is no longer considered to be experimental and it's quite easy to find a kernel that supports ReiserFS. Unfortunately, Red Hat has removed ReiserFS support from the official Red Hat Enterprise Linux kernel, but it available in the stock Linux kernel sources, as well as various RHEL-based kernels.
+
Let's take a look at some of tmpfs's more interesting properties. As I mentioned above, tmpfs can use both RAM and swap. This might seem a bit arbitrary at first, but remember that tmpfs is also known as the "virtual memory filesystem". And, as you probably know, the Linux kernel's virtual memory resources come from both your RAM and swap devices. The VM subsystem in the kernel allocates these resources to other parts of the system and takes care of managing these resources behind-the-scenes, often transparently moving RAM pages to swap and vice-versa.
 +
The tmpfs filesystem requests pages from the VM subsystem to store files. tmpfs itself doesn't know whether these pages are on swap or in RAM; it's the VM subsystem's job to make those kinds of decisions. All the tmpfs filesystem knows is that it is using some form of virtual memory.
  
If for some reason you are using a 2.4 kernel version, try to avoid early revisions of the kernel and use something that is fairly recent, like 2.4.30 or higher.
+
== Not a Block Device ==
 +
Here's another interesting property of the tmpfs filesystem. Unlike most "normal" filesystems, like ext3, ext2, XFS, JFS, ReiserFS and friends, tmpfs does not exist on top of an under
 +
lying block device. Because tmpfs sits on top of VM directly, you can create a tmpfs filesystem with a simple mount command:
  
=== Are You Ready? ===
+
<pre># mount tmpfs /mnt/tmpfs -t tmpfs</pre>After executing this command, you'll have a new tmpfs filesystem mounted at /mnt/tmpfs, ready for use. Note that there's no need to run mkfs.tmpfs; in fact, it's impossible, as no such command exists. Immediately after the mount command, the filesystem is mounted and available for use, and is of type tmpfs. This is very different from how Linux ramdisks are used; standard Linux ramdisks are block devices, so they must be formatted with a filesystem of your choice before you can use them. In contrast, tmpfs is a filesystem. So, you can just mount it and go.
The first step in using ReiserFS is to make sure that your kernel has ReiserFS support available. To do this, type:
+
<pre>
+
cat /proc/filesystems
+
</pre>
+
If you see "reiserfs" listed in the resultant list, then reiserfs support is currently available. You're ready to go!
+
  
Now, what happens if you don't see ReiserFS support listed? Well, it's possible that it's actually there, but available as a kernel module and not yet loaded. To see if this is the case, first become the root user if you aren't root already, and type:
+
== Tmpfs Advantages ==
<pre>
+
# modprobe reiserfs
+
</pre>
+
Was modprobe able to load the reiserfs module? Run the <span style="color:green">cat /proc/filesystems</span> command again and see if reiserfs is in the list. If it is, great! If not, then it looks like you are going to need to either upgrade to a kernel with ReiserFS support or recompile your existing kernel, if you enjoy doing that kind of thing.
+
  
If you're up for recompiling your own kernel, here's how you'd go about enabling ReiserFS. First, type <span style="color:green">make menuconfig</span> in your kernel source tree. Under the ''Code maturity level options'' section, make sure that the ''Prompt for development and/or incomplete code/drivers'' option is enabled if you are using a 2.4 kernel. Then, head over to the ''File systems'' section, and enable ''ReiserFS support''. It's recommended that you enable ReiserFS support to be compiled directly into your kernel (not as a module.) You may enable the extra ReiserFS capabilities if you wish. Now, save your settings, compile your kernel (<span style="color:green">make dep</span> (for kernel 2.4 only); <span style="color:green">make bzImage; make modules; make modules_install</span>) and configure your boot loader to load the new ReiserFS-enabled kernel.
+
=== Dynamic Filesystem Size ===
 +
You're probably wondering about how big that tmpfs filesystem was that we mounted at <tt>/mnt/tmpfs</tt>, above. The answer to that question is a bit unexpected, especially when compared to disk-based filesystems. <tt>/mnt/tmpfs</tt> will initially have a very small capacity, but as files are copied and created, the tmpfs filesystem driver will allocate more VM and will dynamically increase the filesystem capacity as needed. And, as files are removed from <tt>/mnt/tmpfs</tt>, the tmpfs filesystem driver will dynamically shrink the size of the filesystem and free VM resources, and by doing so return VM into circulation so that it can be used by other parts of the system as needed. Since VM is a precious resource, you don't want anything hogging more VM than it ac
 +
tually needs, and the great thing about tmpfs is that this all happens automatically.
  
{{fancyimportant|It's always a good idea to save your current kernel and configure your boot loader so that you can boot with your original kernel, just in case your new kernel doesn't work.}}
+
=== Speed ===
 +
The other major benefit of tmpfs is its blazing speed. Because a typical tmpfs filesystem will reside completely in RAM, reads and writes can be almost instantaneous. Even if some swap is used, performance is still excellent and those parts of the tmpfs filesystem will be moved to RAM as more free VM resources become available. Having the VM subsystem automatically move parts of the tmpfs filesystem to swap can actually be good for performance, since by doing so, the VM subsystem can free up RAM for processes that need it. This, along with its dynamic resizing abilities, allow for much better overall OS performance and flexibility than the alternative of using a traditional RAM disk.
  
=== Installing the Tools ===
+
=== No Persistence ===
Now, before you potentially reboot with a brand-new, ReiserFS-enabled kernel, we need to make sure that you have the "reiserfsprogs" tools installed. Most modern distributions will have these tools available. To determine if they are installed, run the following command as root:
+
<pre>
+
# reiserfsck
+
</pre>
+
Was it found? If so, great! This means that the reiserfsprogs are installed and available. If they aren't available, I recommend using your distribution's package manager to track down these tools and install them. Once the tools are installed, now would be a good time to reboot to enable a new ReiserFS-enabled kernel if you installed one.
+
  
=== Creating and Mounting the Filesystem ===
+
While this may not seem like a positive, tmpfs data is not preserved between reboots, because virtual memory is volatile in nature. I guess you probably figured that tmpfs was called &quot;tmpf
Once rebooted, you'll be able to create a ReiserFS filesystem on an empty partition as follows:
+
s&quot; for a reason, didn't you? However, this can actually be a good thing. It makes tmpfs an excellent filesystem for holding data that you don't need to keep, such as temporary files (those found in <tt>/tmp</tt>) and parts of the <tt>/var</tt> filesystem tree.
<pre>
+
# mkreiserfs /dev/sdxy
+
</pre>
+
In the above example, '''/dev/hdxy''' should be a device node corresponding to a free partition. Mount it as you would any other filesystem:
+
<pre>
+
# mkdir /mnt/reiser
+
# mount /dev/hdxy /mnt/reiser
+
</pre>
+
And, if you'd like to add a ReiserFS filesystem to your '''/etc/fstab''' file, simply set the freq and passno fields to 0, as follows:
+
<pre>
+
/dev/sdc1  /home  reiserfs  defaults  0  0
+
</pre>
+
From this point forward, your ReiserFS filesystems should act identically to their ext2 counterparts, except that you'll no longer need to worry about long fsck times, and overall performance will be much better -- especially for small files.
+
  
== ReiserFS Technical Notes ==
+
== Using Tmpfs ==
  
=== Filesystem Stability ===
+
To use tmpfs, all you need is a modern (2.4+) kernel with <tt>Virtual memory file system support (former shm fs)</tt> enabled; this option lives under the <tt>File systems</tt> section of the kernel configuration options. Once you have a tmpfs-enabled kernel, you can go ahead and mount tmpfs filesystems. In fact, it's a good idea to enable tmpfs in all your kernels if you compile the
 +
m yourself - whether you plan to use tmpfs or not. This is because you need to have kernel tmpfs support in order to use POSIX shared memory. System V shared memory will work without tmpfs in y
 +
our kernel, however. Note that you do not need a tmpfs filesystem to be mounted for POSIX shared memory to work; you simply need the support in your kernel. POSIX shared memory isn't used too much right now, but this situation will likely change as time goes on.
  
With a modern kernel, ReiserFS is generally just as reliable as ext2 or ext3.
+
=== Avoiding low VM conditions ===
As with all filesystems, a spattering of older kernels had some filesystem
+
corruption bugs in them and should be avoided. However, if you are relying on
+
your Linux distribution's selection of kernels, then you should not experience
+
any issues with ReiserFS.
+
  
=== No dump/restore ===
+
The fact that tmpfs dynamically grows and shrinks as needed makes one wonder: what happens when your tmpfs filesystem grows to the point where it exhausts all of your virtual memory, and you have no RAM or swap left? Well, generally, this kind of situation is a bit ugly. With kernel 2.4.4, the kernel would immediately lock up. With more recent kernels, the VM subsystem has in many ways been fixed, and while exhausting VM isn't exactly a wonderful experience, things don't blow up completely, either. When a modern kernel gets to the point where it can't allocate any more VM, you obviously won't be unable to write any new data to your tmpfs filesystem. In addition, it's likely that some other things will happen. First, the other processes on the system will be unable to allocate much more memory; generally, this means that the system will most likely become extremely sluggish and almost unresponsive. Thus, it may be tricky or unusually time-consuming for the superuser to take the necessary steps to alleviate this low-VM condition.
  
Yes, it's true; ReiserFS does not yet have a <tt>dump</tt> and <tt>restore</tt>
+
In addition, the kernel has a built-in last-ditch system for freeing memory when no more is available; it'll find a process that's hogging VM resources and kill it. Unfortunately, this &quot;kill a process&quot; solution generally backfires when tmpfs growth is to blame for VM exhaustion. Here's the reason. Tmpfs itself can't (and shouldn't) be killed, since it is part of the kernel  and not a user process, and there's no easy way for the kernel to find out which process is filling up the tmpfs filesystem. So, the kernel mistakenly attacks the biggest VM-hog of a process it can find, which is generally your X server if you happen to be running one. So, your X server dies, and the root cause of the low-VM condition (tmpfs) isn't addressed. Ick.
implementation. If you want to user ReiserFS and happen to be a <tt>dump</tt>
+
fan, you'll have to find some alternate way of backing data. In reality, this
+
turns out to be a non-issue, since 2.4+ kernels are incompatible with
+
<tt>dump</tt> and <tt>restore</tt> in the first place. For more information on
+
the dump/kernel incompatibility, read the LKML posting by Linus Torvalds where
+
he says that &quot;Dump was a stupid program in the first place. Leave it
+
behind.&quot;
+
  
=== Performance Issues ===
+
=== Low VM: the solution ===
  
While ReiserFS generally blows the socks off ext2, ReiserFS does have a few
+
Fortunately, tmpfs allows you to specify a maximum upper bound for the filesystem size when a filesystem is mounted or remounted. Actually, as of kernel 2.4.6 and util-linux-2.11g, these parameters can only be set on mount, not on remount, but we can expect them to be settable on remount sometime in the near future. The optimal maximum tmpfs size setting depends on the resources and
special-case performance weaknesses. The first is sparse file performance.
+
usage pattern of your particular Linux box; the idea is to prevent a completely full tmpfs filesystem from exhausting all virtual memory and thus causing the ugly low-VM conditions that we talked about earlier. A good way to find a good tmpfs upper-bound is to use top to monitor your system's swap usage during peak usage periods. Then, make sure that you specify a tmpfs upper-bound that's slightly less than the sum of all free swap and free RAM during these peak usage times.
ReiserFS sparse file performance will be significantly worse than ext2. This
+
will change at some point, when the Namesys developers get around to optimizing
+
that part of ReiserFS for ReiserFS 4. Until then, ext2 is a better solution for
+
applications that place heavy demands on sparse files.
+
  
=== Performance Tweaks ===
+
Creating a tmpfs filesystem with a maximum size is easy. To create a new tmpfs filesystem with a maximum filesystem size of 32 MB, type:
  
Fortunately, there are a couple of easy general performance tweaks you can use
+
<pre># mount tmpfs /dev/shm -t tmpfs -o size=32m</pre>
to make these problems less severe. The first is to mount your ReiserFS
+
filesystem with the `noatime` mount option (a mount option that's available for
+
other filesystems as well as ReiserFS). As you probably know, UNIX systems
+
record an atime, or access time, for each object on the filesystem that gets
+
updated every time a file is read. For most people, the atime stamp isn't very
+
useful and hardly any applications (none I can think of) rely on the atime for
+
any critical task. For this reason, it can usually be safely turned off, which
+
gives a nice all-around performance boost. Generally, unless you specifically
+
know that you need atime support, you should be mounting your filesystems with
+
the noatime option. Use an `/etc/fstab` entry like this:
+
  
<pre>/dev/hdc1  /home  reiserfs  noatime  0  0</pre>
+
This time, instead of mounting our new tmpfs filesystem at /mnt/tmpfs, we created it at /dev/shm, which is a directory that happens to be the &quot;official&quot; mount point for a tmpfs filesystem. If you happen to be using devfs, you'll find that this directory has already been created for you.
 +
Also, if we want to limit the filesystem size to 512 KB or 1 GB, we can specify size=512k and size=1g, respectively. In addition to limiting size, we can also limit the number of inodes (filesystem objects) by specifying the nr_inodes=x parameter. When using nr_inodes, x can be a simple integer, and can also be followed with a k, m, or g to specify thousands, millions, or billions (!) of inodes.
  
 +
Also, if you'd like to add the equivalent of the above mount tmpfs command to your /etc/fstab, it'd look like this:
  
In my first ReiserFS article, I mentioned that ReiserFS has a special feature
+
<pre>tmpfs  /dev/shm    tmpfs  size=32m    0  0</pre>
called &quot;tail packing&quot;. In ReiserFS lingo, &quot;tails&quot; are files
+
that are smaller than a filesystem block (4k) or the trailing portions of files
+
that don't quite fill up a complete filesystem block. ReiserFS has really
+
excellent small-file performance because it is able to incorporate these tails
+
into its b*tree (its primary organizational data structure) so that they are
+
really close to the stat-data (ReiserFS' equivalent of an i-node). However,
+
since tails don't fill up a complete block, they can waste a lot of disk space
+
(relatively speaking, of course). To solve this problem, ReiserFS uses its
+
&quot;tail packing&quot; functionality to squish tails into as small a space as
+
possible. Generally, this allows a ReiserFS filesystem to hold around 5% more
+
than an equivalent ext2 filesystem.
+
  
=== Tail Packing Pros and Cons ===
+
=== Mounting On Top of Existing Mount Points ===
 +
Back in the 2.2 days, any attempt to mount something to a mount point where something had already been mounted resulted in an error. However, thanks to a rewrite of the kernel mounting code, using mount points multiple times is not a problem. Here's an example scenario: let's say that we have an existing filesystem mounted at <tt>/tmp</tt>. However, we decide that we'd like to start
 +
using tmpfs for <tt>/tmp</tt> storage. In the old days, your only option would be to unmount <tt>/tmp</tt> and remount your new tmpfs <tt>/tmp</tt> filesystem in its place, as follows:
  
However, tail packing also has its disadvantages. For one, it does give you a
+
<pre>#  umount /tmp
small but significant performance hit. Fortunately, the ReiserFS guys
+
#  mount tmpfs /tmp -t tmpfs -o size=64m</pre>
anticipated that some people would be willing to sacrifice around 5% of their
+
However, this solution may not work for you. Maybe there are a number of running processes that have open files in <tt>/tmp</tt>; if so, when trying to unmount <tt>/tmp</tt>, you'd get the following error:
disk capacity for a little extra performance, so they created the
+
<tt>notail</tt> mount option. When a filesystem is mounted with this option,
+
tail packing will be turned off, giving you greater speed and less storage
+
capacity. In general, filesystem performance freaks mount their filesystems
+
with both <tt>notail</tt> and <tt>noatime</tt> enabled, producing a noticeable
+
performance improvement:
+
  
<pre>/dev/hdc1  /home  reiserfs  noatime,notail  0  0</pre>
+
<pre>umount: /tmp: device is busy</pre>
 +
However, with Linux 2.4+, you can mount your new <tt>/tmp</tt> filesystem without getting the &quot;device is busy&quot; error:
  
Even if you want to save some disk space, there are times when temporarily
+
<pre># mount tmpfs /tmp -t tmpfs -o size=64m</pre>
mounting your filesystem with the <tt>notail</tt> option can be a good thing.
+
With a single command, your new tmpfs <tt>/tmp</tt> filesystem is mounted at <tt>/tmp</tt>, on top of the already-mounted partition, which can no longer be directly accessed. However, while you can't get to the original <tt>/tmp</tt>, any processes that still have open files on this original filesystem can continue to access them. And, if you umount your tmpfs-based <tt>/tmp</tt>, your original mounted <tt>/tmp</tt> filesystem will reappear. In fact, you can mount any number of filesystems to the same mount point, and the mount point will act like a stack; unmount the current filesystem, and the last-most-recently mounted filesystem will reappear from underneath.
In particular, some older boot-loaders have problems loading kernels that were
+
created on a ReiserFS filesystem with tail packing enabled. If you're using a
+
LILO earlier than version 21.6, you'll have this problem. You will also have
+
problems with old versions of GRUB, which will not be able to load its
+
<tt>stage1</tt> and <tt>stage1_5</tt> files. If you're already experiencing
+
this problem, you can fix it by mounting the filesystem with the
+
<tt>notail</tt> option, moving the files to another filesystem, and then moving
+
them back. When they're recreated, they won't have tails. Also, remember that
+
you can easily remount a filesystem (with new options) without unmounting it.
+
This particular example remounts the root filesystem with the <tt>notail</tt>
+
option:
+
  
<pre># mount / -o remount,notail</pre>
+
== Bind Mounts ==
  
== Conclusion ==
+
Using bind mounts, we can mount all, or even part of an already-mounted filesystem to another location, and have the filesystem accessible from both mount points at the same time! For example, you can use bind mounts to mount your existing root filesystem to <tt>/home/drobbins/nifty</tt>, as follows:
  
I've found ReiserFS to be a truly incredible filesystem, offering oodles of
+
<pre>#  mount --bind / /home/drobbins/nifty</pre>
small file performance and great (normally better than ext2) regular file
+
Now, if you look inside <tt>/home/drobbins/nifty</tt>, you'll see your root filesystem (<tt>/home/drobbins/nifty/etc</tt>, <tt>/home/drobbins/nifty/opt</tt>, etc.). And if you modify a file on your root filesystem, you'll see the modifications in <tt>/home/drobbins/nifty</tt> as well. This is because they are one and the same filesystem; the kernel is simply mapping the filesystem to two different mount points for us. Note that when you mount a filesystem somewhere else, any filesystems that were mounted to mount points inside the bind-mounted filesystem will not be moved along. In other words, if you have <tt>/usr</tt> on a separate filesystem, the bind mount we performed above will leave <tt>/home/drobbins/nifty/usr</tt> empty. You'll need an additional bind mount command to allow you to browse the contents of <tt>/usr</tt> at <tt>/home/drobbins/nifty/usr</tt>:
performance. For example, updates to source code repositories using cvs and
+
ReiserFS have been observed to complete in only fifteen seconds, where the same
+
source code tree takes about two minutes to update with ext2. ReiserFS makes
+
many peoples' lives more pleasant, and allows servers to handle large amounts
+
of simultaneous IO without thrashing hard drives and negatively affecting
+
interactive performance.
+
  
In future articles, I hope to take a look at Reiser4, a completely new (and
+
<pre>#  mount --bind /usr /home/drobbins/nifty/usr</pre>
incompatible) version of ReiserFS which sports some interesting new
+
=== Bind mounting parts of filesystems ===
capabilities.
+
 
 +
Bind mounting makes even more neat things possible. Let's say that you have a tmpfs filesystem mounted at <tt>/dev/shm</tt>, its traditional location, and you decide that you'd like to start using tmpfs for <tt>/tmp</tt>, which currently lives on your root filesystem. Rather than mounting a new tmpfs filesystem to <tt>/tmp</tt> (which is possible), you may decide that you'd like the new <tt>/tmp</tt> to share the currently mounted <tt>/dev/shm</tt> filesystem. However, while you could bind mount <tt>/dev/shm</tt> to <tt>/tmp</tt> and be done with it, your <tt>/dev/shm</tt> contains some directories that you don't want to appear in <tt>/tmp</tt>. So, what do you do? How about this:
 +
 
 +
<pre># mkdir /dev/shm/tmp
 +
# chmod 1777 /dev/shm/tmp
 +
# mount --bind /dev/shm/tmp /tmp</pre>
 +
In this example, we first create a <tt>/dev/shm/tmp</tt> directory and then give it 1777 perms, the proper permissions for <tt>/tmp</tt>. Now that our directory is ready, we can mount <tt>/dev/shm/tmp</tt>, and only <tt>/dev/shm/tmp</tt> to <tt>/tmp</tt>. So, while <tt>/tmp/foo</tt> would map to <tt>/dev/shm/tmp/foo</tt>, there's no way for you to access the <tt>/dev/shm/bar</tt> file from <tt>/tmp</tt>.
 +
 
 +
As you can see, bind mounts are extremely powerful and make it easy to make modifications to your filesystem layout without any fuss. Next article, we'll check out ext3.
  
 
== Resources ==
 
== Resources ==

Revision as of 08:53, December 28, 2014

Support Funtoo and help us grow! Donate $15 per month and get a free SSD-based Funtoo Virtual Container.

Introduction

In my previous articles in this series, I introduced the benefits of journaling and the ReiserFS and showed how to set up a rock-solid ReiserFS system. In this article, we're going to tackle a couple of semi-offbeat topics. First, we'll take a look at tmpfs, also known as the virtual memory (VM) filesystem. Tmpfs is probably the best RAM disk-like system available for Linux right now, and was introduced with Linux kernel 2.4. Then, we'll take a look at another capability introduced with Linux kernel 2.4 called "bind mounts", which allow a great deal of flexibilit y when it comes to mounting (and remounting) filesystems.

Introducing Tmpfs

If I had to explain tmpfs in one breath, I'd say that tmpfs is like a ramdisk, but different. Like a ramdisk, tmpfs can use your RAM, but it can also use your swap devices for storage. And while a traditional ramdisk is a block device and requires a mkfs command of some kind before you can actually use it, tmpfs is a filesystem, not a block device; you just mount it, and it's there. All in all, this makes tmpfs the niftiest RAM-based filesystem I've had the opportunity to meet.

Tmpfs and VM

Let's take a look at some of tmpfs's more interesting properties. As I mentioned above, tmpfs can use both RAM and swap. This might seem a bit arbitrary at first, but remember that tmpfs is also known as the "virtual memory filesystem". And, as you probably know, the Linux kernel's virtual memory resources come from both your RAM and swap devices. The VM subsystem in the kernel allocates these resources to other parts of the system and takes care of managing these resources behind-the-scenes, often transparently moving RAM pages to swap and vice-versa. The tmpfs filesystem requests pages from the VM subsystem to store files. tmpfs itself doesn't know whether these pages are on swap or in RAM; it's the VM subsystem's job to make those kinds of decisions. All the tmpfs filesystem knows is that it is using some form of virtual memory.

Not a Block Device

Here's another interesting property of the tmpfs filesystem. Unlike most "normal" filesystems, like ext3, ext2, XFS, JFS, ReiserFS and friends, tmpfs does not exist on top of an under lying block device. Because tmpfs sits on top of VM directly, you can create a tmpfs filesystem with a simple mount command:

# mount tmpfs /mnt/tmpfs -t tmpfs
After executing this command, you'll have a new tmpfs filesystem mounted at /mnt/tmpfs, ready for use. Note that there's no need to run mkfs.tmpfs; in fact, it's impossible, as no such command exists. Immediately after the mount command, the filesystem is mounted and available for use, and is of type tmpfs. This is very different from how Linux ramdisks are used; standard Linux ramdisks are block devices, so they must be formatted with a filesystem of your choice before you can use them. In contrast, tmpfs is a filesystem. So, you can just mount it and go.

Tmpfs Advantages

Dynamic Filesystem Size

You're probably wondering about how big that tmpfs filesystem was that we mounted at /mnt/tmpfs, above. The answer to that question is a bit unexpected, especially when compared to disk-based filesystems. /mnt/tmpfs will initially have a very small capacity, but as files are copied and created, the tmpfs filesystem driver will allocate more VM and will dynamically increase the filesystem capacity as needed. And, as files are removed from /mnt/tmpfs, the tmpfs filesystem driver will dynamically shrink the size of the filesystem and free VM resources, and by doing so return VM into circulation so that it can be used by other parts of the system as needed. Since VM is a precious resource, you don't want anything hogging more VM than it ac tually needs, and the great thing about tmpfs is that this all happens automatically.

Speed

The other major benefit of tmpfs is its blazing speed. Because a typical tmpfs filesystem will reside completely in RAM, reads and writes can be almost instantaneous. Even if some swap is used, performance is still excellent and those parts of the tmpfs filesystem will be moved to RAM as more free VM resources become available. Having the VM subsystem automatically move parts of the tmpfs filesystem to swap can actually be good for performance, since by doing so, the VM subsystem can free up RAM for processes that need it. This, along with its dynamic resizing abilities, allow for much better overall OS performance and flexibility than the alternative of using a traditional RAM disk.

No Persistence

While this may not seem like a positive, tmpfs data is not preserved between reboots, because virtual memory is volatile in nature. I guess you probably figured that tmpfs was called "tmpf s" for a reason, didn't you? However, this can actually be a good thing. It makes tmpfs an excellent filesystem for holding data that you don't need to keep, such as temporary files (those found in /tmp) and parts of the /var filesystem tree.

Using Tmpfs

To use tmpfs, all you need is a modern (2.4+) kernel with Virtual memory file system support (former shm fs) enabled; this option lives under the File systems section of the kernel configuration options. Once you have a tmpfs-enabled kernel, you can go ahead and mount tmpfs filesystems. In fact, it's a good idea to enable tmpfs in all your kernels if you compile the m yourself - whether you plan to use tmpfs or not. This is because you need to have kernel tmpfs support in order to use POSIX shared memory. System V shared memory will work without tmpfs in y our kernel, however. Note that you do not need a tmpfs filesystem to be mounted for POSIX shared memory to work; you simply need the support in your kernel. POSIX shared memory isn't used too much right now, but this situation will likely change as time goes on.

Avoiding low VM conditions

The fact that tmpfs dynamically grows and shrinks as needed makes one wonder: what happens when your tmpfs filesystem grows to the point where it exhausts all of your virtual memory, and you have no RAM or swap left? Well, generally, this kind of situation is a bit ugly. With kernel 2.4.4, the kernel would immediately lock up. With more recent kernels, the VM subsystem has in many ways been fixed, and while exhausting VM isn't exactly a wonderful experience, things don't blow up completely, either. When a modern kernel gets to the point where it can't allocate any more VM, you obviously won't be unable to write any new data to your tmpfs filesystem. In addition, it's likely that some other things will happen. First, the other processes on the system will be unable to allocate much more memory; generally, this means that the system will most likely become extremely sluggish and almost unresponsive. Thus, it may be tricky or unusually time-consuming for the superuser to take the necessary steps to alleviate this low-VM condition.

In addition, the kernel has a built-in last-ditch system for freeing memory when no more is available; it'll find a process that's hogging VM resources and kill it. Unfortunately, this "kill a process" solution generally backfires when tmpfs growth is to blame for VM exhaustion. Here's the reason. Tmpfs itself can't (and shouldn't) be killed, since it is part of the kernel and not a user process, and there's no easy way for the kernel to find out which process is filling up the tmpfs filesystem. So, the kernel mistakenly attacks the biggest VM-hog of a process it can find, which is generally your X server if you happen to be running one. So, your X server dies, and the root cause of the low-VM condition (tmpfs) isn't addressed. Ick.

Low VM: the solution

Fortunately, tmpfs allows you to specify a maximum upper bound for the filesystem size when a filesystem is mounted or remounted. Actually, as of kernel 2.4.6 and util-linux-2.11g, these parameters can only be set on mount, not on remount, but we can expect them to be settable on remount sometime in the near future. The optimal maximum tmpfs size setting depends on the resources and usage pattern of your particular Linux box; the idea is to prevent a completely full tmpfs filesystem from exhausting all virtual memory and thus causing the ugly low-VM conditions that we talked about earlier. A good way to find a good tmpfs upper-bound is to use top to monitor your system's swap usage during peak usage periods. Then, make sure that you specify a tmpfs upper-bound that's slightly less than the sum of all free swap and free RAM during these peak usage times.

Creating a tmpfs filesystem with a maximum size is easy. To create a new tmpfs filesystem with a maximum filesystem size of 32 MB, type:

# mount tmpfs /dev/shm -t tmpfs -o size=32m

This time, instead of mounting our new tmpfs filesystem at /mnt/tmpfs, we created it at /dev/shm, which is a directory that happens to be the "official" mount point for a tmpfs filesystem. If you happen to be using devfs, you'll find that this directory has already been created for you. Also, if we want to limit the filesystem size to 512 KB or 1 GB, we can specify size=512k and size=1g, respectively. In addition to limiting size, we can also limit the number of inodes (filesystem objects) by specifying the nr_inodes=x parameter. When using nr_inodes, x can be a simple integer, and can also be followed with a k, m, or g to specify thousands, millions, or billions (!) of inodes.

Also, if you'd like to add the equivalent of the above mount tmpfs command to your /etc/fstab, it'd look like this:

tmpfs   /dev/shm    tmpfs   size=32m    0   0

Mounting On Top of Existing Mount Points

Back in the 2.2 days, any attempt to mount something to a mount point where something had already been mounted resulted in an error. However, thanks to a rewrite of the kernel mounting code, using mount points multiple times is not a problem. Here's an example scenario: let's say that we have an existing filesystem mounted at /tmp. However, we decide that we'd like to start using tmpfs for /tmp storage. In the old days, your only option would be to unmount /tmp and remount your new tmpfs /tmp filesystem in its place, as follows:

#  umount /tmp
#  mount tmpfs /tmp -t tmpfs -o size=64m

However, this solution may not work for you. Maybe there are a number of running processes that have open files in /tmp; if so, when trying to unmount /tmp, you'd get the following error:

umount: /tmp: device is busy

However, with Linux 2.4+, you can mount your new /tmp filesystem without getting the "device is busy" error:

# mount tmpfs /tmp -t tmpfs -o size=64m

With a single command, your new tmpfs /tmp filesystem is mounted at /tmp, on top of the already-mounted partition, which can no longer be directly accessed. However, while you can't get to the original /tmp, any processes that still have open files on this original filesystem can continue to access them. And, if you umount your tmpfs-based /tmp, your original mounted /tmp filesystem will reappear. In fact, you can mount any number of filesystems to the same mount point, and the mount point will act like a stack; unmount the current filesystem, and the last-most-recently mounted filesystem will reappear from underneath.

Bind Mounts

Using bind mounts, we can mount all, or even part of an already-mounted filesystem to another location, and have the filesystem accessible from both mount points at the same time! For example, you can use bind mounts to mount your existing root filesystem to /home/drobbins/nifty, as follows:

#  mount --bind / /home/drobbins/nifty

Now, if you look inside /home/drobbins/nifty, you'll see your root filesystem (/home/drobbins/nifty/etc, /home/drobbins/nifty/opt, etc.). And if you modify a file on your root filesystem, you'll see the modifications in /home/drobbins/nifty as well. This is because they are one and the same filesystem; the kernel is simply mapping the filesystem to two different mount points for us. Note that when you mount a filesystem somewhere else, any filesystems that were mounted to mount points inside the bind-mounted filesystem will not be moved along. In other words, if you have /usr on a separate filesystem, the bind mount we performed above will leave /home/drobbins/nifty/usr empty. You'll need an additional bind mount command to allow you to browse the contents of /usr at /home/drobbins/nifty/usr:

#  mount --bind /usr /home/drobbins/nifty/usr

Bind mounting parts of filesystems

Bind mounting makes even more neat things possible. Let's say that you have a tmpfs filesystem mounted at /dev/shm, its traditional location, and you decide that you'd like to start using tmpfs for /tmp, which currently lives on your root filesystem. Rather than mounting a new tmpfs filesystem to /tmp (which is possible), you may decide that you'd like the new /tmp to share the currently mounted /dev/shm filesystem. However, while you could bind mount /dev/shm to /tmp and be done with it, your /dev/shm contains some directories that you don't want to appear in /tmp. So, what do you do? How about this:

# mkdir /dev/shm/tmp
# chmod 1777 /dev/shm/tmp
# mount --bind /dev/shm/tmp /tmp

In this example, we first create a /dev/shm/tmp directory and then give it 1777 perms, the proper permissions for /tmp. Now that our directory is ready, we can mount /dev/shm/tmp, and only /dev/shm/tmp to /tmp. So, while /tmp/foo would map to /dev/shm/tmp/foo, there's no way for you to access the /dev/shm/bar file from /tmp.

As you can see, bind mounts are extremely powerful and make it easy to make modifications to your filesystem layout without any fuss. Next article, we'll check out ext3.

Resources

Be sure to checkout the other articles in this series:

  • Part 1: Journaling and ReiserFS
  • Part 2: Using ReiserFS and Linux
  • Part 3: Tmpfs and bind mounts
  • Part 4: Introducing Ext3
  • Part 5: Ext3 in action

Next >>>

Read the next article in this series: Funtoo Filesystem Guide, Part 4

Support Funtoo and help us grow! Donate $15 per month and get a free SSD-based Funtoo Virtual Container.

About the Author

Daniel Robbins is best known as the creator of Gentoo Linux and author of many IBM developerWorks articles about Linux. Daniel currently serves as Benevolent Dictator for Life (BDFL) of Funtoo Linux. Funtoo Linux is a Gentoo-based distribution and continuation of Daniel's original Gentoo vision.

Got Funtoo?

Have you installed Funtoo Linux yet? Discover the power of a from-source meta-distribution optimized for your hardware! See our installation instructions and browse our CPU-optimized builds.

Funtoo News

Drobbins

ARM Rebuild

ARM systems will use new stage3's that are not compatible with earlier versions.
2015-06-27 by Drobbins
Drobbins

ABI X86 64 and 32

Funtoo Linux has new 32-bit compatibility libraries inherited from Gentoo. Learn about them here.
2015-06-18 by Drobbins
Drobbins

Pre-built kernels!

Funtoo stage3's are now starting to offer pre-built kernels for ease of install. read more....
2015-05-12 by Drobbins
More...

More Articles

Browse all our Linux-related articles, below:

A

B

F

G

K

L

M

O

P

S

T

W

X