diff options
| -rw-r--r-- | fs/ceph/locks.c | 61 | ||||
| -rw-r--r-- | fs/ceph/super.c | 1 | ||||
| -rw-r--r-- | fs/ceph/super.h | 1 | ||||
| -rw-r--r-- | include/linux/ceph/ceph_fs.h | 4 |
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 | ||
| 11 | static u64 lock_secret; | ||
| 12 | |||
| 13 | static 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 | |||
| 25 | void __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); | |||
| 871 | extern const struct export_operations ceph_export_ops; | 871 | extern const struct export_operations ceph_export_ops; |
| 872 | 872 | ||
| 873 | /* locks.c */ | 873 | /* locks.c */ |
| 874 | extern __init void ceph_flock_init(void); | ||
| 874 | extern int ceph_lock(struct file *file, int cmd, struct file_lock *fl); | 875 | extern int ceph_lock(struct file *file, int cmd, struct file_lock *fl); |
| 875 | extern int ceph_flock(struct file *file, int cmd, struct file_lock *fl); | 876 | extern int ceph_flock(struct file *file, int cmd, struct file_lock *fl); |
| 876 | extern void ceph_count_locks(struct inode *inode, int *p_num, int *f_num); | 877 | extern 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 | ||
