diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-12 18:46:17 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-12 18:46:17 -0500 |
commit | 065019a38feab5f2659cbd44080d528f8dff0b00 (patch) | |
tree | 80e8fcd6fea433ba9ddd3a3ba9333446947be78f | |
parent | 4f31d774dd5239e563f22ffe1403292414e6f779 (diff) | |
parent | b4d629a39e104a8326d5b281ce07c21240c130c9 (diff) |
Merge tag 'locks-v4.5-1' of git://git.samba.org/jlayton/linux
Pull file locking updates from Jeff Layton:
"File locking related changes for v4.5 (pile #1)
Highlights:
- new Kconfig option to allow disabling mandatory locking (which is
racy anyway)
- new tracepoints for setlk and close codepaths
- fix for a long-standing bug in code that handles races between
setting a POSIX lock and close()"
* tag 'locks-v4.5-1' of git://git.samba.org/jlayton/linux:
locks: rename __posix_lock_file to posix_lock_inode
locks: prink more detail when there are leaked locks
locks: pass inode pointer to locks_free_lock_context
locks: sprinkle some tracepoints around the file locking code
locks: don't check for race with close when setting OFD lock
locks: fix unlock when fcntl_setlk races with a close
fs: make locks.c explicitly non-modular
locks: use list_first_entry_or_null()
locks: Don't allow mounts in user namespaces to enable mandatory locking
locks: Allow disabling mandatory locking at compile time
-rw-r--r-- | fs/Kconfig | 10 | ||||
-rw-r--r-- | fs/inode.c | 2 | ||||
-rw-r--r-- | fs/locks.c | 138 | ||||
-rw-r--r-- | fs/namespace.c | 10 | ||||
-rw-r--r-- | include/linux/fs.h | 78 | ||||
-rw-r--r-- | include/trace/events/filelock.h | 77 |
6 files changed, 232 insertions, 83 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index 6ce72d8d1ee1..2bb1ef86c411 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -73,6 +73,16 @@ config FILE_LOCKING | |||
73 | for filesystems like NFS and for the flock() system | 73 | for filesystems like NFS and for the flock() system |
74 | call. Disabling this option saves about 11k. | 74 | call. Disabling this option saves about 11k. |
75 | 75 | ||
76 | config MANDATORY_FILE_LOCKING | ||
77 | bool "Enable Mandatory file locking" | ||
78 | depends on FILE_LOCKING | ||
79 | default y | ||
80 | help | ||
81 | This option enables files appropriately marked files on appropriely | ||
82 | mounted filesystems to support mandatory locking. | ||
83 | |||
84 | To the best of my knowledge this is dead code that no one cares about. | ||
85 | |||
76 | source "fs/notify/Kconfig" | 86 | source "fs/notify/Kconfig" |
77 | 87 | ||
78 | source "fs/quota/Kconfig" | 88 | source "fs/quota/Kconfig" |
diff --git a/fs/inode.c b/fs/inode.c index 5bb85a064ce7..4230f66b7410 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -225,7 +225,7 @@ void __destroy_inode(struct inode *inode) | |||
225 | inode_detach_wb(inode); | 225 | inode_detach_wb(inode); |
226 | security_inode_free(inode); | 226 | security_inode_free(inode); |
227 | fsnotify_inode_delete(inode); | 227 | fsnotify_inode_delete(inode); |
228 | locks_free_lock_context(inode->i_flctx); | 228 | locks_free_lock_context(inode); |
229 | if (!inode->i_nlink) { | 229 | if (!inode->i_nlink) { |
230 | WARN_ON(atomic_long_read(&inode->i_sb->s_remove_count) == 0); | 230 | WARN_ON(atomic_long_read(&inode->i_sb->s_remove_count) == 0); |
231 | atomic_long_dec(&inode->i_sb->s_remove_count); | 231 | atomic_long_dec(&inode->i_sb->s_remove_count); |
diff --git a/fs/locks.c b/fs/locks.c index 0d2b3267e2a3..a91f4ab00a90 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -119,7 +119,6 @@ | |||
119 | #include <linux/fdtable.h> | 119 | #include <linux/fdtable.h> |
120 | #include <linux/fs.h> | 120 | #include <linux/fs.h> |
121 | #include <linux/init.h> | 121 | #include <linux/init.h> |
122 | #include <linux/module.h> | ||
123 | #include <linux/security.h> | 122 | #include <linux/security.h> |
124 | #include <linux/slab.h> | 123 | #include <linux/slab.h> |
125 | #include <linux/syscalls.h> | 124 | #include <linux/syscalls.h> |
@@ -230,16 +229,44 @@ locks_get_lock_context(struct inode *inode, int type) | |||
230 | ctx = smp_load_acquire(&inode->i_flctx); | 229 | ctx = smp_load_acquire(&inode->i_flctx); |
231 | } | 230 | } |
232 | out: | 231 | out: |
232 | trace_locks_get_lock_context(inode, type, ctx); | ||
233 | return ctx; | 233 | return ctx; |
234 | } | 234 | } |
235 | 235 | ||
236 | static void | ||
237 | locks_dump_ctx_list(struct list_head *list, char *list_type) | ||
238 | { | ||
239 | struct file_lock *fl; | ||
240 | |||
241 | list_for_each_entry(fl, list, fl_list) { | ||
242 | pr_warn("%s: fl_owner=%p fl_flags=0x%x fl_type=0x%x fl_pid=%u\n", list_type, fl->fl_owner, fl->fl_flags, fl->fl_type, fl->fl_pid); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | static void | ||
247 | locks_check_ctx_lists(struct inode *inode) | ||
248 | { | ||
249 | struct file_lock_context *ctx = inode->i_flctx; | ||
250 | |||
251 | if (unlikely(!list_empty(&ctx->flc_flock) || | ||
252 | !list_empty(&ctx->flc_posix) || | ||
253 | !list_empty(&ctx->flc_lease))) { | ||
254 | pr_warn("Leaked locks on dev=0x%x:0x%x ino=0x%lx:\n", | ||
255 | MAJOR(inode->i_sb->s_dev), MINOR(inode->i_sb->s_dev), | ||
256 | inode->i_ino); | ||
257 | locks_dump_ctx_list(&ctx->flc_flock, "FLOCK"); | ||
258 | locks_dump_ctx_list(&ctx->flc_posix, "POSIX"); | ||
259 | locks_dump_ctx_list(&ctx->flc_lease, "LEASE"); | ||
260 | } | ||
261 | } | ||
262 | |||
236 | void | 263 | void |
237 | locks_free_lock_context(struct file_lock_context *ctx) | 264 | locks_free_lock_context(struct inode *inode) |
238 | { | 265 | { |
239 | if (ctx) { | 266 | struct file_lock_context *ctx = inode->i_flctx; |
240 | WARN_ON_ONCE(!list_empty(&ctx->flc_flock)); | 267 | |
241 | WARN_ON_ONCE(!list_empty(&ctx->flc_posix)); | 268 | if (unlikely(ctx)) { |
242 | WARN_ON_ONCE(!list_empty(&ctx->flc_lease)); | 269 | locks_check_ctx_lists(inode); |
243 | kmem_cache_free(flctx_cache, ctx); | 270 | kmem_cache_free(flctx_cache, ctx); |
244 | } | 271 | } |
245 | } | 272 | } |
@@ -934,7 +961,8 @@ out: | |||
934 | return error; | 961 | return error; |
935 | } | 962 | } |
936 | 963 | ||
937 | static int __posix_lock_file(struct inode *inode, struct file_lock *request, struct file_lock *conflock) | 964 | static int posix_lock_inode(struct inode *inode, struct file_lock *request, |
965 | struct file_lock *conflock) | ||
938 | { | 966 | { |
939 | struct file_lock *fl, *tmp; | 967 | struct file_lock *fl, *tmp; |
940 | struct file_lock *new_fl = NULL; | 968 | struct file_lock *new_fl = NULL; |
@@ -1142,6 +1170,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
1142 | if (new_fl2) | 1170 | if (new_fl2) |
1143 | locks_free_lock(new_fl2); | 1171 | locks_free_lock(new_fl2); |
1144 | locks_dispose_list(&dispose); | 1172 | locks_dispose_list(&dispose); |
1173 | trace_posix_lock_inode(inode, request, error); | ||
1174 | |||
1145 | return error; | 1175 | return error; |
1146 | } | 1176 | } |
1147 | 1177 | ||
@@ -1162,7 +1192,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, str | |||
1162 | int posix_lock_file(struct file *filp, struct file_lock *fl, | 1192 | int posix_lock_file(struct file *filp, struct file_lock *fl, |
1163 | struct file_lock *conflock) | 1193 | struct file_lock *conflock) |
1164 | { | 1194 | { |
1165 | return __posix_lock_file(file_inode(filp), fl, conflock); | 1195 | return posix_lock_inode(file_inode(filp), fl, conflock); |
1166 | } | 1196 | } |
1167 | EXPORT_SYMBOL(posix_lock_file); | 1197 | EXPORT_SYMBOL(posix_lock_file); |
1168 | 1198 | ||
@@ -1178,7 +1208,7 @@ static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl) | |||
1178 | int error; | 1208 | int error; |
1179 | might_sleep (); | 1209 | might_sleep (); |
1180 | for (;;) { | 1210 | for (;;) { |
1181 | error = __posix_lock_file(inode, fl, NULL); | 1211 | error = posix_lock_inode(inode, fl, NULL); |
1182 | if (error != FILE_LOCK_DEFERRED) | 1212 | if (error != FILE_LOCK_DEFERRED) |
1183 | break; | 1213 | break; |
1184 | error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); | 1214 | error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); |
@@ -1191,6 +1221,7 @@ static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl) | |||
1191 | return error; | 1221 | return error; |
1192 | } | 1222 | } |
1193 | 1223 | ||
1224 | #ifdef CONFIG_MANDATORY_FILE_LOCKING | ||
1194 | /** | 1225 | /** |
1195 | * locks_mandatory_locked - Check for an active lock | 1226 | * locks_mandatory_locked - Check for an active lock |
1196 | * @file: the file to check | 1227 | * @file: the file to check |
@@ -1260,7 +1291,7 @@ int locks_mandatory_area(int read_write, struct inode *inode, | |||
1260 | if (filp) { | 1291 | if (filp) { |
1261 | fl.fl_owner = filp; | 1292 | fl.fl_owner = filp; |
1262 | fl.fl_flags &= ~FL_SLEEP; | 1293 | fl.fl_flags &= ~FL_SLEEP; |
1263 | error = __posix_lock_file(inode, &fl, NULL); | 1294 | error = posix_lock_inode(inode, &fl, NULL); |
1264 | if (!error) | 1295 | if (!error) |
1265 | break; | 1296 | break; |
1266 | } | 1297 | } |
@@ -1268,7 +1299,7 @@ int locks_mandatory_area(int read_write, struct inode *inode, | |||
1268 | if (sleep) | 1299 | if (sleep) |
1269 | fl.fl_flags |= FL_SLEEP; | 1300 | fl.fl_flags |= FL_SLEEP; |
1270 | fl.fl_owner = current->files; | 1301 | fl.fl_owner = current->files; |
1271 | error = __posix_lock_file(inode, &fl, NULL); | 1302 | error = posix_lock_inode(inode, &fl, NULL); |
1272 | if (error != FILE_LOCK_DEFERRED) | 1303 | if (error != FILE_LOCK_DEFERRED) |
1273 | break; | 1304 | break; |
1274 | error = wait_event_interruptible(fl.fl_wait, !fl.fl_next); | 1305 | error = wait_event_interruptible(fl.fl_wait, !fl.fl_next); |
@@ -1289,6 +1320,7 @@ int locks_mandatory_area(int read_write, struct inode *inode, | |||
1289 | } | 1320 | } |
1290 | 1321 | ||
1291 | EXPORT_SYMBOL(locks_mandatory_area); | 1322 | EXPORT_SYMBOL(locks_mandatory_area); |
1323 | #endif /* CONFIG_MANDATORY_FILE_LOCKING */ | ||
1292 | 1324 | ||
1293 | static void lease_clear_pending(struct file_lock *fl, int arg) | 1325 | static void lease_clear_pending(struct file_lock *fl, int arg) |
1294 | { | 1326 | { |
@@ -1503,12 +1535,10 @@ void lease_get_mtime(struct inode *inode, struct timespec *time) | |||
1503 | ctx = smp_load_acquire(&inode->i_flctx); | 1535 | ctx = smp_load_acquire(&inode->i_flctx); |
1504 | if (ctx && !list_empty_careful(&ctx->flc_lease)) { | 1536 | if (ctx && !list_empty_careful(&ctx->flc_lease)) { |
1505 | spin_lock(&ctx->flc_lock); | 1537 | spin_lock(&ctx->flc_lock); |
1506 | if (!list_empty(&ctx->flc_lease)) { | 1538 | fl = list_first_entry_or_null(&ctx->flc_lease, |
1507 | fl = list_first_entry(&ctx->flc_lease, | 1539 | struct file_lock, fl_list); |
1508 | struct file_lock, fl_list); | 1540 | if (fl && (fl->fl_type == F_WRLCK)) |
1509 | if (fl->fl_type == F_WRLCK) | 1541 | has_lease = true; |
1510 | has_lease = true; | ||
1511 | } | ||
1512 | spin_unlock(&ctx->flc_lock); | 1542 | spin_unlock(&ctx->flc_lock); |
1513 | } | 1543 | } |
1514 | 1544 | ||
@@ -2165,6 +2195,8 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, | |||
2165 | if (file_lock == NULL) | 2195 | if (file_lock == NULL) |
2166 | return -ENOLCK; | 2196 | return -ENOLCK; |
2167 | 2197 | ||
2198 | inode = file_inode(filp); | ||
2199 | |||
2168 | /* | 2200 | /* |
2169 | * This might block, so we do it before checking the inode. | 2201 | * This might block, so we do it before checking the inode. |
2170 | */ | 2202 | */ |
@@ -2172,8 +2204,6 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, | |||
2172 | if (copy_from_user(&flock, l, sizeof(flock))) | 2204 | if (copy_from_user(&flock, l, sizeof(flock))) |
2173 | goto out; | 2205 | goto out; |
2174 | 2206 | ||
2175 | inode = file_inode(filp); | ||
2176 | |||
2177 | /* Don't allow mandatory locks on files that may be memory mapped | 2207 | /* Don't allow mandatory locks on files that may be memory mapped |
2178 | * and shared. | 2208 | * and shared. |
2179 | */ | 2209 | */ |
@@ -2182,7 +2212,6 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, | |||
2182 | goto out; | 2212 | goto out; |
2183 | } | 2213 | } |
2184 | 2214 | ||
2185 | again: | ||
2186 | error = flock_to_posix_lock(filp, file_lock, &flock); | 2215 | error = flock_to_posix_lock(filp, file_lock, &flock); |
2187 | if (error) | 2216 | if (error) |
2188 | goto out; | 2217 | goto out; |
@@ -2221,23 +2250,29 @@ again: | |||
2221 | error = do_lock_file_wait(filp, cmd, file_lock); | 2250 | error = do_lock_file_wait(filp, cmd, file_lock); |
2222 | 2251 | ||
2223 | /* | 2252 | /* |
2224 | * Attempt to detect a close/fcntl race and recover by | 2253 | * Attempt to detect a close/fcntl race and recover by releasing the |
2225 | * releasing the lock that was just acquired. | 2254 | * lock that was just acquired. There is no need to do that when we're |
2226 | */ | 2255 | * unlocking though, or for OFD locks. |
2227 | /* | ||
2228 | * we need that spin_lock here - it prevents reordering between | ||
2229 | * update of i_flctx->flc_posix and check for it done in close(). | ||
2230 | * rcu_read_lock() wouldn't do. | ||
2231 | */ | 2256 | */ |
2232 | spin_lock(¤t->files->file_lock); | 2257 | if (!error && file_lock->fl_type != F_UNLCK && |
2233 | f = fcheck(fd); | 2258 | !(file_lock->fl_flags & FL_OFDLCK)) { |
2234 | spin_unlock(¤t->files->file_lock); | 2259 | /* |
2235 | if (!error && f != filp && flock.l_type != F_UNLCK) { | 2260 | * We need that spin_lock here - it prevents reordering between |
2236 | flock.l_type = F_UNLCK; | 2261 | * update of i_flctx->flc_posix and check for it done in |
2237 | goto again; | 2262 | * close(). rcu_read_lock() wouldn't do. |
2263 | */ | ||
2264 | spin_lock(¤t->files->file_lock); | ||
2265 | f = fcheck(fd); | ||
2266 | spin_unlock(¤t->files->file_lock); | ||
2267 | if (f != filp) { | ||
2268 | file_lock->fl_type = F_UNLCK; | ||
2269 | error = do_lock_file_wait(filp, cmd, file_lock); | ||
2270 | WARN_ON_ONCE(error); | ||
2271 | error = -EBADF; | ||
2272 | } | ||
2238 | } | 2273 | } |
2239 | |||
2240 | out: | 2274 | out: |
2275 | trace_fcntl_setlk(inode, file_lock, error); | ||
2241 | locks_free_lock(file_lock); | 2276 | locks_free_lock(file_lock); |
2242 | return error; | 2277 | return error; |
2243 | } | 2278 | } |
@@ -2322,7 +2357,6 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, | |||
2322 | goto out; | 2357 | goto out; |
2323 | } | 2358 | } |
2324 | 2359 | ||
2325 | again: | ||
2326 | error = flock64_to_posix_lock(filp, file_lock, &flock); | 2360 | error = flock64_to_posix_lock(filp, file_lock, &flock); |
2327 | if (error) | 2361 | if (error) |
2328 | goto out; | 2362 | goto out; |
@@ -2361,17 +2395,27 @@ again: | |||
2361 | error = do_lock_file_wait(filp, cmd, file_lock); | 2395 | error = do_lock_file_wait(filp, cmd, file_lock); |
2362 | 2396 | ||
2363 | /* | 2397 | /* |
2364 | * Attempt to detect a close/fcntl race and recover by | 2398 | * Attempt to detect a close/fcntl race and recover by releasing the |
2365 | * releasing the lock that was just acquired. | 2399 | * lock that was just acquired. There is no need to do that when we're |
2400 | * unlocking though, or for OFD locks. | ||
2366 | */ | 2401 | */ |
2367 | spin_lock(¤t->files->file_lock); | 2402 | if (!error && file_lock->fl_type != F_UNLCK && |
2368 | f = fcheck(fd); | 2403 | !(file_lock->fl_flags & FL_OFDLCK)) { |
2369 | spin_unlock(¤t->files->file_lock); | 2404 | /* |
2370 | if (!error && f != filp && flock.l_type != F_UNLCK) { | 2405 | * We need that spin_lock here - it prevents reordering between |
2371 | flock.l_type = F_UNLCK; | 2406 | * update of i_flctx->flc_posix and check for it done in |
2372 | goto again; | 2407 | * close(). rcu_read_lock() wouldn't do. |
2408 | */ | ||
2409 | spin_lock(¤t->files->file_lock); | ||
2410 | f = fcheck(fd); | ||
2411 | spin_unlock(¤t->files->file_lock); | ||
2412 | if (f != filp) { | ||
2413 | file_lock->fl_type = F_UNLCK; | ||
2414 | error = do_lock_file_wait(filp, cmd, file_lock); | ||
2415 | WARN_ON_ONCE(error); | ||
2416 | error = -EBADF; | ||
2417 | } | ||
2373 | } | 2418 | } |
2374 | |||
2375 | out: | 2419 | out: |
2376 | locks_free_lock(file_lock); | 2420 | locks_free_lock(file_lock); |
2377 | return error; | 2421 | return error; |
@@ -2385,6 +2429,7 @@ out: | |||
2385 | */ | 2429 | */ |
2386 | void locks_remove_posix(struct file *filp, fl_owner_t owner) | 2430 | void locks_remove_posix(struct file *filp, fl_owner_t owner) |
2387 | { | 2431 | { |
2432 | int error; | ||
2388 | struct file_lock lock; | 2433 | struct file_lock lock; |
2389 | struct file_lock_context *ctx; | 2434 | struct file_lock_context *ctx; |
2390 | 2435 | ||
@@ -2407,10 +2452,11 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner) | |||
2407 | lock.fl_ops = NULL; | 2452 | lock.fl_ops = NULL; |
2408 | lock.fl_lmops = NULL; | 2453 | lock.fl_lmops = NULL; |
2409 | 2454 | ||
2410 | vfs_lock_file(filp, F_SETLK, &lock, NULL); | 2455 | error = vfs_lock_file(filp, F_SETLK, &lock, NULL); |
2411 | 2456 | ||
2412 | if (lock.fl_ops && lock.fl_ops->fl_release_private) | 2457 | if (lock.fl_ops && lock.fl_ops->fl_release_private) |
2413 | lock.fl_ops->fl_release_private(&lock); | 2458 | lock.fl_ops->fl_release_private(&lock); |
2459 | trace_locks_remove_posix(file_inode(filp), &lock, error); | ||
2414 | } | 2460 | } |
2415 | 2461 | ||
2416 | EXPORT_SYMBOL(locks_remove_posix); | 2462 | EXPORT_SYMBOL(locks_remove_posix); |
@@ -2706,7 +2752,7 @@ static int __init proc_locks_init(void) | |||
2706 | proc_create("locks", 0, NULL, &proc_locks_operations); | 2752 | proc_create("locks", 0, NULL, &proc_locks_operations); |
2707 | return 0; | 2753 | return 0; |
2708 | } | 2754 | } |
2709 | module_init(proc_locks_init); | 2755 | fs_initcall(proc_locks_init); |
2710 | #endif | 2756 | #endif |
2711 | 2757 | ||
2712 | static int __init filelock_init(void) | 2758 | static int __init filelock_init(void) |
diff --git a/fs/namespace.c b/fs/namespace.c index 0570729c87fd..4d2c8f64b7bf 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1584,6 +1584,14 @@ static inline bool may_mount(void) | |||
1584 | return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN); | 1584 | return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN); |
1585 | } | 1585 | } |
1586 | 1586 | ||
1587 | static inline bool may_mandlock(void) | ||
1588 | { | ||
1589 | #ifndef CONFIG_MANDATORY_FILE_LOCKING | ||
1590 | return false; | ||
1591 | #endif | ||
1592 | return capable(CAP_SYS_ADMIN); | ||
1593 | } | ||
1594 | |||
1587 | /* | 1595 | /* |
1588 | * Now umount can handle mount points as well as block devices. | 1596 | * Now umount can handle mount points as well as block devices. |
1589 | * This is important for filesystems which use unnamed block devices. | 1597 | * This is important for filesystems which use unnamed block devices. |
@@ -2677,6 +2685,8 @@ long do_mount(const char *dev_name, const char __user *dir_name, | |||
2677 | type_page, flags, data_page); | 2685 | type_page, flags, data_page); |
2678 | if (!retval && !may_mount()) | 2686 | if (!retval && !may_mount()) |
2679 | retval = -EPERM; | 2687 | retval = -EPERM; |
2688 | if (!retval && (flags & MS_MANDLOCK) && !may_mandlock()) | ||
2689 | retval = -EPERM; | ||
2680 | if (retval) | 2690 | if (retval) |
2681 | goto dput_out; | 2691 | goto dput_out; |
2682 | 2692 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index ef3cd36689f6..566f8e078ffc 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1043,7 +1043,7 @@ extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg); | |||
1043 | extern int fcntl_getlease(struct file *filp); | 1043 | extern int fcntl_getlease(struct file *filp); |
1044 | 1044 | ||
1045 | /* fs/locks.c */ | 1045 | /* fs/locks.c */ |
1046 | void locks_free_lock_context(struct file_lock_context *ctx); | 1046 | void locks_free_lock_context(struct inode *inode); |
1047 | void locks_free_lock(struct file_lock *fl); | 1047 | void locks_free_lock(struct file_lock *fl); |
1048 | extern void locks_init_lock(struct file_lock *); | 1048 | extern void locks_init_lock(struct file_lock *); |
1049 | extern struct file_lock * locks_alloc_lock(void); | 1049 | extern struct file_lock * locks_alloc_lock(void); |
@@ -1104,7 +1104,7 @@ static inline int fcntl_getlease(struct file *filp) | |||
1104 | } | 1104 | } |
1105 | 1105 | ||
1106 | static inline void | 1106 | static inline void |
1107 | locks_free_lock_context(struct file_lock_context *ctx) | 1107 | locks_free_lock_context(struct inode *inode) |
1108 | { | 1108 | { |
1109 | } | 1109 | } |
1110 | 1110 | ||
@@ -2030,7 +2030,7 @@ extern struct kobject *fs_kobj; | |||
2030 | #define FLOCK_VERIFY_READ 1 | 2030 | #define FLOCK_VERIFY_READ 1 |
2031 | #define FLOCK_VERIFY_WRITE 2 | 2031 | #define FLOCK_VERIFY_WRITE 2 |
2032 | 2032 | ||
2033 | #ifdef CONFIG_FILE_LOCKING | 2033 | #ifdef CONFIG_MANDATORY_FILE_LOCKING |
2034 | extern int locks_mandatory_locked(struct file *); | 2034 | extern int locks_mandatory_locked(struct file *); |
2035 | extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size_t); | 2035 | extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size_t); |
2036 | 2036 | ||
@@ -2075,6 +2075,45 @@ static inline int locks_verify_truncate(struct inode *inode, | |||
2075 | return 0; | 2075 | return 0; |
2076 | } | 2076 | } |
2077 | 2077 | ||
2078 | #else /* !CONFIG_MANDATORY_FILE_LOCKING */ | ||
2079 | |||
2080 | static inline int locks_mandatory_locked(struct file *file) | ||
2081 | { | ||
2082 | return 0; | ||
2083 | } | ||
2084 | |||
2085 | static inline int locks_mandatory_area(int rw, struct inode *inode, | ||
2086 | struct file *filp, loff_t offset, | ||
2087 | size_t count) | ||
2088 | { | ||
2089 | return 0; | ||
2090 | } | ||
2091 | |||
2092 | static inline int __mandatory_lock(struct inode *inode) | ||
2093 | { | ||
2094 | return 0; | ||
2095 | } | ||
2096 | |||
2097 | static inline int mandatory_lock(struct inode *inode) | ||
2098 | { | ||
2099 | return 0; | ||
2100 | } | ||
2101 | |||
2102 | static inline int locks_verify_locked(struct file *file) | ||
2103 | { | ||
2104 | return 0; | ||
2105 | } | ||
2106 | |||
2107 | static inline int locks_verify_truncate(struct inode *inode, struct file *filp, | ||
2108 | size_t size) | ||
2109 | { | ||
2110 | return 0; | ||
2111 | } | ||
2112 | |||
2113 | #endif /* CONFIG_MANDATORY_FILE_LOCKING */ | ||
2114 | |||
2115 | |||
2116 | #ifdef CONFIG_FILE_LOCKING | ||
2078 | static inline int break_lease(struct inode *inode, unsigned int mode) | 2117 | static inline int break_lease(struct inode *inode, unsigned int mode) |
2079 | { | 2118 | { |
2080 | /* | 2119 | /* |
@@ -2136,39 +2175,6 @@ static inline int break_layout(struct inode *inode, bool wait) | |||
2136 | } | 2175 | } |
2137 | 2176 | ||
2138 | #else /* !CONFIG_FILE_LOCKING */ | 2177 | #else /* !CONFIG_FILE_LOCKING */ |
2139 | static inline int locks_mandatory_locked(struct file *file) | ||
2140 | { | ||
2141 | return 0; | ||
2142 | } | ||
2143 | |||
2144 | static inline int locks_mandatory_area(int rw, struct inode *inode, | ||
2145 | struct file *filp, loff_t offset, | ||
2146 | size_t count) | ||
2147 | { | ||
2148 | return 0; | ||
2149 | } | ||
2150 | |||
2151 | static inline int __mandatory_lock(struct inode *inode) | ||
2152 | { | ||
2153 | return 0; | ||
2154 | } | ||
2155 | |||
2156 | static inline int mandatory_lock(struct inode *inode) | ||
2157 | { | ||
2158 | return 0; | ||
2159 | } | ||
2160 | |||
2161 | static inline int locks_verify_locked(struct file *file) | ||
2162 | { | ||
2163 | return 0; | ||
2164 | } | ||
2165 | |||
2166 | static inline int locks_verify_truncate(struct inode *inode, struct file *filp, | ||
2167 | size_t size) | ||
2168 | { | ||
2169 | return 0; | ||
2170 | } | ||
2171 | |||
2172 | static inline int break_lease(struct inode *inode, unsigned int mode) | 2178 | static inline int break_lease(struct inode *inode, unsigned int mode) |
2173 | { | 2179 | { |
2174 | return 0; | 2180 | return 0; |
diff --git a/include/trace/events/filelock.h b/include/trace/events/filelock.h index c72f2dc01d0b..63a7680347cb 100644 --- a/include/trace/events/filelock.h +++ b/include/trace/events/filelock.h | |||
@@ -34,6 +34,83 @@ | |||
34 | { F_WRLCK, "F_WRLCK" }, \ | 34 | { F_WRLCK, "F_WRLCK" }, \ |
35 | { F_UNLCK, "F_UNLCK" }) | 35 | { F_UNLCK, "F_UNLCK" }) |
36 | 36 | ||
37 | TRACE_EVENT(locks_get_lock_context, | ||
38 | TP_PROTO(struct inode *inode, int type, struct file_lock_context *ctx), | ||
39 | |||
40 | TP_ARGS(inode, type, ctx), | ||
41 | |||
42 | TP_STRUCT__entry( | ||
43 | __field(unsigned long, i_ino) | ||
44 | __field(dev_t, s_dev) | ||
45 | __field(unsigned char, type) | ||
46 | __field(struct file_lock_context *, ctx) | ||
47 | ), | ||
48 | |||
49 | TP_fast_assign( | ||
50 | __entry->s_dev = inode->i_sb->s_dev; | ||
51 | __entry->i_ino = inode->i_ino; | ||
52 | __entry->type = type; | ||
53 | __entry->ctx = ctx; | ||
54 | ), | ||
55 | |||
56 | TP_printk("dev=0x%x:0x%x ino=0x%lx type=%s ctx=%p", | ||
57 | MAJOR(__entry->s_dev), MINOR(__entry->s_dev), | ||
58 | __entry->i_ino, show_fl_type(__entry->type), __entry->ctx) | ||
59 | ); | ||
60 | |||
61 | DECLARE_EVENT_CLASS(filelock_lock, | ||
62 | TP_PROTO(struct inode *inode, struct file_lock *fl, int ret), | ||
63 | |||
64 | TP_ARGS(inode, fl, ret), | ||
65 | |||
66 | TP_STRUCT__entry( | ||
67 | __field(struct file_lock *, fl) | ||
68 | __field(unsigned long, i_ino) | ||
69 | __field(dev_t, s_dev) | ||
70 | __field(struct file_lock *, fl_next) | ||
71 | __field(fl_owner_t, fl_owner) | ||
72 | __field(unsigned int, fl_pid) | ||
73 | __field(unsigned int, fl_flags) | ||
74 | __field(unsigned char, fl_type) | ||
75 | __field(loff_t, fl_start) | ||
76 | __field(loff_t, fl_end) | ||
77 | __field(int, ret) | ||
78 | ), | ||
79 | |||
80 | TP_fast_assign( | ||
81 | __entry->fl = fl ? fl : NULL; | ||
82 | __entry->s_dev = inode->i_sb->s_dev; | ||
83 | __entry->i_ino = inode->i_ino; | ||
84 | __entry->fl_next = fl ? fl->fl_next : NULL; | ||
85 | __entry->fl_owner = fl ? fl->fl_owner : NULL; | ||
86 | __entry->fl_pid = fl ? fl->fl_pid : 0; | ||
87 | __entry->fl_flags = fl ? fl->fl_flags : 0; | ||
88 | __entry->fl_type = fl ? fl->fl_type : 0; | ||
89 | __entry->fl_start = fl ? fl->fl_start : 0; | ||
90 | __entry->fl_end = fl ? fl->fl_end : 0; | ||
91 | __entry->ret = ret; | ||
92 | ), | ||
93 | |||
94 | 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", | ||
95 | __entry->fl, MAJOR(__entry->s_dev), MINOR(__entry->s_dev), | ||
96 | __entry->i_ino, __entry->fl_next, __entry->fl_owner, | ||
97 | __entry->fl_pid, show_fl_flags(__entry->fl_flags), | ||
98 | show_fl_type(__entry->fl_type), | ||
99 | __entry->fl_start, __entry->fl_end, __entry->ret) | ||
100 | ); | ||
101 | |||
102 | DEFINE_EVENT(filelock_lock, posix_lock_inode, | ||
103 | TP_PROTO(struct inode *inode, struct file_lock *fl, int ret), | ||
104 | TP_ARGS(inode, fl, ret)); | ||
105 | |||
106 | DEFINE_EVENT(filelock_lock, fcntl_setlk, | ||
107 | TP_PROTO(struct inode *inode, struct file_lock *fl, int ret), | ||
108 | TP_ARGS(inode, fl, ret)); | ||
109 | |||
110 | DEFINE_EVENT(filelock_lock, locks_remove_posix, | ||
111 | TP_PROTO(struct inode *inode, struct file_lock *fl, int ret), | ||
112 | TP_ARGS(inode, fl, ret)); | ||
113 | |||
37 | DECLARE_EVENT_CLASS(filelock_lease, | 114 | DECLARE_EVENT_CLASS(filelock_lease, |
38 | 115 | ||
39 | TP_PROTO(struct inode *inode, struct file_lock *fl), | 116 | TP_PROTO(struct inode *inode, struct file_lock *fl), |