2006-01-16 16:50:04 +00:00
/*
* Copyright ( C ) Sistina Software , Inc . 1997 - 2003 All rights reserved .
2006-05-18 15:09:15 -04:00
* Copyright ( C ) 2004 - 2006 Red Hat , Inc . All rights reserved .
2006-01-16 16:50:04 +00:00
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
2006-09-01 11:05:15 -04:00
* of the GNU General Public License version 2.
2006-01-16 16:50:04 +00:00
*/
# include <linux/sched.h>
# include <linux/slab.h>
# include <linux/spinlock.h>
# include <linux/completion.h>
# include <linux/buffer_head.h>
2006-02-27 17:23:27 -05:00
# include <linux/gfs2_ondisk.h>
2006-09-19 07:56:29 +02:00
# include <linux/lm_interface.h>
2006-01-16 16:50:04 +00:00
# include "gfs2.h"
2006-02-27 17:23:27 -05:00
# include "incore.h"
2006-01-16 16:50:04 +00:00
# include "mount.h"
# include "sys.h"
2006-02-27 17:23:27 -05:00
# include "util.h"
2006-01-16 16:50:04 +00:00
/**
* gfs2_mount_args - Parse mount options
* @ sdp :
* @ data :
*
* Return : errno
*/
int gfs2_mount_args ( struct gfs2_sbd * sdp , char * data_arg , int remount )
{
struct gfs2_args * args = & sdp - > sd_args ;
char * data = data_arg ;
char * options , * o , * v ;
int error = 0 ;
if ( ! remount ) {
/* If someone preloaded options, use those instead */
spin_lock ( & gfs2_sys_margs_lock ) ;
if ( gfs2_sys_margs ) {
data = gfs2_sys_margs ;
gfs2_sys_margs = NULL ;
}
spin_unlock ( & gfs2_sys_margs_lock ) ;
/* Set some defaults */
args - > ar_num_glockd = GFS2_GLOCKD_DEFAULT ;
args - > ar_quota = GFS2_QUOTA_DEFAULT ;
args - > ar_data = GFS2_DATA_DEFAULT ;
}
/* Split the options into tokens with the "," character and
process them */
for ( options = data ; ( o = strsep ( & options , " , " ) ) ; ) {
if ( ! * o )
continue ;
v = strchr ( o , ' = ' ) ;
if ( v )
* v + + = 0 ;
if ( ! strcmp ( o , " lockproto " ) ) {
if ( ! v )
goto need_value ;
if ( remount & & strcmp ( v , args - > ar_lockproto ) )
goto cant_remount ;
strncpy ( args - > ar_lockproto , v , GFS2_LOCKNAME_LEN ) ;
args - > ar_lockproto [ GFS2_LOCKNAME_LEN - 1 ] = 0 ;
}
else if ( ! strcmp ( o , " locktable " ) ) {
if ( ! v )
goto need_value ;
if ( remount & & strcmp ( v , args - > ar_locktable ) )
goto cant_remount ;
strncpy ( args - > ar_locktable , v , GFS2_LOCKNAME_LEN ) ;
args - > ar_locktable [ GFS2_LOCKNAME_LEN - 1 ] = 0 ;
}
else if ( ! strcmp ( o , " hostdata " ) ) {
if ( ! v )
goto need_value ;
if ( remount & & strcmp ( v , args - > ar_hostdata ) )
goto cant_remount ;
strncpy ( args - > ar_hostdata , v , GFS2_LOCKNAME_LEN ) ;
args - > ar_hostdata [ GFS2_LOCKNAME_LEN - 1 ] = 0 ;
}
else if ( ! strcmp ( o , " spectator " ) ) {
if ( remount & & ! args - > ar_spectator )
goto cant_remount ;
args - > ar_spectator = 1 ;
sdp - > sd_vfs - > s_flags | = MS_RDONLY ;
}
else if ( ! strcmp ( o , " ignore_local_fs " ) ) {
if ( remount & & ! args - > ar_ignore_local_fs )
goto cant_remount ;
args - > ar_ignore_local_fs = 1 ;
}
else if ( ! strcmp ( o , " localflocks " ) ) {
if ( remount & & ! args - > ar_localflocks )
goto cant_remount ;
args - > ar_localflocks = 1 ;
}
else if ( ! strcmp ( o , " localcaching " ) ) {
if ( remount & & ! args - > ar_localcaching )
goto cant_remount ;
args - > ar_localcaching = 1 ;
}
else if ( ! strcmp ( o , " debug " ) )
args - > ar_debug = 1 ;
else if ( ! strcmp ( o , " nodebug " ) )
args - > ar_debug = 0 ;
else if ( ! strcmp ( o , " upgrade " ) ) {
if ( remount & & ! args - > ar_upgrade )
goto cant_remount ;
args - > ar_upgrade = 1 ;
}
else if ( ! strcmp ( o , " num_glockd " ) ) {
unsigned int x ;
if ( ! v )
goto need_value ;
sscanf ( v , " %u " , & x ) ;
if ( remount & & x ! = args - > ar_num_glockd )
goto cant_remount ;
if ( ! x | | x > GFS2_GLOCKD_MAX ) {
fs_info ( sdp , " 0 < num_glockd <= %u (not %u) \n " ,
GFS2_GLOCKD_MAX , x ) ;
error = - EINVAL ;
break ;
}
args - > ar_num_glockd = x ;
}
else if ( ! strcmp ( o , " acl " ) ) {
args - > ar_posix_acl = 1 ;
sdp - > sd_vfs - > s_flags | = MS_POSIXACL ;
}
else if ( ! strcmp ( o , " noacl " ) ) {
args - > ar_posix_acl = 0 ;
sdp - > sd_vfs - > s_flags & = ~ MS_POSIXACL ;
}
else if ( ! strcmp ( o , " quota " ) ) {
if ( ! v )
goto need_value ;
if ( ! strcmp ( v , " off " ) )
args - > ar_quota = GFS2_QUOTA_OFF ;
else if ( ! strcmp ( v , " account " ) )
args - > ar_quota = GFS2_QUOTA_ACCOUNT ;
else if ( ! strcmp ( v , " on " ) )
args - > ar_quota = GFS2_QUOTA_ON ;
else {
fs_info ( sdp , " invalid value for quota \n " ) ;
error = - EINVAL ;
break ;
}
}
else if ( ! strcmp ( o , " suiddir " ) )
args - > ar_suiddir = 1 ;
else if ( ! strcmp ( o , " nosuiddir " ) )
args - > ar_suiddir = 0 ;
else if ( ! strcmp ( o , " data " ) ) {
if ( ! v )
goto need_value ;
if ( ! strcmp ( v , " writeback " ) )
args - > ar_data = GFS2_DATA_WRITEBACK ;
else if ( ! strcmp ( v , " ordered " ) )
args - > ar_data = GFS2_DATA_ORDERED ;
else {
fs_info ( sdp , " invalid value for data \n " ) ;
error = - EINVAL ;
break ;
}
}
else {
fs_info ( sdp , " unknown option: %s \n " , o ) ;
error = - EINVAL ;
break ;
}
}
if ( error )
fs_info ( sdp , " invalid mount option(s) \n " ) ;
if ( data ! = data_arg )
kfree ( data ) ;
return error ;
2006-09-04 12:04:26 -04:00
need_value :
2006-01-16 16:50:04 +00:00
fs_info ( sdp , " need value for option %s \n " , o ) ;
return - EINVAL ;
2006-09-04 12:04:26 -04:00
cant_remount :
2006-01-16 16:50:04 +00:00
fs_info ( sdp , " can't remount with option %s \n " , o ) ;
return - EINVAL ;
}