kern_lockf.c (178873) | kern_lockf.c (180025) |
---|---|
1/*- 2 * Copyright (c) 2008 Isilon Inc http://www.isilon.com/ 3 * Authors: Doug Rabson <dfr@rabson.org> 4 * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 45 unchanged lines hidden (view full) --- 54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 * SUCH DAMAGE. 57 * 58 * @(#)ufs_lockf.c 8.3 (Berkeley) 1/6/94 59 */ 60 61#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2008 Isilon Inc http://www.isilon.com/ 3 * Authors: Doug Rabson <dfr@rabson.org> 4 * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 45 unchanged lines hidden (view full) --- 54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 * SUCH DAMAGE. 57 * 58 * @(#)ufs_lockf.c 8.3 (Berkeley) 1/6/94 59 */ 60 61#include <sys/cdefs.h> |
62__FBSDID("$FreeBSD: head/sys/kern/kern_lockf.c 178873 2008-05-09 10:34:23Z dfr $"); | 62__FBSDID("$FreeBSD: head/sys/kern/kern_lockf.c 180025 2008-06-26 10:21:54Z dfr $"); |
63 64#include "opt_debug_lockf.h" 65 66#include <sys/param.h> 67#include <sys/systm.h> 68#include <sys/hash.h> 69#include <sys/kernel.h> 70#include <sys/limits.h> --- 1278 unchanged lines hidden (view full) --- 1349#endif /* LOCKF_DEBUG */ 1350 1351 /* 1352 * Set the priority 1353 */ 1354 priority = PLOCK; 1355 if (lock->lf_type == F_WRLCK) 1356 priority += 4; | 63 64#include "opt_debug_lockf.h" 65 66#include <sys/param.h> 67#include <sys/systm.h> 68#include <sys/hash.h> 69#include <sys/kernel.h> 70#include <sys/limits.h> --- 1278 unchanged lines hidden (view full) --- 1349#endif /* LOCKF_DEBUG */ 1350 1351 /* 1352 * Set the priority 1353 */ 1354 priority = PLOCK; 1355 if (lock->lf_type == F_WRLCK) 1356 priority += 4; |
1357 priority |= PCATCH; | 1357 if (!(lock->lf_flags & F_NOINTR)) 1358 priority |= PCATCH; |
1358 /* 1359 * Scan lock list for this file looking for locks that would block us. 1360 */ 1361 while ((block = lf_getblock(state, lock))) { 1362 /* 1363 * Free the structure and return if nonblocking. 1364 */ 1365 if ((lock->lf_flags & F_WAIT) == 0 --- 443 unchanged lines hidden (view full) --- 1809 lf_set_end(state, lock1, lock2->lf_start - 1, granted); 1810 1811 /* 1812 * OK, now link it in 1813 */ 1814 lf_insert_lock(state, splitlock); 1815} 1816 | 1359 /* 1360 * Scan lock list for this file looking for locks that would block us. 1361 */ 1362 while ((block = lf_getblock(state, lock))) { 1363 /* 1364 * Free the structure and return if nonblocking. 1365 */ 1366 if ((lock->lf_flags & F_WAIT) == 0 --- 443 unchanged lines hidden (view full) --- 1810 lf_set_end(state, lock1, lock2->lf_start - 1, granted); 1811 1812 /* 1813 * OK, now link it in 1814 */ 1815 lf_insert_lock(state, splitlock); 1816} 1817 |
1817struct clearlock { 1818 STAILQ_ENTRY(clearlock) link; | 1818struct lockdesc { 1819 STAILQ_ENTRY(lockdesc) link; |
1819 struct vnode *vp; 1820 struct flock fl; 1821}; | 1820 struct vnode *vp; 1821 struct flock fl; 1822}; |
1822STAILQ_HEAD(clearlocklist, clearlock); | 1823STAILQ_HEAD(lockdesclist, lockdesc); |
1823 | 1824 |
1824void 1825lf_clearremotesys(int sysid) | 1825int 1826lf_iteratelocks_sysid(int sysid, lf_iterator *fn, void *arg) |
1826{ 1827 struct lockf *ls; 1828 struct lockf_entry *lf; | 1827{ 1828 struct lockf *ls; 1829 struct lockf_entry *lf; |
1829 struct clearlock *cl; 1830 struct clearlocklist locks; | 1830 struct lockdesc *ldesc; 1831 struct lockdesclist locks; 1832 int error; |
1831 | 1833 |
1832 KASSERT(sysid != 0, ("Can't clear local locks with F_UNLCKSYS")); 1833 | |
1834 /* 1835 * In order to keep the locking simple, we iterate over the 1836 * active lock lists to build a list of locks that need | 1834 /* 1835 * In order to keep the locking simple, we iterate over the 1836 * active lock lists to build a list of locks that need |
1837 * releasing. We then call VOP_ADVLOCK for each one in turn. | 1837 * releasing. We then call the iterator for each one in turn. |
1838 * 1839 * We take an extra reference to the vnode for the duration to 1840 * make sure it doesn't go away before we are finished. 1841 */ 1842 STAILQ_INIT(&locks); 1843 sx_xlock(&lf_lock_states_lock); 1844 LIST_FOREACH(ls, &lf_lock_states, ls_link) { 1845 sx_xlock(&ls->ls_lock); 1846 LIST_FOREACH(lf, &ls->ls_active, lf_link) { 1847 if (lf->lf_owner->lo_sysid != sysid) 1848 continue; 1849 | 1838 * 1839 * We take an extra reference to the vnode for the duration to 1840 * make sure it doesn't go away before we are finished. 1841 */ 1842 STAILQ_INIT(&locks); 1843 sx_xlock(&lf_lock_states_lock); 1844 LIST_FOREACH(ls, &lf_lock_states, ls_link) { 1845 sx_xlock(&ls->ls_lock); 1846 LIST_FOREACH(lf, &ls->ls_active, lf_link) { 1847 if (lf->lf_owner->lo_sysid != sysid) 1848 continue; 1849 |
1850 cl = malloc(sizeof(struct clearlock), M_LOCKF, | 1850 ldesc = malloc(sizeof(struct lockdesc), M_LOCKF, |
1851 M_WAITOK); | 1851 M_WAITOK); |
1852 cl->vp = lf->lf_vnode; 1853 vref(cl->vp); 1854 cl->fl.l_start = lf->lf_start; | 1852 ldesc->vp = lf->lf_vnode; 1853 vref(ldesc->vp); 1854 ldesc->fl.l_start = lf->lf_start; |
1855 if (lf->lf_end == OFF_MAX) | 1855 if (lf->lf_end == OFF_MAX) |
1856 cl->fl.l_len = 0; | 1856 ldesc->fl.l_len = 0; |
1857 else | 1857 else |
1858 cl->fl.l_len = | 1858 ldesc->fl.l_len = |
1859 lf->lf_end - lf->lf_start + 1; | 1859 lf->lf_end - lf->lf_start + 1; |
1860 cl->fl.l_whence = SEEK_SET; 1861 cl->fl.l_type = F_UNLCK; 1862 cl->fl.l_pid = lf->lf_owner->lo_pid; 1863 cl->fl.l_sysid = sysid; 1864 STAILQ_INSERT_TAIL(&locks, cl, link); | 1860 ldesc->fl.l_whence = SEEK_SET; 1861 ldesc->fl.l_type = F_UNLCK; 1862 ldesc->fl.l_pid = lf->lf_owner->lo_pid; 1863 ldesc->fl.l_sysid = sysid; 1864 STAILQ_INSERT_TAIL(&locks, ldesc, link); |
1865 } 1866 sx_xunlock(&ls->ls_lock); 1867 } 1868 sx_xunlock(&lf_lock_states_lock); 1869 | 1865 } 1866 sx_xunlock(&ls->ls_lock); 1867 } 1868 sx_xunlock(&lf_lock_states_lock); 1869 |
1870 while ((cl = STAILQ_FIRST(&locks)) != NULL) { | 1870 /* 1871 * Call the iterator function for each lock in turn. If the 1872 * iterator returns an error code, just free the rest of the 1873 * lockdesc structures. 1874 */ 1875 error = 0; 1876 while ((ldesc = STAILQ_FIRST(&locks)) != NULL) { |
1871 STAILQ_REMOVE_HEAD(&locks, link); | 1877 STAILQ_REMOVE_HEAD(&locks, link); |
1872 VOP_ADVLOCK(cl->vp, 0, F_UNLCK, &cl->fl, F_REMOTE); 1873 vrele(cl->vp); 1874 free(cl, M_LOCKF); | 1878 if (!error) 1879 error = fn(ldesc->vp, &ldesc->fl, arg); 1880 vrele(ldesc->vp); 1881 free(ldesc, M_LOCKF); |
1875 } | 1882 } |
1883 1884 return (error); |
|
1876} 1877 1878int | 1885} 1886 1887int |
1888lf_iteratelocks_vnode(struct vnode *vp, lf_iterator *fn, void *arg) 1889{ 1890 struct lockf *ls; 1891 struct lockf_entry *lf; 1892 struct lockdesc *ldesc; 1893 struct lockdesclist locks; 1894 int error; 1895 1896 /* 1897 * In order to keep the locking simple, we iterate over the 1898 * active lock lists to build a list of locks that need 1899 * releasing. We then call the iterator for each one in turn. 1900 * 1901 * We take an extra reference to the vnode for the duration to 1902 * make sure it doesn't go away before we are finished. 1903 */ 1904 STAILQ_INIT(&locks); 1905 ls = vp->v_lockf; 1906 if (!ls) 1907 return (0); 1908 1909 sx_xlock(&ls->ls_lock); 1910 LIST_FOREACH(lf, &ls->ls_active, lf_link) { 1911 ldesc = malloc(sizeof(struct lockdesc), M_LOCKF, 1912 M_WAITOK); 1913 ldesc->vp = lf->lf_vnode; 1914 vref(ldesc->vp); 1915 ldesc->fl.l_start = lf->lf_start; 1916 if (lf->lf_end == OFF_MAX) 1917 ldesc->fl.l_len = 0; 1918 else 1919 ldesc->fl.l_len = 1920 lf->lf_end - lf->lf_start + 1; 1921 ldesc->fl.l_whence = SEEK_SET; 1922 ldesc->fl.l_type = F_UNLCK; 1923 ldesc->fl.l_pid = lf->lf_owner->lo_pid; 1924 ldesc->fl.l_sysid = lf->lf_owner->lo_sysid; 1925 STAILQ_INSERT_TAIL(&locks, ldesc, link); 1926 } 1927 sx_xunlock(&ls->ls_lock); 1928 1929 /* 1930 * Call the iterator function for each lock in turn. If the 1931 * iterator returns an error code, just free the rest of the 1932 * lockdesc structures. 1933 */ 1934 error = 0; 1935 while ((ldesc = STAILQ_FIRST(&locks)) != NULL) { 1936 STAILQ_REMOVE_HEAD(&locks, link); 1937 if (!error) 1938 error = fn(ldesc->vp, &ldesc->fl, arg); 1939 vrele(ldesc->vp); 1940 free(ldesc, M_LOCKF); 1941 } 1942 1943 return (error); 1944} 1945 1946static int 1947lf_clearremotesys_iterator(struct vnode *vp, struct flock *fl, void *arg) 1948{ 1949 1950 VOP_ADVLOCK(vp, 0, F_UNLCK, fl, F_REMOTE); 1951 return (0); 1952} 1953 1954void 1955lf_clearremotesys(int sysid) 1956{ 1957 1958 KASSERT(sysid != 0, ("Can't clear local locks with F_UNLCKSYS")); 1959 lf_iteratelocks_sysid(sysid, lf_clearremotesys_iterator, NULL); 1960} 1961 1962int |
|
1879lf_countlocks(int sysid) 1880{ 1881 int i; 1882 struct lock_owner *lo; 1883 int count; 1884 1885 count = 0; 1886 sx_xlock(&lf_lock_owners_lock); --- 531 unchanged lines hidden --- | 1963lf_countlocks(int sysid) 1964{ 1965 int i; 1966 struct lock_owner *lo; 1967 int count; 1968 1969 count = 0; 1970 sx_xlock(&lf_lock_owners_lock); --- 531 unchanged lines hidden --- |