Lines Matching +full:lock +full:- +full:state

1 // SPDX-License-Identifier: GPL-2.0-or-later
25 static inline void afs_set_lock_state(struct afs_vnode *vnode, enum afs_lock_state state) in afs_set_lock_state() argument
27 _debug("STATE %u -> %u", vnode->lock_state, state); in afs_set_lock_state()
28 vnode->lock_state = state; in afs_set_lock_state()
34 * if the callback is broken on this vnode, then the lock may now be available
38 _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode); in afs_lock_may_be_available()
40 spin_lock(&vnode->lock); in afs_lock_may_be_available()
41 if (vnode->lock_state == AFS_VNODE_LOCK_WAITING_FOR_CB) in afs_lock_may_be_available()
44 spin_unlock(&vnode->lock); in afs_lock_may_be_available()
48 * the lock will time out in 5 minutes unless we extend it, so schedule
56 expires_at = ktime_add_ms(vnode->locked_at, AFS_LOCKWAIT * 1000 / 2); in afs_schedule_lock_extension()
64 queue_delayed_work(afs_lock_manager, &vnode->lock_work, duration_j); in afs_schedule_lock_extension()
68 * In the case of successful completion of a lock operation, record the time
69 * the reply appeared and start the lock extension timer.
73 struct afs_operation *op = call->op; in afs_lock_op_done()
74 struct afs_vnode *vnode = op->file[0].vnode; in afs_lock_op_done()
76 if (call->error == 0) { in afs_lock_op_done()
77 spin_lock(&vnode->lock); in afs_lock_op_done()
79 vnode->locked_at = call->issue_time; in afs_lock_op_done()
81 spin_unlock(&vnode->lock); in afs_lock_op_done()
87 * first lock in the queue is itself a readlock)
88 * - the caller must hold the vnode lock
93 bool exclusive = (vnode->lock_type == AFS_LOCK_WRITE); in afs_grant_locks()
95 list_for_each_entry_safe(p, _p, &vnode->pending_locks, fl_u.afs.link) { in afs_grant_locks()
96 if (!exclusive && p->fl_type == F_WRLCK) in afs_grant_locks()
99 list_move_tail(&p->fl_u.afs.link, &vnode->granted_locks); in afs_grant_locks()
100 p->fl_u.afs.state = AFS_LOCK_GRANTED; in afs_grant_locks()
102 wake_up(&p->fl_wait); in afs_grant_locks()
107 * If an error is specified, reject every pending lock that matches the
108 * authentication and type of the lock we failed to get. If there are any
114 struct key *key = vnode->lock_key; in afs_next_locker()
119 if (vnode->lock_type == AFS_LOCK_WRITE) in afs_next_locker()
122 list_for_each_entry_safe(p, _p, &vnode->pending_locks, fl_u.afs.link) { in afs_next_locker()
124 p->fl_type == fl_type && in afs_next_locker()
125 afs_file_key(p->fl_file) == key) { in afs_next_locker()
126 list_del_init(&p->fl_u.afs.link); in afs_next_locker()
127 p->fl_u.afs.state = error; in afs_next_locker()
128 wake_up(&p->fl_wait); in afs_next_locker()
133 (next->fl_type == F_WRLCK || p->fl_type == F_RDLCK)) in afs_next_locker()
138 vnode->lock_key = NULL; in afs_next_locker()
143 next->fl_u.afs.state = AFS_LOCK_YOUR_TRY; in afs_next_locker()
145 wake_up(&next->fl_wait); in afs_next_locker()
155 * Kill off all waiters in the the pending lock queue due to the vnode being
164 while (!list_empty(&vnode->pending_locks)) { in afs_kill_lockers_enoent()
165 p = list_entry(vnode->pending_locks.next, in afs_kill_lockers_enoent()
167 list_del_init(&p->fl_u.afs.link); in afs_kill_lockers_enoent()
168 p->fl_u.afs.state = -ENOENT; in afs_kill_lockers_enoent()
169 wake_up(&p->fl_wait); in afs_kill_lockers_enoent()
172 key_put(vnode->lock_key); in afs_kill_lockers_enoent()
173 vnode->lock_key = NULL; in afs_kill_lockers_enoent()
178 _enter("op=%08x", op->debug_id); in afs_lock_success()
179 afs_vnode_commit_status(op, &op->file[0]); in afs_lock_success()
190 * Get a lock on a file
198 vnode->volume->name, in afs_set_lock()
199 vnode->fid.vid, in afs_set_lock()
200 vnode->fid.vnode, in afs_set_lock()
201 vnode->fid.unique, in afs_set_lock()
204 op = afs_alloc_operation(key, vnode->volume); in afs_set_lock()
210 op->lock.type = type; in afs_set_lock()
211 op->ops = &afs_set_lock_operation; in afs_set_lock()
222 * Extend a lock on a file
229 vnode->volume->name, in afs_extend_lock()
230 vnode->fid.vid, in afs_extend_lock()
231 vnode->fid.vnode, in afs_extend_lock()
232 vnode->fid.unique, in afs_extend_lock()
235 op = afs_alloc_operation(key, vnode->volume); in afs_extend_lock()
241 op->flags |= AFS_OPERATION_UNINTR; in afs_extend_lock()
242 op->ops = &afs_extend_lock_operation; in afs_extend_lock()
253 * Release a lock on a file
260 vnode->volume->name, in afs_release_lock()
261 vnode->fid.vid, in afs_release_lock()
262 vnode->fid.vnode, in afs_release_lock()
263 vnode->fid.unique, in afs_release_lock()
266 op = afs_alloc_operation(key, vnode->volume); in afs_release_lock()
272 op->flags |= AFS_OPERATION_UNINTR; in afs_release_lock()
273 op->ops = &afs_release_lock_operation; in afs_release_lock()
278 * do work for a lock, including:
279 * - probing for a lock we're waiting on but didn't get immediately
280 * - extending a lock that's close to timing out
289 _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode); in afs_lock_work()
291 spin_lock(&vnode->lock); in afs_lock_work()
294 _debug("wstate %u for %p", vnode->lock_state, vnode); in afs_lock_work()
295 switch (vnode->lock_state) { in afs_lock_work()
299 spin_unlock(&vnode->lock); in afs_lock_work()
301 /* attempt to release the server lock; if it fails, we just in afs_lock_work()
303 ret = afs_release_lock(vnode, vnode->lock_key); in afs_lock_work()
304 if (ret < 0 && vnode->lock_state != AFS_VNODE_LOCK_DELETED) { in afs_lock_work()
308 " Failed to release lock on {%llx:%llx} error %d\n", in afs_lock_work()
309 vnode->fid.vid, vnode->fid.vnode, ret); in afs_lock_work()
312 spin_lock(&vnode->lock); in afs_lock_work()
313 if (ret == -ENOENT) in afs_lock_work()
317 spin_unlock(&vnode->lock); in afs_lock_work()
320 /* If we've already got a lock, then it must be time to extend that in afs_lock_work()
321 * lock as AFS locks time out after 5 minutes. in afs_lock_work()
326 ASSERT(!list_empty(&vnode->granted_locks)); in afs_lock_work()
328 key = key_get(vnode->lock_key); in afs_lock_work()
331 spin_unlock(&vnode->lock); in afs_lock_work()
339 pr_warn("AFS: Failed to extend lock on {%llx:%llx} error %d\n", in afs_lock_work()
340 vnode->fid.vid, vnode->fid.vnode, ret); in afs_lock_work()
343 spin_lock(&vnode->lock); in afs_lock_work()
345 if (ret == -ENOENT) { in afs_lock_work()
347 spin_unlock(&vnode->lock); in afs_lock_work()
351 if (vnode->lock_state != AFS_VNODE_LOCK_EXTENDING) in afs_lock_work()
356 queue_delayed_work(afs_lock_manager, &vnode->lock_work, in afs_lock_work()
358 spin_unlock(&vnode->lock); in afs_lock_work()
362 /* If we're waiting for a callback to indicate lock release, we can't in afs_lock_work()
364 * problem is that the server might not notify us if the lock just in afs_lock_work()
371 spin_unlock(&vnode->lock); in afs_lock_work()
376 spin_unlock(&vnode->lock); in afs_lock_work()
380 /* Looks like a lock request was withdrawn. */ in afs_lock_work()
381 spin_unlock(&vnode->lock); in afs_lock_work()
391 * - the caller must hold the vnode lock
395 _enter("%u", vnode->lock_state); in afs_defer_unlock()
397 if (list_empty(&vnode->granted_locks) && in afs_defer_unlock()
398 (vnode->lock_state == AFS_VNODE_LOCK_GRANTED || in afs_defer_unlock()
399 vnode->lock_state == AFS_VNODE_LOCK_EXTENDING)) { in afs_defer_unlock()
400 cancel_delayed_work(&vnode->lock_work); in afs_defer_unlock()
404 queue_delayed_work(afs_lock_manager, &vnode->lock_work, 0); in afs_defer_unlock()
426 * allowed to get a lock on this file. in afs_do_setlk_check()
432 /* At a rough estimation, you need LOCK, WRITE or INSERT perm to in afs_do_setlk_check()
433 * read-lock a file and WRITE or INSERT perm to write-lock a file. in afs_do_setlk_check()
436 * share a read lock that we already have, we won't go the server. in afs_do_setlk_check()
440 return -EACCES; in afs_do_setlk_check()
443 return -EACCES; in afs_do_setlk_check()
450 * request a lock on a file on the server
456 enum afs_flock_mode mode = AFS_FS_S(inode->i_sb)->flock_mode; in afs_do_setlk()
465 _enter("{%llx:%llu},%llu-%llu,%u,%u", in afs_do_setlk()
466 vnode->fid.vid, vnode->fid.vnode, in afs_do_setlk()
467 fl->fl_start, fl->fl_end, fl->fl_type, mode); in afs_do_setlk()
469 fl->fl_ops = &afs_lock_ops; in afs_do_setlk()
470 INIT_LIST_HEAD(&fl->fl_u.afs.link); in afs_do_setlk()
471 fl->fl_u.afs.state = AFS_LOCK_PENDING; in afs_do_setlk()
473 partial = (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX); in afs_do_setlk()
474 type = (fl->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE; in afs_do_setlk()
484 /* AFS3 protocol only supports full-file locks and doesn't provide any in afs_do_setlk()
485 * method of upgrade/downgrade, so we need to emulate for partial-file in afs_do_setlk()
488 * The OpenAFS client only gets a server lock for a full-file lock and in afs_do_setlk()
489 * keeps partial-file locks local. Allow this behaviour to be emulated in afs_do_setlk()
498 spin_lock(&vnode->lock); in afs_do_setlk()
499 list_add_tail(&fl->fl_u.afs.link, &vnode->pending_locks); in afs_do_setlk()
501 ret = -ENOENT; in afs_do_setlk()
502 if (vnode->lock_state == AFS_VNODE_LOCK_DELETED) in afs_do_setlk()
505 /* If we've already got a lock on the server then try to move to having in afs_do_setlk()
506 * the VFS grant the requested lock. Note that this means that other in afs_do_setlk()
509 _debug("try %u", vnode->lock_state); in afs_do_setlk()
510 if (vnode->lock_state == AFS_VNODE_LOCK_GRANTED) { in afs_do_setlk()
513 list_move_tail(&fl->fl_u.afs.link, &vnode->granted_locks); in afs_do_setlk()
514 fl->fl_u.afs.state = AFS_LOCK_GRANTED; in afs_do_setlk()
518 if (vnode->lock_type == AFS_LOCK_WRITE) { in afs_do_setlk()
520 list_move_tail(&fl->fl_u.afs.link, &vnode->granted_locks); in afs_do_setlk()
521 fl->fl_u.afs.state = AFS_LOCK_GRANTED; in afs_do_setlk()
526 if (vnode->lock_state == AFS_VNODE_LOCK_NONE && in afs_do_setlk()
527 !(fl->fl_flags & FL_SLEEP)) { in afs_do_setlk()
528 ret = -EAGAIN; in afs_do_setlk()
530 if (vnode->status.lock_count == -1) in afs_do_setlk()
533 if (vnode->status.lock_count != 0) in afs_do_setlk()
538 if (vnode->lock_state != AFS_VNODE_LOCK_NONE) in afs_do_setlk()
542 /* We don't have a lock on this vnode and we aren't currently waiting in afs_do_setlk()
543 * for one either, so ask the server for a lock. in afs_do_setlk()
546 * after dispatching the request as we may still get the lock, even in afs_do_setlk()
547 * though we don't wait for the reply (it's not too bad a problem - the in afs_do_setlk()
548 * lock will expire in 5 mins anyway). in afs_do_setlk()
551 vnode->lock_key = key_get(key); in afs_do_setlk()
552 vnode->lock_type = type; in afs_do_setlk()
554 spin_unlock(&vnode->lock); in afs_do_setlk()
558 spin_lock(&vnode->lock); in afs_do_setlk()
560 case -EKEYREJECTED: in afs_do_setlk()
561 case -EKEYEXPIRED: in afs_do_setlk()
562 case -EKEYREVOKED: in afs_do_setlk()
563 case -EPERM: in afs_do_setlk()
564 case -EACCES: in afs_do_setlk()
565 fl->fl_u.afs.state = ret; in afs_do_setlk()
567 list_del_init(&fl->fl_u.afs.link); in afs_do_setlk()
571 case -ENOENT: in afs_do_setlk()
572 fl->fl_u.afs.state = ret; in afs_do_setlk()
574 list_del_init(&fl->fl_u.afs.link); in afs_do_setlk()
579 fl->fl_u.afs.state = ret; in afs_do_setlk()
581 list_del_init(&fl->fl_u.afs.link); in afs_do_setlk()
585 case -EWOULDBLOCK: in afs_do_setlk()
586 /* The server doesn't have a lock-waiting queue, so the client in afs_do_setlk()
588 * callbacks on a file when a lock is released. in afs_do_setlk()
590 ASSERT(list_empty(&vnode->granted_locks)); in afs_do_setlk()
591 ASSERTCMP(vnode->pending_locks.next, ==, &fl->fl_u.afs.link); in afs_do_setlk()
602 spin_unlock(&vnode->lock); in afs_do_setlk()
604 /* the lock has been granted by the server... */ in afs_do_setlk()
605 ASSERTCMP(fl->fl_u.afs.state, ==, AFS_LOCK_GRANTED); in afs_do_setlk()
624 if (!(fl->fl_flags & FL_SLEEP)) { in afs_do_setlk()
625 list_del_init(&fl->fl_u.afs.link); in afs_do_setlk()
627 ret = -EAGAIN; in afs_do_setlk()
633 queue_delayed_work(afs_lock_manager, &vnode->lock_work, HZ * 5); in afs_do_setlk()
636 /* We're going to have to wait. Either this client doesn't have a lock in afs_do_setlk()
638 * the client does have a lock on the server, but it's shared and we in afs_do_setlk()
639 * need an exclusive lock. in afs_do_setlk()
641 spin_unlock(&vnode->lock); in afs_do_setlk()
644 ret = wait_event_interruptible(fl->fl_wait, in afs_do_setlk()
645 fl->fl_u.afs.state != AFS_LOCK_PENDING); in afs_do_setlk()
648 if (fl->fl_u.afs.state >= 0 && fl->fl_u.afs.state != AFS_LOCK_GRANTED) { in afs_do_setlk()
649 spin_lock(&vnode->lock); in afs_do_setlk()
651 switch (fl->fl_u.afs.state) { in afs_do_setlk()
653 fl->fl_u.afs.state = AFS_LOCK_PENDING; in afs_do_setlk()
657 /* We need to retry the lock. We may not be in afs_do_setlk()
661 ASSERTCMP(vnode->lock_state, ==, AFS_VNODE_LOCK_WAITING_FOR_CB); in afs_do_setlk()
663 fl->fl_u.afs.state = AFS_LOCK_PENDING; in afs_do_setlk()
672 spin_unlock(&vnode->lock); in afs_do_setlk()
675 if (fl->fl_u.afs.state == AFS_LOCK_GRANTED) in afs_do_setlk()
677 ret = fl->fl_u.afs.state; in afs_do_setlk()
681 /* The VFS rejected the lock we just obtained, so we have to discard in afs_do_setlk()
682 * what we just got. We defer this to the lock manager work item to in afs_do_setlk()
688 spin_lock(&vnode->lock); in afs_do_setlk()
689 list_del_init(&fl->fl_u.afs.link); in afs_do_setlk()
693 spin_unlock(&vnode->lock); in afs_do_setlk()
707 _enter("{%llx:%llu},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type); in afs_do_unlk()
715 _leave(" = %d [%u]", ret, vnode->lock_state); in afs_do_unlk()
720 * return information about a lock we currently hold, if indeed we hold one
730 if (vnode->lock_state == AFS_VNODE_LOCK_DELETED) in afs_do_getlk()
731 return -ENOENT; in afs_do_getlk()
733 fl->fl_type = F_UNLCK; in afs_do_getlk()
735 /* check local lock records first */ in afs_do_getlk()
737 if (fl->fl_type == F_UNLCK) { in afs_do_getlk()
743 lock_count = READ_ONCE(vnode->status.lock_count); in afs_do_getlk()
746 fl->fl_type = F_RDLCK; in afs_do_getlk()
748 fl->fl_type = F_WRLCK; in afs_do_getlk()
749 fl->fl_start = 0; in afs_do_getlk()
750 fl->fl_end = OFFSET_MAX; in afs_do_getlk()
751 fl->fl_pid = 0; in afs_do_getlk()
757 _leave(" = %d [%hd]", ret, fl->fl_type); in afs_do_getlk()
771 vnode->fid.vid, vnode->fid.vnode, cmd, in afs_lock()
772 fl->fl_type, fl->fl_flags, in afs_lock()
773 (long long) fl->fl_start, (long long) fl->fl_end); in afs_lock()
778 fl->fl_u.afs.debug_id = atomic_inc_return(&afs_file_lock_debug_id); in afs_lock()
781 if (fl->fl_type == F_UNLCK) in afs_lock()
788 case -EAGAIN: op = afs_flock_op_return_eagain; break; in afs_lock()
789 case -EDEADLK: op = afs_flock_op_return_edeadlk; break; in afs_lock()
806 vnode->fid.vid, vnode->fid.vnode, cmd, in afs_flock()
807 fl->fl_type, fl->fl_flags); in afs_flock()
811 * Note: we could try to fake a POSIX lock request here by in afs_flock()
816 if (!(fl->fl_flags & FL_FLOCK)) in afs_flock()
817 return -ENOLCK; in afs_flock()
819 fl->fl_u.afs.debug_id = atomic_inc_return(&afs_file_lock_debug_id); in afs_flock()
823 if (fl->fl_type == F_UNLCK) in afs_flock()
830 case -EAGAIN: op = afs_flock_op_return_eagain; break; in afs_flock()
831 case -EDEADLK: op = afs_flock_op_return_edeadlk; break; in afs_flock()
839 * the POSIX lock management core VFS code copies the lock record and adds the
840 * copy into its own list, so we need to add that copy to the vnode's lock
846 struct afs_vnode *vnode = AFS_FS_I(file_inode(fl->fl_file)); in afs_fl_copy_lock()
850 new->fl_u.afs.debug_id = atomic_inc_return(&afs_file_lock_debug_id); in afs_fl_copy_lock()
852 spin_lock(&vnode->lock); in afs_fl_copy_lock()
854 list_add(&new->fl_u.afs.link, &fl->fl_u.afs.link); in afs_fl_copy_lock()
855 spin_unlock(&vnode->lock); in afs_fl_copy_lock()
859 * need to remove this lock from the vnode queue when it's removed from the
864 struct afs_vnode *vnode = AFS_FS_I(file_inode(fl->fl_file)); in afs_fl_release_private()
868 spin_lock(&vnode->lock); in afs_fl_release_private()
871 list_del_init(&fl->fl_u.afs.link); in afs_fl_release_private()
872 if (list_empty(&vnode->granted_locks)) in afs_fl_release_private()
875 _debug("state %u for %p", vnode->lock_state, vnode); in afs_fl_release_private()
876 spin_unlock(&vnode->lock); in afs_fl_release_private()