Ffs: Difference between revisions

From Hackepedia
Jump to navigationJump to search
No edit summary
m →‎Intro: link
 
(22 intermediate revisions by the same user not shown)
Line 1: Line 1:
The Berkeley FFS resides on a disk [[partition]] in blocks greater or equal to 4096 bytes (no less).  It has a super block that contains filesystem specific data (eg. when the last [[fsck]] took place) which is at block 0.  It also has backup superblocks in case the first superblock is corrupted ([[fsck]] -b to repair a broken superblock and check the filesystem with an alternate superblock), the next superblock is at block 32 and the others are made known at [[newfs]] time.
== Intro ==
 
The Berkeley FFS was written by Marshall Kirk McKusick for 4.2BSD at [[UCB]].  It resides on a disk [[partition]] in blocks greater or equal to 4096 bytes (no less).  It has a super block that contains filesystem specific data (eg. when the last [[fsck]] took place, use dumpfs(8) to display the superblock, this is a very long listing) which is at block 0.  It also has backup superblocks in case the first superblock is corrupted ([[fsck]] -b to repair a broken superblock and check the filesystem with an alternate superblock), the next superblock is at block 32 and the others are made known at [[newfs]] time.


  # newfs /dev/rsvnd0a
  # newfs /dev/rsvnd0a
Line 11: Line 13:
Here in the example the backups are 32, 25032 and 50032.  To find out the alternate superblocks after a filesystem has already been created use [[newfs]] -N.   
Here in the example the backups are 32, 25032 and 50032.  To find out the alternate superblocks after a filesystem has already been created use [[newfs]] -N.   


Next (not counting the super-blocks) the filesystem is split into 2 parts.  One for a long sequence of [[inode]]s and the other for data.  The inodes are the reference points for objects and data in the filesystem and they hold information such as permissions, file link count, file size, [[atime]], [[mtime]], [[ctime]], disk blocks used by file, chflags, file owner and file group.  The size of a UFS1 inode is 128 bytes.  By default an inode exists for every 8192 bytes of filesystem space, this is tweakable with [[newfs]].
Next (not counting the super-blocks) the filesystem is split into 2 different parts.  One part is data and the other is meta-data ([[inode|inodes]]).  The way inodes are placed on the disk is original, the cylinders on the disk are placed in cylinder groups and each cylinder group holds inodes and data, inodes at the beginning of the cylinder group and data after.  The inodes are the reference points for objects and data in the filesystem and they hold information such as:


