locks.c (3a485c2be49dde899e506684bb5f06d5b3f73e82) locks.c (89aa593010135660991d05c92528c2c9163d5900)
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/ceph/ceph_debug.h>
3
4#include <linux/file.h>
5#include <linux/namei.h>
6#include <linux/random.h>
7
8#include "super.h"

--- 16 unchanged lines hidden (view full) ---

25 return v;
26}
27
28void __init ceph_flock_init(void)
29{
30 get_random_bytes(&lock_secret, sizeof(lock_secret));
31}
32
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/ceph/ceph_debug.h>
3
4#include <linux/file.h>
5#include <linux/namei.h>
6#include <linux/random.h>
7
8#include "super.h"

--- 16 unchanged lines hidden (view full) ---

25 return v;
26}
27
28void __init ceph_flock_init(void)
29{
30 get_random_bytes(&lock_secret, sizeof(lock_secret));
31}
32
33static void ceph_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
34{
35 struct inode *inode = file_inode(src->fl_file);
36 atomic_inc(&ceph_inode(inode)->i_filelock_ref);
37}
38
39static void ceph_fl_release_lock(struct file_lock *fl)
40{
41 struct inode *inode = file_inode(fl->fl_file);
42 atomic_dec(&ceph_inode(inode)->i_filelock_ref);
43}
44
45static const struct file_lock_operations ceph_fl_lock_ops = {
46 .fl_copy_lock = ceph_fl_copy_lock,
47 .fl_release_private = ceph_fl_release_lock,
48};
49
33/**
34 * Implement fcntl and flock locking functions.
35 */
50/**
51 * Implement fcntl and flock locking functions.
52 */
36static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
53static int ceph_lock_message(u8 lock_type, u16 operation, struct inode *inode,
37 int cmd, u8 wait, struct file_lock *fl)
38{
54 int cmd, u8 wait, struct file_lock *fl)
55{
39 struct inode *inode = file_inode(file);
40 struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
41 struct ceph_mds_request *req;
42 int err;
43 u64 length = 0;
44 u64 owner;
45
56 struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
57 struct ceph_mds_request *req;
58 int err;
59 u64 length = 0;
60 u64 owner;
61
62 if (operation == CEPH_MDS_OP_SETFILELOCK) {
63 /*
64 * increasing i_filelock_ref closes race window between
65 * handling request reply and adding file_lock struct to
66 * inode. Otherwise, auth caps may get trimmed in the
67 * window. Caller function will decrease the counter.
68 */
69 fl->fl_ops = &ceph_fl_lock_ops;
70 atomic_inc(&ceph_inode(inode)->i_filelock_ref);
71 }
72
46 if (operation != CEPH_MDS_OP_SETFILELOCK || cmd == CEPH_LOCK_UNLOCK)
47 wait = 0;
48
49 req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS);
50 if (IS_ERR(req))
51 return PTR_ERR(req);
52 req->r_inode = inode;
53 ihold(inode);

--- 121 unchanged lines hidden (view full) ---

175}
176
177/**
178 * Attempt to set an fcntl lock.
179 * For now, this just goes away to the server. Later it may be more awesome.
180 */
181int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
182{
73 if (operation != CEPH_MDS_OP_SETFILELOCK || cmd == CEPH_LOCK_UNLOCK)
74 wait = 0;
75
76 req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS);
77 if (IS_ERR(req))
78 return PTR_ERR(req);
79 req->r_inode = inode;
80 ihold(inode);

--- 121 unchanged lines hidden (view full) ---

