Everything Penguin

Focusing on Linux-based Operating Systems
htDig Search:

Operating Systems
  • /pub/OS/Linux

  • Storage
  • File Systems
  • HPC
  • /pub/Storage

  • Networking
  • /pub/Networking

  • Network Services
  • /pub/NetworkServices

  • Security
  • /pub/Security
  • Keytool/OpenSSL

  • Clustering
  • HA
  • DRM

  • Development
  • Design
  • C/C++
  • Java
  • Perl
  • Python
  • Shell
  • Web / J2EE

  • Not Linux ?
  • BSD
  • HP-UX
  • Mac
  • Solaris
  • VM
  • Windows
  • /pub/OS

  • Other
  • /pub
  • /pub/3rdParty
  •  Parent Directory

    Linux Inodes - Notes about atime, ctime, mtime, and more...
    Brett Lee
    An inode for a file contains information about the file.  In fact, it contains
      most everything about a file.  One item of note is not there.
      Can you guess what it is?  If you don't know, keep reading to find out.
    Some interesting attributes associate with a file are:
      atime : last time the file was accessed (read)
      mtime : last time the file was modified
      ctime : last time the *inode* was modified
    How do we look at these values?  Different ways.
    1.  The "ls" way:
        ls -l  : mtime
        ls -lc : ctime
        ls -lu : atime (u? - maybe think of it as "used")
    2.  The "stat" function from your favorite language (C, Perl, Java)
        Here is an example from Perl:
    #!/usr/bin/perl -w
    # These values exist in the Inode:
    #   ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime,
    #    $mtime, $ctime, $blksize, $blocks) = stat( $filename );
    use strict;
    use File::stat;
    sub usage() { print("Usage $0 <filename>\n"); exit; }
    if ( $#ARGV < 0 ) { usage; }
    my ($inode, $ctime, $mtime, $atime, $filename);
    $filename = shift;
    $inode = stat( $filename );
    $ctime = $inode->ctime;
    $mtime = $inode->mtime;
    $atime = $inode->atime;
    print("ctime: " . $ctime . "\n");
    print("mtime: " . $mtime . "\n");
    print("atime: " . $atime . "\n");
    3.  The "debugfs" command:
    [root@daffy inode]# debugfs /dev/sda3
    debugfs 1.32 (09-Nov-2002)
    debugfs:  stat /tmp/inode/file
    Inode: 50375   Type: regular    Mode:  0644   Flags: 0x0   Generation: 3183639857
    User:     0   Group:     0   Size: 2
    File ACL: 0    Directory ACL: 0
    Links: 2   Blockcount: 8
    Fragment:  Address: 0    Number: 0    Size: 0
    ctime: 0x46d48ee9 -- Tue Aug 28 14:08:57 2007
    atime: 0x46d4873c -- Tue Aug 28 14:36:12 2007
    mtime: 0x46d48ee9 -- Tue Aug 28 14:08:57 2007
    TOTAL: 1
    Most folks are familiar with the Unix "find" command and the ability to pass in
    values like:
      -mtime +365 (not updated for a year)
      -atime -1   (read in the last day)
    Now, thinking about the definitions above for atime, ctime and mtime, which
    would you expect to change when you:
      1. cat the file ?
      2. rename the file ?
      3. vi the file, not making changes ?
      4. chmod the file ?
      5. update the file ?
    Let's look at each of these and briefly discuss.
    The "time" value that changes is specified in parentheses:
      1. cat the file (atime)
         In this case the file is read, which means that the inode reference that
         points to the first block of the file was "accessed".  So it makes sense
         that access time (atime) alone is updated.  Nothing is changed in the file
         and nothing is changed in the inode - well, sort of.  The inode will
         contain a new timestamp for the atime, but that "doesn't count" when it
         comes to changing the inode.  Instead, changes to ctime are relagated to
         changing other parts of the inode (owner, permissions) or the content of
         the file itself (and thus mtime).  Time for a short quiz.
    Short Quiz:
    Below is an example of a file (echo "1" > file) viewed with "stat":
    [root@daffy inode]# debugfs /dev/sda3
    debugfs 1.32 (09-Nov-2002)
    debugfs:  stat /tmp/inode/file
    Inode: 50375   Type: regular    Mode:  0644   Flags: 0x0   Generation: 3183639857
    User:     0   Group:     0   Size: 2
    File ACL: 0    Directory ACL: 0
    Links: 2   Blockcount: 8
    Fragment:  Address: 0    Number: 0    Size: 0
    ctime: 0x46d48ee9 -- Thu Jan 01 14:08:57 1970
    atime: 0x46d4873c -- Thu Jan 01 14:36:12 1970
    mtime: 0x46d48ee9 -- Thu Jan 01 14:08:57 1970
    TOTAL: 1
    This file was changed by this command (echo "2" > file) without changing its
    size.  See if you can spot the (non-time) inode difference from above:
    Inode: 50375   Type: regular    Mode:  0644   Flags: 0x0   Generation: 3183639857
    User:     0   Group:     0   Size: 2
    File ACL: 0    Directory ACL: 0
    Links: 2   Blockcount: 8
    Fragment:  Address: 0    Number: 0    Size: 0
    ctime: 0x46d48f6e -- Thu Jan 01 15:11:10 1970
    atime: 0x46d4873c -- Thu Jan 01 14:36:12 1970
    mtime: 0x46d48f6e -- Thu Jan 01 15:11:10 1970
    TOTAL: 1
    Yep!!  Near the end the block number has change.  It has been written back
    to a different block.
    As you can see there is more to an inode than just the timestamps.
    Here are a list of a few things to look for in the inode:
    TYPE_OF_FILE (regular, device, etc.)
    LAST CHANGED (inode)
    Point to remember, if any of these items changes (except atime) the inode
    will be considered changed, and thus ctime will be updated.
    And now, back to our topic!
      2. rename the file (nothing, none, nada, zip, nix)
         Althought it seems obvious that the inode should change since the
         filename is changed, it turns out that the filename is *NOT* stored in
         the inode.  If you paid attention to the quiz, you got this one right.
         If you didn't, now would be a good time to review the quiz.
         So where *is* the filename stored?  In the inode for the directory that
         this file is in, of course.  Yep, directories have an inode.  It's just
         a different type; one that maintains a mapping between filenames and file
         inodes.  This mapping is in a fixed size array, defined when the
         filesystem is created.
         So, how does this work?  Lets say you want to execute a file in 
         /usr/local/bin.  Well, the kernel works in inodes and not paths, so 
         it first finds the directory inode associate with /.  It searches that
         inode for an entry for "usr", and upon finding one it learns of both the
         inode number of "usr" and the block (offset) where that inode can be
         found.  It reads that block, locates the inode, and reads the inode
         looking for an entry for "local."  (Of course, each step of the way it is
         checking permissions to see if the effective UID/GID has the permission
         to read the inode.)  Anyway, the process continues until the file is
         found and executed.
         And while we're on the subject, what do we see in a directory listing
         that doesn't have its own inode?  Answer, hard links.  When I'm referring
         to a hard link, I'm talking about additional hard links to a file after
         the initial one.  Hard links register their name in the directory inode
         as a second name to the same inode, and they also update the link count
         in the inode of what they are linked to.  Since the directory only has
         a reference to an inode, it cannot point to another filesystem.  That's
         where symbolic links come in - they contain yet another type of inode
         that contains a UNIX path to the destination.
      3. vi the file, but don't save any changes back (atime)
         Assuming you do not write the file back to disk, only the atime is updated
         for the same reason as 'cat'.
      4. chmod the file (ctime)
         In this case, the file is not read nor modified, so atime and mtime will
         not change.  The permissions (contained in the inode) are changed, so only
         ctime will change.
      5. vi the file, make save changes to file (atime, mtime, ctime)
         In this case, the file will be read, so atime will be changed.  The
         file will also be modified, so mtime will be updated.  And per #1, a
         modification to the file itself implies a change to the inode, so
         ctime will change also.
         Yep, the Full Monty! :)

    Other Sites

  • FAQ's
  • IETF
  • RFC Sourcebook

  • Linux
  • Linux - Intro
  • Linux Kernel
  • Linux Kernel (LKML)
  • Bash - Intro
  • Bash - Advanced
  • Command Line
  • System Administration
  • Network Administration
  • Man Pages (& more)
  • More Guides
  • Red Hat Manuals
  • HOWTO's

  • Reference/Tutorials
  • C++ @ cppreference
  • C++ @ cplusplus
  • CSS @ echoecho
  • DNS @ Zytrax
  • HTML @ W3 Schools
  • Java @ Sun
  • LDAP @ Zytrax
  • Linux @ YoLinux
  • MySQL
  • NetFilter
  • Network Protocols
  • OpenLDAP
  • Quagga
  • Samba
  • Unix Programming

  • This site contains many of my notes from research into different aspects of the Linux kernel as well as some of the software provided by GNU and others. Thouugh these notes are not fully comprehensive or even completetly accurate, they are part of my on-going attempt to better understand this complex field. And, they are your to use.

    Should you wish to report any errors or suggestions, please let me know.

    Should you wish to make a donation for anything you may have learned here, please direct that donation to the ASPCA, with my sincere thanks.

    Brett Lee
    Everything Penguin

    The code for this site, which is just a few CGI scripts, may be found on GitHub (https://github.com/userbrett/cgindex).

    For both data encryption and password protection, try Personal Data Security (https://www.trustpds.com).

    "We left all that stuff out. If there's an error, we have this routine called 'panic', and when its called, the machine crashes, and you holler down the hall, 'Hey, reboot it.'"

        - Dennis Ritchie on Unix (vs Multics)

    [ Powered by Red Hat Linux ] [ Powered by Apache Server] [ Powered by MySQL ]

    [ Statistics by AWStats ]