diff options
-rw-r--r-- | fs/ext4/file.c | 82 |
1 files changed, 46 insertions, 36 deletions
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 655d1c7bc614..c48ea76b63e4 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
@@ -381,50 +381,60 @@ static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
381 | return 0; | 381 | return 0; |
382 | } | 382 | } |
383 | 383 | ||
384 | static int ext4_file_open(struct inode * inode, struct file * filp) | 384 | static int ext4_sample_last_mounted(struct super_block *sb, |
385 | struct vfsmount *mnt) | ||
385 | { | 386 | { |
386 | struct super_block *sb = inode->i_sb; | 387 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
387 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | ||
388 | struct vfsmount *mnt = filp->f_path.mnt; | ||
389 | struct path path; | 388 | struct path path; |
390 | char buf[64], *cp; | 389 | char buf[64], *cp; |
390 | handle_t *handle; | ||
391 | int err; | ||
392 | |||
393 | if (likely(sbi->s_mount_flags & EXT4_MF_MNTDIR_SAMPLED)) | ||
394 | return 0; | ||
395 | |||
396 | if (sb_rdonly(sb)) | ||
397 | return 0; | ||
398 | |||
399 | sbi->s_mount_flags |= EXT4_MF_MNTDIR_SAMPLED; | ||
400 | /* | ||
401 | * Sample where the filesystem has been mounted and | ||
402 | * store it in the superblock for sysadmin convenience | ||
403 | * when trying to sort through large numbers of block | ||
404 | * devices or filesystem images. | ||
405 | */ | ||
406 | memset(buf, 0, sizeof(buf)); | ||
407 | path.mnt = mnt; | ||
408 | path.dentry = mnt->mnt_root; | ||
409 | cp = d_path(&path, buf, sizeof(buf)); | ||
410 | if (IS_ERR(cp)) | ||
411 | return 0; | ||
412 | |||
413 | handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1); | ||
414 | if (IS_ERR(handle)) | ||
415 | return PTR_ERR(handle); | ||
416 | BUFFER_TRACE(sbi->s_sbh, "get_write_access"); | ||
417 | err = ext4_journal_get_write_access(handle, sbi->s_sbh); | ||
418 | if (err) | ||
419 | goto out; | ||
420 | strlcpy(sbi->s_es->s_last_mounted, cp, | ||
421 | sizeof(sbi->s_es->s_last_mounted)); | ||
422 | ext4_handle_dirty_super(handle, sb); | ||
423 | out: | ||
424 | ext4_journal_stop(handle); | ||
425 | return err; | ||
426 | } | ||
427 | |||
428 | static int ext4_file_open(struct inode * inode, struct file * filp) | ||
429 | { | ||
391 | int ret; | 430 | int ret; |
392 | 431 | ||
393 | if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) | 432 | if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) |
394 | return -EIO; | 433 | return -EIO; |
395 | 434 | ||
396 | if (unlikely(!(sbi->s_mount_flags & EXT4_MF_MNTDIR_SAMPLED) && | 435 | ret = ext4_sample_last_mounted(inode->i_sb, filp->f_path.mnt); |
397 | !sb_rdonly(sb))) { | 436 | if (ret) |
398 | sbi->s_mount_flags |= EXT4_MF_MNTDIR_SAMPLED; | 437 | return ret; |
399 | /* | ||
400 | * Sample where the filesystem has been mounted and | ||
401 | * store it in the superblock for sysadmin convenience | ||
402 | * when trying to sort through large numbers of block | ||
403 | * devices or filesystem images. | ||
404 | */ | ||
405 | memset(buf, 0, sizeof(buf)); | ||
406 | path.mnt = mnt; | ||
407 | path.dentry = mnt->mnt_root; | ||
408 | cp = d_path(&path, buf, sizeof(buf)); | ||
409 | if (!IS_ERR(cp)) { | ||
410 | handle_t *handle; | ||
411 | int err; | ||
412 | |||
413 | handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1); | ||
414 | if (IS_ERR(handle)) | ||
415 | return PTR_ERR(handle); | ||
416 | BUFFER_TRACE(sbi->s_sbh, "get_write_access"); | ||
417 | err = ext4_journal_get_write_access(handle, sbi->s_sbh); | ||
418 | if (err) { | ||
419 | ext4_journal_stop(handle); | ||
420 | return err; | ||
421 | } | ||
422 | strlcpy(sbi->s_es->s_last_mounted, cp, | ||
423 | sizeof(sbi->s_es->s_last_mounted)); | ||
424 | ext4_handle_dirty_super(handle, sb); | ||
425 | ext4_journal_stop(handle); | ||
426 | } | ||
427 | } | ||
428 | 438 | ||
429 | ret = fscrypt_file_open(inode, filp); | 439 | ret = fscrypt_file_open(inode, filp); |
430 | if (ret) | 440 | if (ret) |