diff options
author | Jeff Layton <jlayton@redhat.com> | 2014-02-03 12:13:07 -0500 |
---|---|---|
committer | Jeff Layton <jlayton@redhat.com> | 2014-03-31 08:24:42 -0400 |
commit | 8c3cac5e6a85f03602ffe09c44f14418699e31ec (patch) | |
tree | f831e23dbc12c4e3dc3dba31c1395678268da354 | |
parent | b03dfdec0381857db2c01c877b7064f3f5d97d7e (diff) |
locks: eliminate BUG() call when there's an unexpected lock on file close
A leftover lock on the list is surely a sign of a problem of some sort,
but it's not necessarily a reason to panic the box. Instead, just log a
warning with some info about the lock, and then delete it like we would
any other lock.
In the event that the filesystem declares a ->lock f_op, we may end up
leaking something, but that's generally preferable to an immediate
panic.
Acked-by: J. Bruce Fields <bfields@fieldses.org>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
-rw-r--r-- | fs/locks.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/fs/locks.c b/fs/locks.c index 6084f5a32e9c..dd309333afc9 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -2281,16 +2281,28 @@ void locks_remove_flock(struct file *filp) | |||
2281 | 2281 | ||
2282 | while ((fl = *before) != NULL) { | 2282 | while ((fl = *before) != NULL) { |
2283 | if (fl->fl_file == filp) { | 2283 | if (fl->fl_file == filp) { |
2284 | if (IS_FLOCK(fl)) { | ||
2285 | locks_delete_lock(before); | ||
2286 | continue; | ||
2287 | } | ||
2288 | if (IS_LEASE(fl)) { | 2284 | if (IS_LEASE(fl)) { |
2289 | lease_modify(before, F_UNLCK); | 2285 | lease_modify(before, F_UNLCK); |
2290 | continue; | 2286 | continue; |
2291 | } | 2287 | } |
2292 | /* What? */ | 2288 | |
2293 | BUG(); | 2289 | /* |
2290 | * There's a leftover lock on the list of a type that | ||
2291 | * we didn't expect to see. Most likely a classic | ||
2292 | * POSIX lock that ended up not getting released | ||
2293 | * properly, or that raced onto the list somehow. Log | ||
2294 | * some info about it and then just remove it from | ||
2295 | * the list. | ||
2296 | */ | ||
2297 | WARN(!IS_FLOCK(fl), | ||
2298 | "leftover lock: dev=%u:%u ino=%lu type=%hhd flags=0x%x start=%lld end=%lld\n", | ||
2299 | MAJOR(inode->i_sb->s_dev), | ||
2300 | MINOR(inode->i_sb->s_dev), inode->i_ino, | ||
2301 | fl->fl_type, fl->fl_flags, | ||
2302 | fl->fl_start, fl->fl_end); | ||
2303 | |||
2304 | locks_delete_lock(before); | ||
2305 | continue; | ||
2294 | } | 2306 | } |
2295 | before = &fl->fl_next; | 2307 | before = &fl->fl_next; |
2296 | } | 2308 | } |