1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved. 4 */ 5 6 #include <linux/fs.h> 7 #include <linux/capability.h> 8 #include <linux/filelock.h> 9 #include <linux/miscdevice.h> 10 #include <linux/poll.h> 11 #include <linux/dlm.h> 12 #include <linux/dlm_plock.h> 13 #include <linux/slab.h> 14 15 #include <trace/events/dlm.h> 16 17 #include "dlm_internal.h" 18 #include "lockspace.h" 19 20 static DEFINE_SPINLOCK(ops_lock); 21 static LIST_HEAD(send_list); 22 static LIST_HEAD(recv_list); 23 static DECLARE_WAIT_QUEUE_HEAD(send_wq); 24 static DECLARE_WAIT_QUEUE_HEAD(recv_wq); 25 26 struct plock_async_data { 27 void *fl; 28 void *file; 29 struct file_lock flc; 30 int (*callback)(struct file_lock *fl, int result); 31 }; 32 33 struct plock_op { 34 struct list_head list; 35 int done; 36 struct dlm_plock_info info; 37 /* if set indicates async handling */ 38 struct plock_async_data *data; 39 }; 40 41 static inline void set_version(struct dlm_plock_info *info) 42 { 43 info->version[0] = DLM_PLOCK_VERSION_MAJOR; 44 info->version[1] = DLM_PLOCK_VERSION_MINOR; 45 info->version[2] = DLM_PLOCK_VERSION_PATCH; 46 } 47 48 static struct plock_op *plock_lookup_waiter(const struct dlm_plock_info *info) 49 { 50 struct plock_op *op = NULL, *iter; 51 52 list_for_each_entry(iter, &recv_list, list) { 53 if (iter->info.fsid == info->fsid && 54 iter->info.number == info->number && 55 iter->info.owner == info->owner && 56 iter->info.pid == info->pid && 57 iter->info.start == info->start && 58 iter->info.end == info->end && 59 iter->info.ex == info->ex && 60 iter->info.wait) { 61 op = iter; 62 break; 63 } 64 } 65 66 return op; 67 } 68 69 static int check_version(struct dlm_plock_info *info) 70 { 71 if ((DLM_PLOCK_VERSION_MAJOR != info->version[0]) || 72 (DLM_PLOCK_VERSION_MINOR < info->version[1])) { 73 log_print("plock device version mismatch: " 74 "kernel (%u.%u.%u), user (%u.%u.%u)", 75 DLM_PLOCK_VERSION_MAJOR, 76 DLM_PLOCK_VERSION_MINOR, 77 DLM_PLOCK_VERSION_PATCH, 78 info->version[0], 79 info->version[1], 80 info->version[2]); 81 return -EINVAL; 82 } 83 return 0; 84 } 85 86 static void dlm_release_plock_op(struct plock_op *op) 87 { 88 kfree(op->data); 89 kfree(op); 90 } 91 92 static void send_op(struct plock_op *op) 93 { 94 set_version(&op->info); 95 spin_lock(&ops_lock); 96 list_add_tail(&op->list, &send_list); 97 spin_unlock(&ops_lock); 98 wake_up(&send_wq); 99 } 100 101 static int do_lock_cancel(const struct dlm_plock_info *orig_info) 102 { 103 struct plock_op *op; 104 int rv; 105 106 op = kzalloc_obj(*op, GFP_NOFS); 107 if (!op) 108 return -ENOMEM; 109 110 op->info = *orig_info; 111 op->info.optype = DLM_PLOCK_OP_CANCEL; 112 op->info.wait = 0; 113 114 send_op(op); 115 wait_event(recv_wq, (op->done != 0)); 116 117 rv = op->info.rv; 118 119 dlm_release_plock_op(op); 120 return rv; 121 } 122 123 int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, 124 int cmd, struct file_lock *fl) 125 { 126 struct plock_async_data *op_data; 127 struct dlm_ls *ls; 128 struct plock_op *op; 129 int rv; 130 131 ls = dlm_find_lockspace_local(lockspace); 132 if (!ls) 133 return -EINVAL; 134 135 op = kzalloc_obj(*op, GFP_NOFS); 136 if (!op) { 137 rv = -ENOMEM; 138 goto out; 139 } 140 141 op->info.optype = DLM_PLOCK_OP_LOCK; 142 op->info.pid = fl->c.flc_pid; 143 op->info.ex = lock_is_write(fl); 144 op->info.wait = !!(fl->c.flc_flags & FL_SLEEP); 145 op->info.fsid = ls->ls_global_id; 146 op->info.number = number; 147 op->info.start = fl->fl_start; 148 op->info.end = fl->fl_end; 149 op->info.owner = (__u64)(long) fl->c.flc_owner; 150 /* async handling */ 151 if (fl->fl_lmops && fl->fl_lmops->lm_grant) { 152 op_data = kzalloc_obj(*op_data, GFP_NOFS); 153 if (!op_data) { 154 dlm_release_plock_op(op); 155 rv = -ENOMEM; 156 goto out; 157 } 158 159 op_data->callback = fl->fl_lmops->lm_grant; 160 locks_init_lock(&op_data->flc); 161 locks_copy_lock(&op_data->flc, fl); 162 op_data->fl = fl; 163 op_data->file = file; 164 165 op->data = op_data; 166 167 send_op(op); 168 rv = FILE_LOCK_DEFERRED; 169 goto out; 170 } 171 172 send_op(op); 173 174 if (op->info.wait) { 175 rv = wait_event_interruptible(recv_wq, (op->done != 0)); 176 if (rv == -ERESTARTSYS) { 177 spin_lock(&ops_lock); 178 /* recheck under ops_lock if we got a done != 0, 179 * if so this interrupt case should be ignored 180 */ 181 if (op->done != 0) { 182 spin_unlock(&ops_lock); 183 goto do_lock_wait; 184 } 185 spin_unlock(&ops_lock); 186 187 rv = do_lock_cancel(&op->info); 188 switch (rv) { 189 case 0: 190 /* waiter was deleted in user space, answer will never come 191 * remove original request. The original request must be 192 * on recv_list because the answer of do_lock_cancel() 193 * synchronized it. 194 */ 195 spin_lock(&ops_lock); 196 list_del(&op->list); 197 spin_unlock(&ops_lock); 198 rv = -EINTR; 199 break; 200 case -ENOENT: 201 /* cancellation wasn't successful but op should be done */ 202 fallthrough; 203 default: 204 /* internal error doing cancel we need to wait */ 205 goto wait; 206 } 207 208 log_debug(ls, "%s: wait interrupted %x %llx pid %d", 209 __func__, ls->ls_global_id, 210 (unsigned long long)number, op->info.pid); 211 dlm_release_plock_op(op); 212 goto out; 213 } 214 } else { 215 wait: 216 wait_event(recv_wq, (op->done != 0)); 217 } 218 219 do_lock_wait: 220 221 WARN_ON(!list_empty(&op->list)); 222 223 rv = op->info.rv; 224 225 if (!rv) { 226 if (locks_lock_file_wait(file, fl) < 0) 227 log_error(ls, "dlm_posix_lock: vfs lock error %llx", 228 (unsigned long long)number); 229 } 230 231 dlm_release_plock_op(op); 232 out: 233 dlm_put_lockspace(ls); 234 return rv; 235 } 236 EXPORT_SYMBOL_GPL(dlm_posix_lock); 237 238 /* Returns failure iff a successful lock operation should be canceled */ 239 static int dlm_plock_callback(struct plock_op *op) 240 { 241 struct plock_async_data *op_data = op->data; 242 struct file *file; 243 struct file_lock *fl; 244 struct file_lock *flc; 245 int (*notify)(struct file_lock *fl, int result) = NULL; 246 int rv = 0; 247 248 WARN_ON(!list_empty(&op->list)); 249 250 /* check if the following 2 are still valid or make a copy */ 251 file = op_data->file; 252 flc = &op_data->flc; 253 fl = op_data->fl; 254 notify = op_data->callback; 255 256 if (op->info.rv) { 257 notify(fl, op->info.rv); 258 goto out; 259 } 260 261 /* got fs lock; bookkeep locally as well: */ 262 flc->c.flc_flags &= ~FL_SLEEP; 263 if (posix_lock_file(file, flc, NULL)) { 264 /* 265 * This can only happen in the case of kmalloc() failure. 266 * The filesystem's own lock is the authoritative lock, 267 * so a failure to get the lock locally is not a disaster. 268 * As long as the fs cannot reliably cancel locks (especially 269 * in a low-memory situation), we're better off ignoring 270 * this failure than trying to recover. 271 */ 272 log_print("dlm_plock_callback: vfs lock error %llx file %p fl %p", 273 (unsigned long long)op->info.number, file, fl); 274 } 275 276 rv = notify(fl, 0); 277 if (rv) { 278 /* XXX: We need to cancel the fs lock here: */ 279 log_print("%s: lock granted after lock request failed; dangling lock!", 280 __func__); 281 goto out; 282 } 283 284 out: 285 dlm_release_plock_op(op); 286 return rv; 287 } 288 289 int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file, 290 struct file_lock *fl) 291 { 292 struct dlm_ls *ls; 293 struct plock_op *op; 294 int rv; 295 unsigned char saved_flags = fl->c.flc_flags; 296 297 ls = dlm_find_lockspace_local(lockspace); 298 if (!ls) 299 return -EINVAL; 300 301 op = kzalloc_obj(*op, GFP_NOFS); 302 if (!op) { 303 rv = -ENOMEM; 304 goto out; 305 } 306 307 /* cause the vfs unlock to return ENOENT if lock is not found */ 308 fl->c.flc_flags |= FL_EXISTS; 309 310 rv = locks_lock_file_wait(file, fl); 311 if (rv == -ENOENT) { 312 rv = 0; 313 goto out_free; 314 } 315 if (rv < 0) { 316 log_error(ls, "dlm_posix_unlock: vfs unlock error %d %llx", 317 rv, (unsigned long long)number); 318 } 319 320 op->info.optype = DLM_PLOCK_OP_UNLOCK; 321 op->info.pid = fl->c.flc_pid; 322 op->info.fsid = ls->ls_global_id; 323 op->info.number = number; 324 op->info.start = fl->fl_start; 325 op->info.end = fl->fl_end; 326 op->info.owner = (__u64)(long) fl->c.flc_owner; 327 328 if (fl->c.flc_flags & FL_CLOSE) { 329 op->info.flags |= DLM_PLOCK_FL_CLOSE; 330 send_op(op); 331 rv = 0; 332 goto out; 333 } 334 335 send_op(op); 336 wait_event(recv_wq, (op->done != 0)); 337 338 WARN_ON(!list_empty(&op->list)); 339 340 rv = op->info.rv; 341 342 if (rv == -ENOENT) 343 rv = 0; 344 345 out_free: 346 dlm_release_plock_op(op); 347 out: 348 dlm_put_lockspace(ls); 349 fl->c.flc_flags = saved_flags; 350 return rv; 351 } 352 EXPORT_SYMBOL_GPL(dlm_posix_unlock); 353 354 /* 355 * NOTE: This implementation can only handle async lock requests as nfs 356 * do it. It cannot handle cancellation of a pending lock request sitting 357 * in wait_event(), but for now only nfs is the only user local kernel 358 * user. 359 */ 360 int dlm_posix_cancel(dlm_lockspace_t *lockspace, u64 number, struct file *file, 361 struct file_lock *fl) 362 { 363 struct dlm_plock_info info; 364 struct plock_op *op; 365 struct dlm_ls *ls; 366 int rv; 367 368 /* this only works for async request for now and nfs is the only 369 * kernel user right now. 370 */ 371 if (WARN_ON_ONCE(!fl->fl_lmops || !fl->fl_lmops->lm_grant)) 372 return -EOPNOTSUPP; 373 374 ls = dlm_find_lockspace_local(lockspace); 375 if (!ls) 376 return -EINVAL; 377 378 memset(&info, 0, sizeof(info)); 379 info.pid = fl->c.flc_pid; 380 info.ex = lock_is_write(fl); 381 info.fsid = ls->ls_global_id; 382 dlm_put_lockspace(ls); 383 info.number = number; 384 info.start = fl->fl_start; 385 info.end = fl->fl_end; 386 info.owner = (__u64)(long) fl->c.flc_owner; 387 388 rv = do_lock_cancel(&info); 389 switch (rv) { 390 case 0: 391 spin_lock(&ops_lock); 392 /* lock request to cancel must be on recv_list because 393 * do_lock_cancel() synchronizes it. 394 */ 395 op = plock_lookup_waiter(&info); 396 if (WARN_ON_ONCE(!op)) { 397 spin_unlock(&ops_lock); 398 rv = -ENOLCK; 399 break; 400 } 401 402 list_del(&op->list); 403 spin_unlock(&ops_lock); 404 WARN_ON(op->info.optype != DLM_PLOCK_OP_LOCK); 405 op->data->callback(op->data->fl, -EINTR); 406 dlm_release_plock_op(op); 407 rv = -EINTR; 408 break; 409 case -ENOENT: 410 /* if cancel wasn't successful we probably were to late 411 * or it was a non-blocking lock request, so just unlock it. 412 */ 413 rv = dlm_posix_unlock(lockspace, number, file, fl); 414 break; 415 default: 416 break; 417 } 418 419 return rv; 420 } 421 EXPORT_SYMBOL_GPL(dlm_posix_cancel); 422 423 int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file, 424 struct file_lock *fl) 425 { 426 struct dlm_ls *ls; 427 struct plock_op *op; 428 int rv; 429 430 ls = dlm_find_lockspace_local(lockspace); 431 if (!ls) 432 return -EINVAL; 433 434 op = kzalloc_obj(*op, GFP_NOFS); 435 if (!op) { 436 rv = -ENOMEM; 437 goto out; 438 } 439 440 op->info.optype = DLM_PLOCK_OP_GET; 441 op->info.pid = fl->c.flc_pid; 442 op->info.ex = lock_is_write(fl); 443 op->info.fsid = ls->ls_global_id; 444 op->info.number = number; 445 op->info.start = fl->fl_start; 446 op->info.end = fl->fl_end; 447 op->info.owner = (__u64)(long) fl->c.flc_owner; 448 449 send_op(op); 450 wait_event(recv_wq, (op->done != 0)); 451 452 WARN_ON(!list_empty(&op->list)); 453 454 /* info.rv from userspace is 1 for conflict, 0 for no-conflict, 455 -ENOENT if there are no locks on the file */ 456 457 rv = op->info.rv; 458 459 fl->c.flc_type = F_UNLCK; 460 if (rv == -ENOENT) 461 rv = 0; 462 else if (rv > 0) { 463 locks_init_lock(fl); 464 fl->c.flc_type = (op->info.ex) ? F_WRLCK : F_RDLCK; 465 fl->c.flc_flags = FL_POSIX; 466 fl->c.flc_pid = op->info.pid; 467 if (op->info.nodeid != dlm_our_nodeid()) 468 fl->c.flc_pid = -fl->c.flc_pid; 469 fl->fl_start = op->info.start; 470 fl->fl_end = op->info.end; 471 rv = 0; 472 } 473 474 dlm_release_plock_op(op); 475 out: 476 dlm_put_lockspace(ls); 477 return rv; 478 } 479 EXPORT_SYMBOL_GPL(dlm_posix_get); 480 481 static int dev_open(struct inode *inode, struct file *file) 482 { 483 /* Userspace plock daemon is a privileged cluster component. */ 484 if (!capable(CAP_SYS_ADMIN)) 485 return -EPERM; 486 487 return 0; 488 } 489 490 /* a read copies out one plock request from the send list */ 491 static ssize_t dev_read(struct file *file, char __user *u, size_t count, 492 loff_t *ppos) 493 { 494 struct dlm_plock_info info; 495 struct plock_op *op = NULL; 496 497 if (count < sizeof(info)) 498 return -EINVAL; 499 500 spin_lock(&ops_lock); 501 if (!list_empty(&send_list)) { 502 op = list_first_entry(&send_list, struct plock_op, list); 503 if (op->info.flags & DLM_PLOCK_FL_CLOSE) 504 list_del(&op->list); 505 else 506 list_move_tail(&op->list, &recv_list); 507 memcpy(&info, &op->info, sizeof(info)); 508 } 509 spin_unlock(&ops_lock); 510 511 if (!op) 512 return -EAGAIN; 513 514 trace_dlm_plock_read(&info); 515 516 /* there is no need to get a reply from userspace for unlocks 517 that were generated by the vfs cleaning up for a close 518 (the process did not make an unlock call). */ 519 520 if (op->info.flags & DLM_PLOCK_FL_CLOSE) 521 dlm_release_plock_op(op); 522 523 if (copy_to_user(u, &info, sizeof(info))) 524 return -EFAULT; 525 return sizeof(info); 526 } 527 528 /* a write copies in one plock result that should match a plock_op 529 on the recv list */ 530 static ssize_t dev_write(struct file *file, const char __user *u, size_t count, 531 loff_t *ppos) 532 { 533 struct plock_op *op = NULL, *iter; 534 struct dlm_plock_info info; 535 int do_callback = 0; 536 537 if (count != sizeof(info)) 538 return -EINVAL; 539 540 if (copy_from_user(&info, u, sizeof(info))) 541 return -EFAULT; 542 543 trace_dlm_plock_write(&info); 544 545 if (check_version(&info)) 546 return -EINVAL; 547 548 /* 549 * The results for waiting ops (SETLKW) can be returned in any 550 * order, so match all fields to find the op. The results for 551 * non-waiting ops are returned in the order that they were sent 552 * to userspace, so match the result with the first non-waiting op. 553 */ 554 spin_lock(&ops_lock); 555 if (info.wait) { 556 op = plock_lookup_waiter(&info); 557 } else { 558 list_for_each_entry(iter, &recv_list, list) { 559 if (!iter->info.wait && 560 iter->info.fsid == info.fsid) { 561 op = iter; 562 break; 563 } 564 } 565 } 566 567 if (op) { 568 /* Sanity check that op and info match. */ 569 if (info.wait) 570 WARN_ON(op->info.optype != DLM_PLOCK_OP_LOCK); 571 else 572 WARN_ON(op->info.number != info.number || 573 op->info.owner != info.owner || 574 op->info.optype != info.optype); 575 576 list_del_init(&op->list); 577 memcpy(&op->info, &info, sizeof(info)); 578 if (op->data) 579 do_callback = 1; 580 else 581 op->done = 1; 582 } 583 spin_unlock(&ops_lock); 584 585 if (op) { 586 if (do_callback) 587 dlm_plock_callback(op); 588 else 589 wake_up(&recv_wq); 590 } else 591 pr_debug("%s: no op %x %llx", __func__, 592 info.fsid, (unsigned long long)info.number); 593 return count; 594 } 595 596 static __poll_t dev_poll(struct file *file, poll_table *wait) 597 { 598 __poll_t mask = 0; 599 600 poll_wait(file, &send_wq, wait); 601 602 spin_lock(&ops_lock); 603 if (!list_empty(&send_list)) 604 mask = EPOLLIN | EPOLLRDNORM; 605 spin_unlock(&ops_lock); 606 607 return mask; 608 } 609 610 static const struct file_operations dev_fops = { 611 .open = dev_open, 612 .read = dev_read, 613 .write = dev_write, 614 .poll = dev_poll, 615 .owner = THIS_MODULE, 616 .llseek = noop_llseek, 617 }; 618 619 static struct miscdevice plock_dev_misc = { 620 .minor = MISC_DYNAMIC_MINOR, 621 .name = DLM_PLOCK_MISC_NAME, 622 .fops = &dev_fops, 623 .mode = 0600, 624 }; 625 626 int dlm_plock_init(void) 627 { 628 int rv; 629 630 rv = misc_register(&plock_dev_misc); 631 if (rv) 632 log_print("dlm_plock_init: misc_register failed %d", rv); 633 return rv; 634 } 635 636 void dlm_plock_exit(void) 637 { 638 misc_deregister(&plock_dev_misc); 639 WARN_ON(!list_empty(&send_list)); 640 WARN_ON(!list_empty(&recv_list)); 641 } 642 643