* Set a byte-range lock. */
| 1375 | * Set a byte-range lock. |
| 1376 | */ |
| 1377 | static int |
| 1378 | lf_setlock(struct lockf *state, struct lockf_entry *lock, struct vnode *vp, |
| 1379 | void **cookiep) |
| 1380 | { |
| 1381 | static char lockstr[] = "lockf"; |
| 1382 | int error, priority, stops_deferred; |
| 1383 | |
| 1384 | #ifdef LOCKF_DEBUG |
| 1385 | if (lockf_debug & 1) |
| 1386 | lf_print("lf_setlock", lock); |
| 1387 | #endif /* LOCKF_DEBUG */ |
| 1388 | |
| 1389 | /* |
| 1390 | * Set the priority |
| 1391 | */ |
| 1392 | priority = PLOCK; |
| 1393 | if (lock->lf_type == F_WRLCK) |
| 1394 | priority += 4; |
| 1395 | if (!(lock->lf_flags & F_NOINTR)) |
| 1396 | priority |= PCATCH; |
| 1397 | /* |
| 1398 | * Scan lock list for this file looking for locks that would block us. |
| 1399 | */ |
| 1400 | if (lf_getblock(state, lock)) { |
| 1401 | /* |
| 1402 | * Free the structure and return if nonblocking. |
| 1403 | */ |
| 1404 | if ((lock->lf_flags & F_WAIT) == 0 |
| 1405 | && lock->lf_async_task == NULL) { |
| 1406 | lf_free_lock(lock); |
| 1407 | error = EAGAIN; |
| 1408 | goto out; |
| 1409 | } |
| 1410 | |
| 1411 | /* |
| 1412 | * For flock type locks, we must first remove |
| 1413 | * any shared locks that we hold before we sleep |
| 1414 | * waiting for an exclusive lock. |
| 1415 | */ |
| 1416 | if ((lock->lf_flags & F_FLOCK) && |
| 1417 | lock->lf_type == F_WRLCK) { |
| 1418 | lock->lf_type = F_UNLCK; |
| 1419 | lf_activate_lock(state, lock); |
| 1420 | lock->lf_type = F_WRLCK; |
| 1421 | } |
| 1422 | |
| 1423 | /* |
| 1424 | * We are blocked. Create edges to each blocking lock, |
| 1425 | * checking for deadlock using the owner graph. For |
| 1426 | * simplicity, we run deadlock detection for all |
| 1427 | * locks, posix and otherwise. |
| 1428 | */ |
| 1429 | sx_xlock(&lf_owner_graph_lock); |
| 1430 | error = lf_add_outgoing(state, lock); |
| 1431 | sx_xunlock(&lf_owner_graph_lock); |
| 1432 | |
| 1433 | if (error) { |
| 1434 | #ifdef LOCKF_DEBUG |
no test coverage detected