aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2014-03-09 11:16:40 -0400
committerSage Weil <sage@inktank.com>2014-04-05 00:07:11 -0400
commiteb13e832f823f6c110ea53e3067bafe22b87de63 (patch)
treee7e06eaf5ded86bb0d64b363b1c98c5909cf4847
parenteb70c0ce4e877c6854c682c0fc009d7875994942 (diff)
ceph: use fl->fl_file as owner identifier of flock and posix lock
flock and posix lock should use fl->fl_file instead of process ID as owner identifier. (posix lock uses fl->fl_owner. fl->fl_owner is usually equal to fl->fl_file, but it also can be a customized value). The process ID of who holds the lock is just for F_GETLK fcntl(2). The fix is rename the 'pid' fields of struct ceph_mds_request_args and struct ceph_filelock to 'owner', rename 'pid_namespace' fields to 'pid'. Assign fl->fl_file to the 'owner' field of lock messages. We also set the most significant bit of the 'owner' field. MDS can use that bit to distinguish between old and new clients. The MDS counterpart of this patch modifies the flock code to not take the 'pid_namespace' into consideration when checking conflict locks. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com> Reviewed-by: Sage Weil <sage@inktank.com>
-rw-r--r--fs/ceph/locks.c61
-rw-r--r--fs/ceph/super.c1
-rw-r--r--fs/ceph/super.h1
-rw-r--r--include/linux/ceph/ceph_fs.h4
4 files changed, 45 insertions, 22 deletions
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c
index f91a569a20fb..d94ba0df9f4d 100644
--- a/fs/ceph/locks.c
+++ b/fs/ceph/locks.c
@@ -2,11 +2,31 @@
2 2
3#include <linux/file.h> 3#include <linux/file.h>
4#include <linux/namei.h> 4#include <linux/namei.h>
5#include <linux/random.h>
5 6
6#include "super.h" 7#include "super.h"
7#include "mds_client.h" 8#include "mds_client.h"
8#include <linux/ceph/pagelist.h> 9#include <linux/ceph/pagelist.h>
9 10
11static u64 lock_secret;
12
13static inline u64 secure_addr(void *addr)
14{
15 u64 v = lock_secret ^ (u64)(unsigned long)addr;
16 /*
17 * Set the most significant bit, so that MDS knows the 'owner'
18 * is sufficient to identify the owner of lock. (old code uses
19 * both 'owner' and 'pid')
20 */
21 v |= (1ULL << 63);
22 return v;
23}
24
25void __init ceph_flock_init(void)
26{
27 get_random_bytes(&lock_secret, sizeof(lock_secret));
28}
29
10/** 30/**
11 * Implement fcntl and flock locking functions. 31 * Implement fcntl and flock locking functions.
12 */ 32 */
@@ -14,11 +34,11 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
14 int cmd, u8 wait, struct file_lock *fl) 34 int cmd, u8 wait, struct file_lock *fl)
15{ 35{
16 struct inode *inode = file_inode(file); 36 struct inode *inode = file_inode(file);
17 struct ceph_mds_client *mdsc = 37 struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
18 ceph_sb_to_client(inode->i_sb)->mdsc;
19 struct ceph_mds_request *req; 38 struct ceph_mds_request *req;
20 int err; 39 int err;
21 u64 length = 0; 40 u64 length = 0;
41 u64 owner;
22 42
23 req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS); 43 req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS);
24 if (IS_ERR(req)) 44 if (IS_ERR(req))
@@ -32,25 +52,27 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
32 else 52 else
33 length = fl->fl_end - fl->fl_start + 1; 53 length = fl->fl_end - fl->fl_start + 1;
34 54
35 dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " 55 if (lock_type == CEPH_LOCK_FCNTL)
36 "length: %llu, wait: %d, type: %d", (int)lock_type, 56 owner = secure_addr(fl->fl_owner);
37 (int)operation, (u64)fl->fl_pid, fl->fl_start, 57 else
38 length, wait, fl->fl_type); 58 owner = secure_addr(fl->fl_file);
59
60 dout("ceph_lock_message: rule: %d, op: %d, owner: %llx, pid: %llu, "
61 "start: %llu, length: %llu, wait: %d, type: %d", (int)lock_type,
62 (int)operation, owner, (u64)fl->fl_pid, fl->fl_start, length,
63 wait, fl->fl_type);
39 64
40 req->r_args.filelock_change.rule = lock_type; 65 req->r_args.filelock_change.rule = lock_type;
41 req->r_args.filelock_change.type = cmd; 66 req->r_args.filelock_change.type = cmd;
67 req->r_args.filelock_change.owner = cpu_to_le64(owner);
42 req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid); 68 req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid);
43 /* This should be adjusted, but I'm not sure if
44 namespaces actually get id numbers*/
45 req->r_args.filelock_change.pid_namespace =
46 cpu_to_le64((u64)(unsigned long)fl->fl_nspid);
47 req->r_args.filelock_change.start = cpu_to_le64(fl->fl_start); 69 req->r_args.filelock_change.start = cpu_to_le64(fl->fl_start);
48 req->r_args.filelock_change.length = cpu_to_le64(length); 70 req->r_args.filelock_change.length = cpu_to_le64(length);
49 req->r_args.filelock_change.wait = wait; 71 req->r_args.filelock_change.wait = wait;
50 72
51 err = ceph_mdsc_do_request(mdsc, inode, req); 73 err = ceph_mdsc_do_request(mdsc, inode, req);
52 74
53 if ( operation == CEPH_MDS_OP_GETFILELOCK){ 75 if (operation == CEPH_MDS_OP_GETFILELOCK) {
54 fl->fl_pid = le64_to_cpu(req->r_reply_info.filelock_reply->pid); 76 fl->fl_pid = le64_to_cpu(req->r_reply_info.filelock_reply->pid);
55 if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type) 77 if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type)
56 fl->fl_type = F_RDLCK; 78 fl->fl_type = F_RDLCK;
@@ -93,8 +115,7 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
93 if (__mandatory_lock(file->f_mapping->host) && fl->fl_type != F_UNLCK) 115 if (__mandatory_lock(file->f_mapping->host) && fl->fl_type != F_UNLCK)
94 return -ENOLCK; 116 return -ENOLCK;
95 117
96 fl->fl_nspid = get_pid(task_tgid(current)); 118 dout("ceph_lock, fl_owner: %p", fl->fl_owner);
97 dout("ceph_lock, fl_pid:%d", fl->fl_pid);
98 119
99 /* set wait bit as appropriate, then make command as Ceph expects it*/ 120 /* set wait bit as appropriate, then make command as Ceph expects it*/
100 if (IS_GETLK(cmd)) 121 if (IS_GETLK(cmd))
@@ -111,7 +132,7 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
111 132
112 err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, lock_cmd, wait, fl); 133 err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, lock_cmd, wait, fl);
113 if (!err) { 134 if (!err) {
114 if ( op != CEPH_MDS_OP_GETFILELOCK ){ 135 if (op != CEPH_MDS_OP_GETFILELOCK) {
115 dout("mds locked, locking locally"); 136 dout("mds locked, locking locally");
116 err = posix_lock_file(file, fl, NULL); 137 err = posix_lock_file(file, fl, NULL);
117 if (err && (CEPH_MDS_OP_SETFILELOCK == op)) { 138 if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
@@ -145,8 +166,7 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
145 if (__mandatory_lock(file->f_mapping->host) && fl->fl_type != F_UNLCK) 166 if (__mandatory_lock(file->f_mapping->host) && fl->fl_type != F_UNLCK)
146 return -ENOLCK; 167 return -ENOLCK;
147 168
148 fl->fl_nspid = get_pid(task_tgid(current)); 169 dout("ceph_flock, fl_file: %p", fl->fl_file);
149 dout("ceph_flock, fl_pid:%d", fl->fl_pid);
150 170
151 if (IS_SETLKW(cmd)) 171 if (IS_SETLKW(cmd))
152 wait = 1; 172 wait = 1;
@@ -289,13 +309,14 @@ int lock_to_ceph_filelock(struct file_lock *lock,
289 struct ceph_filelock *cephlock) 309 struct ceph_filelock *cephlock)
290{ 310{
291 int err = 0; 311 int err = 0;
292
293 cephlock->start = cpu_to_le64(lock->fl_start); 312 cephlock->start = cpu_to_le64(lock->fl_start);
294 cephlock->length = cpu_to_le64(lock->fl_end - lock->fl_start + 1); 313 cephlock->length = cpu_to_le64(lock->fl_end - lock->fl_start + 1);
295 cephlock->client = cpu_to_le64(0); 314 cephlock->client = cpu_to_le64(0);
296 cephlock->pid = cpu_to_le64(lock->fl_pid); 315 cephlock->pid = cpu_to_le64((u64)lock->fl_pid);
297 cephlock->pid_namespace = 316 if (lock->fl_flags & FL_POSIX)
298 cpu_to_le64((u64)(unsigned long)lock->fl_nspid); 317 cephlock->owner = cpu_to_le64(secure_addr(lock->fl_owner));
318 else
319 cephlock->owner = cpu_to_le64(secure_addr(lock->fl_file));
299 320
300 switch (lock->fl_type) { 321 switch (lock->fl_type) {
301 case F_RDLCK: 322 case F_RDLCK:
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index 10a4ccbf38da..06150fd745ac 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -1026,6 +1026,7 @@ static int __init init_ceph(void)
1026 if (ret) 1026 if (ret)
1027 goto out; 1027 goto out;
1028 1028
1029 ceph_flock_init();
1029 ceph_xattr_init(); 1030 ceph_xattr_init();
1030 ret = register_filesystem(&ceph_fs_type); 1031 ret = register_filesystem(&ceph_fs_type);
1031 if (ret) 1032 if (ret)
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 70bb183385b7..7866cd05a6bb 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -871,6 +871,7 @@ extern long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
871extern const struct export_operations ceph_export_ops; 871extern const struct export_operations ceph_export_ops;
872 872
873/* locks.c */ 873/* locks.c */
874extern __init void ceph_flock_init(void);
874extern int ceph_lock(struct file *file, int cmd, struct file_lock *fl); 875extern int ceph_lock(struct file *file, int cmd, struct file_lock *fl);
875extern int ceph_flock(struct file *file, int cmd, struct file_lock *fl); 876extern int ceph_flock(struct file *file, int cmd, struct file_lock *fl);
876extern void ceph_count_locks(struct inode *inode, int *p_num, int *f_num); 877extern void ceph_count_locks(struct inode *inode, int *p_num, int *f_num);
diff --git a/include/linux/ceph/ceph_fs.h b/include/linux/ceph/ceph_fs.h
index 35f345f7b3a3..5f6db18d72e8 100644
--- a/include/linux/ceph/ceph_fs.h
+++ b/include/linux/ceph/ceph_fs.h
@@ -421,8 +421,8 @@ union ceph_mds_request_args {
421 struct { 421 struct {
422 __u8 rule; /* currently fcntl or flock */ 422 __u8 rule; /* currently fcntl or flock */
423 __u8 type; /* shared, exclusive, remove*/ 423 __u8 type; /* shared, exclusive, remove*/
424 __le64 owner; /* owner of the lock */
424 __le64 pid; /* process id requesting the lock */ 425 __le64 pid; /* process id requesting the lock */
425 __le64 pid_namespace;
426 __le64 start; /* initial location to lock */ 426 __le64 start; /* initial location to lock */
427 __le64 length; /* num bytes to lock from start */ 427 __le64 length; /* num bytes to lock from start */
428 __u8 wait; /* will caller wait for lock to become available? */ 428 __u8 wait; /* will caller wait for lock to become available? */
@@ -533,8 +533,8 @@ struct ceph_filelock {
533 __le64 start;/* file offset to start lock at */ 533 __le64 start;/* file offset to start lock at */
534 __le64 length; /* num bytes to lock; 0 for all following start */ 534 __le64 length; /* num bytes to lock; 0 for all following start */
535 __le64 client; /* which client holds the lock */ 535 __le64 client; /* which client holds the lock */
536 __le64 owner; /* owner the lock */
536 __le64 pid; /* process id holding the lock on the client */ 537 __le64 pid; /* process id holding the lock on the client */
537 __le64 pid_namespace;
538 __u8 type; /* shared lock, exclusive lock, or unlock */ 538 __u8 type; /* shared lock, exclusive lock, or unlock */
539} __attribute__ ((packed)); 539} __attribute__ ((packed));
540 540