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 | } |
