Commit 57a2b306 authored by Dave Kleikamp's avatar Dave Kleikamp

JFS: add nointegrity mount option

This option allows a performance boost by not writing to the journal at the
expense of loss of data integrity if the system crashes or is powered off.
The intended use of this option is to allow faster restores from backup media.
parent f01b6051
......@@ -23,6 +23,15 @@ resize=value Resize the volume to <value> blocks. JFS only supports
read-write. The resize keyword with no value will grow
the volume to the full size of the partition.
nointegrity Do not write to the journal. The primary use of this option
is to allow for higher performance when restoring a volume
from backup media. The integrity of the volume is not
guaranteed if the system abnormally abends.
integrity Default. Commit metadata changes to the journal. Use this
option to remount a volume where the nointegrity option was
previously specified in order to restore normal behavior.
JFS TODO list:
Plans for our near term development items
......
/*
* Copyright (c) International Business Machines Corp., 2000-2001
* Copyright (c) International Business Machines Corp., 2000-2003
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -29,6 +29,9 @@
/*
* file system option (superblock flag)
*/
/* mount time flag to disable journaling to disk */
#define JFS_NOINTEGRITY 0x00000010
/* platform option (conditional compilation) */
#define JFS_AIX 0x80000000 /* AIX support */
/* POSIX name/directory support */
......
/*
* Copyright (c) International Business Machines Corp., 2000-2002
* Copyright (c) International Business Machines Corp., 2000-2003
* Portions Copyright (c) Christoph Hellwig, 2001-2002
*
* This program is free software; you can redistribute it and/or modify
......@@ -130,32 +130,34 @@ enum cflags {
* JFS-private superblock information.
*/
struct jfs_sb_info {
unsigned long mntflag; /* 4: aggregate attributes */
struct inode *ipbmap; /* 4: block map inode */
struct inode *ipaimap; /* 4: aggregate inode map inode */
struct inode *ipaimap2; /* 4: secondary aimap inode */
struct inode *ipimap; /* 4: aggregate inode map inode */
struct jfs_log *log; /* 4: log */
short bsize; /* 2: logical block size */
short l2bsize; /* 2: log2 logical block size */
short nbperpage; /* 2: blocks per page */
short l2nbperpage; /* 2: log2 blocks per page */
short l2niperblk; /* 2: log2 inodes per page */
u32 logdev; /* 2: external log device */
unsigned long mntflag; /* aggregate attributes */
struct inode *ipbmap; /* block map inode */
struct inode *ipaimap; /* aggregate inode map inode */
struct inode *ipaimap2; /* secondary aimap inode */
struct inode *ipimap; /* aggregate inode map inode */
struct jfs_log *log; /* log */
short bsize; /* logical block size */
short l2bsize; /* log2 logical block size */
short nbperpage; /* blocks per page */
short l2nbperpage; /* log2 blocks per page */
short l2niperblk; /* log2 inodes per page */
u32 logdev; /* external log device */
uint aggregate; /* volume identifier in log record */
pxd_t logpxd; /* 8: pxd describing log */
pxd_t fsckpxd; /* 8: pxd describing fsck wkspc */
pxd_t ait2; /* 8: pxd describing AIT copy */
char uuid[16]; /* 16: 128-bit uuid for volume */
char loguuid[16]; /* 16: 128-bit uuid for log */
pxd_t logpxd; /* pxd describing log */
pxd_t fsckpxd; /* pxd describing fsck wkspc */
pxd_t ait2; /* pxd describing AIT copy */
char uuid[16]; /* 128-bit uuid for volume */
char loguuid[16]; /* 128-bit uuid for log */
/* Formerly in ipimap */
uint gengen; /* 4: inode generation generator*/
uint inostamp; /* 4: shows inode belongs to fileset*/
uint gengen; /* inode generation generator*/
uint inostamp; /* shows inode belongs to fileset*/
/* Formerly in ipbmap */
struct bmap *bmap; /* 4: incore bmap descriptor */
struct nls_table *nls_tab; /* 4: current codepage */
uint state; /* 4: mount/recovery state */
struct bmap *bmap; /* incore bmap descriptor */
struct nls_table *nls_tab; /* current codepage */
uint state; /* mount/recovery state */
unsigned long flag; /* mount time flags */
uint p_state; /* state prior to going no integrity */
};
static inline struct jfs_inode_info *JFS_IP(struct inode *inode)
......
/*
* Copyright (c) International Business Machines Corp., 2000-2002
* Copyright (c) International Business Machines Corp., 2000-2003
* Portions Copyright (c) Christoph Hellwig, 2001-2002
*
* This program is free software; you can redistribute it and/or modify
......@@ -1241,6 +1241,15 @@ int lmLogInit(struct jfs_log * log)
log->page = le32_to_cpu(logsuper->end) / LOGPSIZE;
log->eor = le32_to_cpu(logsuper->end) - (LOGPSIZE * log->page);
/* check for disabled journaling to disk */
if (JFS_SBI(log->sb)->flag & JFS_NOINTEGRITY) {
log->no_integrity = 1;
log->ni_page = log->page;
log->ni_eor = log->eor;
}
else
log->no_integrity = 0;
/*
* initialize for log append write mode
*/
......@@ -1524,6 +1533,14 @@ int lmLogShutdown(struct jfs_log * log)
lrd.type = cpu_to_le16(LOG_SYNCPT);
lrd.length = 0;
lrd.log.syncpt.sync = 0;
/* check for disabled journaling to disk */
if (JFS_SBI(log->sb)->flag & JFS_NOINTEGRITY) {
log->no_integrity = 0;
log->page = log->ni_page;
log->eor = log->ni_eor;
}
lsn = lmWriteRecord(log, NULL, &lrd, NULL);
bp = log->bp;
lp = (struct logpage *) bp->l_ldata;
......@@ -1985,10 +2002,18 @@ static void lbmStartIO(struct lbuf * bp)
bio->bi_end_io = lbmIODone;
bio->bi_private = bp;
submit_bio(WRITE, bio);
INCREMENT(lmStat.submitted);
blk_run_queues();
/* check if journaling to disk has been disabled */
if (!log->no_integrity) {
submit_bio(WRITE, bio);
INCREMENT(lmStat.submitted);
blk_run_queues();
}
else {
bio->bi_size = 0;
lbmIODone(bio, 0, 0); /* 2nd argument appears to not be used => 0
* 3rd argument appears to not be used => 0
*/
}
}
......
/*
* Copyright (c) International Business Machines Corp., 2000-2002
* Copyright (c) International Business Machines Corp., 2000-2003
* Portions Copyright (c) Christoph Hellwig, 2001-2002
*
* This program is free software; you can redistribute it and/or modify
......@@ -417,6 +417,10 @@ struct jfs_log {
struct lbuf *wqueue; /* 4: log pageout queue */
int count; /* 4: count */
char uuid[16]; /* 16: 128-bit uuid of log device */
int no_integrity; /* 3: flag to disable journaling to disk */
int ni_page; /* 4: backup of page for nointegrity option */
int ni_eor; /* 4: backup of eor for nointegrity option */
};
/*
......
/*
* Copyright (c) International Business Machines Corp., 2000-2002
* Copyright (c) International Business Machines Corp., 2000-2003
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -420,12 +420,20 @@ int updateSuper(struct super_block *sb, uint state)
struct buffer_head *bh;
int rc;
/*
* Only fsck can fix dirty state
*/
if (sbi->state == FM_DIRTY)
if (sbi->flag & JFS_NOINTEGRITY) {
if (state == FM_DIRTY) {
sbi->p_state = state;
return 0;
} else if (state == FM_MOUNT) {
sbi->p_state = sbi->state;
state = FM_DIRTY;
} else if (state == FM_CLEAN) {
state = sbi->p_state;
} else
jfs_err("updateSuper: bad state");
} else if (sbi->state == FM_DIRTY)
return 0;
if ((rc = readSuper(sb, &bh)))
return rc;
......
/*
* Copyright (c) International Business Machines Corp., 2000-2002
* Copyright (c) International Business Machines Corp., 2000-2003
* Portions Copyright (c) Christoph Hellwig, 2001-2002
*
* This program is free software; you can redistribute it and/or modify
......@@ -2736,7 +2736,7 @@ void txLazyCommit(struct tblock * tblk)
/* We must have gotten ahead of the user thread
*/
jfs_info("jfs_lazycommit: tblk 0x%p not unlocked", tblk);
schedule();
yield();
}
jfs_info("txLazyCommit: processing tblk 0x%p", tblk);
......
/*
* Copyright (c) International Business Machines Corp., 2000-2002
* Copyright (c) International Business Machines Corp., 2000-2003
* Portions Copyright (c) Christoph Hellwig, 2001-2002
*
* This program is free software; you can redistribute it and/or modify
......@@ -164,7 +164,8 @@ static void jfs_put_super(struct super_block *sb)
kfree(sbi);
}
static int parse_options(char *options, struct super_block *sb, s64 *newLVSize)
static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
int *flag)
{
void *nls_map = NULL;
char *this_char;
......@@ -180,7 +181,11 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize)
continue;
if ((value = strchr(this_char, '=')) != NULL)
*value++ = 0;
if (!strcmp(this_char, "iocharset")) {
if (!strcmp(this_char, "integrity")) {
*flag &= ~JFS_NOINTEGRITY;
} else if (!strcmp(this_char, "nointegrity")) {
*flag |= JFS_NOINTEGRITY;
} else if (!strcmp(this_char, "iocharset")) {
if (!value || !*value)
goto needs_arg;
if (nls_map) /* specified iocharset twice! */
......@@ -231,8 +236,9 @@ int jfs_remount(struct super_block *sb, int *flags, char *data)
{
s64 newLVSize = 0;
int rc = 0;
int flag = JFS_SBI(sb)->flag;
if (!parse_options(data, sb, &newLVSize)) {
if (!parse_options(data, sb, &newLVSize, &flag)) {
return -EINVAL;
}
if (newLVSize) {
......@@ -246,10 +252,24 @@ int jfs_remount(struct super_block *sb, int *flags, char *data)
return rc;
}
if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY))
if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
JFS_SBI(sb)->flag = flag;
return jfs_mount_rw(sb, 1);
else if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY))
return jfs_umount_rw(sb);
}
if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY)) {
rc = jfs_umount_rw(sb);
JFS_SBI(sb)->flag = flag;
return rc;
}
if ((JFS_SBI(sb)->flag & JFS_NOINTEGRITY) != (flag & JFS_NOINTEGRITY))
if (!(sb->s_flags & MS_RDONLY)) {
rc = jfs_umount_rw(sb);
if (rc)
return rc;
JFS_SBI(sb)->flag = flag;
return jfs_mount_rw(sb, 1);
}
JFS_SBI(sb)->flag = flag;
return 0;
}
......@@ -260,6 +280,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
struct inode *inode;
int rc;
s64 newLVSize = 0;
int flag;
jfs_info("In jfs_read_super: s_flags=0x%lx", sb->s_flags);
......@@ -269,10 +290,12 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
memset(sbi, 0, sizeof (struct jfs_sb_info));
sb->s_fs_info = sbi;
if (!parse_options((char *) data, sb, &newLVSize)) {
flag = 0;
if (!parse_options((char *) data, sb, &newLVSize, &flag)) {
kfree(sbi);
return -EINVAL;
}
sbi->flag = flag;
if (newLVSize) {
printk(KERN_ERR "resize option for remount only\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment