summaryrefslogtreecommitdiffstats
path: root/fs/jfs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jfs/super.c')
-rw-r--r--fs/jfs/super.c99
1 files changed, 77 insertions, 22 deletions
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index c55c7452d285..1a543be09c79 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -33,6 +33,7 @@
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/seq_file.h>
+#include <linux/blkdev.h>
#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,33 +316,76 @@ 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:
{
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:
{
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 +419,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);
@@ -443,7 +488,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;
@@ -457,7 +504,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;
}
@@ -617,14 +664,16 @@ 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)
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)
@@ -903,6 +952,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);
}