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 --- |