| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: coda_vnops.c,v 1.109 2020/02/23 15:46:39 ad Exp $ */ | | 1 | /* $NetBSD: coda_vnops.c,v 1.110 2020/02/24 20:53:11 ad Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * | | 4 | * |
5 | * Coda: an Experimental Distributed File System | | 5 | * Coda: an Experimental Distributed File System |
6 | * Release 3.1 | | 6 | * Release 3.1 |
7 | * | | 7 | * |
8 | * Copyright (c) 1987-1998 Carnegie Mellon University | | 8 | * Copyright (c) 1987-1998 Carnegie Mellon University |
9 | * All Rights Reserved | | 9 | * All Rights Reserved |
10 | * | | 10 | * |
11 | * Permission to use, copy, modify and distribute this software and its | | 11 | * Permission to use, copy, modify and distribute this software and its |
12 | * documentation is hereby granted, provided that both the copyright | | 12 | * documentation is hereby granted, provided that both the copyright |
13 | * notice and this permission notice appear in all copies of the | | 13 | * notice and this permission notice appear in all copies of the |
14 | * software, derivative works or modified versions, and any portions | | 14 | * software, derivative works or modified versions, and any portions |
| @@ -36,27 +36,27 @@ | | | @@ -36,27 +36,27 @@ |
36 | * Copyright (c) 1990 Carnegie-Mellon University | | 36 | * Copyright (c) 1990 Carnegie-Mellon University |
37 | * Copyright (c) 1989 Carnegie-Mellon University | | 37 | * Copyright (c) 1989 Carnegie-Mellon University |
38 | * All rights reserved. The CMU software License Agreement specifies | | 38 | * All rights reserved. The CMU software License Agreement specifies |
39 | * the terms and conditions for use and redistribution. | | 39 | * the terms and conditions for use and redistribution. |
40 | */ | | 40 | */ |
41 | | | 41 | |
42 | /* | | 42 | /* |
43 | * This code was written for the Coda file system at Carnegie Mellon | | 43 | * This code was written for the Coda file system at Carnegie Mellon |
44 | * University. Contributers include David Steere, James Kistler, and | | 44 | * University. Contributers include David Steere, James Kistler, and |
45 | * M. Satyanarayanan. | | 45 | * M. Satyanarayanan. |
46 | */ | | 46 | */ |
47 | | | 47 | |
48 | #include <sys/cdefs.h> | | 48 | #include <sys/cdefs.h> |
49 | __KERNEL_RCSID(0, "$NetBSD: coda_vnops.c,v 1.109 2020/02/23 15:46:39 ad Exp $"); | | 49 | __KERNEL_RCSID(0, "$NetBSD: coda_vnops.c,v 1.110 2020/02/24 20:53:11 ad Exp $"); |
50 | | | 50 | |
51 | #include <sys/param.h> | | 51 | #include <sys/param.h> |
52 | #include <sys/systm.h> | | 52 | #include <sys/systm.h> |
53 | #include <sys/malloc.h> | | 53 | #include <sys/malloc.h> |
54 | #include <sys/errno.h> | | 54 | #include <sys/errno.h> |
55 | #include <sys/acct.h> | | 55 | #include <sys/acct.h> |
56 | #include <sys/file.h> | | 56 | #include <sys/file.h> |
57 | #include <sys/uio.h> | | 57 | #include <sys/uio.h> |
58 | #include <sys/namei.h> | | 58 | #include <sys/namei.h> |
59 | #include <sys/ioctl.h> | | 59 | #include <sys/ioctl.h> |
60 | #include <sys/mount.h> | | 60 | #include <sys/mount.h> |
61 | #include <sys/proc.h> | | 61 | #include <sys/proc.h> |
62 | #include <sys/select.h> | | 62 | #include <sys/select.h> |
| @@ -1879,66 +1879,68 @@ coda_getpages(void *v) | | | @@ -1879,66 +1879,68 @@ coda_getpages(void *v) |
1879 | int *a_count; | | 1879 | int *a_count; |
1880 | int a_centeridx; | | 1880 | int a_centeridx; |
1881 | vm_prot_t a_access_type; | | 1881 | vm_prot_t a_access_type; |
1882 | int a_advice; | | 1882 | int a_advice; |
1883 | int a_flags; | | 1883 | int a_flags; |
1884 | } */ *ap = v; | | 1884 | } */ *ap = v; |
1885 | vnode_t *vp = ap->a_vp, *cvp; | | 1885 | vnode_t *vp = ap->a_vp, *cvp; |
1886 | struct cnode *cp = VTOC(vp); | | 1886 | struct cnode *cp = VTOC(vp); |
1887 | struct lwp *l = curlwp; | | 1887 | struct lwp *l = curlwp; |
1888 | kauth_cred_t cred = l->l_cred; | | 1888 | kauth_cred_t cred = l->l_cred; |
1889 | int error, cerror; | | 1889 | int error, cerror; |
1890 | int waslocked; /* 1 if vnode lock was held on entry */ | | 1890 | int waslocked; /* 1 if vnode lock was held on entry */ |
1891 | int didopen = 0; /* 1 if we opened container file */ | | 1891 | int didopen = 0; /* 1 if we opened container file */ |
| | | 1892 | krw_t op; |
1892 | | | 1893 | |
1893 | /* | | 1894 | /* |
1894 | * Handle a case that uvm_fault doesn't quite use yet. | | 1895 | * Handle a case that uvm_fault doesn't quite use yet. |
1895 | * See layer_vnops.c. for inspiration. | | 1896 | * See layer_vnops.c. for inspiration. |
1896 | */ | | 1897 | */ |
1897 | if (ap->a_flags & PGO_LOCKED) { | | 1898 | if (ap->a_flags & PGO_LOCKED) { |
1898 | return EBUSY; | | 1899 | return EBUSY; |
1899 | } | | 1900 | } |
1900 | | | 1901 | |
1901 | KASSERT(mutex_owned(vp->v_interlock)); | | 1902 | KASSERT(rw_lock_held(vp->v_uobj.vmobjlock)); |
1902 | | | 1903 | |
1903 | /* Check for control object. */ | | 1904 | /* Check for control object. */ |
1904 | if (IS_CTL_VP(vp)) { | | 1905 | if (IS_CTL_VP(vp)) { |
1905 | #ifdef CODA_VERBOSE | | 1906 | #ifdef CODA_VERBOSE |
1906 | printf("%s: control object %p\n", __func__, vp); | | 1907 | printf("%s: control object %p\n", __func__, vp); |
1907 | #endif | | 1908 | #endif |
1908 | return(EINVAL); | | 1909 | return(EINVAL); |
1909 | } | | 1910 | } |
1910 | | | 1911 | |
1911 | /* | | 1912 | /* |
1912 | * XXX It's really not ok to be releasing the lock we get, | | 1913 | * XXX It's really not ok to be releasing the lock we get, |
1913 | * because we could be overlapping with another call to | | 1914 | * because we could be overlapping with another call to |
1914 | * getpages and drop a lock they are relying on. We need to | | 1915 | * getpages and drop a lock they are relying on. We need to |
1915 | * figure out whether getpages ever is called holding the | | 1916 | * figure out whether getpages ever is called holding the |
1916 | * lock, and if we should serialize getpages calls by some | | 1917 | * lock, and if we should serialize getpages calls by some |
1917 | * mechanism. | | 1918 | * mechanism. |
1918 | */ | | 1919 | */ |
1919 | /* XXX VOP_ISLOCKED() may not be used for lock decisions. */ | | 1920 | /* XXX VOP_ISLOCKED() may not be used for lock decisions. */ |
| | | 1921 | op = rw_lock_op(vp->v_uobj.vmobjlock); |
1920 | waslocked = VOP_ISLOCKED(vp); | | 1922 | waslocked = VOP_ISLOCKED(vp); |
1921 | | | 1923 | |
1922 | /* Get container file if not already present. */ | | 1924 | /* Get container file if not already present. */ |
1923 | cvp = cp->c_ovp; | | 1925 | cvp = cp->c_ovp; |
1924 | if (cvp == NULL) { | | 1926 | if (cvp == NULL) { |
1925 | /* | | 1927 | /* |
1926 | * VOP_OPEN requires a locked vnode. We must avoid | | 1928 | * VOP_OPEN requires a locked vnode. We must avoid |
1927 | * locking the vnode if it is already locked, and | | 1929 | * locking the vnode if it is already locked, and |
1928 | * leave it in the same state on exit. | | 1930 | * leave it in the same state on exit. |
1929 | */ | | 1931 | */ |
1930 | if (waslocked == 0) { | | 1932 | if (waslocked == 0) { |
1931 | mutex_exit(vp->v_interlock); | | 1933 | rw_exit(vp->v_uobj.vmobjlock); |
1932 | cerror = vn_lock(vp, LK_EXCLUSIVE); | | 1934 | cerror = vn_lock(vp, LK_EXCLUSIVE); |
1933 | if (cerror) { | | 1935 | if (cerror) { |
1934 | #ifdef CODA_VERBOSE | | 1936 | #ifdef CODA_VERBOSE |
1935 | printf("%s: can't lock vnode %p\n", | | 1937 | printf("%s: can't lock vnode %p\n", |
1936 | __func__, vp); | | 1938 | __func__, vp); |
1937 | #endif | | 1939 | #endif |
1938 | return cerror; | | 1940 | return cerror; |
1939 | } | | 1941 | } |
1940 | #ifdef CODA_VERBOSE | | 1942 | #ifdef CODA_VERBOSE |
1941 | printf("%s: locked vnode %p\n", __func__, vp); | | 1943 | printf("%s: locked vnode %p\n", __func__, vp); |
1942 | #endif | | 1944 | #endif |
1943 | } | | 1945 | } |
1944 | | | 1946 | |
| @@ -1956,32 +1958,32 @@ coda_getpages(void *v) | | | @@ -1956,32 +1958,32 @@ coda_getpages(void *v) |
1956 | vp, cerror); | | 1958 | vp, cerror); |
1957 | #endif | | 1959 | #endif |
1958 | if (waslocked == 0) | | 1960 | if (waslocked == 0) |
1959 | VOP_UNLOCK(vp); | | 1961 | VOP_UNLOCK(vp); |
1960 | return cerror; | | 1962 | return cerror; |
1961 | } | | 1963 | } |
1962 | | | 1964 | |
1963 | #ifdef CODA_VERBOSE | | 1965 | #ifdef CODA_VERBOSE |
1964 | printf("%s: opened vnode %p\n", __func__, vp); | | 1966 | printf("%s: opened vnode %p\n", __func__, vp); |
1965 | #endif | | 1967 | #endif |
1966 | cvp = cp->c_ovp; | | 1968 | cvp = cp->c_ovp; |
1967 | didopen = 1; | | 1969 | didopen = 1; |
1968 | if (waslocked == 0) | | 1970 | if (waslocked == 0) |
1969 | mutex_enter(vp->v_interlock); | | 1971 | rw_enter(vp->v_uobj.vmobjlock, op); |
1970 | } | | 1972 | } |
1971 | KASSERT(cvp != NULL); | | 1973 | KASSERT(cvp != NULL); |
1972 | | | 1974 | |
1973 | /* Munge the arg structure to refer to the container vnode. */ | | 1975 | /* Munge the arg structure to refer to the container vnode. */ |
1974 | KASSERT(cvp->v_interlock == vp->v_interlock); | | 1976 | KASSERT(cvp->v_uobj.vmobjlock == vp->v_uobj.vmobjlock); |
1975 | ap->a_vp = cp->c_ovp; | | 1977 | ap->a_vp = cp->c_ovp; |
1976 | | | 1978 | |
1977 | /* Finally, call getpages on it. */ | | 1979 | /* Finally, call getpages on it. */ |
1978 | error = VCALL(ap->a_vp, VOFFSET(vop_getpages), ap); | | 1980 | error = VCALL(ap->a_vp, VOFFSET(vop_getpages), ap); |
1979 | | | 1981 | |
1980 | /* If we opened the vnode, we must close it. */ | | 1982 | /* If we opened the vnode, we must close it. */ |
1981 | if (didopen) { | | 1983 | if (didopen) { |
1982 | /* | | 1984 | /* |
1983 | * VOP_CLOSE requires a locked vnode, but we are still | | 1985 | * VOP_CLOSE requires a locked vnode, but we are still |
1984 | * holding the lock (or riding a caller's lock). | | 1986 | * holding the lock (or riding a caller's lock). |
1985 | */ | | 1987 | */ |
1986 | cerror = VOP_CLOSE(vp, FREAD, cred); | | 1988 | cerror = VOP_CLOSE(vp, FREAD, cred); |
1987 | #ifdef CODA_VERBOSE | | 1989 | #ifdef CODA_VERBOSE |
| @@ -2005,45 +2007,45 @@ coda_getpages(void *v) | | | @@ -2005,45 +2007,45 @@ coda_getpages(void *v) |
2005 | int | | 2007 | int |
2006 | coda_putpages(void *v) | | 2008 | coda_putpages(void *v) |
2007 | { | | 2009 | { |
2008 | struct vop_putpages_args /* { | | 2010 | struct vop_putpages_args /* { |
2009 | vnode_t *a_vp; | | 2011 | vnode_t *a_vp; |
2010 | voff_t a_offlo; | | 2012 | voff_t a_offlo; |
2011 | voff_t a_offhi; | | 2013 | voff_t a_offhi; |
2012 | int a_flags; | | 2014 | int a_flags; |
2013 | } */ *ap = v; | | 2015 | } */ *ap = v; |
2014 | vnode_t *vp = ap->a_vp, *cvp; | | 2016 | vnode_t *vp = ap->a_vp, *cvp; |
2015 | struct cnode *cp = VTOC(vp); | | 2017 | struct cnode *cp = VTOC(vp); |
2016 | int error; | | 2018 | int error; |
2017 | | | 2019 | |
2018 | KASSERT(mutex_owned(vp->v_interlock)); | | 2020 | KASSERT(rw_write_held(vp->v_uobj.vmobjlock)); |
2019 | | | 2021 | |
2020 | /* Check for control object. */ | | 2022 | /* Check for control object. */ |
2021 | if (IS_CTL_VP(vp)) { | | 2023 | if (IS_CTL_VP(vp)) { |
2022 | mutex_exit(vp->v_interlock); | | 2024 | rw_exit(vp->v_uobj.vmobjlock); |
2023 | #ifdef CODA_VERBOSE | | 2025 | #ifdef CODA_VERBOSE |
2024 | printf("%s: control object %p\n", __func__, vp); | | 2026 | printf("%s: control object %p\n", __func__, vp); |
2025 | #endif | | 2027 | #endif |
2026 | return 0; | | 2028 | return 0; |
2027 | } | | 2029 | } |
2028 | | | 2030 | |
2029 | /* | | 2031 | /* |
2030 | * If container object is not present, then there are no pages | | 2032 | * If container object is not present, then there are no pages |
2031 | * to put; just return without error. This happens all the | | 2033 | * to put; just return without error. This happens all the |
2032 | * time, apparently during discard of a closed vnode (which | | 2034 | * time, apparently during discard of a closed vnode (which |
2033 | * trivially can't have dirty pages). | | 2035 | * trivially can't have dirty pages). |
2034 | */ | | 2036 | */ |
2035 | cvp = cp->c_ovp; | | 2037 | cvp = cp->c_ovp; |
2036 | if (cvp == NULL) { | | 2038 | if (cvp == NULL) { |
2037 | mutex_exit(vp->v_interlock); | | 2039 | rw_exit(vp->v_uobj.vmobjlock); |
2038 | return 0; | | 2040 | return 0; |
2039 | } | | 2041 | } |
2040 | | | 2042 | |
2041 | /* Munge the arg structure to refer to the container vnode. */ | | 2043 | /* Munge the arg structure to refer to the container vnode. */ |
2042 | KASSERT(cvp->v_interlock == vp->v_interlock); | | 2044 | KASSERT(cvp->v_uobj.vmobjlock == vp->v_uobj.vmobjlock); |
2043 | ap->a_vp = cvp; | | 2045 | ap->a_vp = cvp; |
2044 | | | 2046 | |
2045 | /* Finally, call putpages on it. */ | | 2047 | /* Finally, call putpages on it. */ |
2046 | error = VCALL(ap->a_vp, VOFFSET(vop_putpages), ap); | | 2048 | error = VCALL(ap->a_vp, VOFFSET(vop_putpages), ap); |
2047 | | | 2049 | |
2048 | return error; | | 2050 | return error; |
2049 | } | | 2051 | } |