msdosfs_vnops.c (3152) | msdosfs_vnops.c (3167) |
---|---|
1/* $Id: msdosfs_vnops.c,v 1.2 1994/09/21 03:47:17 wollman Exp $ */ | 1/* $Id: msdosfs_vnops.c,v 1.3 1994/09/27 20:42:56 phk Exp $ */ |
2/* $NetBSD: msdosfs_vnops.c,v 1.20 1994/08/21 18:44:13 ws Exp $ */ 3 4/*- 5 * Copyright (C) 1994 Wolfgang Solfrank. 6 * Copyright (C) 1994 TooLs GmbH. 7 * All rights reserved. 8 * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below). 9 * --- 1429 unchanged lines hidden (view full) --- 1439 struct buf *bp; 1440 struct denode *dep = VTODE(ap->a_vp); 1441 struct msdosfsmount *pmp = dep->de_pmp; 1442 struct direntry *dentp; 1443 struct dirent *prev; 1444 struct dirent *crnt; 1445 u_char dirbuf[512]; /* holds converted dos directories */ 1446 struct uio *uio = ap->a_uio; | 2/* $NetBSD: msdosfs_vnops.c,v 1.20 1994/08/21 18:44:13 ws Exp $ */ 3 4/*- 5 * Copyright (C) 1994 Wolfgang Solfrank. 6 * Copyright (C) 1994 TooLs GmbH. 7 * All rights reserved. 8 * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below). 9 * --- 1429 unchanged lines hidden (view full) --- 1439 struct buf *bp; 1440 struct denode *dep = VTODE(ap->a_vp); 1441 struct msdosfsmount *pmp = dep->de_pmp; 1442 struct direntry *dentp; 1443 struct dirent *prev; 1444 struct dirent *crnt; 1445 u_char dirbuf[512]; /* holds converted dos directories */ 1446 struct uio *uio = ap->a_uio; |
1447 int ncookies = 1; 1448 u_int* cookies = NULL; | 1447 off_t off; 1448 int ncookies = 0; |
1449 1450#ifdef MSDOSFS_DEBUG 1451 printf("msdosfs_readdir(): vp %08x, uio %08x, cred %08x, eofflagp %08x\n", 1452 ap->a_vp, uio, ap->a_cred, ap->a_eofflag); 1453#endif 1454 | 1449 1450#ifdef MSDOSFS_DEBUG 1451 printf("msdosfs_readdir(): vp %08x, uio %08x, cred %08x, eofflagp %08x\n", 1452 ap->a_vp, uio, ap->a_cred, ap->a_eofflag); 1453#endif 1454 |
1455#if 0 1456 if (!ap->a_cookies) 1457 ncookies = 1; 1458#endif 1459 | |
1460 /* 1461 * msdosfs_readdir() won't operate properly on regular files since 1462 * it does i/o only with the the filesystem vnode, and hence can 1463 * retrieve the wrong block from the buffer cache for a plain file. 1464 * So, fail attempts to readdir() on a plain file. 1465 */ 1466 if ((dep->de_Attributes & ATTR_DIRECTORY) == 0) 1467 return ENOTDIR; --- 5 unchanged lines hidden (view full) --- 1473 */ 1474 count = uio->uio_resid & ~(sizeof(struct direntry) - 1); 1475 lost = uio->uio_resid - count; 1476 if (count < sizeof(struct direntry) || 1477 (uio->uio_offset & (sizeof(struct direntry) - 1))) 1478 return EINVAL; 1479 uio->uio_resid = count; 1480 uio->uio_iov->iov_len = count; | 1455 /* 1456 * msdosfs_readdir() won't operate properly on regular files since 1457 * it does i/o only with the the filesystem vnode, and hence can 1458 * retrieve the wrong block from the buffer cache for a plain file. 1459 * So, fail attempts to readdir() on a plain file. 1460 */ 1461 if ((dep->de_Attributes & ATTR_DIRECTORY) == 0) 1462 return ENOTDIR; --- 5 unchanged lines hidden (view full) --- 1468 */ 1469 count = uio->uio_resid & ~(sizeof(struct direntry) - 1); 1470 lost = uio->uio_resid - count; 1471 if (count < sizeof(struct direntry) || 1472 (uio->uio_offset & (sizeof(struct direntry) - 1))) 1473 return EINVAL; 1474 uio->uio_resid = count; 1475 uio->uio_iov->iov_len = count; |
1476 off = uio->uio_offset; |
|
1481 1482 /* 1483 * If they are reading from the root directory then, we simulate 1484 * the . and .. entries since these don't exist in the root 1485 * directory. We also set the offset bias to make up for having to 1486 * simulate these entries. By this I mean that at file offset 64 we 1487 * read the first entry in the root directory that lives on disk. 1488 */ --- 7 unchanged lines hidden (view full) --- 1496 if (uio->uio_offset 1497 && uio->uio_offset != sizeof(struct direntry)) { 1498 error = EINVAL; 1499 goto out; 1500 } 1501 n = 1; 1502 if (!uio->uio_offset) { 1503 n = 2; | 1477 1478 /* 1479 * If they are reading from the root directory then, we simulate 1480 * the . and .. entries since these don't exist in the root 1481 * directory. We also set the offset bias to make up for having to 1482 * simulate these entries. By this I mean that at file offset 64 we 1483 * read the first entry in the root directory that lives on disk. 1484 */ --- 7 unchanged lines hidden (view full) --- 1492 if (uio->uio_offset 1493 && uio->uio_offset != sizeof(struct direntry)) { 1494 error = EINVAL; 1495 goto out; 1496 } 1497 n = 1; 1498 if (!uio->uio_offset) { 1499 n = 2; |
1504 if (cookies) { 1505 *cookies++ = sizeof(struct direntry); 1506 ncookies--; 1507 } | 1500 ncookies++; |
1508 } | 1501 } |
1509 if (cookies) { 1510 if (ncookies-- <= 0) 1511 n--; 1512 else 1513 *cookies++ = 2 * sizeof(struct direntry); 1514 } 1515 | 1502 ncookies++; |
1516 error = uiomove((char *) rootdots + uio->uio_offset, 1517 n * sizeof(struct direntry), uio); 1518 } 1519 } | 1503 error = uiomove((char *) rootdots + uio->uio_offset, 1504 n * sizeof(struct direntry), uio); 1505 } 1506 } |
1520 while (!error && uio->uio_resid > 0 && ncookies > 0) { | 1507 while (!error && uio->uio_resid > 0) { |
1521 lbn = (uio->uio_offset - bias) >> pmp->pm_cnshift; 1522 on = (uio->uio_offset - bias) & pmp->pm_crbomask; 1523 n = min((u_long) (pmp->pm_bpcluster - on), uio->uio_resid); 1524 diff = dep->de_FileSize - (uio->uio_offset - bias); 1525 if (diff <= 0) 1526 return 0; 1527 if (diff < n) 1528 n = diff; --- 27 unchanged lines hidden (view full) --- 1556 * previous entry or, manufacture an empty entry if 1557 * there is no previous entry. 1558 */ 1559 if (dentp->deName[0] == SLOT_EMPTY || 1560 dentp->deName[0] == SLOT_DELETED || 1561 (dentp->deAttributes & ATTR_VOLUME)) { 1562 if (prev) { 1563 prev->d_reclen += sizeof(struct direntry); | 1508 lbn = (uio->uio_offset - bias) >> pmp->pm_cnshift; 1509 on = (uio->uio_offset - bias) & pmp->pm_crbomask; 1510 n = min((u_long) (pmp->pm_bpcluster - on), uio->uio_resid); 1511 diff = dep->de_FileSize - (uio->uio_offset - bias); 1512 if (diff <= 0) 1513 return 0; 1514 if (diff < n) 1515 n = diff; --- 27 unchanged lines hidden (view full) --- 1543 * previous entry or, manufacture an empty entry if 1544 * there is no previous entry. 1545 */ 1546 if (dentp->deName[0] == SLOT_EMPTY || 1547 dentp->deName[0] == SLOT_DELETED || 1548 (dentp->deAttributes & ATTR_VOLUME)) { 1549 if (prev) { 1550 prev->d_reclen += sizeof(struct direntry); |
1564 if (cookies) { 1565 ncookies++; 1566 cookies--; 1567 } | |
1568 } else { 1569 prev = crnt; 1570 prev->d_fileno = 0; 1571 prev->d_reclen = sizeof(struct direntry); 1572 prev->d_type = DT_UNKNOWN; 1573 prev->d_namlen = 0; 1574 prev->d_name[0] = 0; | 1551 } else { 1552 prev = crnt; 1553 prev->d_fileno = 0; 1554 prev->d_reclen = sizeof(struct direntry); 1555 prev->d_type = DT_UNKNOWN; 1556 prev->d_namlen = 0; 1557 prev->d_name[0] = 0; |
1558 ncookies++; |
|
1575 } 1576 } else { 1577 /* 1578 * this computation of d_fileno must match 1579 * the computation of va_fileid in 1580 * msdosfs_getattr 1581 */ 1582 if (dentp->deAttributes & ATTR_DIRECTORY) { --- 18 unchanged lines hidden (view full) --- 1601 crnt->d_namlen = dos2unixfn(dentp->deName, 1602 (u_char *)crnt->d_name); 1603 /* 1604 * printf("readdir: file %s, fileno %08x, attr %02x, start %08x\n", 1605 * crnt->d_name, crnt->d_fileno, dentp->deAttributes, 1606 * dentp->deStartCluster); 1607 */ 1608 prev = crnt; | 1559 } 1560 } else { 1561 /* 1562 * this computation of d_fileno must match 1563 * the computation of va_fileid in 1564 * msdosfs_getattr 1565 */ 1566 if (dentp->deAttributes & ATTR_DIRECTORY) { --- 18 unchanged lines hidden (view full) --- 1585 crnt->d_namlen = dos2unixfn(dentp->deName, 1586 (u_char *)crnt->d_name); 1587 /* 1588 * printf("readdir: file %s, fileno %08x, attr %02x, start %08x\n", 1589 * crnt->d_name, crnt->d_fileno, dentp->deAttributes, 1590 * dentp->deStartCluster); 1591 */ 1592 prev = crnt; |
1593 ncookies++; |
|
1609 } 1610 dentp++; | 1594 } 1595 dentp++; |
1611 if (cookies) { 1612 *cookies++ = (u_int)((char *)dentp - bp->b_data - on) 1613 + uio->uio_offset; 1614 ncookies--; 1615 } | |
1616 1617 crnt = (struct dirent *) ((char *) crnt + sizeof(struct direntry)); 1618 pushout = 1; 1619 1620 /* 1621 * If our intermediate buffer is full then copy its 1622 * contents to user space. I would just use the 1623 * buffer the buf header points to but, I'm afraid --- 5 unchanged lines hidden (view full) --- 1629 if ((u_char *) crnt >= &dirbuf[sizeof dirbuf]) { 1630 pushout = 0; 1631 error = uiomove(dirbuf, sizeof(dirbuf), uio); 1632 if (error) 1633 break; 1634 prev = 0; 1635 crnt = (struct dirent *) dirbuf; 1636 } | 1596 1597 crnt = (struct dirent *) ((char *) crnt + sizeof(struct direntry)); 1598 pushout = 1; 1599 1600 /* 1601 * If our intermediate buffer is full then copy its 1602 * contents to user space. I would just use the 1603 * buffer the buf header points to but, I'm afraid --- 5 unchanged lines hidden (view full) --- 1609 if ((u_char *) crnt >= &dirbuf[sizeof dirbuf]) { 1610 pushout = 0; 1611 error = uiomove(dirbuf, sizeof(dirbuf), uio); 1612 if (error) 1613 break; 1614 prev = 0; 1615 crnt = (struct dirent *) dirbuf; 1616 } |
1637 if (ncookies <= 0) 1638 break; | |
1639 } 1640 if (pushout) { 1641 pushout = 0; 1642 error = uiomove(dirbuf, (char *) crnt - (char *) dirbuf, 1643 uio); 1644 } 1645 1646#if 0 --- 7 unchanged lines hidden (view full) --- 1654 bp->b_flags |= B_AGE; 1655#endif /* if 0 */ 1656 brelse(bp); 1657 if (n == 0) 1658 break; 1659 } 1660out: ; 1661 uio->uio_resid += lost; | 1617 } 1618 if (pushout) { 1619 pushout = 0; 1620 error = uiomove(dirbuf, (char *) crnt - (char *) dirbuf, 1621 uio); 1622 } 1623 1624#if 0 --- 7 unchanged lines hidden (view full) --- 1632 bp->b_flags |= B_AGE; 1633#endif /* if 0 */ 1634 brelse(bp); 1635 if (n == 0) 1636 break; 1637 } 1638out: ; 1639 uio->uio_resid += lost; |
1640 if (!error && ap->a_ncookies != NULL) { 1641 struct dirent* dpStart; 1642 struct dirent* dpEnd; 1643 struct dirent* dp; 1644 u_int *cookies; 1645 u_int *cookiep; |
|
1662 | 1646 |
1663#if 0 | 1647 if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) 1648 panic("msdosfs_readdir: unexpected uio from NFS server"); 1649 dpStart = (struct dirent *) 1650 (uio->uio_iov->iov_base - (uio->uio_offset - off)); 1651 dpEnd = (struct dirent *) uio->uio_iov->iov_base; 1652 MALLOC(cookies, u_int *, ncookies * sizeof(u_int), 1653 M_TEMP, M_WAITOK); 1654 for (dp = dpStart, cookiep = cookies; 1655 dp < dpEnd; 1656 dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) { 1657 off += dp->d_reclen; 1658 *cookiep++ = (u_int) off; 1659 } 1660 *ap->a_ncookies = ncookies; 1661 *ap->a_cookies = cookies; 1662 } 1663 |
1664 /* 1665 * I don't know why we bother setting this eofflag, getdirentries() 1666 * in vfs_syscalls.c doesn't bother to look at it when we return. 1667 * (because NFS uses it in nfs_serv.c -- JMP) 1668 */ | 1664 /* 1665 * I don't know why we bother setting this eofflag, getdirentries() 1666 * in vfs_syscalls.c doesn't bother to look at it when we return. 1667 * (because NFS uses it in nfs_serv.c -- JMP) 1668 */ |
1669 if (dep->de_FileSize - uio->uio_offset - bias <= 0) 1670 *ap->a_eofflag = 1; 1671 else 1672 *ap->a_eofflag = 0; 1673#endif | 1669 if (ap->a_eofflag) 1670 if (dep->de_FileSize - uio->uio_offset - bias <= 0) 1671 *ap->a_eofflag = 1; 1672 else 1673 *ap->a_eofflag = 0; |
1674 1675 return error; 1676} 1677 1678/* 1679 * DOS filesystems don't know what symlinks are. 1680 */ 1681int --- 266 unchanged lines hidden --- | 1674 1675 return error; 1676} 1677 1678/* 1679 * DOS filesystems don't know what symlinks are. 1680 */ 1681int --- 266 unchanged lines hidden --- |