Skip to content

Commit bc0b0d6

Browse files
committed
ext4: update the s_last_mounted field in the superblock
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>
1 parent 7f4520c commit bc0b0d6

2 files changed

Lines changed: 42 additions & 1 deletion

File tree

fs/ext4/ext4.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,12 @@ struct ext4_super_block {
834834
};
835835

836836
#ifdef __KERNEL__
837+
838+
/*
839+
* Mount flags
840+
*/
841+
#define EXT4_MF_MNTDIR_SAMPLED 0x0001
842+
837843
/*
838844
* fourth extended-fs super-block data in memory
839845
*/
@@ -853,6 +859,7 @@ struct ext4_sb_info {
853859
struct ext4_super_block *s_es; /* Pointer to the super block in the buffer */
854860
struct buffer_head **s_group_desc;
855861
unsigned int s_mount_opt;
862+
unsigned int s_mount_flags;
856863
ext4_fsblk_t s_sb_block;
857864
uid_t s_resuid;
858865
gid_t s_resgid;

fs/ext4/file.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include <linux/time.h>
2222
#include <linux/fs.h>
2323
#include <linux/jbd2.h>
24+
#include <linux/mount.h>
25+
#include <linux/path.h>
2426
#include "ext4.h"
2527
#include "ext4_jbd2.h"
2628
#include "xattr.h"
@@ -145,6 +147,38 @@ static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
145147
return 0;
146148
}
147149

150+
static int ext4_file_open(struct inode * inode, struct file * filp)
151+
{
152+
struct super_block *sb = inode->i_sb;
153+
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
154+
struct vfsmount *mnt = filp->f_path.mnt;
155+
struct path path;
156+
char buf[64], *cp;
157+
158+
if (unlikely(!(sbi->s_mount_flags & EXT4_MF_MNTDIR_SAMPLED) &&
159+
!(sb->s_flags & MS_RDONLY))) {
160+
sbi->s_mount_flags |= EXT4_MF_MNTDIR_SAMPLED;
161+
/*
162+
* Sample where the filesystem has been mounted and
163+
* store it in the superblock for sysadmin convenience
164+
* when trying to sort through large numbers of block
165+
* devices or filesystem images.
166+
*/
167+
memset(buf, 0, sizeof(buf));
168+
path.mnt = mnt->mnt_parent;
169+
path.dentry = mnt->mnt_mountpoint;
170+
path_get(&path);
171+
cp = d_path(&path, buf, sizeof(buf));
172+
path_put(&path);
173+
if (!IS_ERR(cp)) {
174+
memcpy(sbi->s_es->s_last_mounted, cp,
175+
sizeof(sbi->s_es->s_last_mounted));
176+
sb->s_dirt = 1;
177+
}
178+
}
179+
return generic_file_open(inode, filp);
180+
}
181+
148182
const struct file_operations ext4_file_operations = {
149183
.llseek = generic_file_llseek,
150184
.read = do_sync_read,
@@ -156,7 +190,7 @@ const struct file_operations ext4_file_operations = {
156190
.compat_ioctl = ext4_compat_ioctl,
157191
#endif
158192
.mmap = ext4_file_mmap,
159-
.open = generic_file_open,
193+
.open = ext4_file_open,
160194
.release = ext4_release_file,
161195
.fsync = ext4_sync_file,
162196
.splice_read = generic_file_splice_read,

0 commit comments

Comments
 (0)