Deleted Added
full compact
linux_file.c (179651) linux_file.c (182892)
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

--- 13 unchanged lines hidden (view full) ---

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
29#include <sys/cdefs.h>
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

--- 13 unchanged lines hidden (view full) ---

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
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/compat/linux/linux_file.c 179651 2008-06-08 11:09:25Z rdivacky $");
30__FBSDID("$FreeBSD: head/sys/compat/linux/linux_file.c 182892 2008-09-09 16:00:17Z rdivacky $");
31
32#include "opt_compat.h"
33#include "opt_mac.h"
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/conf.h>
38#include <sys/dirent.h>

--- 259 unchanged lines hidden (view full) ---

298struct l_dirent64 {
299 uint64_t d_ino;
300 int64_t d_off;
301 l_ushort d_reclen;
302 u_char d_type;
303 char d_name[LINUX_NAME_MAX + 1];
304};
305
31
32#include "opt_compat.h"
33#include "opt_mac.h"
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/conf.h>
38#include <sys/dirent.h>

--- 259 unchanged lines hidden (view full) ---

298struct l_dirent64 {
299 uint64_t d_ino;
300 int64_t d_off;
301 l_ushort d_reclen;
302 u_char d_type;
303 char d_name[LINUX_NAME_MAX + 1];
304};
305
306#define LINUX_RECLEN(de,namlen) \
307 ALIGN((((char *)&(de)->d_name - (char *)de) + (namlen) + 1))
306/*
307 * Linux uses the last byte in the dirent buffer to store d_type,
308 * at least glibc-2.7 requires it. That is why l_dirent is padded with 2 bytes.
309 */
310#define LINUX_RECLEN(namlen) \
311 roundup((offsetof(struct l_dirent, d_name) + (namlen) + 2), \
312 sizeof(l_ulong))
308
313
314#define LINUX_RECLEN64(namlen) \
315 roundup((offsetof(struct l_dirent64, d_name) + (namlen) + 1), \
316 sizeof(uint64_t))
317
318#define LINUX_MAXRECLEN max(LINUX_RECLEN(LINUX_NAME_MAX), \
319 LINUX_RECLEN64(LINUX_NAME_MAX))
309#define LINUX_DIRBLKSIZ 512
310
311static int
312getdents_common(struct thread *td, struct linux_getdents64_args *args,
313 int is64bit)
314{
315 struct dirent *bdp;
316 struct vnode *vp;
317 caddr_t inp, buf; /* BSD-format */
318 int len, reclen; /* BSD-format */
319 caddr_t outp; /* Linux-format */
320 int resid, linuxreclen=0; /* Linux-format */
320#define LINUX_DIRBLKSIZ 512
321
322static int
323getdents_common(struct thread *td, struct linux_getdents64_args *args,
324 int is64bit)
325{
326 struct dirent *bdp;
327 struct vnode *vp;
328 caddr_t inp, buf; /* BSD-format */
329 int len, reclen; /* BSD-format */
330 caddr_t outp; /* Linux-format */
331 int resid, linuxreclen=0; /* Linux-format */
332 caddr_t lbuf; /* Linux-format */
321 struct file *fp;
322 struct uio auio;
323 struct iovec aiov;
324 off_t off;
333 struct file *fp;
334 struct uio auio;
335 struct iovec aiov;
336 off_t off;
325 struct l_dirent linux_dirent;
326 struct l_dirent64 linux_dirent64;
337 struct l_dirent *linux_dirent;
338 struct l_dirent64 *linux_dirent64;
327 int buflen, error, eofflag, nbytes, justone;
328 u_long *cookies = NULL, *cookiep;
329 int ncookies, vfslocked;
330
331 nbytes = args->count;
332 if (nbytes == 1) {
333 /* readdir(2) case. Always struct dirent. */
334 if (is64bit)

--- 19 unchanged lines hidden (view full) ---

354 return (EINVAL);
355 }
356
357 off = fp->f_offset;
358
359 buflen = max(LINUX_DIRBLKSIZ, nbytes);
360 buflen = min(buflen, MAXBSIZE);
361 buf = malloc(buflen, M_TEMP, M_WAITOK);
339 int buflen, error, eofflag, nbytes, justone;
340 u_long *cookies = NULL, *cookiep;
341 int ncookies, vfslocked;
342
343 nbytes = args->count;
344 if (nbytes == 1) {
345 /* readdir(2) case. Always struct dirent. */
346 if (is64bit)

--- 19 unchanged lines hidden (view full) ---

366 return (EINVAL);
367 }
368
369 off = fp->f_offset;
370
371 buflen = max(LINUX_DIRBLKSIZ, nbytes);
372 buflen = min(buflen, MAXBSIZE);
373 buf = malloc(buflen, M_TEMP, M_WAITOK);
374 lbuf = malloc(LINUX_MAXRECLEN, M_TEMP, M_WAITOK | M_ZERO);
362 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
363
364again:
365 aiov.iov_base = buf;
366 aiov.iov_len = buflen;
367 auio.uio_iov = &aiov;
368 auio.uio_iovcnt = 1;
369 auio.uio_rw = UIO_READ;

--- 61 unchanged lines hidden (view full) ---

431 } else
432 off += reclen;
433
434 len -= reclen;
435 continue;
436 }
437
438 linuxreclen = (is64bit)
375 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
376
377again:
378 aiov.iov_base = buf;
379 aiov.iov_len = buflen;
380 auio.uio_iov = &aiov;
381 auio.uio_iovcnt = 1;
382 auio.uio_rw = UIO_READ;

