diff options
Diffstat (limited to 'fs/autofs4/dev-ioctl.c')
| -rw-r--r-- | fs/autofs4/dev-ioctl.c | 77 | 
1 files changed, 35 insertions, 42 deletions
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index c7fcc7438843..fc09eb77ddf3 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c @@ -75,7 +75,7 @@ static int check_dev_ioctl_version(int cmd, struct autofs_dev_ioctl *param)  	if ((param->ver_major != AUTOFS_DEV_IOCTL_VERSION_MAJOR) ||  	    (param->ver_minor > AUTOFS_DEV_IOCTL_VERSION_MINOR)) {  		pr_warn("ioctl control interface version mismatch: " -			"kernel(%u.%u), user(%u.%u), cmd(%d)\n", +			"kernel(%u.%u), user(%u.%u), cmd(0x%08x)\n",  			AUTOFS_DEV_IOCTL_VERSION_MAJOR,  			AUTOFS_DEV_IOCTL_VERSION_MINOR,  			param->ver_major, param->ver_minor, cmd); @@ -172,6 +172,17 @@ static struct autofs_sb_info *autofs_dev_ioctl_sbi(struct file *f)  	return sbi;  } +/* Return autofs dev ioctl version */ +static int autofs_dev_ioctl_version(struct file *fp, +				    struct autofs_sb_info *sbi, +				    struct autofs_dev_ioctl *param) +{ +	/* This should have already been set. */ +	param->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR; +	param->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR; +	return 0; +} +  /* Return autofs module protocol version */  static int autofs_dev_ioctl_protover(struct file *fp,  				     struct autofs_sb_info *sbi, @@ -586,41 +597,25 @@ out:  static ioctl_fn lookup_dev_ioctl(unsigned int cmd)  { -	static struct { -		int cmd; -		ioctl_fn fn; -	} _ioctls[] = { -		{cmd_idx(AUTOFS_DEV_IOCTL_VERSION_CMD), NULL}, -		{cmd_idx(AUTOFS_DEV_IOCTL_PROTOVER_CMD), -			 autofs_dev_ioctl_protover}, -		{cmd_idx(AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD), -			 autofs_dev_ioctl_protosubver}, -		{cmd_idx(AUTOFS_DEV_IOCTL_OPENMOUNT_CMD), -			 autofs_dev_ioctl_openmount}, -		{cmd_idx(AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD), -			 autofs_dev_ioctl_closemount}, -		{cmd_idx(AUTOFS_DEV_IOCTL_READY_CMD), -			 autofs_dev_ioctl_ready}, -		{cmd_idx(AUTOFS_DEV_IOCTL_FAIL_CMD), -			 autofs_dev_ioctl_fail}, -		{cmd_idx(AUTOFS_DEV_IOCTL_SETPIPEFD_CMD), -			 autofs_dev_ioctl_setpipefd}, -		{cmd_idx(AUTOFS_DEV_IOCTL_CATATONIC_CMD), -			 autofs_dev_ioctl_catatonic}, -		{cmd_idx(AUTOFS_DEV_IOCTL_TIMEOUT_CMD), -			 autofs_dev_ioctl_timeout}, -		{cmd_idx(AUTOFS_DEV_IOCTL_REQUESTER_CMD), -			 autofs_dev_ioctl_requester}, -		{cmd_idx(AUTOFS_DEV_IOCTL_EXPIRE_CMD), -			 autofs_dev_ioctl_expire}, -		{cmd_idx(AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD), -			 autofs_dev_ioctl_askumount}, -		{cmd_idx(AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD), -			 autofs_dev_ioctl_ismountpoint} +	static ioctl_fn _ioctls[] = { +		autofs_dev_ioctl_version, +		autofs_dev_ioctl_protover, +		autofs_dev_ioctl_protosubver, +		autofs_dev_ioctl_openmount, +		autofs_dev_ioctl_closemount, +		autofs_dev_ioctl_ready, +		autofs_dev_ioctl_fail, +		autofs_dev_ioctl_setpipefd, +		autofs_dev_ioctl_catatonic, +		autofs_dev_ioctl_timeout, +		autofs_dev_ioctl_requester, +		autofs_dev_ioctl_expire, +		autofs_dev_ioctl_askumount, +		autofs_dev_ioctl_ismountpoint,  	};  	unsigned int idx = cmd_idx(cmd); -	return (idx >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[idx].fn; +	return (idx >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[idx];  }  /* ioctl dispatcher */ @@ -642,7 +637,7 @@ static int _autofs_dev_ioctl(unsigned int command,  	cmd = _IOC_NR(command);  	if (_IOC_TYPE(command) != _IOC_TYPE(AUTOFS_DEV_IOCTL_IOC_FIRST) || -	    cmd - cmd_first >= AUTOFS_DEV_IOCTL_IOC_COUNT) { +	    cmd - cmd_first > AUTOFS_DEV_IOCTL_IOC_COUNT) {  		return -ENOTTY;  	} @@ -655,14 +650,11 @@ static int _autofs_dev_ioctl(unsigned int command,  	if (err)  		goto out; -	/* The validate routine above always sets the version */ -	if (cmd == AUTOFS_DEV_IOCTL_VERSION_CMD) -		goto done; -  	fn = lookup_dev_ioctl(cmd);  	if (!fn) {  		pr_warn("unknown command 0x%08x\n", command); -		return -ENOTTY; +		err = -ENOTTY; +		goto out;  	}  	fp = NULL; @@ -671,9 +663,11 @@ static int _autofs_dev_ioctl(unsigned int command,  	/*  	 * For obvious reasons the openmount can't have a file  	 * descriptor yet. We don't take a reference to the -	 * file during close to allow for immediate release. +	 * file during close to allow for immediate release, +	 * and the same for retrieving ioctl version.  	 */ -	if (cmd != AUTOFS_DEV_IOCTL_OPENMOUNT_CMD && +	if (cmd != AUTOFS_DEV_IOCTL_VERSION_CMD && +	    cmd != AUTOFS_DEV_IOCTL_OPENMOUNT_CMD &&  	    cmd != AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD) {  		fp = fget(param->ioctlfd);  		if (!fp) { @@ -706,7 +700,6 @@ cont:  	if (fp)  		fput(fp); -done:  	if (err >= 0 && copy_to_user(user, param, AUTOFS_DEV_IOCTL_SIZE))  		err = -EFAULT;  out:  |