202}
203
204/**
205 * Attempt to set an fcntl lock.
206 * For now, this just goes away to the server. Later it may be more awesome.
207 */
208int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
209{
183 u8 lock_cmd;
210 struct inode *inode = file_inode(file);
184 int err;
211 int err;
185 u8 wait = 0;
186 u16 op = CEPH_MDS_OP_SETFILELOCK;
212 u16 op = CEPH_MDS_OP_SETFILELOCK;
213 u8 lock_cmd;
214 u8 wait = 0;
187
188 if (!(fl->fl_flags & FL_POSIX))
189 return -ENOLCK;
190 /* No mandatory locks */
191 if (__mandatory_lock(file->f_mapping->host) && fl->fl_type != F_UNLCK)
192 return -ENOLCK;
193
194 dout("ceph_lock, fl_owner: %p", fl->fl_owner);
195
196 /* set wait bit as appropriate, then make command as Ceph expects it*/
197 if (IS_GETLK(cmd))
198 op = CEPH_MDS_OP_GETFILELOCK;
199 else if (IS_SETLKW(cmd))
200 wait = 1;
201
215
216 if (!(fl->fl_flags & FL_POSIX))
217 return -ENOLCK;
218 /* No mandatory locks */
219 if (__mandatory_lock(file->f_mapping->host) && fl->fl_type != F_UNLCK)
220 return -ENOLCK;
221
222 dout("ceph_lock, fl_owner: %p", fl->fl_owner);
223
224 /* set wait bit as appropriate, then make command as Ceph expects it*/
225 if (IS_GETLK(cmd))
226 op = CEPH_MDS_OP_GETFILELOCK;
227 else if (IS_SETLKW(cmd))
228 wait = 1;
229
230 if (op == CEPH_MDS_OP_SETFILELOCK) {
231 /*
232 * increasing i_filelock_ref closes race window between
233 * handling request reply and adding file_lock struct to
234 * inode. Otherwise, i_auth_cap may get trimmed in the
235 * window. Caller function will decrease the counter.
236 */
237 fl->fl_ops = &ceph_fl_lock_ops;
238 atomic_inc(&ceph_inode(inode)->i_filelock_ref);
239 }
240
202 if (F_RDLCK == fl->fl_type)
203 lock_cmd = CEPH_LOCK_SHARED;
204 else if (F_WRLCK == fl->fl_type)
205 lock_cmd = CEPH_LOCK_EXCL;
206 else
207 lock_cmd = CEPH_LOCK_UNLOCK;
208
241 if (F_RDLCK == fl->fl_type)
242 lock_cmd = CEPH_LOCK_SHARED;
243 else if (F_WRLCK == fl->fl_type)
244 lock_cmd = CEPH_LOCK_EXCL;
245 else
246 lock_cmd = CEPH_LOCK_UNLOCK;
247
209 err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, lock_cmd, wait, fl);
248 err = ceph_lock_message(CEPH_LOCK_FCNTL, op, inode, lock_cmd, wait, fl);
210 if (!err) {
211 if (op != CEPH_MDS_OP_GETFILELOCK) {
212 dout("mds locked, locking locally");
213 err = posix_lock_file(file, fl, NULL);
214 if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
215 /* undo! This should only happen if
216 * the kernel detects local
217 * deadlock. */
249 if (!err) {
250 if (op != CEPH_MDS_OP_GETFILELOCK) {
251 dout("mds locked, locking locally");
252 err = posix_lock_file(file, fl, NULL);
253 if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
254 /* undo! This should only happen if
255 * the kernel detects local
256 * deadlock. */
218 ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
257 ceph_lock_message(CEPH_LOCK_FCNTL, op, inode,
219 CEPH_LOCK_UNLOCK, 0, fl);
220 dout("got %d on posix_lock_file, undid lock",
221 err);
222 }
223 }
224 }
225 return err;
226}
227
228int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
229{
258 CEPH_LOCK_UNLOCK, 0, fl);
259 dout("got %d on posix_lock_file, undid lock",
260 err);
261 }
262 }
263 }
264 return err;
265}
266
267int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
268{
230 u8 lock_cmd;
269 struct inode *inode = file_inode(file);
231 int err;
270 int err;
271 u8 lock_cmd;
232 u8 wait = 0;
233
234 if (!(fl->fl_flags & FL_FLOCK))
235 return -ENOLCK;
236 /* No mandatory locks */
237 if (fl->fl_type & LOCK_MAND)
238 return -EOPNOTSUPP;
239
240 dout("ceph_flock, fl_file: %p", fl->fl_file);
241
272 u8 wait = 0;
273
274 if (!(fl->fl_flags & FL_FLOCK))
275 return -ENOLCK;
276 /* No mandatory locks */
277 if (fl->fl_type & LOCK_MAND)
278 return -EOPNOTSUPP;
279
280 dout("ceph_flock, fl_file: %p", fl->fl_file);
281
282 /* see comment in ceph_lock */
283 fl->fl_ops = &ceph_fl_lock_ops;
284 atomic_inc(&ceph_inode(inode)->i_filelock_ref);
285
242 if (IS_SETLKW(cmd))
243 wait = 1;
244
245 if (F_RDLCK == fl->fl_type)
246 lock_cmd = CEPH_LOCK_SHARED;
247 else if (F_WRLCK == fl->fl_type)
248 lock_cmd = CEPH_LOCK_EXCL;
249 else
250 lock_cmd = CEPH_LOCK_UNLOCK;
251
252 err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK,
286 if (IS_SETLKW(cmd))
287 wait = 1;
288
289 if (F_RDLCK == fl->fl_type)
290 lock_cmd = CEPH_LOCK_SHARED;
291 else if (F_WRLCK == fl->fl_type)
292 lock_cmd = CEPH_LOCK_EXCL;
293 else
294 lock_cmd = CEPH_LOCK_UNLOCK;
295
296 err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK,
253 file, lock_cmd, wait, fl);
297 inode, lock_cmd, wait, fl);
254 if (!err) {
255 err = locks_lock_file_wait(file, fl);
256 if (err) {
257 ceph_lock_message(CEPH_LOCK_FLOCK,
258 CEPH_MDS_OP_SETFILELOCK,
298 if (!err) {
299 err = locks_lock_file_wait(file, fl);
300 if (err) {
301 ceph_lock_message(CEPH_LOCK_FLOCK,
302 CEPH_MDS_OP_SETFILELOCK,
259 file, CEPH_LOCK_UNLOCK, 0, fl);
303 inode, CEPH_LOCK_UNLOCK, 0, fl);
260 dout("got %d on locks_lock_file_wait, undid lock", err);
261 }
262 }
263 return err;
264}
265
266/*
267 * Fills in the passed counter variables, so you can prepare pagelist metadata

--- 138 unchanged lines hidden ---
304 dout("got %d on locks_lock_file_wait, undid lock", err);
305 }
306 }
307 return err;
308}
309
310/*
311 * Fills in the passed counter variables, so you can prepare pagelist metadata

--- 138 unchanged lines hidden ---