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