ffs_vfsops.c (141526) | ffs_vfsops.c (141539) |
---|---|
1/*- 2 * Copyright (c) 1989, 1991, 1993, 1994 3 * The Regents of the University of California. 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 --- 16 unchanged lines hidden (view full) --- 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)ffs_vfsops.c 8.31 (Berkeley) 5/20/95 30 */ 31 32#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1989, 1991, 1993, 1994 3 * The Regents of the University of California. 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 --- 16 unchanged lines hidden (view full) --- 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)ffs_vfsops.c 8.31 (Berkeley) 5/20/95 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_vfsops.c 141526 2005-02-08 17:40:01Z phk $"); | 33__FBSDID("$FreeBSD: head/sys/ufs/ffs/ffs_vfsops.c 141539 2005-02-08 20:29:10Z phk $"); |
34 35#include "opt_mac.h" 36#include "opt_quota.h" 37#include "opt_ufs.h" 38#include "opt_ffs.h" 39 40#include <sys/param.h> 41#include <sys/systm.h> --- 55 unchanged lines hidden (view full) --- 97 .vfs_unmount = ffs_unmount, 98 .vfs_vget = ffs_vget, 99 .vfs_vptofh = ffs_vptofh, 100}; 101 102VFS_SET(ufs_vfsops, ufs, 0); 103 104static b_strategy_t ffs_geom_strategy; | 34 35#include "opt_mac.h" 36#include "opt_quota.h" 37#include "opt_ufs.h" 38#include "opt_ffs.h" 39 40#include <sys/param.h> 41#include <sys/systm.h> --- 55 unchanged lines hidden (view full) --- 97 .vfs_unmount = ffs_unmount, 98 .vfs_vget = ffs_vget, 99 .vfs_vptofh = ffs_vptofh, 100}; 101 102VFS_SET(ufs_vfsops, ufs, 0); 103 104static b_strategy_t ffs_geom_strategy; |
105static b_write_t ffs_bufwrite; |
|
105 106static struct buf_ops ffs_ops = { 107 .bop_name = "FFS", | 106 107static struct buf_ops ffs_ops = { 108 .bop_name = "FFS", |
108 .bop_write = bufwrite, | 109 .bop_write = ffs_bufwrite, |
109 .bop_strategy = ffs_geom_strategy, 110 .bop_sync = bufsync, 111}; 112 113static const char *ffs_opts[] = { "from", "export", NULL }; 114 115static int 116ffs_mount(struct mount *mp, struct thread *td) --- 1383 unchanged lines hidden (view full) --- 1500 1501 if (ump->um_fstype == UFS1 && ip->i_din1 != NULL) 1502 uma_zfree(uma_ufs1, ip->i_din1); 1503 else if (ip->i_din2 != NULL) 1504 uma_zfree(uma_ufs2, ip->i_din2); 1505 uma_zfree(uma_inode, ip); 1506} 1507 | 110 .bop_strategy = ffs_geom_strategy, 111 .bop_sync = bufsync, 112}; 113 114static const char *ffs_opts[] = { "from", "export", NULL }; 115 116static int 117ffs_mount(struct mount *mp, struct thread *td) --- 1383 unchanged lines hidden (view full) --- 1501 1502 if (ump->um_fstype == UFS1 && ip->i_din1 != NULL) 1503 uma_zfree(uma_ufs1, ip->i_din1); 1504 else if (ip->i_din2 != NULL) 1505 uma_zfree(uma_ufs2, ip->i_din2); 1506 uma_zfree(uma_inode, ip); 1507} 1508 |
1509static int dobkgrdwrite = 1; 1510SYSCTL_INT(_debug, OID_AUTO, dobkgrdwrite, CTLFLAG_RW, &dobkgrdwrite, 0, 1511 "Do background writes (honoring the BV_BKGRDWRITE flag)?"); 1512 1513/* 1514 * Complete a background write started from bwrite. 1515 */ |
|
1508static void | 1516static void |
1517ffs_backgroundwritedone(struct buf *bp) 1518{ 1519 struct buf *origbp; 1520 1521 /* 1522 * Find the original buffer that we are writing. 1523 */ 1524 BO_LOCK(bp->b_bufobj); 1525 if ((origbp = gbincore(bp->b_bufobj, bp->b_lblkno)) == NULL) 1526 panic("backgroundwritedone: lost buffer"); 1527 BO_UNLOCK(bp->b_bufobj); 1528 /* 1529 * Process dependencies then return any unfinished ones. 1530 */ 1531 if (LIST_FIRST(&bp->b_dep) != NULL) 1532 buf_complete(bp); 1533#ifdef SOFTUPDATES 1534 if (LIST_FIRST(&bp->b_dep) != NULL) 1535 softdep_move_dependencies(bp, origbp); 1536#endif 1537 1538 /* 1539 * This buffer is marked B_NOCACHE, so when it is released 1540 * by biodone, it will be tossed. We mark it with BIO_READ 1541 * to avoid biodone doing a second bufobj_wdrop. 1542 */ 1543 bp->b_flags |= B_NOCACHE; 1544 bp->b_iocmd = BIO_READ; 1545 bp->b_flags &= ~(B_CACHE | B_DONE); 1546 bp->b_iodone = 0; 1547 bufdone(bp); 1548 BO_LOCK(origbp->b_bufobj); 1549 /* 1550 * Clear the BV_BKGRDINPROG flag in the original buffer 1551 * and awaken it if it is waiting for the write to complete. 1552 * If BV_BKGRDINPROG is not set in the original buffer it must 1553 * have been released and re-instantiated - which is not legal. 1554 */ 1555 KASSERT((origbp->b_vflags & BV_BKGRDINPROG), 1556 ("backgroundwritedone: lost buffer2")); 1557 origbp->b_vflags &= ~BV_BKGRDINPROG; 1558 if (origbp->b_vflags & BV_BKGRDWAIT) { 1559 origbp->b_vflags &= ~BV_BKGRDWAIT; 1560 wakeup(&origbp->b_xflags); 1561 } 1562 BO_UNLOCK(origbp->b_bufobj); 1563} 1564 1565 1566/* 1567 * Write, release buffer on completion. (Done by iodone 1568 * if async). Do not bother writing anything if the buffer 1569 * is invalid. 1570 * 1571 * Note that we set B_CACHE here, indicating that buffer is 1572 * fully valid and thus cacheable. This is true even of NFS 1573 * now so we set it generally. This could be set either here 1574 * or in biodone() since the I/O is synchronous. We put it 1575 * here. 1576 */ 1577static int 1578ffs_bufwrite(struct buf *bp) 1579{ 1580 int oldflags, s; 1581 struct buf *newbp; 1582 1583 CTR3(KTR_BUF, "bufwrite(%p) vp %p flags %X", bp, bp->b_vp, bp->b_flags); 1584 if (bp->b_flags & B_INVAL) { 1585 brelse(bp); 1586 return (0); 1587 } 1588 1589 oldflags = bp->b_flags; 1590 1591 if (BUF_REFCNT(bp) == 0) 1592 panic("bufwrite: buffer is not busy???"); 1593 s = splbio(); 1594 /* 1595 * If a background write is already in progress, delay 1596 * writing this block if it is asynchronous. Otherwise 1597 * wait for the background write to complete. 1598 */ 1599 BO_LOCK(bp->b_bufobj); 1600 if (bp->b_vflags & BV_BKGRDINPROG) { 1601 if (bp->b_flags & B_ASYNC) { 1602 BO_UNLOCK(bp->b_bufobj); 1603 splx(s); 1604 bdwrite(bp); 1605 return (0); 1606 } 1607 bp->b_vflags |= BV_BKGRDWAIT; 1608 msleep(&bp->b_xflags, BO_MTX(bp->b_bufobj), PRIBIO, "bwrbg", 0); 1609 if (bp->b_vflags & BV_BKGRDINPROG) 1610 panic("bufwrite: still writing"); 1611 } 1612 BO_UNLOCK(bp->b_bufobj); 1613 1614 /* Mark the buffer clean */ 1615 bundirty(bp); 1616 1617 /* 1618 * If this buffer is marked for background writing and we 1619 * do not have to wait for it, make a copy and write the 1620 * copy so as to leave this buffer ready for further use. 1621 * 1622 * This optimization eats a lot of memory. If we have a page 1623 * or buffer shortfall we can't do it. 1624 */ 1625 if (dobkgrdwrite && (bp->b_xflags & BX_BKGRDWRITE) && 1626 (bp->b_flags & B_ASYNC) && 1627 !vm_page_count_severe() && 1628 !buf_dirty_count_severe()) { 1629 KASSERT(bp->b_iodone == NULL, 1630 ("bufwrite: needs chained iodone (%p)", bp->b_iodone)); 1631 1632 /* get a new block */ 1633 newbp = geteblk(bp->b_bufsize); 1634 1635 /* 1636 * set it to be identical to the old block. We have to 1637 * set b_lblkno and BKGRDMARKER before calling bgetvp() 1638 * to avoid confusing the splay tree and gbincore(). 1639 */ 1640 memcpy(newbp->b_data, bp->b_data, bp->b_bufsize); 1641 newbp->b_lblkno = bp->b_lblkno; 1642 newbp->b_xflags |= BX_BKGRDMARKER; 1643 BO_LOCK(bp->b_bufobj); 1644 bp->b_vflags |= BV_BKGRDINPROG; 1645 bgetvp(bp->b_vp, newbp); 1646 BO_UNLOCK(bp->b_bufobj); 1647 newbp->b_bufobj = &bp->b_vp->v_bufobj; 1648 newbp->b_blkno = bp->b_blkno; 1649 newbp->b_offset = bp->b_offset; 1650 newbp->b_iodone = ffs_backgroundwritedone; 1651 newbp->b_flags |= B_ASYNC; 1652 newbp->b_flags &= ~B_INVAL; 1653 1654#ifdef SOFTUPDATES 1655 /* move over the dependencies */ 1656 if (LIST_FIRST(&bp->b_dep) != NULL) 1657 softdep_move_dependencies(bp, newbp); 1658#endif 1659 1660 /* 1661 * Initiate write on the copy, release the original to 1662 * the B_LOCKED queue so that it cannot go away until 1663 * the background write completes. If not locked it could go 1664 * away and then be reconstituted while it was being written. 1665 * If the reconstituted buffer were written, we could end up 1666 * with two background copies being written at the same time. 1667 */ 1668 bqrelse(bp); 1669 bp = newbp; 1670 } 1671 1672 /* Let the normal bufwrite do the rest for us */ 1673 bufwrite(bp); 1674 1675 return (0); 1676} 1677 1678 1679static void |
|
1509ffs_geom_strategy(struct bufobj *bo, struct buf *bp) 1510{ 1511 1512#ifdef SOFTUPDATES 1513 if (bp->b_iocmd == BIO_WRITE && softdep_disk_prewrite(bp)) 1514 return; 1515#endif 1516 g_vfs_strategy(bo, bp); 1517} | 1680ffs_geom_strategy(struct bufobj *bo, struct buf *bp) 1681{ 1682 1683#ifdef SOFTUPDATES 1684 if (bp->b_iocmd == BIO_WRITE && softdep_disk_prewrite(bp)) 1685 return; 1686#endif 1687 g_vfs_strategy(bo, bp); 1688} |