| 1928 | } |
| 1929 | |
| 1930 | int |
| 1931 | lf_iteratelocks_vnode(struct vnode *vp, lf_iterator *fn, void *arg) |
| 1932 | { |
| 1933 | struct lockf *ls; |
| 1934 | struct lockf_entry *lf; |
| 1935 | struct lockdesc *ldesc; |
| 1936 | struct lockdesclist locks; |
| 1937 | int error; |
| 1938 | |
| 1939 | /* |
| 1940 | * In order to keep the locking simple, we iterate over the |
| 1941 | * active lock lists to build a list of locks that need |
| 1942 | * releasing. We then call the iterator for each one in turn. |
| 1943 | * |
| 1944 | * We take an extra reference to the vnode for the duration to |
| 1945 | * make sure it doesn't go away before we are finished. |
| 1946 | */ |
| 1947 | STAILQ_INIT(&locks); |
| 1948 | VI_LOCK(vp); |
| 1949 | ls = vp->v_lockf; |
| 1950 | if (!ls) { |
| 1951 | VI_UNLOCK(vp); |
| 1952 | return (0); |
| 1953 | } |
| 1954 | MPASS(ls->ls_threads >= 0); |
| 1955 | ls->ls_threads++; |
| 1956 | VI_UNLOCK(vp); |
| 1957 | |
| 1958 | sx_xlock(&ls->ls_lock); |
| 1959 | LIST_FOREACH(lf, &ls->ls_active, lf_link) { |
| 1960 | ldesc = malloc(sizeof(struct lockdesc), M_LOCKF, |
| 1961 | M_WAITOK); |
| 1962 | ldesc->vp = lf->lf_vnode; |
| 1963 | vref(ldesc->vp); |
| 1964 | ldesc->fl.l_start = lf->lf_start; |
| 1965 | if (lf->lf_end == OFF_MAX) |
| 1966 | ldesc->fl.l_len = 0; |
| 1967 | else |
| 1968 | ldesc->fl.l_len = |
| 1969 | lf->lf_end - lf->lf_start + 1; |
| 1970 | ldesc->fl.l_whence = SEEK_SET; |
| 1971 | ldesc->fl.l_type = F_UNLCK; |
| 1972 | ldesc->fl.l_pid = lf->lf_owner->lo_pid; |
| 1973 | ldesc->fl.l_sysid = lf->lf_owner->lo_sysid; |
| 1974 | STAILQ_INSERT_TAIL(&locks, ldesc, link); |
| 1975 | } |
| 1976 | sx_xunlock(&ls->ls_lock); |
| 1977 | VI_LOCK(vp); |
| 1978 | MPASS(ls->ls_threads > 0); |
| 1979 | ls->ls_threads--; |
| 1980 | wakeup(ls); |
| 1981 | VI_UNLOCK(vp); |
| 1982 | |
| 1983 | /* |
| 1984 | * Call the iterator function for each lock in turn. If the |
| 1985 | * iterator returns an error code, just free the rest of the |
| 1986 | * lockdesc structures. |
| 1987 | */ |