--- 61 unchanged lines hidden (view full) ---

444 } else
445 off += reclen;
446
447 len -= reclen;
448 continue;
449 }
450
451 linuxreclen = (is64bit)
439 ? LINUX_RECLEN(&linux_dirent64, bdp->d_namlen)
440 : LINUX_RECLEN(&linux_dirent, bdp->d_namlen);
452 ? LINUX_RECLEN64(bdp->d_namlen)
453 : LINUX_RECLEN(bdp->d_namlen);
441
442 if (reclen > len || resid < linuxreclen) {
443 outp++;
444 break;
445 }
446
447 if (justone) {
448 /* readdir(2) case. */
454
455 if (reclen > len || resid < linuxreclen) {
456 outp++;
457 break;
458 }
459
460 if (justone) {
461 /* readdir(2) case. */
449 linux_dirent.d_ino = bdp->d_fileno;
450 linux_dirent.d_off = (l_off_t)linuxreclen;
451 linux_dirent.d_reclen = (l_ushort)bdp->d_namlen;
452 strcpy(linux_dirent.d_name, bdp->d_name);
453 error = copyout(&linux_dirent, outp, linuxreclen);
454 } else {
455 if (is64bit) {
456 linux_dirent64.d_ino = bdp->d_fileno;
457 linux_dirent64.d_off = (cookiep)
458 ? (l_off_t)*cookiep
459 : (l_off_t)(off + reclen);
460 linux_dirent64.d_reclen =
461 (l_ushort)linuxreclen;
462 linux_dirent64.d_type = bdp->d_type;
463 strcpy(linux_dirent64.d_name, bdp->d_name);
464 error = copyout(&linux_dirent64, outp,
465 linuxreclen);
466 } else {
467 linux_dirent.d_ino = bdp->d_fileno;
468 linux_dirent.d_off = (cookiep)
469 ? (l_off_t)*cookiep
470 : (l_off_t)(off + reclen);
471 linux_dirent.d_reclen = (l_ushort)linuxreclen;
472 strcpy(linux_dirent.d_name, bdp->d_name);
473 error = copyout(&linux_dirent, outp,
474 linuxreclen);
475 }
462 linux_dirent = (struct l_dirent*)lbuf;
463 linux_dirent->d_ino = bdp->d_fileno;
464 linux_dirent->d_off = (l_off_t)linuxreclen;
465 linux_dirent->d_reclen = (l_ushort)bdp->d_namlen;
466 strlcpy(linux_dirent->d_name, bdp->d_name,
467 linuxreclen - offsetof(struct l_dirent, d_name));
468 error = copyout(linux_dirent, outp, linuxreclen);
476 }
469 }
470 if (is64bit) {
471 linux_dirent64 = (struct l_dirent64*)lbuf;
472 linux_dirent64->d_ino = bdp->d_fileno;
473 linux_dirent64->d_off = (cookiep)
474 ? (l_off_t)*cookiep
475 : (l_off_t)(off + reclen);
476 linux_dirent64->d_reclen = (l_ushort)linuxreclen;
477 linux_dirent64->d_type = bdp->d_type;
478 strlcpy(linux_dirent64->d_name, bdp->d_name,
479 linuxreclen - offsetof(struct l_dirent64, d_name));
480 error = copyout(linux_dirent64, outp, linuxreclen);
481 } else if (!justone) {
482 linux_dirent = (struct l_dirent*)lbuf;
483 linux_dirent->d_ino = bdp->d_fileno;
484 linux_dirent->d_off = (cookiep)
485 ? (l_off_t)*cookiep
486 : (l_off_t)(off + reclen);
487 linux_dirent->d_reclen = (l_ushort)linuxreclen;
488 /*
489 * Copy d_type to last byte of l_dirent buffer
490 */
491 lbuf[linuxreclen-1] = bdp->d_type;
492 strlcpy(linux_dirent->d_name, bdp->d_name,
493 linuxreclen - offsetof(struct l_dirent, d_name)-1);
494 error = copyout(linux_dirent, outp, linuxreclen);
495 }
496
477 if (error)
478 goto out;
479
480 inp += reclen;
481 if (cookiep) {
482 off = *cookiep++;
483 ncookies--;
484 } else

--- 19 unchanged lines hidden (view full) ---

504out:
505 if (cookies)
506 free(cookies, M_TEMP);
507
508 VOP_UNLOCK(vp, 0);
509 VFS_UNLOCK_GIANT(vfslocked);
510 fdrop(fp, td);
511 free(buf, M_TEMP);
497 if (error)
498 goto out;
499
500 inp += reclen;
501 if (cookiep) {
502 off = *cookiep++;
503 ncookies--;
504 } else

--- 19 unchanged lines hidden (view full) ---

524out:
525 if (cookies)
526 free(cookies, M_TEMP);
527
528 VOP_UNLOCK(vp, 0);
529 VFS_UNLOCK_GIANT(vfslocked);
530 fdrop(fp, td);
531 free(buf, M_TEMP);
532 free(lbuf, M_TEMP);
512 return (error);
513}
514
515int
516linux_getdents(struct thread *td, struct linux_getdents_args *args)
517{
518
519#ifdef DEBUG

--- 986 unchanged lines hidden ---
533 return (error);
534}
535
536int
537linux_getdents(struct thread *td, struct linux_getdents_args *args)
538{
539
540#ifdef DEBUG

--- 986 unchanged lines hidden ---