1/* 2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 4 * 5 * This copyrighted material is made available to anyone wishing to use, 6 * modify, copy, or redistribute it subject to the terms and conditions 7 * of the GNU General Public License version 2. 8 */ 9 10#include <linux/slab.h> 11#include <linux/spinlock.h> 12#include <linux/completion.h> 13#include <linux/buffer_head.h> 14#include <linux/gfs2_ondisk.h> 15#include <linux/lm_interface.h> 16#include <linux/parser.h> 17 18#include "gfs2.h" 19#include "incore.h" 20#include "mount.h" 21#include "sys.h" 22#include "util.h" 23 24enum { 25 Opt_lockproto, 26 Opt_locktable, 27 Opt_hostdata, 28 Opt_spectator, 29 Opt_ignore_local_fs, 30 Opt_localflocks, 31 Opt_localcaching, 32 Opt_debug, 33 Opt_nodebug, 34 Opt_upgrade, 35 Opt_num_glockd, 36 Opt_acl, 37 Opt_noacl, 38 Opt_quota_off, 39 Opt_quota_account, 40 Opt_quota_on, 41 Opt_suiddir, 42 Opt_nosuiddir, 43 Opt_data_writeback, 44 Opt_data_ordered, 45}; 46 47static match_table_t tokens = { 48 {Opt_lockproto, "lockproto=%s"}, 49 {Opt_locktable, "locktable=%s"}, 50 {Opt_hostdata, "hostdata=%s"}, 51 {Opt_spectator, "spectator"}, 52 {Opt_ignore_local_fs, "ignore_local_fs"}, 53 {Opt_localflocks, "localflocks"}, 54 {Opt_localcaching, "localcaching"}, 55 {Opt_debug, "debug"}, 56 {Opt_nodebug, "nodebug"}, 57 {Opt_upgrade, "upgrade"}, 58 {Opt_num_glockd, "num_glockd=%d"}, 59 {Opt_acl, "acl"}, 60 {Opt_noacl, "noacl"}, 61 {Opt_quota_off, "quota=off"}, 62 {Opt_quota_account, "quota=account"}, 63 {Opt_quota_on, "quota=on"}, 64 {Opt_suiddir, "suiddir"}, 65 {Opt_nosuiddir, "nosuiddir"}, 66 {Opt_data_writeback, "data=writeback"}, 67 {Opt_data_ordered, "data=ordered"} 68}; 69 70/** 71 * gfs2_mount_args - Parse mount options 72 * @sdp: 73 * @data: 74 * 75 * Return: errno 76 */ 77 78int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount) 79{ 80 struct gfs2_args *args = &sdp->sd_args; 81 char *data = data_arg; 82 char *options, *o, *v; 83 int error = 0; 84 85 if (!remount) { 86 /* If someone preloaded options, use those instead */ 87 spin_lock(&gfs2_sys_margs_lock); 88 if (gfs2_sys_margs) { 89 data = gfs2_sys_margs; 90 gfs2_sys_margs = NULL; 91 } 92 spin_unlock(&gfs2_sys_margs_lock); 93 94 /* Set some defaults */ 95 args->ar_num_glockd = GFS2_GLOCKD_DEFAULT; 96 args->ar_quota = GFS2_QUOTA_DEFAULT; 97 args->ar_data = GFS2_DATA_DEFAULT; 98 } 99 100 /* Split the options into tokens with the "," character and 101 process them */ 102 103 for (options = data; (o = strsep(&options, ",")); ) { 104 int token, option; 105 substring_t tmp[MAX_OPT_ARGS]; 106 107 if (!*o) 108 continue; 109 110 token = match_token(o, tokens, tmp); 111 switch (token) { 112 case Opt_lockproto: 113 v = match_strdup(&tmp[0]); 114 if (!v) { 115 fs_info(sdp, "no memory for lockproto\n"); 116 error = -ENOMEM; 117 goto out_error; 118 } 119 120 if (remount && strcmp(v, args->ar_lockproto)) { 121 kfree(v); 122 goto cant_remount; 123 } 124 125 strncpy(args->ar_lockproto, v, GFS2_LOCKNAME_LEN); 126 args->ar_lockproto[GFS2_LOCKNAME_LEN - 1] = 0; 127 kfree(v); 128 break; 129 case Opt_locktable: 130 v = match_strdup(&tmp[0]); 131 if (!v) { 132 fs_info(sdp, "no memory for locktable\n"); 133 error = -ENOMEM; 134 goto out_error; 135 } 136 137 if (remount && strcmp(v, args->ar_locktable)) { 138 kfree(v); 139 goto cant_remount; 140 } 141 142 strncpy(args->ar_locktable, v, GFS2_LOCKNAME_LEN); 143 args->ar_locktable[GFS2_LOCKNAME_LEN - 1] = 0; 144 kfree(v); 145 break; 146 case Opt_hostdata: 147 v = match_strdup(&tmp[0]); 148 if (!v) { 149 fs_info(sdp, "no memory for hostdata\n"); 150 error = -ENOMEM; 151 goto out_error; 152 } 153 154 if (remount && strcmp(v, args->ar_hostdata)) { 155 kfree(v); 156 goto cant_remount; 157 } 158 159 strncpy(args->ar_hostdata, v, GFS2_LOCKNAME_LEN); 160 args->ar_hostdata[GFS2_LOCKNAME_LEN - 1] = 0; 161 kfree(v); 162 break; 163 case Opt_spectator: 164 if (remount && !args->ar_spectator) 165 goto cant_remount; 166 args->ar_spectator = 1; 167 sdp->sd_vfs->s_flags |= MS_RDONLY; 168 break; 169 case Opt_ignore_local_fs: 170 if (remount && !args->ar_ignore_local_fs) 171 goto cant_remount; 172 args->ar_ignore_local_fs = 1; 173 break; 174 case Opt_localflocks: 175 if (remount && !args->ar_localflocks) 176 goto cant_remount; 177 args->ar_localflocks = 1; 178 break; 179 case Opt_localcaching: 180 if (remount && !args->ar_localcaching) 181 goto cant_remount; 182 args->ar_localcaching = 1; 183 break; 184 case Opt_debug: 185 args->ar_debug = 1; 186 break; 187 case Opt_nodebug: 188 args->ar_debug = 0; 189 break; 190 case Opt_upgrade: 191 if (remount && !args->ar_upgrade) 192 goto cant_remount; 193 args->ar_upgrade = 1; 194 break; 195 case Opt_num_glockd: 196 if ((error = match_int(&tmp[0], &option))) { 197 fs_info(sdp, "problem getting num_glockd\n"); 198 goto out_error; 199 } 200 201 if (remount && option != args->ar_num_glockd) 202 goto cant_remount; 203 if (!option || option > GFS2_GLOCKD_MAX) { 204 fs_info(sdp, "0 < num_glockd <= %u (not %u)\n", 205 GFS2_GLOCKD_MAX, option); 206 error = -EINVAL; 207 goto out_error; 208 } 209 args->ar_num_glockd = option; 210 break; 211 case Opt_acl: 212 args->ar_posix_acl = 1; 213 sdp->sd_vfs->s_flags |= MS_POSIXACL; 214 break; 215 case Opt_noacl: 216 args->ar_posix_acl = 0; 217 sdp->sd_vfs->s_flags &= ~MS_POSIXACL; 218 break; 219 case Opt_quota_off: 220 args->ar_quota = GFS2_QUOTA_OFF; 221 break; 222 case Opt_quota_account: 223 args->ar_quota = GFS2_QUOTA_ACCOUNT; 224 break; 225 case Opt_quota_on: 226 args->ar_quota = GFS2_QUOTA_ON; 227 break; 228 case Opt_suiddir: 229 args->ar_suiddir = 1; 230 break; 231 case Opt_nosuiddir: 232 args->ar_suiddir = 0; 233 break; 234 case Opt_data_writeback: 235 args->ar_data = GFS2_DATA_WRITEBACK; 236 break; 237 case Opt_data_ordered: 238 args->ar_data = GFS2_DATA_ORDERED; 239 break; 240 default: 241 fs_info(sdp, "unknown option: %s\n", o); 242 error = -EINVAL; 243 goto out_error; 244 } 245 } 246 247out_error: 248 if (error) 249 fs_info(sdp, "invalid mount option(s)\n"); 250 251 if (data != data_arg) 252 kfree(data); 253 254 return error; 255 256cant_remount: 257 fs_info(sdp, "can't remount with option %s\n", o); 258 return -EINVAL; 259} 260