]>
git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - fs/ocfs2/locks.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Userspace file locking support
7 * Copyright (C) 2007 Oracle. All rights reserved.
11 #include <linux/fcntl.h>
13 #include <cluster/masklog.h>
22 static int ocfs2_do_flock(struct file
*file
, struct inode
*inode
,
23 int cmd
, struct file_lock
*fl
)
25 int ret
= 0, level
= 0, trylock
= 0;
26 struct ocfs2_file_private
*fp
= file
->private_data
;
27 struct ocfs2_lock_res
*lockres
= &fp
->fp_flock
;
29 if (fl
->fl_type
== F_WRLCK
)
34 mutex_lock(&fp
->fp_mutex
);
36 if (lockres
->l_flags
& OCFS2_LOCK_ATTACHED
&&
37 lockres
->l_level
> LKM_NLMODE
) {
39 struct file_lock request
;
41 if (lockres
->l_level
== LKM_EXMODE
)
44 if (level
== old_level
)
48 * Converting an existing lock is not guaranteed to be
49 * atomic, so we can get away with simply unlocking
50 * here and allowing the lock code to try at the new
54 locks_init_lock(&request
);
55 request
.fl_type
= F_UNLCK
;
56 request
.fl_flags
= FL_FLOCK
;
57 locks_lock_file_wait(file
, &request
);
59 ocfs2_file_unlock(file
);
62 ret
= ocfs2_file_lock(file
, level
, trylock
);
64 if (ret
== -EAGAIN
&& trylock
)
71 ret
= locks_lock_file_wait(file
, fl
);
73 ocfs2_file_unlock(file
);
76 mutex_unlock(&fp
->fp_mutex
);
81 static int ocfs2_do_funlock(struct file
*file
, int cmd
, struct file_lock
*fl
)
84 struct ocfs2_file_private
*fp
= file
->private_data
;
86 mutex_lock(&fp
->fp_mutex
);
87 ocfs2_file_unlock(file
);
88 ret
= locks_lock_file_wait(file
, fl
);
89 mutex_unlock(&fp
->fp_mutex
);
95 * Overall flow of ocfs2_flock() was influenced by gfs2_flock().
97 int ocfs2_flock(struct file
*file
, int cmd
, struct file_lock
*fl
)
99 struct inode
*inode
= file
->f_mapping
->host
;
100 struct ocfs2_super
*osb
= OCFS2_SB(inode
->i_sb
);
102 if (!(fl
->fl_flags
& FL_FLOCK
))
104 if (__mandatory_lock(inode
))
107 if ((osb
->s_mount_opt
& OCFS2_MOUNT_LOCALFLOCKS
) ||
108 ocfs2_mount_local(osb
))
109 return locks_lock_file_wait(file
, fl
);
111 if (fl
->fl_type
== F_UNLCK
)
112 return ocfs2_do_funlock(file
, cmd
, fl
);
114 return ocfs2_do_flock(file
, inode
, cmd
, fl
);
117 int ocfs2_lock(struct file
*file
, int cmd
, struct file_lock
*fl
)
119 struct inode
*inode
= file
->f_mapping
->host
;
120 struct ocfs2_super
*osb
= OCFS2_SB(inode
->i_sb
);
122 if (!(fl
->fl_flags
& FL_POSIX
))
124 if (__mandatory_lock(inode
) && fl
->fl_type
!= F_UNLCK
)
127 return ocfs2_plock(osb
->cconn
, OCFS2_I(inode
)->ip_blkno
, file
, cmd
, fl
);