4 * Kernel compatibililty routines for e.g. 32 bit syscall support
7 * Copyright (C) 2002 Stephen Rothwell, IBM Corporation
8 * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
9 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
10 * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
11 * Copyright (C) 2003 Pavel Machek (pavel@ucw.cz)
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
18 #include <linux/compat.h>
19 #include <linux/ncp_mount.h>
20 #include <linux/nfs4_mount.h>
21 #include <linux/syscalls.h>
22 #include <linux/slab.h>
23 #include <linux/uaccess.h>
26 struct compat_ncp_mount_data
{
29 __compat_uid_t mounted_uid
;
30 compat_pid_t wdog_pid
;
31 unsigned char mounted_vol
[NCP_VOLNAME_LEN
+ 1];
32 compat_uint_t time_out
;
33 compat_uint_t retry_count
;
37 compat_mode_t file_mode
;
38 compat_mode_t dir_mode
;
41 struct compat_ncp_mount_data_v4
{
44 compat_ulong_t mounted_uid
;
45 compat_long_t wdog_pid
;
47 compat_uint_t time_out
;
48 compat_uint_t retry_count
;
51 compat_ulong_t file_mode
;
52 compat_ulong_t dir_mode
;
55 static void *do_ncp_super_data_conv(void *raw_data
)
57 int version
= *(unsigned int *)raw_data
;
60 struct compat_ncp_mount_data
*c_n
= raw_data
;
61 struct ncp_mount_data
*n
= raw_data
;
63 n
->dir_mode
= c_n
->dir_mode
;
64 n
->file_mode
= c_n
->file_mode
;
67 memmove (n
->mounted_vol
, c_n
->mounted_vol
, (sizeof (c_n
->mounted_vol
) + 3 * sizeof (unsigned int)));
68 n
->wdog_pid
= c_n
->wdog_pid
;
69 n
->mounted_uid
= c_n
->mounted_uid
;
70 } else if (version
== 4) {
71 struct compat_ncp_mount_data_v4
*c_n
= raw_data
;
72 struct ncp_mount_data_v4
*n
= raw_data
;
74 n
->dir_mode
= c_n
->dir_mode
;
75 n
->file_mode
= c_n
->file_mode
;
78 n
->retry_count
= c_n
->retry_count
;
79 n
->time_out
= c_n
->time_out
;
80 n
->ncp_fd
= c_n
->ncp_fd
;
81 n
->wdog_pid
= c_n
->wdog_pid
;
82 n
->mounted_uid
= c_n
->mounted_uid
;
83 n
->flags
= c_n
->flags
;
84 } else if (version
!= 5) {
92 struct compat_nfs_string
{
97 static inline void compat_nfs_string(struct nfs_string
*dst
,
98 struct compat_nfs_string
*src
)
100 dst
->data
= compat_ptr(src
->data
);
104 struct compat_nfs4_mount_data_v1
{
105 compat_int_t version
;
110 compat_int_t retrans
;
111 compat_int_t acregmin
;
112 compat_int_t acregmax
;
113 compat_int_t acdirmin
;
114 compat_int_t acdirmax
;
115 struct compat_nfs_string client_addr
;
116 struct compat_nfs_string mnt_path
;
117 struct compat_nfs_string hostname
;
118 compat_uint_t host_addrlen
;
119 compat_uptr_t host_addr
;
121 compat_int_t auth_flavourlen
;
122 compat_uptr_t auth_flavours
;
125 static int do_nfs4_super_data_conv(void *raw_data
)
127 int version
= *(compat_uint_t
*) raw_data
;
130 struct compat_nfs4_mount_data_v1
*raw
= raw_data
;
131 struct nfs4_mount_data
*real
= raw_data
;
133 /* copy the fields backwards */
134 real
->auth_flavours
= compat_ptr(raw
->auth_flavours
);
135 real
->auth_flavourlen
= raw
->auth_flavourlen
;
136 real
->proto
= raw
->proto
;
137 real
->host_addr
= compat_ptr(raw
->host_addr
);
138 real
->host_addrlen
= raw
->host_addrlen
;
139 compat_nfs_string(&real
->hostname
, &raw
->hostname
);
140 compat_nfs_string(&real
->mnt_path
, &raw
->mnt_path
);
141 compat_nfs_string(&real
->client_addr
, &raw
->client_addr
);
142 real
->acdirmax
= raw
->acdirmax
;
143 real
->acdirmin
= raw
->acdirmin
;
144 real
->acregmax
= raw
->acregmax
;
145 real
->acregmin
= raw
->acregmin
;
146 real
->retrans
= raw
->retrans
;
147 real
->timeo
= raw
->timeo
;
148 real
->wsize
= raw
->wsize
;
149 real
->rsize
= raw
->rsize
;
150 real
->flags
= raw
->flags
;
151 real
->version
= raw
->version
;
157 #define NCPFS_NAME "ncpfs"
158 #define NFS4_NAME "nfs4"
160 COMPAT_SYSCALL_DEFINE5(mount
, const char __user
*, dev_name
,
161 const char __user
*, dir_name
,
162 const char __user
*, type
, compat_ulong_t
, flags
,
163 const void __user
*, data
)
170 kernel_type
= copy_mount_string(type
);
171 retval
= PTR_ERR(kernel_type
);
172 if (IS_ERR(kernel_type
))
175 kernel_dev
= copy_mount_string(dev_name
);
176 retval
= PTR_ERR(kernel_dev
);
177 if (IS_ERR(kernel_dev
))
180 options
= copy_mount_options(data
);
181 retval
= PTR_ERR(options
);
185 if (kernel_type
&& options
) {
186 if (!strcmp(kernel_type
, NCPFS_NAME
)) {
187 do_ncp_super_data_conv(options
);
188 } else if (!strcmp(kernel_type
, NFS4_NAME
)) {
190 if (do_nfs4_super_data_conv(options
))
195 retval
= do_mount(kernel_dev
, dir_name
, kernel_type
, flags
, options
);