]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
ext4: update the s_last_mounted field in the superblock
authorTheodore Ts'o <tytso@mit.edu>
Sat, 13 Jun 2009 14:09:48 +0000 (10:09 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 13 Jun 2009 14:09:48 +0000 (10:09 -0400)
This field can be very helpful when a system administrator is trying
to sort through large numbers of block devices or filesystem images.
What is stored in this field can be ambiguous if multiple filesystem
namespaces are in play; what we store in practice is the mountpoint
interpreted by the process's namespace which first opens a file in the
filesystem.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
fs/ext4/ext4.h
fs/ext4/file.c

index 569f527080bf6f0e95143e6de37ab03e49525296..9e268c97eeca9013a7bb4bf28182f053be7c6cae 100644 (file)
@@ -834,6 +834,12 @@ struct ext4_super_block {
 };
 
 #ifdef __KERNEL__
+
+/*
+ * Mount flags
+ */
+#define EXT4_MF_MNTDIR_SAMPLED 0x0001
+
 /*
  * fourth extended-fs super-block data in memory
  */
@@ -853,6 +859,7 @@ struct ext4_sb_info {
        struct ext4_super_block *s_es;  /* Pointer to the super block in the buffer */
        struct buffer_head **s_group_desc;
        unsigned int s_mount_opt;
+       unsigned int s_mount_flags;
        ext4_fsblk_t s_sb_block;
        uid_t s_resuid;
        gid_t s_resgid;
index 588af8c77246f71b9a2b088602dba33b88c43f52..3f1873fef1c64240db9b2b32cb4909ce4349d088 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/jbd2.h>
+#include <linux/mount.h>
+#include <linux/path.h>
 #include "ext4.h"
 #include "ext4_jbd2.h"
 #include "xattr.h"
@@ -145,6 +147,38 @@ static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
        return 0;
 }
 
+static int ext4_file_open(struct inode * inode, struct file * filp)
+{
+       struct super_block *sb = inode->i_sb;
+       struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+       struct vfsmount *mnt = filp->f_path.mnt;
+       struct path path;
+       char buf[64], *cp;
+
+       if (unlikely(!(sbi->s_mount_flags & EXT4_MF_MNTDIR_SAMPLED) &&
+                    !(sb->s_flags & MS_RDONLY))) {
+               sbi->s_mount_flags |= EXT4_MF_MNTDIR_SAMPLED;
+               /*
+                * Sample where the filesystem has been mounted and
+                * store it in the superblock for sysadmin convenience
+                * when trying to sort through large numbers of block
+                * devices or filesystem images.
+                */
+               memset(buf, 0, sizeof(buf));
+               path.mnt = mnt->mnt_parent;
+               path.dentry = mnt->mnt_mountpoint;
+               path_get(&path);
+               cp = d_path(&path, buf, sizeof(buf));
+               path_put(&path);
+               if (!IS_ERR(cp)) {
+                       memcpy(sbi->s_es->s_last_mounted, cp,
+                              sizeof(sbi->s_es->s_last_mounted));
+                       sb->s_dirt = 1;
+               }
+       }
+       return generic_file_open(inode, filp);
+}
+
 const struct file_operations ext4_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = do_sync_read,
@@ -156,7 +190,7 @@ const struct file_operations ext4_file_operations = {
        .compat_ioctl   = ext4_compat_ioctl,
 #endif
        .mmap           = ext4_file_mmap,
-       .open           = generic_file_open,
+       .open           = ext4_file_open,
        .release        = ext4_release_file,
        .fsync          = ext4_sync_file,
        .splice_read    = generic_file_splice_read,