Deleted Added
full compact
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}