File: [Development] / linux-2.6-xfs / fs / dmapi / dmapi_sysent.c (download)
Revision 1.8, Wed Jun 6 21:08:08 2001 UTC (16 years, 4 months ago) by roehrich
Branch: MAIN
Changes since 1.7: +10 -6
lines
set MOD_INC_USE_COUNT, and do not unset it unless dm_uninit gives an okay.
Also, deregister our device.
|
/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston MA 02111-1307, USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/
/* Data Migration API (DMAPI)
*/
/* We're using MISC_MAJOR / DMAPI_MINOR. */
/* mknod /dev/dmapi c 10 140 */
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include "dmapi_private.h"
void dm_init(void);
int dm_uninit(void);
static int
dmapi_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
sys_dmapi_args_t kargs;
sys_dmapi_args_t *uap = &kargs;
int error = 0;
int rvp = -ENOSYS;
int use_rvp = 0;
if (!capable(CAP_MKNOD))
return(-EPERM);
if( copy_from_user( &kargs, (sys_dmapi_args_t*)arg,
sizeof(sys_dmapi_args_t) ) )
return -EFAULT;
switch (cmd) {
case DM_CLEAR_INHERIT:
error = dm_clear_inherit(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(dm_attrname_t *) uap->arg5); /* attrnamep */
break;
case DM_CREATE_BY_HANDLE:
error = dm_create_by_handle(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* dirhanp */
(size_t) uap->arg3, /* dirhlen */
(dm_token_t) uap->arg4, /* token */
(void *) uap->arg5, /* hanp */
(size_t) uap->arg6, /* hlen */
(char *) uap->arg7); /* cname */
break;
case DM_CREATE_SESSION:
error = dm_create_session(
(dm_sessid_t) uap->arg1, /* oldsid */
(char *) uap->arg2, /* sessinfop */
(dm_sessid_t *) uap->arg3); /* newsidp */
break;
case DM_CREATE_USEREVENT:
error = dm_create_userevent(
(dm_sessid_t) uap->arg1, /* sid */
(size_t) uap->arg2, /* msglen */
(void *) uap->arg3, /* msgdatap */
(dm_token_t *) uap->arg4); /* tokenp */
break;
case DM_DESTROY_SESSION:
error = dm_destroy_session(
(dm_sessid_t) uap->arg1); /* sid */
break;
case DM_DOWNGRADE_RIGHT:
error = dm_downgrade_right(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4); /* token */
break;
case DM_FD_TO_HANDLE:
error = dm_fd_to_hdl(
(int) uap->arg1, /* fd */
(void *) uap->arg2, /* hanp */
(size_t *) uap->arg3); /* hlenp */
break;
case DM_FIND_EVENTMSG:
error = dm_find_eventmsg(
(dm_sessid_t) uap->arg1, /* sid */
(dm_token_t) uap->arg2, /* token */
(size_t) uap->arg3, /* buflen */
(void *) uap->arg4, /* bufp */
(size_t *) uap->arg5); /* rlenp */
break;
case DM_GET_ALLOCINFO:
use_rvp = 1;
error = dm_get_allocinfo_rvp(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(dm_off_t *) uap->arg5, /* offp */
(u_int) uap->arg6, /* nelem */
(dm_extent_t *) uap->arg7, /* extentp */
(u_int *) uap->arg8, /* nelemp */
&rvp);
break;
case DM_GET_BULKALL:
use_rvp = 1;
error = dm_get_bulkall_rvp(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(u_int) uap->arg5, /* mask */
(dm_attrname_t *) uap->arg6, /* attrnamep */
(dm_attrloc_t *) uap->arg7, /* locp */
(size_t) uap->arg8, /* buflen */
(void *) uap->arg9, /* bufp */
(size_t *) uap->arg10, /* rlenp */
&rvp);
break;
case DM_GET_BULKATTR:
use_rvp = 1;
error = dm_get_bulkattr_rvp(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(u_int) uap->arg5, /* mask */
(dm_attrloc_t *)uap->arg6, /* locp */
(size_t) uap->arg7, /* buflen */
(void *) uap->arg8, /* bufp */
(size_t *) uap->arg9, /* rlenp */
&rvp);
break;
case DM_GET_CONFIG:
error = dm_get_config(
(void *) uap->arg1, /* hanp */
(size_t) uap->arg2, /* hlen */
(dm_config_t) uap->arg3, /* flagname */
(dm_size_t *) uap->arg4); /* retvalp */
break;
case DM_GET_CONFIG_EVENTS:
error = dm_get_config_events(
(void *) uap->arg1, /* hanp */
(size_t) uap->arg2, /* hlen */
(u_int) uap->arg3, /* nelem */
(dm_eventset_t *) uap->arg4, /* eventsetp */
(u_int *) uap->arg5); /* nelemp */
break;
case DM_GET_DIOINFO:
error = dm_get_dioinfo(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(dm_dioinfo_t *)uap->arg5); /* diop */
break;
case DM_GET_DIRATTRS:
use_rvp = 1;
error = dm_get_dirattrs_rvp(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(u_int) uap->arg5, /* mask */
(dm_attrloc_t *)uap->arg6, /* locp */
(size_t) uap->arg7, /* buflen */
(void *) uap->arg8, /* bufp */
(size_t *) uap->arg9, /* rlenp */
&rvp);
break;
case DM_GET_DMATTR:
error = dm_get_dmattr(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(dm_attrname_t *) uap->arg5, /* attrnamep */
(size_t) uap->arg6, /* buflen */
(void *) uap->arg7, /* bufp */
(size_t *) uap->arg8); /* rlenp */
break;
case DM_GET_EVENTLIST:
error = dm_get_eventlist(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(u_int) uap->arg5, /* nelem */
(dm_eventset_t *) uap->arg6, /* eventsetp */
(u_int *) uap->arg7); /* nelemp */
break;
case DM_GET_EVENTS:
error = dm_get_events(
(dm_sessid_t) uap->arg1, /* sid */
(u_int) uap->arg2, /* maxmsgs */
(u_int) uap->arg3, /* flags */
(size_t) uap->arg4, /* buflen */
(void *) uap->arg5, /* bufp */
(size_t *) uap->arg6); /* rlenp */
break;
case DM_GET_FILEATTR:
error = dm_get_fileattr(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(u_int) uap->arg5, /* mask */
(dm_stat_t *) uap->arg6); /* statp */
break;
case DM_GET_MOUNTINFO:
error = dm_get_mountinfo(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(size_t) uap->arg5, /* buflen */
(void *) uap->arg6, /* bufp */
(size_t *) uap->arg7); /* rlenp */
break;
case DM_GET_REGION:
error = dm_get_region(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(u_int) uap->arg5, /* nelem */
(dm_region_t *) uap->arg6, /* regbufp */
(u_int *) uap->arg7); /* nelemp */
break;
case DM_GETALL_DISP:
error = dm_getall_disp(
(dm_sessid_t) uap->arg1, /* sid */
(size_t) uap->arg2, /* buflen */
(void *) uap->arg3, /* bufp */
(size_t *) uap->arg4); /* rlenp */
break;
case DM_GETALL_DMATTR:
error = dm_getall_dmattr(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(size_t) uap->arg5, /* buflen */
(void *) uap->arg6, /* bufp */
(size_t *) uap->arg7); /* rlenp */
break;
case DM_GETALL_INHERIT:
error = dm_getall_inherit(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(u_int) uap->arg5, /* nelem */
(dm_inherit_t *)uap->arg6, /* inheritbufp*/
(u_int *) uap->arg7); /* nelemp */
break;
case DM_GETALL_SESSIONS:
error = dm_getall_sessions(
(u_int) uap->arg1, /* nelem */
(dm_sessid_t *) uap->arg2, /* sidbufp */
(u_int *) uap->arg3); /* nelemp */
break;
case DM_GETALL_TOKENS:
error = dm_getall_tokens(
(dm_sessid_t) uap->arg1, /* sid */
(u_int) uap->arg2, /* nelem */
(dm_token_t *) uap->arg3, /* tokenbufp */
(u_int *) uap->arg4); /* nelemp */
break;
case DM_INIT_ATTRLOC:
error = dm_init_attrloc(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(dm_attrloc_t *) uap->arg5); /* locp */
break;
case DM_MKDIR_BY_HANDLE:
error = dm_mkdir_by_handle(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* dirhanp */
(size_t) uap->arg3, /* dirhlen */
(dm_token_t) uap->arg4, /* token */
(void *) uap->arg5, /* hanp */
(size_t) uap->arg6, /* hlen */
(char *) uap->arg7); /* cname */
break;
case DM_MOVE_EVENT:
error = dm_move_event(
(dm_sessid_t) uap->arg1, /* srcsid */
(dm_token_t) uap->arg2, /* token */
(dm_sessid_t) uap->arg3, /* targetsid */
(dm_token_t *) uap->arg4); /* rtokenp */
break;
case DM_OBJ_REF_HOLD:
error = dm_obj_ref_hold(
(dm_sessid_t) uap->arg1, /* sid */
(dm_token_t) uap->arg2, /* token */
(void *) uap->arg3, /* hanp */
(size_t) uap->arg4); /* hlen */
break;
case DM_OBJ_REF_QUERY:
use_rvp = 1;
error = dm_obj_ref_query_rvp(
(dm_sessid_t) uap->arg1, /* sid */
(dm_token_t) uap->arg2, /* token */
(void *) uap->arg3, /* hanp */
(size_t) uap->arg4, /* hlen */
&rvp);
break;
case DM_OBJ_REF_RELE:
error = dm_obj_ref_rele(
(dm_sessid_t) uap->arg1, /* sid */
(dm_token_t) uap->arg2, /* token */
(void *) uap->arg3, /* hanp */
(size_t) uap->arg4); /* hlen */
break;
case DM_PATH_TO_FSHANDLE:
error = dm_path_to_fshdl(
(char *) uap->arg1, /* path */
(void *) uap->arg2, /* hanp */
(size_t *) uap->arg3); /* hlenp */
break;
case DM_PATH_TO_HANDLE:
error = dm_path_to_hdl(
(char *) uap->arg1, /* path */
(void *) uap->arg2, /* hanp */
(size_t *) uap->arg3); /* hlenp */
break;
case DM_PENDING:
error = dm_pending(
(dm_sessid_t) uap->arg1, /* sid */
(dm_token_t) uap->arg2, /* token */
(dm_timestruct_t *) uap->arg3); /* delay */
break;
case DM_PROBE_HOLE:
error = dm_probe_hole(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(dm_off_t) uap->arg5, /* off */
(dm_size_t) uap->arg6, /* len */
(dm_off_t *) uap->arg7, /* roffp */
(dm_size_t *) uap->arg8); /* rlenp */
break;
case DM_PUNCH_HOLE:
error = dm_punch_hole(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(dm_off_t) uap->arg5, /* off */
(dm_size_t) uap->arg6); /* len */
break;
case DM_QUERY_RIGHT:
error = dm_query_right(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(dm_right_t *) uap->arg5); /* rightp */
break;
case DM_QUERY_SESSION:
error = dm_query_session(
(dm_sessid_t) uap->arg1, /* sid */
(size_t) uap->arg2, /* buflen */
(void *) uap->arg3, /* bufp */
(size_t *) uap->arg4); /* rlenp */
break;
case DM_READ_INVIS:
use_rvp = 1;
error = dm_read_invis_rvp(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(dm_off_t) uap->arg5, /* off */
(dm_size_t) uap->arg6, /* len */
(void *) uap->arg7, /* bufp */
&rvp);
break;
case DM_RELEASE_RIGHT:
error = dm_release_right(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4); /* token */
break;
case DM_REMOVE_DMATTR:
error = dm_remove_dmattr(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(int) uap->arg5, /* setdtime */
(dm_attrname_t *) uap->arg6); /* attrnamep */
break;
case DM_REQUEST_RIGHT:
error = dm_request_right(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(u_int) uap->arg5, /* flags */
(dm_right_t) uap->arg6); /* right */
break;
case DM_RESPOND_EVENT:
error = dm_respond_event(
(dm_sessid_t) uap->arg1, /* sid */
(dm_token_t) uap->arg2, /* token */
(dm_response_t) uap->arg3, /* response */
(int) uap->arg4, /* reterror */
(size_t) uap->arg5, /* buflen */
(void *) uap->arg6); /* respbufp */
break;
case DM_SEND_MSG:
error = dm_send_msg(
(dm_sessid_t) uap->arg1, /* targetsid */
(dm_msgtype_t) uap->arg2, /* msgtype */
(size_t) uap->arg3, /* buflen */
(void *) uap->arg4); /* bufp */
break;
case DM_SET_DISP:
error = dm_set_disp(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(dm_eventset_t *) uap->arg5, /* eventsetp */
(u_int) uap->arg6); /* maxevent */
break;
case DM_SET_DMATTR:
error = dm_set_dmattr(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(dm_attrname_t *) uap->arg5, /* attrnamep */
(int) uap->arg6, /* setdtime */
(size_t) uap->arg7, /* buflen */
(void *) uap->arg8); /* bufp */
break;
case DM_SET_EVENTLIST:
error = dm_set_eventlist(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(dm_eventset_t *) uap->arg5, /* eventsetp */
(u_int) uap->arg6); /* maxevent */
break;
case DM_SET_FILEATTR:
error = dm_set_fileattr(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(u_int) uap->arg5, /* mask */
(dm_fileattr_t *)uap->arg6); /* attrp */
break;
case DM_SET_INHERIT:
error = dm_set_inherit(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(dm_attrname_t *)uap->arg5, /* attrnamep */
(mode_t) uap->arg6); /* mode */
break;
case DM_SET_REGION:
error = dm_set_region(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(u_int) uap->arg5, /* nelem */
(dm_region_t *) uap->arg6, /* regbufp */
(dm_boolean_t *) uap->arg7); /* exactflagp */
break;
case DM_SET_RETURN_ON_DESTROY:
error = dm_set_return_on_destroy(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(dm_attrname_t *) uap->arg5, /* attrnamep */
(dm_boolean_t) uap->arg6); /* enable */
break;
case DM_SYMLINK_BY_HANDLE:
error = dm_symlink_by_handle(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* dirhanp */
(size_t) uap->arg3, /* dirhlen */
(dm_token_t) uap->arg4, /* token */
(void *) uap->arg5, /* hanp */
(size_t) uap->arg6, /* hlen */
(char *) uap->arg7, /* cname */
(char *) uap->arg8); /* path */
break;
case DM_SYNC_BY_HANDLE:
error = dm_sync_by_handle(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4); /* token */
break;
case DM_UPGRADE_RIGHT:
error = dm_upgrade_right(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4); /* token */
break;
case DM_WRITE_INVIS:
use_rvp = 1;
error = dm_write_invis_rvp(
(dm_sessid_t) uap->arg1, /* sid */
(void *) uap->arg2, /* hanp */
(size_t) uap->arg3, /* hlen */
(dm_token_t) uap->arg4, /* token */
(int) uap->arg5, /* flags */
(dm_off_t) uap->arg6, /* off */
(dm_size_t) uap->arg7, /* len */
(void *) uap->arg8, /* bufp */
&rvp);
break;
default:
error = ENOSYS;
break;
}
/* If it was an *_rvp() function, then
if error==0, return |rvp|
*/
if( use_rvp && (error == 0) )
return rvp;
else
return -error;
}
/* XXX a debugging tool */
/* use 'cat /dev/dmapi' to get dump of info */
static ssize_t
dmapi_dump(struct file *file, char *buf, size_t count, loff_t *ppos)
{
char tmp[1024];
int l, len;
extern u_int dm_sessions_active;
extern dm_sessid_t dm_next_sessid;
extern dm_token_t dm_next_token;
extern dm_sequence_t dm_next_sequence;
extern int dm_fsys_cnt;
if( *ppos == 0 ){
l = sprintf( tmp, "# " DM_VER_STR_CONTENTS "\n"
"dm_sessions_active=%u\n"
"dm_next_sessid=%d\n"
"dm_next_token=%d\n"
"dm_next_sequence=%u\n"
"dm_fsys_cnt=%d\n",
dm_sessions_active,
(int)dm_next_sessid,
(int)dm_next_token,
(u_int)dm_next_sequence,
dm_fsys_cnt );
}
else {
return 0;
}
#define min(a,b) (((a)<(b))?(a):(b))
len = min(l,count);
#undef min
if( copy_to_user(buf, tmp, len) )
return -EFAULT;
*ppos += 1;
return len;
}
static int
dmapi_open(struct inode *inode, struct file *file)
{
return 0;
}
static int
dmapi_release(struct inode *inode, struct file *file)
{
return 0;
}
static struct file_operations dmapi_fops = {
open: dmapi_open,
ioctl: dmapi_ioctl,
read: dmapi_dump,
release: dmapi_release
};
static struct miscdevice dmapi_dev = {
minor: DMAPI_MINOR,
name: "dmapi",
fops: &dmapi_fops
};
void dmapi_init(void)
{
int ret;
ret = misc_register(&dmapi_dev);
if( ret != 0 )
printk(KERN_ERR "dmapi_init: misc_register returned %d\n", ret);
MOD_INC_USE_COUNT;
dm_init();
}
void dmapi_uninit(void)
{
if( dm_uninit() == 0 ){
MOD_DEC_USE_COUNT;
misc_deregister(&dmapi_dev);
}
}