^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* -*- mode: c; c-basic-offset: 8; -*-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * vim: noexpandtab sw=8 ts=8 sts=0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * locks.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Userspace file locking support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2007 Oracle. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <cluster/masklog.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "ocfs2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "dlmglue.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "file.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "locks.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static int ocfs2_do_flock(struct file *file, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) int cmd, struct file_lock *fl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int ret = 0, level = 0, trylock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct ocfs2_file_private *fp = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct ocfs2_lock_res *lockres = &fp->fp_flock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) if (fl->fl_type == F_WRLCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) level = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (!IS_SETLKW(cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) trylock = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) mutex_lock(&fp->fp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (lockres->l_flags & OCFS2_LOCK_ATTACHED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) lockres->l_level > LKM_NLMODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int old_level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct file_lock request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (lockres->l_level == LKM_EXMODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) old_level = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (level == old_level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * Converting an existing lock is not guaranteed to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * atomic, so we can get away with simply unlocking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * here and allowing the lock code to try at the new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) locks_init_lock(&request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) request.fl_type = F_UNLCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) request.fl_flags = FL_FLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) locks_lock_file_wait(file, &request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) ocfs2_file_unlock(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ret = ocfs2_file_lock(file, level, trylock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (ret == -EAGAIN && trylock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) ret = -EWOULDBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) mlog_errno(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ret = locks_lock_file_wait(file, fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ocfs2_file_unlock(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) mutex_unlock(&fp->fp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static int ocfs2_do_funlock(struct file *file, int cmd, struct file_lock *fl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct ocfs2_file_private *fp = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) mutex_lock(&fp->fp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ocfs2_file_unlock(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ret = locks_lock_file_wait(file, fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) mutex_unlock(&fp->fp_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * Overall flow of ocfs2_flock() was influenced by gfs2_flock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) int ocfs2_flock(struct file *file, int cmd, struct file_lock *fl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct inode *inode = file->f_mapping->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (!(fl->fl_flags & FL_FLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return -ENOLCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (__mandatory_lock(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return -ENOLCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if ((osb->s_mount_opt & OCFS2_MOUNT_LOCALFLOCKS) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ocfs2_mount_local(osb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return locks_lock_file_wait(file, fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (fl->fl_type == F_UNLCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return ocfs2_do_funlock(file, cmd, fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return ocfs2_do_flock(file, inode, cmd, fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int ocfs2_lock(struct file *file, int cmd, struct file_lock *fl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct inode *inode = file->f_mapping->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (!(fl->fl_flags & FL_POSIX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return -ENOLCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return -ENOLCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return ocfs2_plock(osb->cconn, OCFS2_I(inode)->ip_blkno, file, cmd, fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }