| Commit | Line | Data |
|---|---|---|
| 984263bc MD |
1 | /*- |
| 2 | * Copyright (c) 1994-1995 Søren Schmidt | |
| 3 | * All rights reserved. | |
| 4 | * | |
| 5 | * Redistribution and use in source and binary forms, with or without | |
| 6 | * modification, are permitted provided that the following conditions | |
| 7 | * are met: | |
| 8 | * 1. Redistributions of source code must retain the above copyright | |
| 9 | * notice, this list of conditions and the following disclaimer | |
| 10 | * in this position and unchanged. | |
| 11 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 12 | * notice, this list of conditions and the following disclaimer in the | |
| 13 | * documentation and/or other materials provided with the distribution. | |
| 14 | * 3. The name of the author may not be used to endorse or promote products | |
| 15 | * derived from this software withough specific prior written permission | |
| 16 | * | |
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
| 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
| 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
| 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
| 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
| 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
| 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 27 | * | |
| 28 | * $FreeBSD: src/sys/compat/linux/linux_stats.c,v 1.22.2.3 2001/11/05 19:08:23 marcel Exp $ | |
| 8b953559 | 29 | * $DragonFly: src/sys/emulation/linux/linux_stats.c,v 1.27 2008/09/28 05:08:16 dillon Exp $ |
| 984263bc MD |
30 | */ |
| 31 | ||
| 32 | #include <sys/param.h> | |
| dadab5e9 | 33 | #include <sys/systm.h> |
| 984263bc MD |
34 | #include <sys/conf.h> |
| 35 | #include <sys/dirent.h> | |
| 36 | #include <sys/file.h> | |
| 37 | #include <sys/filedesc.h> | |
| 38 | #include <sys/proc.h> | |
| 39 | #include <sys/mount.h> | |
| 21739618 | 40 | #include <sys/nlookup.h> |
| 984263bc MD |
41 | #include <sys/stat.h> |
| 42 | #include <sys/sysctl.h> | |
| 43 | #include <sys/systm.h> | |
| 0f8362a6 | 44 | #include <sys/unistd.h> |
| 984263bc | 45 | #include <sys/vnode.h> |
| 335dda38 | 46 | #include <sys/device.h> |
| dadab5e9 | 47 | #include <sys/file2.h> |
| 8f6f8622 | 48 | #include <sys/kern_syscall.h> |
| 984263bc | 49 | |
| 932f49b9 MD |
50 | #include <arch_linux/linux.h> |
| 51 | #include <arch_linux/linux_proto.h> | |
| 1f2de5d4 | 52 | #include "linux_util.h" |
| 984263bc MD |
53 | |
| 54 | static int | |
| 55 | newstat_copyout(struct stat *buf, void *ubuf) | |
| 56 | { | |
| 57 | struct l_newstat tbuf; | |
| b13267a5 | 58 | cdev_t dev; |
| 136178b3 | 59 | int error; |
| 984263bc MD |
60 | |
| 61 | tbuf.st_dev = uminor(buf->st_dev) | (umajor(buf->st_dev) << 8); | |
| 8b953559 | 62 | tbuf.st_ino = INO64TO32(buf->st_ino); |
| 984263bc MD |
63 | tbuf.st_mode = buf->st_mode; |
| 64 | tbuf.st_nlink = buf->st_nlink; | |
| 65 | tbuf.st_uid = buf->st_uid; | |
| 66 | tbuf.st_gid = buf->st_gid; | |
| 67 | tbuf.st_rdev = buf->st_rdev; | |
| 68 | tbuf.st_size = buf->st_size; | |
| 69 | tbuf.st_atime = buf->st_atime; | |
| 70 | tbuf.st_mtime = buf->st_mtime; | |
| 71 | tbuf.st_ctime = buf->st_ctime; | |
| 72 | tbuf.st_blksize = buf->st_blksize; | |
| 73 | tbuf.st_blocks = buf->st_blocks; | |
| 74 | ||
| 75 | /* Lie about disk drives which are character devices | |
| 76 | * in FreeBSD but block devices under Linux. | |
| 77 | */ | |
| 78 | if (S_ISCHR(tbuf.st_mode) && | |
| 028066b1 | 79 | (dev = udev2dev(buf->st_rdev, 0)) != NULL) { |
| e4c9c0c8 | 80 | if (dev_is_good(dev) && (dev_dflags(dev) & D_DISK)) { |
| 984263bc MD |
81 | tbuf.st_mode &= ~S_IFMT; |
| 82 | tbuf.st_mode |= S_IFBLK; | |
| 83 | ||
| 84 | /* XXX this may not be quite right */ | |
| 85 | /* Map major number to 0 */ | |
| 86 | tbuf.st_dev = uminor(buf->st_dev) & 0xf; | |
| 87 | tbuf.st_rdev = buf->st_rdev & 0xff; | |
| 88 | } | |
| 89 | } | |
| 90 | ||
| 136178b3 DRJ |
91 | error = copyout(&tbuf, ubuf, sizeof(tbuf)); |
| 92 | return (error); | |
| 984263bc MD |
93 | } |
| 94 | ||
| 3919ced0 MD |
95 | /* |
| 96 | * MPALMOSTSAFE | |
| 97 | */ | |
| 984263bc | 98 | int |
| 753fd850 | 99 | sys_linux_newstat(struct linux_newstat_args *args) |
| 984263bc MD |
100 | { |
| 101 | struct stat buf; | |
| 21739618 | 102 | struct nlookupdata nd; |
| 136178b3 | 103 | char *path; |
| 984263bc | 104 | int error; |
| 984263bc | 105 | |
| 136178b3 DRJ |
106 | error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS); |
| 107 | if (error) | |
| 108 | return (error); | |
| 984263bc MD |
109 | #ifdef DEBUG |
| 110 | if (ldebug(newstat)) | |
| 26be20a0 | 111 | kprintf(ARGS(newstat, "%s, *"), path); |
| 984263bc | 112 | #endif |
| 3919ced0 | 113 | get_mplock(); |
| 21739618 MD |
114 | error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); |
| 115 | if (error == 0) { | |
| 116 | error = kern_stat(&nd, &buf); | |
| 117 | if (error == 0) | |
| 118 | error = newstat_copyout(&buf, args->buf); | |
| 524c845c | 119 | nlookup_done(&nd); |
| 21739618 | 120 | } |
| 3919ced0 | 121 | rel_mplock(); |
| 136178b3 DRJ |
122 | linux_free_path(&path); |
| 123 | return (error); | |
| 984263bc MD |
124 | } |
| 125 | ||
| 3919ced0 MD |
126 | /* |
| 127 | * MPALMOSTSAFE | |
| 128 | */ | |
| 984263bc | 129 | int |
| 753fd850 | 130 | sys_linux_newlstat(struct linux_newlstat_args *args) |
| 984263bc | 131 | { |
| 984263bc | 132 | struct stat sb; |
| 21739618 | 133 | struct nlookupdata nd; |
| 136178b3 DRJ |
134 | char *path; |
| 135 | int error; | |
| 984263bc | 136 | |
| 136178b3 DRJ |
137 | error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS); |
| 138 | if (error) | |
| 139 | return (error); | |
| 984263bc MD |
140 | #ifdef DEBUG |
| 141 | if (ldebug(newlstat)) | |
| 26be20a0 | 142 | kprintf(ARGS(newlstat, "%s, *"), path); |
| 984263bc | 143 | #endif |
| 3919ced0 | 144 | get_mplock(); |
| 21739618 MD |
145 | error = nlookup_init(&nd, path, UIO_SYSSPACE, 0); |
| 146 | if (error == 0) { | |
| 147 | error = kern_stat(&nd, &sb); | |
| 148 | if (error == 0) | |
| 149 | error = newstat_copyout(&sb, args->buf); | |
| 524c845c | 150 | nlookup_done(&nd); |
| 21739618 | 151 | } |
| 3919ced0 | 152 | rel_mplock(); |
| 136178b3 DRJ |
153 | linux_free_path(&path); |
| 154 | return (error); | |
| 984263bc MD |
155 | } |
| 156 | ||
| 3919ced0 MD |
157 | /* |
| 158 | * MPALMOSTSAFE | |
| 159 | */ | |
| 984263bc | 160 | int |
| 753fd850 | 161 | sys_linux_newfstat(struct linux_newfstat_args *args) |
| 984263bc | 162 | { |
| 984263bc MD |
163 | struct stat buf; |
| 164 | int error; | |
| 165 | ||
| 166 | #ifdef DEBUG | |
| 167 | if (ldebug(newfstat)) | |
| 26be20a0 | 168 | kprintf(ARGS(newfstat, "%d, *"), args->fd); |
| 984263bc | 169 | #endif |
| 3919ced0 | 170 | get_mplock(); |
| 8f6f8622 | 171 | error = kern_fstat(args->fd, &buf); |
| 3919ced0 | 172 | rel_mplock(); |
| 984263bc | 173 | |
| 8f6f8622 | 174 | if (error == 0) |
| 984263bc | 175 | error = newstat_copyout(&buf, args->buf); |
| 984263bc MD |
176 | return (error); |
| 177 | } | |
| 178 | ||
| 179 | /* XXX - All fields of type l_int are defined as l_long on i386 */ | |
| 180 | struct l_statfs { | |
| 181 | l_int f_type; | |
| 182 | l_int f_bsize; | |
| 183 | l_int f_blocks; | |
| 184 | l_int f_bfree; | |
| 185 | l_int f_bavail; | |
| 186 | l_int f_files; | |
| 187 | l_int f_ffree; | |
| 188 | l_fsid_t f_fsid; | |
| 189 | l_int f_namelen; | |
| 190 | l_int f_spare[6]; | |
| 191 | }; | |
| 192 | ||
| 193 | #define LINUX_CODA_SUPER_MAGIC 0x73757245L | |
| 194 | #define LINUX_EXT2_SUPER_MAGIC 0xEF53L | |
| 195 | #define LINUX_HPFS_SUPER_MAGIC 0xf995e849L | |
| 196 | #define LINUX_ISOFS_SUPER_MAGIC 0x9660L | |
| 197 | #define LINUX_MSDOS_SUPER_MAGIC 0x4d44L | |
| 198 | #define LINUX_NCP_SUPER_MAGIC 0x564cL | |
| 199 | #define LINUX_NFS_SUPER_MAGIC 0x6969L | |
| 200 | #define LINUX_NTFS_SUPER_MAGIC 0x5346544EL | |
| 201 | #define LINUX_PROC_SUPER_MAGIC 0x9fa0L | |
| 202 | #define LINUX_UFS_SUPER_MAGIC 0x00011954L /* XXX - UFS_MAGIC in Linux */ | |
| 203 | ||
| 204 | static long | |
| 205 | bsd_to_linux_ftype(const char *fstypename) | |
| 206 | { | |
| 207 | int i; | |
| 208 | static struct {const char *bsd_name; long linux_type;} b2l_tbl[] = { | |
| 209 | {"ufs", LINUX_UFS_SUPER_MAGIC}, | |
| 210 | {"cd9660", LINUX_ISOFS_SUPER_MAGIC}, | |
| 211 | {"nfs", LINUX_NFS_SUPER_MAGIC}, | |
| 212 | {"ext2fs", LINUX_EXT2_SUPER_MAGIC}, | |
| 213 | {"procfs", LINUX_PROC_SUPER_MAGIC}, | |
| 214 | {"msdosfs", LINUX_MSDOS_SUPER_MAGIC}, | |
| 215 | {"ntfs", LINUX_NTFS_SUPER_MAGIC}, | |
| 216 | {"nwfs", LINUX_NCP_SUPER_MAGIC}, | |
| 217 | {"hpfs", LINUX_HPFS_SUPER_MAGIC}, | |
| 984263bc MD |
218 | {NULL, 0L}}; |
| 219 | ||
| 220 | for (i = 0; b2l_tbl[i].bsd_name != NULL; i++) | |
| 221 | if (strcmp(b2l_tbl[i].bsd_name, fstypename) == 0) | |
| 222 | return (b2l_tbl[i].linux_type); | |
| 223 | ||
| 224 | return (0L); | |
| 225 | } | |
| 226 | ||
| 136178b3 | 227 | static int |
| 0f8362a6 | 228 | statfs_copyout(struct statfs *statfs, struct l_statfs_buf *buf, l_int namelen) |
| 136178b3 DRJ |
229 | { |
| 230 | struct l_statfs linux_statfs; | |
| 231 | int error; | |
| 232 | ||
| 233 | linux_statfs.f_type = bsd_to_linux_ftype(statfs->f_fstypename); | |
| 234 | linux_statfs.f_bsize = statfs->f_bsize; | |
| 235 | linux_statfs.f_blocks = statfs->f_blocks; | |
| 236 | linux_statfs.f_bfree = statfs->f_bfree; | |
| 237 | linux_statfs.f_bavail = statfs->f_bavail; | |
| 238 | linux_statfs.f_ffree = statfs->f_ffree; | |
| 239 | linux_statfs.f_files = statfs->f_files; | |
| 240 | linux_statfs.f_fsid.val[0] = statfs->f_fsid.val[0]; | |
| 241 | linux_statfs.f_fsid.val[1] = statfs->f_fsid.val[1]; | |
| 0f8362a6 | 242 | linux_statfs.f_namelen = namelen; |
| 136178b3 DRJ |
243 | |
| 244 | error = copyout(&linux_statfs, buf, sizeof(linux_statfs)); | |
| 245 | return (error); | |
| 246 | } | |
| 247 | ||
| 3919ced0 MD |
248 | /* |
| 249 | * MPALMOSTSAFE | |
| 250 | */ | |
| 984263bc | 251 | int |
| 753fd850 | 252 | sys_linux_statfs(struct linux_statfs_args *args) |
| 984263bc | 253 | { |
| 136178b3 | 254 | struct statfs statfs; |
| fad57d0e | 255 | struct nlookupdata nd; |
| 136178b3 | 256 | char *path; |
| 0f8362a6 | 257 | int error, namelen; |
| 984263bc | 258 | |
| 136178b3 DRJ |
259 | error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS); |
| 260 | if (error) | |
| 261 | return (error); | |
| 984263bc MD |
262 | #ifdef DEBUG |
| 263 | if (ldebug(statfs)) | |
| 26be20a0 | 264 | kprintf(ARGS(statfs, "%s, *"), path); |
| 984263bc | 265 | #endif |
| 3919ced0 | 266 | get_mplock(); |
| fad57d0e MD |
267 | error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); |
| 268 | if (error == 0) | |
| 269 | error = kern_statfs(&nd, &statfs); | |
| 2789f826 | 270 | if (error == 0) { |
| 28623bf9 MD |
271 | if (nd.nl_nch.ncp->nc_vp != NULL) |
| 272 | error = vn_get_namelen(nd.nl_nch.ncp->nc_vp, &namelen); | |
| 2789f826 JS |
273 | else |
| 274 | error = EINVAL; | |
| 275 | } | |
| fad57d0e | 276 | nlookup_done(&nd); |
| 3919ced0 | 277 | rel_mplock(); |
| 136178b3 | 278 | if (error == 0) |
| 0f8362a6 | 279 | error = statfs_copyout(&statfs, args->buf, (l_int)namelen); |
| 136178b3 DRJ |
280 | linux_free_path(&path); |
| 281 | return (error); | |
| 984263bc MD |
282 | } |
| 283 | ||
| 3919ced0 MD |
284 | /* |
| 285 | * MPALMOSTSAFE | |
| 286 | */ | |
| 984263bc | 287 | int |
| 753fd850 | 288 | sys_linux_fstatfs(struct linux_fstatfs_args *args) |
| 984263bc | 289 | { |
| 0f8362a6 JS |
290 | struct proc *p = curthread->td_proc; |
| 291 | struct file *fp; | |
| 136178b3 | 292 | struct statfs statfs; |
| 0f8362a6 | 293 | int error, namelen; |
| 984263bc MD |
294 | |
| 295 | #ifdef DEBUG | |
| 296 | if (ldebug(fstatfs)) | |
| 26be20a0 | 297 | kprintf(ARGS(fstatfs, "%d, *"), args->fd); |
| 984263bc | 298 | #endif |
| 3919ced0 | 299 | get_mplock(); |
| 5b287bba MD |
300 | if ((error = kern_fstatfs(args->fd, &statfs)) != 0) |
| 301 | return (error); | |
| 302 | if ((error = holdvnode(p->p_fd, args->fd, &fp)) != 0) | |
| 303 | return (error); | |
| 304 | error = vn_get_namelen((struct vnode *)fp->f_data, &namelen); | |
| 3919ced0 | 305 | rel_mplock(); |
| 5b287bba | 306 | fdrop(fp); |
| 0f8362a6 JS |
307 | if (error == 0) |
| 308 | error = statfs_copyout(&statfs, args->buf, (l_int)namelen); | |
| 136178b3 | 309 | return (error); |
| 984263bc MD |
310 | } |
| 311 | ||
| 312 | struct l_ustat | |
| 313 | { | |
| 314 | l_daddr_t f_tfree; | |
| 315 | l_ino_t f_tinode; | |
| 316 | char f_fname[6]; | |
| 317 | char f_fpack[6]; | |
| 318 | }; | |
| 319 | ||
| 3919ced0 MD |
320 | /* |
| 321 | * MPALMOSTSAFE | |
| 322 | */ | |
| 984263bc | 323 | int |
| 753fd850 | 324 | sys_linux_ustat(struct linux_ustat_args *args) |
| 984263bc | 325 | { |
| 9910d07b | 326 | struct thread *td = curthread; |
| 984263bc | 327 | struct l_ustat lu; |
| b13267a5 | 328 | cdev_t dev; |
| 984263bc MD |
329 | struct vnode *vp; |
| 330 | struct statfs *stat; | |
| 331 | int error; | |
| 332 | ||
| 333 | #ifdef DEBUG | |
| 334 | if (ldebug(ustat)) | |
| 26be20a0 | 335 | kprintf(ARGS(ustat, "%d, *"), args->dev); |
| 984263bc MD |
336 | #endif |
| 337 | ||
| 338 | /* | |
| 339 | * lu.f_fname and lu.f_fpack are not used. They are always zeroed. | |
| 340 | * lu.f_tinode and lu.f_tfree are set from the device's super block. | |
| 341 | */ | |
| 342 | bzero(&lu, sizeof(lu)); | |
| 343 | ||
| 344 | /* | |
| 345 | * XXX - Don't return an error if we can't find a vnode for the | |
| b13267a5 MD |
346 | * device. Our cdev_t is 32-bits whereas Linux only has a 16-bits |
| 347 | * cdev_t. The dev_t that is used now may as well be a truncated | |
| 348 | * cdev_t returned from previous syscalls. Just return a bzeroed | |
| 984263bc MD |
349 | * ustat in that case. |
| 350 | */ | |
| 3919ced0 | 351 | get_mplock(); |
| e4c9c0c8 | 352 | dev = udev2dev(makeudev(args->dev >> 8, args->dev & 0xFF), 0); |
| 028066b1 | 353 | if (dev != NULL && vfinddev(dev, VCHR, &vp)) { |
| e4c9c0c8 | 354 | if (vp->v_mount == NULL) { |
| 3875f5b0 | 355 | vrele(vp); |
| 3919ced0 MD |
356 | error = EINVAL; |
| 357 | goto done; | |
| e4c9c0c8 | 358 | } |
| 984263bc | 359 | stat = &(vp->v_mount->mnt_stat); |
| 9910d07b | 360 | error = VFS_STATFS(vp->v_mount, stat, td->td_ucred); |
| 3875f5b0 | 361 | vrele(vp); |
| 3919ced0 MD |
362 | if (error == 0) { |
| 363 | lu.f_tfree = stat->f_bfree; | |
| 364 | lu.f_tinode = stat->f_ffree; | |
| e4c9c0c8 | 365 | } |
| 3919ced0 MD |
366 | } else { |
| 367 | error = 0; | |
| 984263bc | 368 | } |
| 3919ced0 MD |
369 | done: |
| 370 | rel_mplock(); | |
| 371 | if (error == 0) | |
| 372 | error = copyout(&lu, args->ubuf, sizeof(lu)); | |
| 373 | return (error); | |
| 984263bc MD |
374 | } |
| 375 | ||
| 376 | #if defined(__i386__) | |
| 377 | ||
| 378 | static int | |
| 379 | stat64_copyout(struct stat *buf, void *ubuf) | |
| 380 | { | |
| 381 | struct l_stat64 lbuf; | |
| 136178b3 | 382 | int error; |
| 984263bc MD |
383 | |
| 384 | bzero(&lbuf, sizeof(lbuf)); | |
| 385 | lbuf.st_dev = uminor(buf->st_dev) | (umajor(buf->st_dev) << 8); | |
| 386 | lbuf.st_ino = buf->st_ino; | |
| 387 | lbuf.st_mode = buf->st_mode; | |
| 388 | lbuf.st_nlink = buf->st_nlink; | |
| 389 | lbuf.st_uid = buf->st_uid; | |
| 390 | lbuf.st_gid = buf->st_gid; | |
| 391 | lbuf.st_rdev = buf->st_rdev; | |
| 392 | lbuf.st_size = buf->st_size; | |
| 393 | lbuf.st_atime = buf->st_atime; | |
| 394 | lbuf.st_mtime = buf->st_mtime; | |
| 395 | lbuf.st_ctime = buf->st_ctime; | |
| 396 | lbuf.st_blksize = buf->st_blksize; | |
| 397 | lbuf.st_blocks = buf->st_blocks; | |
| 398 | ||
| 399 | /* | |
| 400 | * The __st_ino field makes all the difference. In the Linux kernel | |
| 401 | * it is conditionally compiled based on STAT64_HAS_BROKEN_ST_INO, | |
| 402 | * but without the assignment to __st_ino the runtime linker refuses | |
| 403 | * to mmap(2) any shared libraries. I guess it's broken alright :-) | |
| 404 | */ | |
| 8b953559 | 405 | lbuf.__st_ino = INO64TO32(buf->st_ino); |
| 984263bc | 406 | |
| 136178b3 DRJ |
407 | error = copyout(&lbuf, ubuf, sizeof(lbuf)); |
| 408 | return (error); | |
| 984263bc MD |
409 | } |
| 410 | ||
| 3919ced0 MD |
411 | /* |
| 412 | * MPALMOSTSAFE | |
| 413 | */ | |
| 984263bc | 414 | int |
| 753fd850 | 415 | sys_linux_stat64(struct linux_stat64_args *args) |
| 984263bc | 416 | { |
| 21739618 | 417 | struct nlookupdata nd; |
| 136178b3 DRJ |
418 | struct stat buf; |
| 419 | char *path; | |
| 984263bc | 420 | int error; |
| 984263bc | 421 | |
| 136178b3 DRJ |
422 | error = linux_copyin_path(args->filename, &path, LINUX_PATH_EXISTS); |
| 423 | if (error) | |
| 424 | return (error); | |
| 984263bc MD |
425 | #ifdef DEBUG |
| 426 | if (ldebug(stat64)) | |
| 26be20a0 | 427 | kprintf(ARGS(stat64, "%s, *"), path); |
| 984263bc | 428 | #endif |
| 3919ced0 | 429 | get_mplock(); |
| 21739618 MD |
430 | error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW); |
| 431 | if (error == 0) { | |
| 432 | error = kern_stat(&nd, &buf); | |
| 524c845c | 433 | nlookup_done(&nd); |
| 21739618 | 434 | } |
| 3919ced0 MD |
435 | rel_mplock(); |
| 436 | if (error == 0) | |
| 437 | error = stat64_copyout(&buf, args->statbuf); | |
| 136178b3 DRJ |
438 | linux_free_path(&path); |
| 439 | return (error); | |
| 984263bc MD |
440 | } |
| 441 | ||
| 3919ced0 MD |
442 | /* |
| 443 | * MPALMOSTSAFE | |
| 444 | */ | |
| 984263bc | 445 | int |
| 753fd850 | 446 | sys_linux_lstat64(struct linux_lstat64_args *args) |
| 984263bc | 447 | { |
| 21739618 | 448 | struct nlookupdata nd; |
| 136178b3 DRJ |
449 | struct stat sb; |
| 450 | char *path; | |
| 451 | int error; | |
| 984263bc | 452 | |
| 136178b3 DRJ |
453 | error = linux_copyin_path(args->filename, &path, LINUX_PATH_EXISTS); |
| 454 | if (error) | |
| 455 | return (error); | |
| 984263bc MD |
456 | #ifdef DEBUG |
| 457 | if (ldebug(lstat64)) | |
| 26be20a0 | 458 | kprintf(ARGS(lstat64, "%s, *"), path); |
| 984263bc | 459 | #endif |
| 3919ced0 | 460 | get_mplock(); |
| 21739618 MD |
461 | error = nlookup_init(&nd, path, UIO_SYSSPACE, 0); |
| 462 | if (error == 0) { | |
| 463 | error = kern_stat(&nd, &sb); | |
| 524c845c | 464 | nlookup_done(&nd); |
| 21739618 | 465 | } |
| 3919ced0 MD |
466 | rel_mplock(); |
| 467 | if (error == 0) | |
| 468 | error = stat64_copyout(&sb, args->statbuf); | |
| 136178b3 DRJ |
469 | linux_free_path(&path); |
| 470 | return (error); | |
| 984263bc MD |
471 | } |
| 472 | ||
| 3919ced0 MD |
473 | /* |
| 474 | * MPALMOSTSAFE | |
| 475 | */ | |
| 984263bc | 476 | int |
| 753fd850 | 477 | sys_linux_fstat64(struct linux_fstat64_args *args) |
| 984263bc | 478 | { |
| 984263bc MD |
479 | struct stat buf; |
| 480 | int error; | |
| 481 | ||
| 482 | #ifdef DEBUG | |
| 483 | if (ldebug(fstat64)) | |
| 26be20a0 | 484 | kprintf(ARGS(fstat64, "%d, *"), args->fd); |
| 984263bc | 485 | #endif |
| 3919ced0 | 486 | get_mplock(); |
| 8f6f8622 | 487 | error = kern_fstat(args->fd, &buf); |
| 3919ced0 | 488 | rel_mplock(); |
| 984263bc | 489 | |
| 8f6f8622 | 490 | if (error == 0) |
| 984263bc | 491 | error = stat64_copyout(&buf, args->statbuf); |
| 984263bc MD |
492 | return (error); |
| 493 | } | |
| 494 | ||
| 495 | #endif /* __i386__ */ |