ext2_vnops.c (221166) | ext2_vnops.c (228507) |
---|---|
1/*- 2 * modified for EXT2FS support in Lites 1.1 3 * 4 * Aug 1995, Godmar Back (gback@cs.utah.edu) 5 * University of Utah, Department of Computer Science 6 */ 7/*- 8 * Copyright (c) 1982, 1986, 1989, 1993 --- 25 unchanged lines hidden (view full) --- 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * @(#)ufs_vnops.c 8.7 (Berkeley) 2/3/94 41 * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 | 1/*- 2 * modified for EXT2FS support in Lites 1.1 3 * 4 * Aug 1995, Godmar Back (gback@cs.utah.edu) 5 * University of Utah, Department of Computer Science 6 */ 7/*- 8 * Copyright (c) 1982, 1986, 1989, 1993 --- 25 unchanged lines hidden (view full) --- 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * @(#)ufs_vnops.c 8.7 (Berkeley) 2/3/94 41 * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 |
42 * $FreeBSD: head/sys/fs/ext2fs/ext2_vnops.c 221166 2011-04-28 14:27:17Z jhb $ | 42 * $FreeBSD: head/sys/fs/ext2fs/ext2_vnops.c 228507 2011-12-14 22:04:14Z pfg $ |
43 */ 44 45#include "opt_suiddir.h" 46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/kernel.h> 50#include <sys/fcntl.h> --- 8 unchanged lines hidden (view full) --- 59#include <sys/vnode.h> 60#include <sys/namei.h> 61#include <sys/lockf.h> 62#include <sys/event.h> 63#include <sys/conf.h> 64#include <sys/file.h> 65 66#include <vm/vm.h> | 43 */ 44 45#include "opt_suiddir.h" 46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/kernel.h> 50#include <sys/fcntl.h> --- 8 unchanged lines hidden (view full) --- 59#include <sys/vnode.h> 60#include <sys/namei.h> 61#include <sys/lockf.h> 62#include <sys/event.h> 63#include <sys/conf.h> 64#include <sys/file.h> 65 66#include <vm/vm.h> |
67#include <vm/vm_page.h> 68#include <vm/vm_object.h> |
|
67#include <vm/vm_extern.h> 68#include <vm/vnode_pager.h> 69 | 69#include <vm/vm_extern.h> 70#include <vm/vnode_pager.h> 71 |
72#include "opt_directio.h" 73 |
|
70#include <fs/fifofs/fifo.h> 71 72#include <ufs/ufs/dir.h> 73 74#include <fs/ext2fs/fs.h> 75#include <fs/ext2fs/inode.h> 76#include <fs/ext2fs/ext2_extern.h> 77#include <fs/ext2fs/ext2fs.h> --- 76 unchanged lines hidden (view full) --- 154 .vop_print = ext2_print, 155 .vop_read = VOP_PANIC, 156 .vop_reclaim = ext2_reclaim, 157 .vop_setattr = ext2_setattr, 158 .vop_write = VOP_PANIC, 159 .vop_vptofh = ext2_vptofh, 160}; 161 | 74#include <fs/fifofs/fifo.h> 75 76#include <ufs/ufs/dir.h> 77 78#include <fs/ext2fs/fs.h> 79#include <fs/ext2fs/inode.h> 80#include <fs/ext2fs/ext2_extern.h> 81#include <fs/ext2fs/ext2fs.h> --- 76 unchanged lines hidden (view full) --- 158 .vop_print = ext2_print, 159 .vop_read = VOP_PANIC, 160 .vop_reclaim = ext2_reclaim, 161 .vop_setattr = ext2_setattr, 162 .vop_write = VOP_PANIC, 163 .vop_vptofh = ext2_vptofh, 164}; 165 |
162#include <fs/ext2fs/ext2_readwrite.c> 163 | |
164/* 165 * A virgin directory (no blushing please). 166 * Note that the type and namlen fields are reversed relative to ext2. 167 * Also, we don't use `struct odirtemplate', since it would just cause 168 * endianness problems. 169 */ 170static struct dirtemplate mastertemplate = { 171 0, 12, 1, EXT2_FT_DIR, ".", --- 1498 unchanged lines hidden (view full) --- 1670 * Write error occurred trying to update the inode 1671 * or the directory so must deallocate the inode. 1672 */ 1673 ip->i_nlink = 0; 1674 ip->i_flag |= IN_CHANGE; 1675 vput(tvp); 1676 return (error); 1677} | 166/* 167 * A virgin directory (no blushing please). 168 * Note that the type and namlen fields are reversed relative to ext2. 169 * Also, we don't use `struct odirtemplate', since it would just cause 170 * endianness problems. 171 */ 172static struct dirtemplate mastertemplate = { 173 0, 12, 1, EXT2_FT_DIR, ".", --- 1498 unchanged lines hidden (view full) --- 1672 * Write error occurred trying to update the inode 1673 * or the directory so must deallocate the inode. 1674 */ 1675 ip->i_nlink = 0; 1676 ip->i_flag |= IN_CHANGE; 1677 vput(tvp); 1678 return (error); 1679} |
1680 1681/* 1682 * Vnode op for reading. 1683 */ 1684static int 1685ext2_read(ap) 1686 struct vop_read_args /* { 1687 struct vnode *a_vp; 1688 struct uio *a_uio; 1689 int a_ioflag; 1690 struct ucred *a_cred; 1691 } */ *ap; 1692{ 1693 struct vnode *vp; 1694 struct inode *ip; 1695 struct uio *uio; 1696 struct m_ext2fs *fs; 1697 struct buf *bp; 1698 daddr_t lbn, nextlbn; 1699 off_t bytesinfile; 1700 long size, xfersize, blkoffset; 1701 int error, orig_resid, seqcount; 1702 int ioflag; 1703 1704 vp = ap->a_vp; 1705 uio = ap->a_uio; 1706 ioflag = ap->a_ioflag; 1707 1708 seqcount = ap->a_ioflag >> IO_SEQSHIFT; 1709 ip = VTOI(vp); 1710 1711#ifdef INVARIANTS 1712 if (uio->uio_rw != UIO_READ) 1713 panic("%s: mode", "ext2_read"); 1714 1715 if (vp->v_type == VLNK) { 1716 if ((int)ip->i_size < vp->v_mount->mnt_maxsymlinklen) 1717 panic("%s: short symlink", "ext2_read"); 1718 } else if (vp->v_type != VREG && vp->v_type != VDIR) 1719 panic("%s: type %d", "ext2_read", vp->v_type); 1720#endif 1721 orig_resid = uio->uio_resid; 1722 KASSERT(orig_resid >= 0, ("ext2_read: uio->uio_resid < 0")); 1723 if (orig_resid == 0) 1724 return (0); 1725 KASSERT(uio->uio_offset >= 0, ("ext2_read: uio->uio_offset < 0")); 1726 fs = ip->i_e2fs; 1727 if (uio->uio_offset < ip->i_size && 1728 uio->uio_offset >= fs->e2fs_maxfilesize) 1729 return (EOVERFLOW); 1730 1731 for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) { 1732 if ((bytesinfile = ip->i_size - uio->uio_offset) <= 0) 1733 break; 1734 lbn = lblkno(fs, uio->uio_offset); 1735 nextlbn = lbn + 1; 1736 size = blksize(fs, ip, lbn); 1737 blkoffset = blkoff(fs, uio->uio_offset); 1738 1739 xfersize = fs->e2fs_fsize - blkoffset; 1740 if (uio->uio_resid < xfersize) 1741 xfersize = uio->uio_resid; 1742 if (bytesinfile < xfersize) 1743 xfersize = bytesinfile; 1744 1745 if (lblktosize(fs, nextlbn) >= ip->i_size) 1746 error = bread(vp, lbn, size, NOCRED, &bp); 1747 else if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) 1748 error = cluster_read(vp, ip->i_size, lbn, size, 1749 NOCRED, blkoffset + uio->uio_resid, seqcount, &bp); 1750 else if (seqcount > 1) { 1751 int nextsize = blksize(fs, ip, nextlbn); 1752 error = breadn(vp, lbn, 1753 size, &nextlbn, &nextsize, 1, NOCRED, &bp); 1754 } else 1755 error = bread(vp, lbn, size, NOCRED, &bp); 1756 if (error) { 1757 brelse(bp); 1758 bp = NULL; 1759 break; 1760 } 1761 1762 /* 1763 * If IO_DIRECT then set B_DIRECT for the buffer. This 1764 * will cause us to attempt to release the buffer later on 1765 * and will cause the buffer cache to attempt to free the 1766 * underlying pages. 1767 */ 1768 if (ioflag & IO_DIRECT) 1769 bp->b_flags |= B_DIRECT; 1770 1771 /* 1772 * We should only get non-zero b_resid when an I/O error 1773 * has occurred, which should cause us to break above. 1774 * However, if the short read did not cause an error, 1775 * then we want to ensure that we do not uiomove bad 1776 * or uninitialized data. 1777 */ 1778 size -= bp->b_resid; 1779 if (size < xfersize) { 1780 if (size == 0) 1781 break; 1782 xfersize = size; 1783 } 1784 error = uiomove((char *)bp->b_data + blkoffset, 1785 (int)xfersize, uio); 1786 if (error) 1787 break; 1788 1789 if (ioflag & (IO_VMIO|IO_DIRECT)) { 1790 /* 1791 * If it's VMIO or direct I/O, then we don't 1792 * need the buf, mark it available for 1793 * freeing. If it's non-direct VMIO, the VM has 1794 * the data. 1795 */ 1796 bp->b_flags |= B_RELBUF; 1797 brelse(bp); 1798 } else { 1799 /* 1800 * Otherwise let whoever 1801 * made the request take care of 1802 * freeing it. We just queue 1803 * it onto another list. 1804 */ 1805 bqrelse(bp); 1806 } 1807 } 1808 1809 /* 1810 * This can only happen in the case of an error 1811 * because the loop above resets bp to NULL on each iteration 1812 * and on normal completion has not set a new value into it. 1813 * so it must have come from a 'break' statement 1814 */ 1815 if (bp != NULL) { 1816 if (ioflag & (IO_VMIO|IO_DIRECT)) { 1817 bp->b_flags |= B_RELBUF; 1818 brelse(bp); 1819 } else { 1820 bqrelse(bp); 1821 } 1822 } 1823 1824 if ((error == 0 || uio->uio_resid != orig_resid) && 1825 (vp->v_mount->mnt_flag & MNT_NOATIME) == 0) 1826 ip->i_flag |= IN_ACCESS; 1827 return (error); 1828} 1829 1830/* 1831 * Vnode op for writing. 1832 */ 1833static int 1834ext2_write(ap) 1835 struct vop_write_args /* { 1836 struct vnode *a_vp; 1837 struct uio *a_uio; 1838 int a_ioflag; 1839 struct ucred *a_cred; 1840 } */ *ap; 1841{ 1842 struct vnode *vp; 1843 struct uio *uio; 1844 struct inode *ip; 1845 struct m_ext2fs *fs; 1846 struct buf *bp; 1847 daddr_t lbn; 1848 off_t osize; 1849 int blkoffset, error, flags, ioflag, resid, size, seqcount, xfersize; 1850 1851 ioflag = ap->a_ioflag; 1852 uio = ap->a_uio; 1853 vp = ap->a_vp; 1854 1855 seqcount = ioflag >> IO_SEQSHIFT; 1856 ip = VTOI(vp); 1857 1858#ifdef INVARIANTS 1859 if (uio->uio_rw != UIO_WRITE) 1860 panic("%s: mode", "ext2_write"); 1861#endif 1862 1863 switch (vp->v_type) { 1864 case VREG: 1865 if (ioflag & IO_APPEND) 1866 uio->uio_offset = ip->i_size; 1867 if ((ip->i_flags & APPEND) && uio->uio_offset != ip->i_size) 1868 return (EPERM); 1869 /* FALLTHROUGH */ 1870 case VLNK: 1871 break; 1872 case VDIR: 1873 /* XXX differs from ffs -- this is called from ext2_mkdir(). */ 1874 if ((ioflag & IO_SYNC) == 0) 1875 panic("ext2_write: nonsync dir write"); 1876 break; 1877 default: 1878 panic("ext2_write: type %p %d (%jd,%jd)", (void *)vp, 1879 vp->v_type, (intmax_t)uio->uio_offset, 1880 (intmax_t)uio->uio_resid); 1881 } 1882 1883 KASSERT(uio->uio_resid >= 0, ("ext2_write: uio->uio_resid < 0")); 1884 KASSERT(uio->uio_offset >= 0, ("ext2_write: uio->uio_offset < 0")); 1885 fs = ip->i_e2fs; 1886 if ((uoff_t)uio->uio_offset + uio->uio_resid > fs->e2fs_maxfilesize) 1887 return (EFBIG); 1888 /* 1889 * Maybe this should be above the vnode op call, but so long as 1890 * file servers have no limits, I don't think it matters. 1891 */ 1892 if (vn_rlimit_fsize(vp, uio, uio->uio_td)) 1893 return (EFBIG); 1894 1895 resid = uio->uio_resid; 1896 osize = ip->i_size; 1897 if (seqcount > BA_SEQMAX) 1898 flags = BA_SEQMAX << BA_SEQSHIFT; 1899 else 1900 flags = seqcount << BA_SEQSHIFT; 1901 if ((ioflag & IO_SYNC) && !DOINGASYNC(vp)) 1902 flags |= IO_SYNC; 1903 1904 for (error = 0; uio->uio_resid > 0;) { 1905 lbn = lblkno(fs, uio->uio_offset); 1906 blkoffset = blkoff(fs, uio->uio_offset); 1907 xfersize = fs->e2fs_fsize - blkoffset; 1908 if (uio->uio_resid < xfersize) 1909 xfersize = uio->uio_resid; 1910 if (uio->uio_offset + xfersize > ip->i_size) 1911 vnode_pager_setsize(vp, uio->uio_offset + xfersize); 1912 1913 /* 1914 * We must perform a read-before-write if the transfer size 1915 * does not cover the entire buffer. 1916 */ 1917 if (fs->e2fs_bsize > xfersize) 1918 flags |= BA_CLRBUF; 1919 else 1920 flags &= ~BA_CLRBUF; 1921 error = ext2_balloc(ip, lbn, blkoffset + xfersize, 1922 ap->a_cred, &bp, flags); 1923 if (error != 0) 1924 break; 1925 1926 /* 1927 * If the buffer is not valid and we did not clear garbage 1928 * out above, we have to do so here even though the write 1929 * covers the entire buffer in order to avoid a mmap()/write 1930 * race where another process may see the garbage prior to 1931 * the uiomove() for a write replacing it. 1932 */ 1933 if ((bp->b_flags & B_CACHE) == 0 && fs->e2fs_bsize <= xfersize) 1934 vfs_bio_clrbuf(bp); 1935 if ((ioflag & (IO_SYNC|IO_INVAL)) == (IO_SYNC|IO_INVAL)) 1936 bp->b_flags |= B_NOCACHE; 1937 if (uio->uio_offset + xfersize > ip->i_size) 1938 ip->i_size = uio->uio_offset + xfersize; 1939 size = blksize(fs, ip, lbn) - bp->b_resid; 1940 if (size < xfersize) 1941 xfersize = size; 1942 1943 error = 1944 uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio); 1945 if (ioflag & (IO_VMIO|IO_DIRECT)) { 1946 bp->b_flags |= B_RELBUF; 1947 } 1948 1949 /* 1950 * If IO_SYNC each buffer is written synchronously. Otherwise 1951 * if we have a severe page deficiency write the buffer 1952 * asynchronously. Otherwise try to cluster, and if that 1953 * doesn't do it then either do an async write (if O_DIRECT), 1954 * or a delayed write (if not). 1955 */ 1956 if (ioflag & IO_SYNC) { 1957 (void)bwrite(bp); 1958 } else if (vm_page_count_severe() || 1959 buf_dirty_count_severe() || 1960 (ioflag & IO_ASYNC)) { 1961 bp->b_flags |= B_CLUSTEROK; 1962 bawrite(bp); 1963 } else if (xfersize + blkoffset == fs->e2fs_fsize) { 1964 if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0) { 1965 bp->b_flags |= B_CLUSTEROK; 1966 cluster_write(vp, bp, ip->i_size, seqcount); 1967 } else { 1968 bawrite(bp); 1969 } 1970 } else if (ioflag & IO_DIRECT) { 1971 bp->b_flags |= B_CLUSTEROK; 1972 bawrite(bp); 1973 } else { 1974 bp->b_flags |= B_CLUSTEROK; 1975 bdwrite(bp); 1976 } 1977 if (error || xfersize == 0) 1978 break; 1979 } 1980 /* 1981 * If we successfully wrote any data, and we are not the superuser 1982 * we clear the setuid and setgid bits as a precaution against 1983 * tampering. 1984 */ 1985 if ((ip->i_mode & (ISUID | ISGID)) && resid > uio->uio_resid && 1986 ap->a_cred) { 1987 if (priv_check_cred(ap->a_cred, PRIV_VFS_RETAINSUGID, 0)) 1988 ip->i_mode &= ~(ISUID | ISGID); 1989 } 1990 if (error) { 1991 if (ioflag & IO_UNIT) { 1992 (void)ext2_truncate(vp, osize, 1993 ioflag & IO_SYNC, ap->a_cred, uio->uio_td); 1994 uio->uio_offset -= resid - uio->uio_resid; 1995 uio->uio_resid = resid; 1996 } 1997 } 1998 if (uio->uio_resid != resid) { 1999 ip->i_flag |= IN_CHANGE | IN_UPDATE; 2000 if (ioflag & IO_SYNC) 2001 error = ext2_update(vp, 1); 2002 } 2003 return (error); 2004} |
|