Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2: ocfs2: Fix calculation of i_blocks during truncate [PATCH] ocfs2: Fix a wrong cluster calculation. [PATCH] ocfs2: fix mount option parsing ocfs2: update docs for new features
This commit is contained in:
commit
577107e8e4
|
@ -28,11 +28,7 @@ Manish Singh <manish.singh@oracle.com>
|
||||||
Caveats
|
Caveats
|
||||||
=======
|
=======
|
||||||
Features which OCFS2 does not support yet:
|
Features which OCFS2 does not support yet:
|
||||||
- sparse files
|
|
||||||
- extended attributes
|
- extended attributes
|
||||||
- shared writable mmap
|
|
||||||
- loopback is supported, but data written will not
|
|
||||||
be cluster coherent.
|
|
||||||
- quotas
|
- quotas
|
||||||
- cluster aware flock
|
- cluster aware flock
|
||||||
- cluster aware lockf
|
- cluster aware lockf
|
||||||
|
@ -57,3 +53,12 @@ nointr Do not allow signals to interrupt cluster
|
||||||
atime_quantum=60(*) OCFS2 will not update atime unless this number
|
atime_quantum=60(*) OCFS2 will not update atime unless this number
|
||||||
of seconds has passed since the last update.
|
of seconds has passed since the last update.
|
||||||
Set to zero to always update atime.
|
Set to zero to always update atime.
|
||||||
|
data=ordered (*) All data are forced directly out to the main file
|
||||||
|
system prior to its metadata being committed to the
|
||||||
|
journal.
|
||||||
|
data=writeback Data ordering is not preserved, data may be written
|
||||||
|
into the main file system after its metadata has been
|
||||||
|
committed to the journal.
|
||||||
|
preferred_slot=0(*) During mount, try to use this filesystem slot first. If
|
||||||
|
it is in use by another node, the first empty one found
|
||||||
|
will be chosen. Invalid values will be ignored.
|
||||||
|
|
|
@ -441,9 +441,6 @@ config OCFS2_FS
|
||||||
|
|
||||||
Note: Features which OCFS2 does not support yet:
|
Note: Features which OCFS2 does not support yet:
|
||||||
- extended attributes
|
- extended attributes
|
||||||
- shared writeable mmap
|
|
||||||
- loopback is supported, but data written will not
|
|
||||||
be cluster coherent.
|
|
||||||
- quotas
|
- quotas
|
||||||
- cluster aware flock
|
- cluster aware flock
|
||||||
- Directory change notification (F_NOTIFY)
|
- Directory change notification (F_NOTIFY)
|
||||||
|
|
|
@ -5602,6 +5602,7 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb,
|
||||||
clusters_to_del;
|
clusters_to_del;
|
||||||
spin_unlock(&OCFS2_I(inode)->ip_lock);
|
spin_unlock(&OCFS2_I(inode)->ip_lock);
|
||||||
le32_add_cpu(&fe->i_clusters, -clusters_to_del);
|
le32_add_cpu(&fe->i_clusters, -clusters_to_del);
|
||||||
|
inode->i_blocks = ocfs2_inode_sector_count(inode);
|
||||||
|
|
||||||
status = ocfs2_trim_tree(inode, path, handle, tc,
|
status = ocfs2_trim_tree(inode, path, handle, tc,
|
||||||
clusters_to_del, &delete_blk);
|
clusters_to_del, &delete_blk);
|
||||||
|
|
|
@ -855,6 +855,7 @@ static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp,
|
||||||
struct ocfs2_super *osb, loff_t pos,
|
struct ocfs2_super *osb, loff_t pos,
|
||||||
unsigned len, struct buffer_head *di_bh)
|
unsigned len, struct buffer_head *di_bh)
|
||||||
{
|
{
|
||||||
|
u32 cend;
|
||||||
struct ocfs2_write_ctxt *wc;
|
struct ocfs2_write_ctxt *wc;
|
||||||
|
|
||||||
wc = kzalloc(sizeof(struct ocfs2_write_ctxt), GFP_NOFS);
|
wc = kzalloc(sizeof(struct ocfs2_write_ctxt), GFP_NOFS);
|
||||||
|
@ -862,7 +863,8 @@ static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
wc->w_cpos = pos >> osb->s_clustersize_bits;
|
wc->w_cpos = pos >> osb->s_clustersize_bits;
|
||||||
wc->w_clen = ocfs2_clusters_for_bytes(osb->sb, len);
|
cend = (pos + len - 1) >> osb->s_clustersize_bits;
|
||||||
|
wc->w_clen = cend - wc->w_cpos + 1;
|
||||||
get_bh(di_bh);
|
get_bh(di_bh);
|
||||||
wc->w_di_bh = di_bh;
|
wc->w_di_bh = di_bh;
|
||||||
|
|
||||||
|
|
|
@ -314,7 +314,6 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb,
|
||||||
}
|
}
|
||||||
|
|
||||||
i_size_write(inode, new_i_size);
|
i_size_write(inode, new_i_size);
|
||||||
inode->i_blocks = ocfs2_align_bytes_to_sectors(new_i_size);
|
|
||||||
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
|
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
|
||||||
|
|
||||||
di = (struct ocfs2_dinode *) fe_bh->b_data;
|
di = (struct ocfs2_dinode *) fe_bh->b_data;
|
||||||
|
|
|
@ -81,8 +81,15 @@ static struct dentry *ocfs2_debugfs_root = NULL;
|
||||||
MODULE_AUTHOR("Oracle");
|
MODULE_AUTHOR("Oracle");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
struct mount_options
|
||||||
|
{
|
||||||
|
unsigned long mount_opt;
|
||||||
|
unsigned int atime_quantum;
|
||||||
|
signed short slot;
|
||||||
|
};
|
||||||
|
|
||||||
static int ocfs2_parse_options(struct super_block *sb, char *options,
|
static int ocfs2_parse_options(struct super_block *sb, char *options,
|
||||||
unsigned long *mount_opt, s16 *slot,
|
struct mount_options *mopt,
|
||||||
int is_remount);
|
int is_remount);
|
||||||
static void ocfs2_put_super(struct super_block *sb);
|
static void ocfs2_put_super(struct super_block *sb);
|
||||||
static int ocfs2_mount_volume(struct super_block *sb);
|
static int ocfs2_mount_volume(struct super_block *sb);
|
||||||
|
@ -367,24 +374,23 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
|
||||||
{
|
{
|
||||||
int incompat_features;
|
int incompat_features;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned long parsed_options;
|
struct mount_options parsed_options;
|
||||||
s16 slot;
|
|
||||||
struct ocfs2_super *osb = OCFS2_SB(sb);
|
struct ocfs2_super *osb = OCFS2_SB(sb);
|
||||||
|
|
||||||
if (!ocfs2_parse_options(sb, data, &parsed_options, &slot, 1)) {
|
if (!ocfs2_parse_options(sb, data, &parsed_options, 1)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) !=
|
if ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) !=
|
||||||
(parsed_options & OCFS2_MOUNT_HB_LOCAL)) {
|
(parsed_options.mount_opt & OCFS2_MOUNT_HB_LOCAL)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
mlog(ML_ERROR, "Cannot change heartbeat mode on remount\n");
|
mlog(ML_ERROR, "Cannot change heartbeat mode on remount\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK) !=
|
if ((osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK) !=
|
||||||
(parsed_options & OCFS2_MOUNT_DATA_WRITEBACK)) {
|
(parsed_options.mount_opt & OCFS2_MOUNT_DATA_WRITEBACK)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
mlog(ML_ERROR, "Cannot change data mode on remount\n");
|
mlog(ML_ERROR, "Cannot change data mode on remount\n");
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -435,7 +441,9 @@ unlock_osb:
|
||||||
|
|
||||||
/* Only save off the new mount options in case of a successful
|
/* Only save off the new mount options in case of a successful
|
||||||
* remount. */
|
* remount. */
|
||||||
osb->s_mount_opt = parsed_options;
|
osb->s_mount_opt = parsed_options.mount_opt;
|
||||||
|
osb->s_atime_quantum = parsed_options.atime_quantum;
|
||||||
|
osb->preferred_slot = parsed_options.slot;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -547,8 +555,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
|
||||||
{
|
{
|
||||||
struct dentry *root;
|
struct dentry *root;
|
||||||
int status, sector_size;
|
int status, sector_size;
|
||||||
unsigned long parsed_opt;
|
struct mount_options parsed_options;
|
||||||
s16 slot;
|
|
||||||
struct inode *inode = NULL;
|
struct inode *inode = NULL;
|
||||||
struct ocfs2_super *osb = NULL;
|
struct ocfs2_super *osb = NULL;
|
||||||
struct buffer_head *bh = NULL;
|
struct buffer_head *bh = NULL;
|
||||||
|
@ -556,14 +563,14 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
|
||||||
|
|
||||||
mlog_entry("%p, %p, %i", sb, data, silent);
|
mlog_entry("%p, %p, %i", sb, data, silent);
|
||||||
|
|
||||||
if (!ocfs2_parse_options(sb, data, &parsed_opt, &slot, 0)) {
|
if (!ocfs2_parse_options(sb, data, &parsed_options, 0)) {
|
||||||
status = -EINVAL;
|
status = -EINVAL;
|
||||||
goto read_super_error;
|
goto read_super_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* for now we only have one cluster/node, make sure we see it
|
/* for now we only have one cluster/node, make sure we see it
|
||||||
* in the heartbeat universe */
|
* in the heartbeat universe */
|
||||||
if (parsed_opt & OCFS2_MOUNT_HB_LOCAL) {
|
if (parsed_options.mount_opt & OCFS2_MOUNT_HB_LOCAL) {
|
||||||
if (!o2hb_check_local_node_heartbeating()) {
|
if (!o2hb_check_local_node_heartbeating()) {
|
||||||
status = -EINVAL;
|
status = -EINVAL;
|
||||||
goto read_super_error;
|
goto read_super_error;
|
||||||
|
@ -585,8 +592,9 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
|
||||||
}
|
}
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
bh = NULL;
|
bh = NULL;
|
||||||
osb->s_mount_opt = parsed_opt;
|
osb->s_mount_opt = parsed_options.mount_opt;
|
||||||
osb->preferred_slot = slot;
|
osb->s_atime_quantum = parsed_options.atime_quantum;
|
||||||
|
osb->preferred_slot = parsed_options.slot;
|
||||||
|
|
||||||
sb->s_magic = OCFS2_SUPER_MAGIC;
|
sb->s_magic = OCFS2_SUPER_MAGIC;
|
||||||
|
|
||||||
|
@ -728,8 +736,7 @@ static struct file_system_type ocfs2_fs_type = {
|
||||||
|
|
||||||
static int ocfs2_parse_options(struct super_block *sb,
|
static int ocfs2_parse_options(struct super_block *sb,
|
||||||
char *options,
|
char *options,
|
||||||
unsigned long *mount_opt,
|
struct mount_options *mopt,
|
||||||
s16 *slot,
|
|
||||||
int is_remount)
|
int is_remount)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
@ -738,8 +745,9 @@ static int ocfs2_parse_options(struct super_block *sb,
|
||||||
mlog_entry("remount: %d, options: \"%s\"\n", is_remount,
|
mlog_entry("remount: %d, options: \"%s\"\n", is_remount,
|
||||||
options ? options : "(none)");
|
options ? options : "(none)");
|
||||||
|
|
||||||
*mount_opt = 0;
|
mopt->mount_opt = 0;
|
||||||
*slot = OCFS2_INVALID_SLOT;
|
mopt->atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM;
|
||||||
|
mopt->slot = OCFS2_INVALID_SLOT;
|
||||||
|
|
||||||
if (!options) {
|
if (!options) {
|
||||||
status = 1;
|
status = 1;
|
||||||
|
@ -749,7 +757,6 @@ static int ocfs2_parse_options(struct super_block *sb,
|
||||||
while ((p = strsep(&options, ",")) != NULL) {
|
while ((p = strsep(&options, ",")) != NULL) {
|
||||||
int token, option;
|
int token, option;
|
||||||
substring_t args[MAX_OPT_ARGS];
|
substring_t args[MAX_OPT_ARGS];
|
||||||
struct ocfs2_super * osb = OCFS2_SB(sb);
|
|
||||||
|
|
||||||
if (!*p)
|
if (!*p)
|
||||||
continue;
|
continue;
|
||||||
|
@ -757,10 +764,10 @@ static int ocfs2_parse_options(struct super_block *sb,
|
||||||
token = match_token(p, tokens, args);
|
token = match_token(p, tokens, args);
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case Opt_hb_local:
|
case Opt_hb_local:
|
||||||
*mount_opt |= OCFS2_MOUNT_HB_LOCAL;
|
mopt->mount_opt |= OCFS2_MOUNT_HB_LOCAL;
|
||||||
break;
|
break;
|
||||||
case Opt_hb_none:
|
case Opt_hb_none:
|
||||||
*mount_opt &= ~OCFS2_MOUNT_HB_LOCAL;
|
mopt->mount_opt &= ~OCFS2_MOUNT_HB_LOCAL;
|
||||||
break;
|
break;
|
||||||
case Opt_barrier:
|
case Opt_barrier:
|
||||||
if (match_int(&args[0], &option)) {
|
if (match_int(&args[0], &option)) {
|
||||||
|
@ -768,27 +775,27 @@ static int ocfs2_parse_options(struct super_block *sb,
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
if (option)
|
if (option)
|
||||||
*mount_opt |= OCFS2_MOUNT_BARRIER;
|
mopt->mount_opt |= OCFS2_MOUNT_BARRIER;
|
||||||
else
|
else
|
||||||
*mount_opt &= ~OCFS2_MOUNT_BARRIER;
|
mopt->mount_opt &= ~OCFS2_MOUNT_BARRIER;
|
||||||
break;
|
break;
|
||||||
case Opt_intr:
|
case Opt_intr:
|
||||||
*mount_opt &= ~OCFS2_MOUNT_NOINTR;
|
mopt->mount_opt &= ~OCFS2_MOUNT_NOINTR;
|
||||||
break;
|
break;
|
||||||
case Opt_nointr:
|
case Opt_nointr:
|
||||||
*mount_opt |= OCFS2_MOUNT_NOINTR;
|
mopt->mount_opt |= OCFS2_MOUNT_NOINTR;
|
||||||
break;
|
break;
|
||||||
case Opt_err_panic:
|
case Opt_err_panic:
|
||||||
*mount_opt |= OCFS2_MOUNT_ERRORS_PANIC;
|
mopt->mount_opt |= OCFS2_MOUNT_ERRORS_PANIC;
|
||||||
break;
|
break;
|
||||||
case Opt_err_ro:
|
case Opt_err_ro:
|
||||||
*mount_opt &= ~OCFS2_MOUNT_ERRORS_PANIC;
|
mopt->mount_opt &= ~OCFS2_MOUNT_ERRORS_PANIC;
|
||||||
break;
|
break;
|
||||||
case Opt_data_ordered:
|
case Opt_data_ordered:
|
||||||
*mount_opt &= ~OCFS2_MOUNT_DATA_WRITEBACK;
|
mopt->mount_opt &= ~OCFS2_MOUNT_DATA_WRITEBACK;
|
||||||
break;
|
break;
|
||||||
case Opt_data_writeback:
|
case Opt_data_writeback:
|
||||||
*mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK;
|
mopt->mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK;
|
||||||
break;
|
break;
|
||||||
case Opt_atime_quantum:
|
case Opt_atime_quantum:
|
||||||
if (match_int(&args[0], &option)) {
|
if (match_int(&args[0], &option)) {
|
||||||
|
@ -796,9 +803,7 @@ static int ocfs2_parse_options(struct super_block *sb,
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
if (option >= 0)
|
if (option >= 0)
|
||||||
osb->s_atime_quantum = option;
|
mopt->atime_quantum = option;
|
||||||
else
|
|
||||||
osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM;
|
|
||||||
break;
|
break;
|
||||||
case Opt_slot:
|
case Opt_slot:
|
||||||
option = 0;
|
option = 0;
|
||||||
|
@ -807,7 +812,7 @@ static int ocfs2_parse_options(struct super_block *sb,
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
if (option)
|
if (option)
|
||||||
*slot = (s16)option;
|
mopt->slot = (s16)option;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mlog(ML_ERROR,
|
mlog(ML_ERROR,
|
||||||
|
|
Loading…
Reference in a new issue