| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* -*- mode: c; c-basic-offset: 8; -*- |
|---|
| 2 | 3 | * vim: noexpandtab sw=8 ts=8 sts=0: |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 10 | 11 | * functions. |
|---|
| 11 | 12 | * |
|---|
| 12 | 13 | * Copyright (C) 2003, 2004 Oracle. All rights reserved. |
|---|
| 13 | | - * |
|---|
| 14 | | - * This program is free software; you can redistribute it and/or |
|---|
| 15 | | - * modify it under the terms of the GNU General Public |
|---|
| 16 | | - * License as published by the Free Software Foundation; either |
|---|
| 17 | | - * version 2 of the License, or (at your option) any later version. |
|---|
| 18 | | - * |
|---|
| 19 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 20 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 21 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 22 | | - * General Public License for more details. |
|---|
| 23 | | - * |
|---|
| 24 | | - * You should have received a copy of the GNU General Public |
|---|
| 25 | | - * License along with this program; if not, write to the |
|---|
| 26 | | - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
|---|
| 27 | | - * Boston, MA 021110-1307, USA. |
|---|
| 28 | 14 | */ |
|---|
| 29 | 15 | |
|---|
| 30 | 16 | #include <linux/signal.h> |
|---|
| .. | .. |
|---|
| 35 | 21 | #include <linux/types.h> |
|---|
| 36 | 22 | #include <linux/crc32.h> |
|---|
| 37 | 23 | |
|---|
| 38 | | -#include "ocfs2_lockingver.h" |
|---|
| 39 | | -#include "stackglue.h" |
|---|
| 24 | +#include "../ocfs2_lockingver.h" |
|---|
| 25 | +#include "../stackglue.h" |
|---|
| 40 | 26 | #include "userdlm.h" |
|---|
| 41 | 27 | |
|---|
| 42 | 28 | #define MLOG_MASK_PREFIX ML_DLMFS |
|---|
| 43 | | -#include "cluster/masklog.h" |
|---|
| 29 | +#include "../cluster/masklog.h" |
|---|
| 44 | 30 | |
|---|
| 45 | 31 | |
|---|
| 46 | 32 | static inline struct user_lock_res *user_lksb_to_lock_res(struct ocfs2_dlm_lksb *lksb) |
|---|
| .. | .. |
|---|
| 449 | 435 | } |
|---|
| 450 | 436 | |
|---|
| 451 | 437 | spin_lock(&lockres->l_lock); |
|---|
| 438 | + if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) { |
|---|
| 439 | + spin_unlock(&lockres->l_lock); |
|---|
| 440 | + status = -EAGAIN; |
|---|
| 441 | + goto bail; |
|---|
| 442 | + } |
|---|
| 452 | 443 | |
|---|
| 453 | 444 | /* We only compare against the currently granted level |
|---|
| 454 | 445 | * here. If the lock is blocked waiting on a downconvert, |
|---|
| .. | .. |
|---|
| 561 | 552 | spin_unlock(&lockres->l_lock); |
|---|
| 562 | 553 | } |
|---|
| 563 | 554 | |
|---|
| 564 | | -ssize_t user_dlm_read_lvb(struct inode *inode, |
|---|
| 565 | | - char *val, |
|---|
| 566 | | - unsigned int len) |
|---|
| 555 | +bool user_dlm_read_lvb(struct inode *inode, char *val) |
|---|
| 567 | 556 | { |
|---|
| 568 | 557 | struct user_lock_res *lockres = &DLMFS_I(inode)->ip_lockres; |
|---|
| 569 | 558 | char *lvb; |
|---|
| 570 | | - ssize_t ret = len; |
|---|
| 571 | | - |
|---|
| 572 | | - BUG_ON(len > DLM_LVB_LEN); |
|---|
| 559 | + bool ret = true; |
|---|
| 573 | 560 | |
|---|
| 574 | 561 | spin_lock(&lockres->l_lock); |
|---|
| 575 | 562 | |
|---|
| 576 | 563 | BUG_ON(lockres->l_level < DLM_LOCK_PR); |
|---|
| 577 | 564 | if (ocfs2_dlm_lvb_valid(&lockres->l_lksb)) { |
|---|
| 578 | 565 | lvb = ocfs2_dlm_lvb(&lockres->l_lksb); |
|---|
| 579 | | - memcpy(val, lvb, len); |
|---|
| 566 | + memcpy(val, lvb, DLM_LVB_LEN); |
|---|
| 580 | 567 | } else |
|---|
| 581 | | - ret = 0; |
|---|
| 568 | + ret = false; |
|---|
| 582 | 569 | |
|---|
| 583 | 570 | spin_unlock(&lockres->l_lock); |
|---|
| 584 | 571 | return ret; |
|---|
| .. | .. |
|---|
| 615 | 602 | spin_lock(&lockres->l_lock); |
|---|
| 616 | 603 | if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) { |
|---|
| 617 | 604 | spin_unlock(&lockres->l_lock); |
|---|
| 618 | | - return 0; |
|---|
| 605 | + goto bail; |
|---|
| 619 | 606 | } |
|---|
| 620 | 607 | |
|---|
| 621 | 608 | lockres->l_flags |= USER_LOCK_IN_TEARDOWN; |
|---|
| .. | .. |
|---|
| 629 | 616 | } |
|---|
| 630 | 617 | |
|---|
| 631 | 618 | if (lockres->l_ro_holders || lockres->l_ex_holders) { |
|---|
| 619 | + lockres->l_flags &= ~USER_LOCK_IN_TEARDOWN; |
|---|
| 632 | 620 | spin_unlock(&lockres->l_lock); |
|---|
| 633 | 621 | goto bail; |
|---|
| 634 | 622 | } |
|---|
| 635 | 623 | |
|---|
| 636 | 624 | status = 0; |
|---|
| 637 | 625 | if (!(lockres->l_flags & USER_LOCK_ATTACHED)) { |
|---|
| 626 | + /* |
|---|
| 627 | + * lock is never requested, leave USER_LOCK_IN_TEARDOWN set |
|---|
| 628 | + * to avoid new lock request coming in. |
|---|
| 629 | + */ |
|---|
| 638 | 630 | spin_unlock(&lockres->l_lock); |
|---|
| 639 | 631 | goto bail; |
|---|
| 640 | 632 | } |
|---|
| .. | .. |
|---|
| 645 | 637 | |
|---|
| 646 | 638 | status = ocfs2_dlm_unlock(conn, &lockres->l_lksb, DLM_LKF_VALBLK); |
|---|
| 647 | 639 | if (status) { |
|---|
| 640 | + spin_lock(&lockres->l_lock); |
|---|
| 641 | + lockres->l_flags &= ~USER_LOCK_IN_TEARDOWN; |
|---|
| 642 | + lockres->l_flags &= ~USER_LOCK_BUSY; |
|---|
| 643 | + spin_unlock(&lockres->l_lock); |
|---|
| 648 | 644 | user_log_dlm_error("ocfs2_dlm_unlock", status, lockres); |
|---|
| 649 | 645 | goto bail; |
|---|
| 650 | 646 | } |
|---|