For more information on FFS see [http://www.cs.berkeley.edu/~brewer/cs262/FFS.pdf A fast filesystem for UNIX].
*[[permissions]]
*file link count
*file size
*[[atime]]
*[[mtime]]
*[[ctime]]
*references to blocks of data
*number disk blocks used by file
*chflags
*file owner
*file group 


The data an inode holds is also called '''metadata'''.  The size of a UFS1 inode is 128 bytes.  By default an inode exists for every 8192 bytes of filesystem space, this is tweakable with [[newfs]] when the filesystem is first created.  To save the tweaked filesystem in a backup one could use dumpfs with the -m option to dump the exact newfs command to create a similar filesystem (neat feature).


=== A breakdown of a disk ===
The inode in FFS does not store the filename, that has to be read out of the data of a directory which contains entries of filenames up to 255 bytes long not including the NUL terminator and also has the inode number stored for reference back to the [[inode]] and thus the data of a file.  Lookup always starts at the root of the system which is usually inode number 2 in FFS:


I created a virtual disk, it is 32MB big:
$ ls -lid /
2 drwxr-xr-x  17 root  wheel  512 Oct 25 22:39 /
^


  # ls -lh disk
This way the path of a program is traversed until the file is found and then the [[inode]] of the file is identified. The system uses a caching mechanism to speed up consecutive lookups of filenames in a path.
-rw-r--r--  1 root  wheel  32.0M Oct 28 08:55 disk


WTF? It's a file!  Ok so lets make it a disk device:
For more information on FFS see [http://www.cs.berkeley.edu/~brewer/cs262/FFS.pdf A fast filesystem for UNIX].


# vnconfig -cv svnd0 disk
== UFS2 ==
svnd0: 33554432 bytes on disk


let's make a new partition on it called a:
[[FreeBSD]] and [[NetBSD]] have a second version of FFS that allows [[filesystem]] sizes greater than 1 TB. This is UFS2. The size of an UFS2 inode is 256 bytes and thus UFS1 and UFS2 are not compatible.
 
# disklabel -E /dev/rsvnd0c
disklabel: Can't get bios geometry: Device not configured
Initial label editor (enter '?' for help at any prompt)
> a
partition: [a]  
offset: [0]
size: [65536]  
FS type: [4.2BSD]  
> p a
device: /dev/rsvnd0c
type: SCSI
disk: vnd device
label: fictitious
bytes/sector: 512
sectors/track: 100
tracks/cylinder: 1
sectors/cylinder: 100
cylinders: 655
total sectors: 65536
free sectors: 0
rpm: 3600
16 partitions:
#            size        offset  fstype [fsize bsize  cpg]
  a:        65536            0  4.2BSD  2048 16384  16 # Cyl    0 -  655*
  c:        65536            0  unused      0    0      # Cyl    0 -  655*
> q
Write new label?: [y] y
#
 
Now write the filesystem on it with [[newfs]]:
 
  # newfs /dev/rsvnd0a
  Warning: cylinder groups must have a multiple of 8 cylinders
Warning: 64 sector(s) in last cylinder unallocated
/dev/rsvnd0a:  65536 sectors in 656 cylinders of 1 tracks, 100 sectors
        32.0MB in 1 cyl groups (656 c/g, 32.03MB/g, 4096 i/g)
super-block backups (for fsck -b #) at:
  32,


mount the new filesystem to /mnt:


# mount /dev/svnd0a /mnt
== Growing an FFS filesystem ==
# df /mnt
Filesystem  512-blocks      Used    Avail Capacity  Mounted on
/dev/svnd0a      64412        4    61188    0%    /mnt
# df -i /mnt
Filesystem  512-blocks      Used    Avail Capacity iused  ifree  %iused  Mounted on
/dev/svnd0a      64412        4    61188    0%      1    4093    0%  /mnt
OK let's count it up, we have 65536 blocks in total for the disk, 4094 inodes exist at 128 bytes size which is 1023 blocks, and we have 2 superblocks (0 and 32) which are 16384 bytes big each or 32 blocks, then the filesystem space claims 64412 blocks, this gives us a total of 65499 blocks which isn't quite the complete disksize of 65536 blocks, however I left the disklabel unaccounted for which also takes up some space.


Now let's fill the drive:
If you happen to have a partition that doesn't use up the entire disk, it is possible to grow this filesystem.  Before [[FreeBSD]] 4.4 this was not possible.  Here is [[growfs|the breakdown on how to grow an ffs filesystem]].


$ dd if=/dev/zero of=fill bs=1
== Soft Updates ==
/mnt: write failed, file system is full
dd: fill: No space left on device
31326209+0 records in
31326208+0 records out
31326208 bytes transferred in 40.458 secs (774289 bytes/sec)
$ df /mnt
Filesystem  512-blocks      Used    Avail Capacity  Mounted on
/dev/svnd0a      64412    61220      -28  100%    /mnt


100% capacity, but the used blocks aren't all the blocks that the filesystem claims, so let's repeat that last step but this time as [[root]]:
What are Soft Updates?  A paper outlining its use and implementation is [http://www.usenix.org/publications/library/proceedings/usenix99/mckusick.html here].
 
# dd if=/dev/zero of=fill bs=1
/mnt: write failed, file system is full
dd: fill: No space left on device
32931841+0 records in
32931840+0 records out
32931840 bytes transferred in 44.276 secs (743779 bytes/sec)
# df /mnt
Filesystem  512-blocks      Used    Avail Capacity  Mounted on
/dev/svnd0a      64412    64356    -3164  105%    /mnt
 
Lovely almost all used up and it can't go further.  Note that we're using up '''105% capacity''' this is built into ffs and can be tweaked at [[newfs]] time.  The superuser gets 5% above 100% of capacity noone else.
 
 
=== UFS2 ===
 
[[FreeBSD]] and [[NetBSD]] have a second version of FFS that allows [[filesystem]] sizes greater than 1 TB.  This is UFS2. The size of an UFS2 inode is 256 bytes and thus UFS1 and UFS2 are not compatible.
 
=== Soft Updates ===


You will want to check out soft-updates if you have ffs, and most likely install it on all partitions except / (example for [[FreeBSD]]):
You will want to check out soft-updates if you have ffs, and most likely install it on all partitions except / (example for [[FreeBSD]]):
Line 133: Line 71:
  /dev/wd0d on /var type ffs (local, nodev, nosuid, softdep)
  /dev/wd0d on /var type ffs (local, nodev, nosuid, softdep)
  mfs:22707 on /tmp type mfs (asynchronous, local, nodev, nosuid, size=261120 512-blocks)
  mfs:22707 on /tmp type mfs (asynchronous, local, nodev, nosuid, size=261120 512-blocks)
Side effects of having soft updates on the / filesystem are that a new kernel written to /bsd shortly before a panic will be corrupted requiring the next boot off a backup of the kernel.
== Magic Numbers ==
In the file /usr/include/ufs/ffs/fs.h
#define FS_MAGIC        0x011954        /* the fast filesystem magic number */
#define FS_UFS1_MAGIC  0x011954        /* the fast filesystem magic number */
#define FS_UFS2_MAGIC  0x19540119      /* UFS fast filesystem magic number */
We suspect these magic numbers are the ffs authors birthdays (in hex). ;-)

Latest revision as of 05:05, 5 June 2008

Intro

The Berkeley FFS was written by Marshall Kirk McKusick for 4.2BSD at UCB. It resides on a disk partition in blocks greater or equal to 4096 bytes (no less). It has a super block that contains filesystem specific data (eg. when the last fsck took place, use dumpfs(8) to display the superblock, this is a very long listing) which is at block 0. It also has backup superblocks in case the first superblock is corrupted (fsck -b to repair a broken superblock and check the filesystem with an alternate superblock), the next superblock is at block 32 and the others are made known at newfs time.

# newfs /dev/rsvnd0a
Warning: cylinder groups must have a multiple of 2 cylinders
Warning: 64 sector(s) in last cylinder unallocated
/dev/rsvnd0a:   65536 sectors in 656 cylinders of 1 tracks, 100 sectors
        32.0MB in 3 cyl groups (250 c/g, 12.21MB/g, 3136 i/g)
super-block backups (for fsck -b #) at:
 32, 25032, 50032,

Here in the example the backups are 32, 25032 and 50032. To find out the alternate superblocks after a filesystem has already been created use newfs -N.

Next (not counting the super-blocks) the filesystem is split into 2 different parts. One part is data and the other is meta-data (inodes). The way inodes are placed on the disk is original, the cylinders on the disk are placed in cylinder groups and each cylinder group holds inodes and data, inodes at the beginning of the cylinder group and data after. The inodes are the reference points for objects and data in the filesystem and they hold information such as:

  • permissions
  • file link count
  • file size
  • atime
  • mtime
  • ctime
  • references to blocks of data
  • number disk blocks used by file
  • chflags
  • file owner
  • file group

The data an inode holds is also called metadata. The size of a UFS1 inode is 128 bytes. By default an inode exists for every 8192 bytes of filesystem space, this is tweakable with newfs when the filesystem is first created. To save the tweaked filesystem in a backup one could use dumpfs with the -m option to dump the exact newfs command to create a similar filesystem (neat feature).

The inode in FFS does not store the filename, that has to be read out of the data of a directory which contains entries of filenames up to 255 bytes long not including the NUL terminator and also has the inode number stored for reference back to the inode and thus the data of a file. Lookup always starts at the root of the system which is usually inode number 2 in FFS:

$ ls -lid /
2 drwxr-xr-x  17 root  wheel  512 Oct 25 22:39 /
^

This way the path of a program is traversed until the file is found and then the inode of the file is identified. The system uses a caching mechanism to speed up consecutive lookups of filenames in a path.

For more information on FFS see A fast filesystem for UNIX.

UFS2

FreeBSD and NetBSD have a second version of FFS that allows filesystem sizes greater than 1 TB. This is UFS2. The size of an UFS2 inode is 256 bytes and thus UFS1 and UFS2 are not compatible.


Growing an FFS filesystem

If you happen to have a partition that doesn't use up the entire disk, it is possible to grow this filesystem. Before FreeBSD 4.4 this was not possible. Here is the breakdown on how to grow an ffs filesystem.

Soft Updates

What are Soft Updates? A paper outlining its use and implementation is here.

You will want to check out soft-updates if you have ffs, and most likely install it on all partitions except / (example for FreeBSD):

$ less -XF /usr/src/sys/contrib/softupdates/README

To see if you have soft-updates enabled: on FreeBSD:

$ mount 
/dev/ad0s1a on / (ufs, local)
devfs on /dev (devfs, local)
/dev/ad0s1g on /backup (ufs, local, soft-updates)
/dev/ad0s1e on /tmp (ufs, local, soft-updates)
/dev/ad0s1f on /usr (ufs, local, soft-updates)
/dev/ad0s1d on /var (ufs, local, soft-updates)

on OpenBSD

$  mount
/dev/wd0a on / type ffs (local, softdep)
/dev/wd0e on /usr type ffs (NFS exported, local, nodev, softdep)
/dev/wd0d on /var type ffs (local, nodev, nosuid, softdep)
mfs:22707 on /tmp type mfs (asynchronous, local, nodev, nosuid, size=261120 512-blocks)

Side effects of having soft updates on the / filesystem are that a new kernel written to /bsd shortly before a panic will be corrupted requiring the next boot off a backup of the kernel.

Magic Numbers

In the file /usr/include/ufs/ffs/fs.h

#define FS_MAGIC        0x011954        /* the fast filesystem magic number */
#define FS_UFS1_MAGIC   0x011954        /* the fast filesystem magic number */
#define FS_UFS2_MAGIC   0x19540119      /* UFS fast filesystem magic number */

We suspect these magic numbers are the ffs authors birthdays (in hex). ;-)