Commit ada5c1da authored by NeilBrown's avatar NeilBrown Committed by Jeff Layton

fs/locks: rename some lists and pointers.

struct file lock contains an 'fl_next' pointer which
is used to point to the lock that this request is blocked
waiting for.  So rename it to fl_blocker.

The fl_blocked list_head in an active lock is the head of a list of
blocked requests.  In a request it is a node in that list.
These are two distinct uses, so replace with two list_heads
with different names.
fl_blocked_requests is the head of a list of blocked requests
fl_blocked_member is a node in a member of that list.

The two different list_heads are never used at the same time, but that
will change in a future patch.

Note that a tracepoint is changed to report fl_blocker instead
of fl_next.
Signed-off-by: default avatarNeilBrown <neilb@suse.com>
Reviewed-by: default avatarJ. Bruce Fields <bfields@redhat.com>
Signed-off-by: default avatarJeff Layton <jlayton@kernel.org>
parent ccda4af0
...@@ -1103,7 +1103,7 @@ cifs_posix_lock_set(struct file *file, struct file_lock *flock) ...@@ -1103,7 +1103,7 @@ cifs_posix_lock_set(struct file *file, struct file_lock *flock)
rc = posix_lock_file(file, flock, NULL); rc = posix_lock_file(file, flock, NULL);
up_write(&cinode->lock_sem); up_write(&cinode->lock_sem);
if (rc == FILE_LOCK_DEFERRED) { if (rc == FILE_LOCK_DEFERRED) {
rc = wait_event_interruptible(flock->fl_wait, !flock->fl_next); rc = wait_event_interruptible(flock->fl_wait, !flock->fl_blocker);
if (!rc) if (!rc)
goto try_again; goto try_again;
posix_unblock_lock(flock); posix_unblock_lock(flock);
......
...@@ -189,9 +189,9 @@ static DEFINE_HASHTABLE(blocked_hash, BLOCKED_HASH_BITS); ...@@ -189,9 +189,9 @@ static DEFINE_HASHTABLE(blocked_hash, BLOCKED_HASH_BITS);
* This lock protects the blocked_hash. Generally, if you're accessing it, you * This lock protects the blocked_hash. Generally, if you're accessing it, you
* want to be holding this lock. * want to be holding this lock.
* *
* In addition, it also protects the fl->fl_block list, and the fl->fl_next * In addition, it also protects the fl->fl_blocked_requests list, and the
* pointer for file_lock structures that are acting as lock requests (in * fl->fl_blocker pointer for file_lock structures that are acting as lock
* contrast to those that are acting as records of acquired locks). * requests (in contrast to those that are acting as records of acquired locks).
* *
* Note that when we acquire this lock in order to change the above fields, * Note that when we acquire this lock in order to change the above fields,
* we often hold the flc_lock as well. In certain cases, when reading the fields * we often hold the flc_lock as well. In certain cases, when reading the fields
...@@ -293,7 +293,8 @@ static void locks_init_lock_heads(struct file_lock *fl) ...@@ -293,7 +293,8 @@ static void locks_init_lock_heads(struct file_lock *fl)
{ {
INIT_HLIST_NODE(&fl->fl_link); INIT_HLIST_NODE(&fl->fl_link);
INIT_LIST_HEAD(&fl->fl_list); INIT_LIST_HEAD(&fl->fl_list);
INIT_LIST_HEAD(&fl->fl_block); INIT_LIST_HEAD(&fl->fl_blocked_requests);
INIT_LIST_HEAD(&fl->fl_blocked_member);
init_waitqueue_head(&fl->fl_wait); init_waitqueue_head(&fl->fl_wait);
} }
...@@ -332,7 +333,8 @@ void locks_free_lock(struct file_lock *fl) ...@@ -332,7 +333,8 @@ void locks_free_lock(struct file_lock *fl)
{ {
BUG_ON(waitqueue_active(&fl->fl_wait)); BUG_ON(waitqueue_active(&fl->fl_wait));
BUG_ON(!list_empty(&fl->fl_list)); BUG_ON(!list_empty(&fl->fl_list));
BUG_ON(!list_empty(&fl->fl_block)); BUG_ON(!list_empty(&fl->fl_blocked_requests));
BUG_ON(!list_empty(&fl->fl_blocked_member));
BUG_ON(!hlist_unhashed(&fl->fl_link)); BUG_ON(!hlist_unhashed(&fl->fl_link));
locks_release_private(fl); locks_release_private(fl);
...@@ -666,8 +668,8 @@ static void locks_delete_global_blocked(struct file_lock *waiter) ...@@ -666,8 +668,8 @@ static void locks_delete_global_blocked(struct file_lock *waiter)
static void __locks_delete_block(struct file_lock *waiter) static void __locks_delete_block(struct file_lock *waiter)
{ {
locks_delete_global_blocked(waiter); locks_delete_global_blocked(waiter);
list_del_init(&waiter->fl_block); list_del_init(&waiter->fl_blocked_member);
waiter->fl_next = NULL; waiter->fl_blocker = NULL;
} }
static void locks_delete_block(struct file_lock *waiter) static void locks_delete_block(struct file_lock *waiter)
...@@ -683,16 +685,17 @@ static void locks_delete_block(struct file_lock *waiter) ...@@ -683,16 +685,17 @@ static void locks_delete_block(struct file_lock *waiter)
* it seems like the reasonable thing to do. * it seems like the reasonable thing to do.
* *
* Must be called with both the flc_lock and blocked_lock_lock held. The * Must be called with both the flc_lock and blocked_lock_lock held. The
* fl_block list itself is protected by the blocked_lock_lock, but by ensuring * fl_blocked_requests list itself is protected by the blocked_lock_lock,
* that the flc_lock is also held on insertions we can avoid taking the * but by ensuring that the flc_lock is also held on insertions we can avoid
* blocked_lock_lock in some cases when we see that the fl_block list is empty. * taking the blocked_lock_lock in some cases when we see that the
* fl_blocked_requests list is empty.
*/ */
static void __locks_insert_block(struct file_lock *blocker, static void __locks_insert_block(struct file_lock *blocker,
struct file_lock *waiter) struct file_lock *waiter)
{ {
BUG_ON(!list_empty(&waiter->fl_block)); BUG_ON(!list_empty(&waiter->fl_blocked_member));
waiter->fl_next = blocker; waiter->fl_blocker = blocker;
list_add_tail(&waiter->fl_block, &blocker->fl_block); list_add_tail(&waiter->fl_blocked_member, &blocker->fl_blocked_requests);
if (IS_POSIX(blocker) && !IS_OFDLCK(blocker)) if (IS_POSIX(blocker) && !IS_OFDLCK(blocker))
locks_insert_global_blocked(waiter); locks_insert_global_blocked(waiter);
} }
...@@ -716,19 +719,19 @@ static void locks_wake_up_blocks(struct file_lock *blocker) ...@@ -716,19 +719,19 @@ static void locks_wake_up_blocks(struct file_lock *blocker)
/* /*
* Avoid taking global lock if list is empty. This is safe since new * Avoid taking global lock if list is empty. This is safe since new
* blocked requests are only added to the list under the flc_lock, and * blocked requests are only added to the list under the flc_lock, and
* the flc_lock is always held here. Note that removal from the fl_block * the flc_lock is always held here. Note that removal from the
* list does not require the flc_lock, so we must recheck list_empty() * fl_blocked_requests list does not require the flc_lock, so we must
* after acquiring the blocked_lock_lock. * recheck list_empty() after acquiring the blocked_lock_lock.
*/ */
if (list_empty(&blocker->fl_block)) if (list_empty(&blocker->fl_blocked_requests))
return; return;
spin_lock(&blocked_lock_lock); spin_lock(&blocked_lock_lock);
while (!list_empty(&blocker->fl_block)) { while (!list_empty(&blocker->fl_blocked_requests)) {
struct file_lock *waiter; struct file_lock *waiter;
waiter = list_first_entry(&blocker->fl_block, waiter = list_first_entry(&blocker->fl_blocked_requests,
struct file_lock, fl_block); struct file_lock, fl_blocked_member);
__locks_delete_block(waiter); __locks_delete_block(waiter);
if (waiter->fl_lmops && waiter->fl_lmops->lm_notify) if (waiter->fl_lmops && waiter->fl_lmops->lm_notify)
waiter->fl_lmops->lm_notify(waiter); waiter->fl_lmops->lm_notify(waiter);
...@@ -878,7 +881,7 @@ static struct file_lock *what_owner_is_waiting_for(struct file_lock *block_fl) ...@@ -878,7 +881,7 @@ static struct file_lock *what_owner_is_waiting_for(struct file_lock *block_fl)
hash_for_each_possible(blocked_hash, fl, fl_link, posix_owner_key(block_fl)) { hash_for_each_possible(blocked_hash, fl, fl_link, posix_owner_key(block_fl)) {
if (posix_same_owner(fl, block_fl)) if (posix_same_owner(fl, block_fl))
return fl->fl_next; return fl->fl_blocker;
} }
return NULL; return NULL;
} }
...@@ -1237,7 +1240,7 @@ static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl) ...@@ -1237,7 +1240,7 @@ static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl)
error = posix_lock_inode(inode, fl, NULL); error = posix_lock_inode(inode, fl, NULL);
if (error != FILE_LOCK_DEFERRED) if (error != FILE_LOCK_DEFERRED)
break; break;
error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); error = wait_event_interruptible(fl->fl_wait, !fl->fl_blocker);
if (!error) if (!error)
continue; continue;
...@@ -1324,7 +1327,7 @@ int locks_mandatory_area(struct inode *inode, struct file *filp, loff_t start, ...@@ -1324,7 +1327,7 @@ int locks_mandatory_area(struct inode *inode, struct file *filp, loff_t start,
error = posix_lock_inode(inode, &fl, NULL); error = posix_lock_inode(inode, &fl, NULL);
if (error != FILE_LOCK_DEFERRED) if (error != FILE_LOCK_DEFERRED)
break; break;
error = wait_event_interruptible(fl.fl_wait, !fl.fl_next); error = wait_event_interruptible(fl.fl_wait, !fl.fl_blocker);
if (!error) { if (!error) {
/* /*
* If we've been sleeping someone might have * If we've been sleeping someone might have
...@@ -1518,7 +1521,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) ...@@ -1518,7 +1521,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
locks_dispose_list(&dispose); locks_dispose_list(&dispose);
error = wait_event_interruptible_timeout(new_fl->fl_wait, error = wait_event_interruptible_timeout(new_fl->fl_wait,
!new_fl->fl_next, break_time); !new_fl->fl_blocker, break_time);
percpu_down_read_preempt_disable(&file_rwsem); percpu_down_read_preempt_disable(&file_rwsem);
spin_lock(&ctx->flc_lock); spin_lock(&ctx->flc_lock);
...@@ -1931,7 +1934,7 @@ static int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl) ...@@ -1931,7 +1934,7 @@ static int flock_lock_inode_wait(struct inode *inode, struct file_lock *fl)
error = flock_lock_inode(inode, fl); error = flock_lock_inode(inode, fl);
if (error != FILE_LOCK_DEFERRED) if (error != FILE_LOCK_DEFERRED)
break; break;
error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); error = wait_event_interruptible(fl->fl_wait, !fl->fl_blocker);
if (!error) if (!error)
continue; continue;
...@@ -2210,7 +2213,7 @@ static int do_lock_file_wait(struct file *filp, unsigned int cmd, ...@@ -2210,7 +2213,7 @@ static int do_lock_file_wait(struct file *filp, unsigned int cmd,
error = vfs_lock_file(filp, cmd, fl, NULL); error = vfs_lock_file(filp, cmd, fl, NULL);
if (error != FILE_LOCK_DEFERRED) if (error != FILE_LOCK_DEFERRED)
break; break;
error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); error = wait_event_interruptible(fl->fl_wait, !fl->fl_blocker);
if (!error) if (!error)
continue; continue;
...@@ -2581,7 +2584,7 @@ posix_unblock_lock(struct file_lock *waiter) ...@@ -2581,7 +2584,7 @@ posix_unblock_lock(struct file_lock *waiter)
int status = 0; int status = 0;
spin_lock(&blocked_lock_lock); spin_lock(&blocked_lock_lock);
if (waiter->fl_next) if (waiter->fl_blocker)
__locks_delete_block(waiter); __locks_delete_block(waiter);
else else
status = -ENOENT; status = -ENOENT;
...@@ -2707,7 +2710,7 @@ static int locks_show(struct seq_file *f, void *v) ...@@ -2707,7 +2710,7 @@ static int locks_show(struct seq_file *f, void *v)
lock_get_status(f, fl, iter->li_pos, ""); lock_get_status(f, fl, iter->li_pos, "");
list_for_each_entry(bfl, &fl->fl_block, fl_block) list_for_each_entry(bfl, &fl->fl_blocked_requests, fl_blocked_member)
lock_get_status(f, bfl, iter->li_pos, " ->"); lock_get_status(f, bfl, iter->li_pos, " ->");
return 0; return 0;
......
...@@ -1044,10 +1044,15 @@ bool opens_in_grace(struct net *); ...@@ -1044,10 +1044,15 @@ bool opens_in_grace(struct net *);
* Obviously, the last two criteria only matter for POSIX locks. * Obviously, the last two criteria only matter for POSIX locks.
*/ */
struct file_lock { struct file_lock {
struct file_lock *fl_next; /* singly linked list for this inode */ struct file_lock *fl_blocker; /* The lock, that is blocking us */
struct list_head fl_list; /* link into file_lock_context */ struct list_head fl_list; /* link into file_lock_context */
struct hlist_node fl_link; /* node in global lists */ struct hlist_node fl_link; /* node in global lists */
struct list_head fl_block; /* circular list of blocked processes */ struct list_head fl_blocked_requests; /* list of requests with
* ->fl_blocker pointing here
*/
struct list_head fl_blocked_member; /* node in
* ->fl_blocker->fl_blocked_requests
*/
fl_owner_t fl_owner; fl_owner_t fl_owner;
unsigned int fl_flags; unsigned int fl_flags;
unsigned char fl_type; unsigned char fl_type;
......
...@@ -68,7 +68,7 @@ DECLARE_EVENT_CLASS(filelock_lock, ...@@ -68,7 +68,7 @@ DECLARE_EVENT_CLASS(filelock_lock,
__field(struct file_lock *, fl) __field(struct file_lock *, fl)
__field(unsigned long, i_ino) __field(unsigned long, i_ino)
__field(dev_t, s_dev) __field(dev_t, s_dev)
__field(struct file_lock *, fl_next) __field(struct file_lock *, fl_blocker)
__field(fl_owner_t, fl_owner) __field(fl_owner_t, fl_owner)
__field(unsigned int, fl_pid) __field(unsigned int, fl_pid)
__field(unsigned int, fl_flags) __field(unsigned int, fl_flags)
...@@ -82,7 +82,7 @@ DECLARE_EVENT_CLASS(filelock_lock, ...@@ -82,7 +82,7 @@ DECLARE_EVENT_CLASS(filelock_lock,
__entry->fl = fl ? fl : NULL; __entry->fl = fl ? fl : NULL;
__entry->s_dev = inode->i_sb->s_dev; __entry->s_dev = inode->i_sb->s_dev;
__entry->i_ino = inode->i_ino; __entry->i_ino = inode->i_ino;
__entry->fl_next = fl ? fl->fl_next : NULL; __entry->fl_blocker = fl ? fl->fl_blocker : NULL;
__entry->fl_owner = fl ? fl->fl_owner : NULL; __entry->fl_owner = fl ? fl->fl_owner : NULL;
__entry->fl_pid = fl ? fl->fl_pid : 0; __entry->fl_pid = fl ? fl->fl_pid : 0;
__entry->fl_flags = fl ? fl->fl_flags : 0; __entry->fl_flags = fl ? fl->fl_flags : 0;
...@@ -92,9 +92,9 @@ DECLARE_EVENT_CLASS(filelock_lock, ...@@ -92,9 +92,9 @@ DECLARE_EVENT_CLASS(filelock_lock,
__entry->ret = ret; __entry->ret = ret;
), ),
TP_printk("fl=0x%p dev=0x%x:0x%x ino=0x%lx fl_next=0x%p fl_owner=0x%p fl_pid=%u fl_flags=%s fl_type=%s fl_start=%lld fl_end=%lld ret=%d", TP_printk("fl=0x%p dev=0x%x:0x%x ino=0x%lx fl_blocker=0x%p fl_owner=0x%p fl_pid=%u fl_flags=%s fl_type=%s fl_start=%lld fl_end=%lld ret=%d",
__entry->fl, MAJOR(__entry->s_dev), MINOR(__entry->s_dev), __entry->fl, MAJOR(__entry->s_dev), MINOR(__entry->s_dev),
__entry->i_ino, __entry->fl_next, __entry->fl_owner, __entry->i_ino, __entry->fl_blocker, __entry->fl_owner,
__entry->fl_pid, show_fl_flags(__entry->fl_flags), __entry->fl_pid, show_fl_flags(__entry->fl_flags),
show_fl_type(__entry->fl_type), show_fl_type(__entry->fl_type),
__entry->fl_start, __entry->fl_end, __entry->ret) __entry->fl_start, __entry->fl_end, __entry->ret)
...@@ -125,7 +125,7 @@ DECLARE_EVENT_CLASS(filelock_lease, ...@@ -125,7 +125,7 @@ DECLARE_EVENT_CLASS(filelock_lease,
__field(struct file_lock *, fl) __field(struct file_lock *, fl)
__field(unsigned long, i_ino) __field(unsigned long, i_ino)
__field(dev_t, s_dev) __field(dev_t, s_dev)
__field(struct file_lock *, fl_next) __field(struct file_lock *, fl_blocker)
__field(fl_owner_t, fl_owner) __field(fl_owner_t, fl_owner)
__field(unsigned int, fl_flags) __field(unsigned int, fl_flags)
__field(unsigned char, fl_type) __field(unsigned char, fl_type)
...@@ -137,7 +137,7 @@ DECLARE_EVENT_CLASS(filelock_lease, ...@@ -137,7 +137,7 @@ DECLARE_EVENT_CLASS(filelock_lease,
__entry->fl = fl ? fl : NULL; __entry->fl = fl ? fl : NULL;
__entry->s_dev = inode->i_sb->s_dev; __entry->s_dev = inode->i_sb->s_dev;
__entry->i_ino = inode->i_ino; __entry->i_ino = inode->i_ino;
__entry->fl_next = fl ? fl->fl_next : NULL; __entry->fl_blocker = fl ? fl->fl_blocker : NULL;
__entry->fl_owner = fl ? fl->fl_owner : NULL; __entry->fl_owner = fl ? fl->fl_owner : NULL;
__entry->fl_flags = fl ? fl->fl_flags : 0; __entry->fl_flags = fl ? fl->fl_flags : 0;
__entry->fl_type = fl ? fl->fl_type : 0; __entry->fl_type = fl ? fl->fl_type : 0;
...@@ -145,9 +145,9 @@ DECLARE_EVENT_CLASS(filelock_lease, ...@@ -145,9 +145,9 @@ DECLARE_EVENT_CLASS(filelock_lease,
__entry->fl_downgrade_time = fl ? fl->fl_downgrade_time : 0; __entry->fl_downgrade_time = fl ? fl->fl_downgrade_time : 0;
), ),
TP_printk("fl=0x%p dev=0x%x:0x%x ino=0x%lx fl_next=0x%p fl_owner=0x%p fl_flags=%s fl_type=%s fl_break_time=%lu fl_downgrade_time=%lu", TP_printk("fl=0x%p dev=0x%x:0x%x ino=0x%lx fl_blocker=0x%p fl_owner=0x%p fl_flags=%s fl_type=%s fl_break_time=%lu fl_downgrade_time=%lu",
__entry->fl, MAJOR(__entry->s_dev), MINOR(__entry->s_dev), __entry->fl, MAJOR(__entry->s_dev), MINOR(__entry->s_dev),
__entry->i_ino, __entry->fl_next, __entry->fl_owner, __entry->i_ino, __entry->fl_blocker, __entry->fl_owner,
show_fl_flags(__entry->fl_flags), show_fl_flags(__entry->fl_flags),
show_fl_type(__entry->fl_type), show_fl_type(__entry->fl_type),
__entry->fl_break_time, __entry->fl_downgrade_time) __entry->fl_break_time, __entry->fl_downgrade_time)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment