From a1177825719ccef3f76ef39bbfd5ebb6087d53c7 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 3 Jul 2012 16:45:29 +0200 Subject: quota: Move quota syncing to ->sync_fs method Since the moment writes to quota files are using block device page cache and space for quota structures is reserved at the moment they are first accessed we have no reason to sync quota before inode writeback. In fact this order is now only harmful since quota information can easily change during inode writeback (either because conversion of delayed-allocated extents or simply because of allocation of new blocks for simple filesystems not using page_mkwrite). So move syncing of quota information after writeback of inodes into ->sync_fs method. This way we do not have to use ->quota_sync callback which is primarily intended for use by quotactl syscall anyway and we get rid of calling ->sync_fs() twice unnecessarily. We skip quota syncing for OCFS2 since it does proper quota journalling in all cases (unlike ext3, ext4, and reiserfs which also support legacy non-journalled quotas) and thus there are no dirty quota structures. CC: "Theodore Ts'o" CC: Joel Becker CC: reiserfs-devel@vger.kernel.org Acked-by: Steven Whitehouse Acked-by: Dave Kleikamp Reviewed-by: Christoph Hellwig Signed-off-by: Jan Kara Signed-off-by: Al Viro --- fs/jfs/super.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'fs/jfs/super.c') diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 4a82950f412..c55c7452d28 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -601,6 +601,11 @@ static int jfs_sync_fs(struct super_block *sb, int wait) /* log == NULL indicates read-only mount */ if (log) { + /* + * Write quota structures to quota file, sync_blockdev() will + * write them to disk later + */ + dquot_writeback_dquots(sb, -1); jfs_flush_journal(log, wait); jfs_syncpt(log, 0); } -- cgit v1.2.3 From b40c2e665cd552eae5fbdbb878bc29a34357668e Mon Sep 17 00:00:00 2001 From: Tino Reichardt Date: Mon, 17 Sep 2012 11:58:19 -0500 Subject: fs/jfs: TRIM support for JFS Filesystem This patch adds support for the two linux interfaces of the discard/TRIM command for SSD devices and sparse/thinly-provisioned LUNs. JFS will support batched discard via FITRIM ioctl and online discard with the discard mount option. Signed-off-by: Tino Reichardt Signed-off-by: Dave Kleikamp --- fs/jfs/super.c | 71 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 15 deletions(-) (limited to 'fs/jfs/super.c') diff --git a/fs/jfs/super.c b/fs/jfs/super.c index c55c7452d28..6f4ac1c070f 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "jfs_incore.h" #include "jfs_filsys.h" @@ -100,7 +101,7 @@ void jfs_error(struct super_block *sb, const char * function, ...) vsnprintf(error_buf, sizeof(error_buf), function, args); va_end(args); - printk(KERN_ERR "ERROR: (device %s): %s\n", sb->s_id, error_buf); + pr_err("ERROR: (device %s): %s\n", sb->s_id, error_buf); jfs_handle_error(sb); } @@ -197,7 +198,8 @@ static void jfs_put_super(struct super_block *sb) enum { Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize, Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota, - Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask + Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask, + Opt_discard, Opt_nodiscard, Opt_discard_minblk }; static const match_table_t tokens = { @@ -214,6 +216,9 @@ static const match_table_t tokens = { {Opt_uid, "uid=%u"}, {Opt_gid, "gid=%u"}, {Opt_umask, "umask=%u"}, + {Opt_discard, "discard"}, + {Opt_nodiscard, "nodiscard"}, + {Opt_discard_minblk, "discard=%u"}, {Opt_err, NULL} }; @@ -255,8 +260,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, else { nls_map = load_nls(args[0].from); if (!nls_map) { - printk(KERN_ERR - "JFS: charset not found\n"); + pr_err("JFS: charset not found\n"); goto cleanup; } } @@ -272,8 +276,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, *newLVSize = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits; if (*newLVSize == 0) - printk(KERN_ERR - "JFS: Cannot determine volume size\n"); + pr_err("JFS: Cannot determine volume size\n"); break; } case Opt_errors: @@ -294,8 +297,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, *flag &= ~JFS_ERR_REMOUNT_RO; *flag |= JFS_ERR_PANIC; } else { - printk(KERN_ERR - "JFS: %s is an invalid error handler\n", + pr_err("JFS: %s is an invalid error handler\n", errors); goto cleanup; } @@ -314,8 +316,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, case Opt_usrquota: case Opt_grpquota: case Opt_quota: - printk(KERN_ERR - "JFS: quota operations not supported\n"); + pr_err("JFS: quota operations not supported\n"); break; #endif case Opt_uid: @@ -324,23 +325,61 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, sbi->uid = simple_strtoul(uid, &uid, 0); break; } + case Opt_gid: { char *gid = args[0].from; sbi->gid = simple_strtoul(gid, &gid, 0); break; } + case Opt_umask: { char *umask = args[0].from; sbi->umask = simple_strtoul(umask, &umask, 8); if (sbi->umask & ~0777) { - printk(KERN_ERR - "JFS: Invalid value of umask\n"); + pr_err("JFS: Invalid value of umask\n"); goto cleanup; } break; } + + case Opt_discard: + { + struct request_queue *q = bdev_get_queue(sb->s_bdev); + /* if set to 1, even copying files will cause + * trimming :O + * -> user has more control over the online trimming + */ + sbi->minblks_trim = 64; + if (blk_queue_discard(q)) { + *flag |= JFS_DISCARD; + } else { + pr_err("JFS: discard option " \ + "not supported on device\n"); + } + break; + } + + case Opt_nodiscard: + *flag &= ~JFS_DISCARD; + break; + + case Opt_discard_minblk: + { + struct request_queue *q = bdev_get_queue(sb->s_bdev); + char *minblks_trim = args[0].from; + if (blk_queue_discard(q)) { + *flag |= JFS_DISCARD; + sbi->minblks_trim = simple_strtoull( + minblks_trim, &minblks_trim, 0); + } else { + pr_err("JFS: discard option " \ + "not supported on device\n"); + } + break; + } + default: printk("jfs: Unrecognized mount option \"%s\" " " or missing value\n", p); @@ -374,8 +413,8 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data) if (newLVSize) { if (sb->s_flags & MS_RDONLY) { - printk(KERN_ERR - "JFS: resize requires volume to be mounted read-write\n"); + pr_err("JFS: resize requires volume" \ + " to be mounted read-write\n"); return -EROFS; } rc = jfs_extendfs(sb, newLVSize, 0); @@ -457,7 +496,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) #endif if (newLVSize) { - printk(KERN_ERR "resize option for remount only\n"); + pr_err("resize option for remount only\n"); goto out_kfree; } @@ -625,6 +664,8 @@ static int jfs_show_options(struct seq_file *seq, struct dentry *root) seq_printf(seq, ",umask=%03o", sbi->umask); if (sbi->flag & JFS_NOINTEGRITY) seq_puts(seq, ",nointegrity"); + if (sbi->flag & JFS_DISCARD) + seq_printf(seq, ",discard=%u", sbi->minblks_trim); if (sbi->nls_tab) seq_printf(seq, ",iocharset=%s", sbi->nls_tab->charset); if (sbi->flag & JFS_ERR_CONTINUE) -- cgit v1.2.3 From c18cdc1a3ec643b5c6c0d65aac1a6bf8e461778f Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 10 Feb 2012 11:40:34 -0800 Subject: userns: Convert jfs to use kuid/kgid where appropriate Cc: Dave Kleikamp Signed-off-by: Eric W. Biederman --- fs/jfs/super.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'fs/jfs/super.c') diff --git a/fs/jfs/super.c b/fs/jfs/super.c index c55c7452d28..706692f2403 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -321,13 +321,19 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, case Opt_uid: { char *uid = args[0].from; - sbi->uid = simple_strtoul(uid, &uid, 0); + uid_t val = simple_strtoul(uid, &uid, 0); + sbi->uid = make_kuid(current_user_ns(), val); + if (!uid_valid(sbi->uid)) + goto cleanup; break; } case Opt_gid: { char *gid = args[0].from; - sbi->gid = simple_strtoul(gid, &gid, 0); + gid_t val = simple_strtoul(gid, &gid, 0); + sbi->gid = make_kgid(current_user_ns(), val); + if (!gid_valid(sbi->gid)) + goto cleanup; break; } case Opt_umask: @@ -443,7 +449,9 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) sb->s_fs_info = sbi; sb->s_max_links = JFS_LINK_MAX; sbi->sb = sb; - sbi->uid = sbi->gid = sbi->umask = -1; + sbi->uid = INVALID_UID; + sbi->gid = INVALID_GID; + sbi->umask = -1; /* initialize the mount flag and determine the default error handler */ flag = JFS_ERR_REMOUNT_RO; @@ -617,10 +625,10 @@ static int jfs_show_options(struct seq_file *seq, struct dentry *root) { struct jfs_sb_info *sbi = JFS_SBI(root->d_sb); - if (sbi->uid != -1) - seq_printf(seq, ",uid=%d", sbi->uid); - if (sbi->gid != -1) - seq_printf(seq, ",gid=%d", sbi->gid); + if (uid_valid(sbi->uid)) + seq_printf(seq, ",uid=%d", from_kuid(&init_user_ns, sbi->uid)); + if (gid_valid(sbi->gid)) + seq_printf(seq, ",gid=%d", from_kgid(&init_user_ns, sbi->gid)); if (sbi->umask != -1) seq_printf(seq, ",umask=%03o", sbi->umask); if (sbi->flag & JFS_NOINTEGRITY) -- cgit v1.2.3 From 8c0a85377048b64c880e76ec7368904fe46d0b94 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Wed, 26 Sep 2012 11:33:07 +1000 Subject: fs: push rcu_barrier() from deactivate_locked_super() to filesystems There's no reason to call rcu_barrier() on every deactivate_locked_super(). We only need to make sure that all delayed rcu free inodes are flushed before we destroy related cache. Removing rcu_barrier() from deactivate_locked_super() affects some fast paths. E.g. on my machine exit_group() of a last process in IPC namespace takes 0.07538s. rcu_barrier() takes 0.05188s of that time. Signed-off-by: Kirill A. Shutemov Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Al Viro --- fs/jfs/super.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'fs/jfs/super.c') diff --git a/fs/jfs/super.c b/fs/jfs/super.c index c55c7452d28..3735347fd5f 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -903,6 +903,12 @@ static void __exit exit_jfs_fs(void) jfs_proc_clean(); #endif unregister_filesystem(&jfs_fs_type); + + /* + * Make sure all delayed rcu free inodes are flushed before we + * destroy cache. + */ + rcu_barrier(); kmem_cache_destroy(jfs_inode_cachep); } -- cgit v1.2.3