3.16.61-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Amir Goldstein <amir73il@xxxxxxxxx> commit 833a950882d33a7dfc319d5e152fdf35028936eb upstream. Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx> Signed-off-by: Theodore Ts'o <tytso@xxxxxxx> Reviewed-by: Jan Kara <jack@xxxxxxx> [bwh: Backported to 3.16: - Move up declaration of ret in ext4_file_open() - Adjust context] Signed-off-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx> --- fs/ext4/file.c | 82 ++++++++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 36 deletions(-) --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -208,52 +208,64 @@ static int ext4_file_mmap(struct file *f return 0; } -static int ext4_file_open(struct inode * inode, struct file * filp) +static int ext4_sample_last_mounted(struct super_block *sb, + struct vfsmount *mnt) { - 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 ext4_sb_info *sbi = EXT4_SB(sb); struct path path; char buf[64], *cp; + handle_t *handle; + int err; + + if (likely(sbi->s_mount_flags & EXT4_MF_MNTDIR_SAMPLED)) + return 0; + + if (sb->s_flags & MS_RDONLY) + return 0; + + 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; + path.dentry = mnt->mnt_root; + cp = d_path(&path, buf, sizeof(buf)); + if (IS_ERR(cp)) + return 0; + + handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1); + if (IS_ERR(handle)) + return PTR_ERR(handle); + BUFFER_TRACE(sbi->s_sbh, "get_write_access"); + err = ext4_journal_get_write_access(handle, sbi->s_sbh); + if (err) + goto out; + strlcpy(sbi->s_es->s_last_mounted, cp, + sizeof(sbi->s_es->s_last_mounted)); + ext4_handle_dirty_super(handle, sb); +out: + ext4_journal_stop(handle); + return err; +} + +static int ext4_file_open(struct inode * inode, struct file * filp) +{ + int ret; + + ret = ext4_sample_last_mounted(inode->i_sb, filp->f_path.mnt); + if (ret) + return ret; - 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; - path.dentry = mnt->mnt_root; - cp = d_path(&path, buf, sizeof(buf)); - if (!IS_ERR(cp)) { - handle_t *handle; - int err; - - handle = ext4_journal_start_sb(sb, EXT4_HT_MISC, 1); - if (IS_ERR(handle)) - return PTR_ERR(handle); - BUFFER_TRACE(sbi->s_sbh, "get_write_access"); - err = ext4_journal_get_write_access(handle, sbi->s_sbh); - if (err) { - ext4_journal_stop(handle); - return err; - } - strlcpy(sbi->s_es->s_last_mounted, cp, - sizeof(sbi->s_es->s_last_mounted)); - ext4_handle_dirty_super(handle, sb); - ext4_journal_stop(handle); - } - } /* * Set up the jbd2_inode if we are opening the inode for * writing and the journal is present */ if (filp->f_mode & FMODE_WRITE) { - int ret = ext4_inode_attach_jinode(inode); + ret = ext4_inode_attach_jinode(inode); if (ret < 0) return ret; }