diff options
Diffstat (limited to 'fs/ceph/locks.c')
| -rw-r--r-- | fs/ceph/locks.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index ff4e753aae92..40abde93c345 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
| @@ -1,11 +1,11 @@ | |||
| 1 | #include "ceph_debug.h" | 1 | #include <linux/ceph/ceph_debug.h> |
| 2 | 2 | ||
| 3 | #include <linux/file.h> | 3 | #include <linux/file.h> |
| 4 | #include <linux/namei.h> | 4 | #include <linux/namei.h> |
| 5 | 5 | ||
| 6 | #include "super.h" | 6 | #include "super.h" |
| 7 | #include "mds_client.h" | 7 | #include "mds_client.h" |
| 8 | #include "pagelist.h" | 8 | #include <linux/ceph/pagelist.h> |
| 9 | 9 | ||
| 10 | /** | 10 | /** |
| 11 | * Implement fcntl and flock locking functions. | 11 | * Implement fcntl and flock locking functions. |
| @@ -16,7 +16,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | |||
| 16 | { | 16 | { |
| 17 | struct inode *inode = file->f_dentry->d_inode; | 17 | struct inode *inode = file->f_dentry->d_inode; |
| 18 | struct ceph_mds_client *mdsc = | 18 | struct ceph_mds_client *mdsc = |
| 19 | &ceph_sb_to_client(inode->i_sb)->mdsc; | 19 | ceph_sb_to_client(inode->i_sb)->mdsc; |
| 20 | struct ceph_mds_request *req; | 20 | struct ceph_mds_request *req; |
| 21 | int err; | 21 | int err; |
| 22 | 22 | ||
| @@ -181,8 +181,9 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count) | |||
| 181 | * Encode the flock and fcntl locks for the given inode into the pagelist. | 181 | * Encode the flock and fcntl locks for the given inode into the pagelist. |
| 182 | * Format is: #fcntl locks, sequential fcntl locks, #flock locks, | 182 | * Format is: #fcntl locks, sequential fcntl locks, #flock locks, |
| 183 | * sequential flock locks. | 183 | * sequential flock locks. |
| 184 | * Must be called with BLK already held, and the lock numbers should have | 184 | * Must be called with lock_flocks() already held. |
| 185 | * been gathered under the same lock holding window. | 185 | * If we encounter more of a specific lock type than expected, |
| 186 | * we return the value 1. | ||
| 186 | */ | 187 | */ |
| 187 | int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, | 188 | int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, |
| 188 | int num_fcntl_locks, int num_flock_locks) | 189 | int num_fcntl_locks, int num_flock_locks) |
| @@ -190,6 +191,8 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, | |||
| 190 | struct file_lock *lock; | 191 | struct file_lock *lock; |
| 191 | struct ceph_filelock cephlock; | 192 | struct ceph_filelock cephlock; |
| 192 | int err = 0; | 193 | int err = 0; |
| 194 | int seen_fcntl = 0; | ||
| 195 | int seen_flock = 0; | ||
| 193 | 196 | ||
| 194 | dout("encoding %d flock and %d fcntl locks", num_flock_locks, | 197 | dout("encoding %d flock and %d fcntl locks", num_flock_locks, |
| 195 | num_fcntl_locks); | 198 | num_fcntl_locks); |
| @@ -198,6 +201,11 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, | |||
| 198 | goto fail; | 201 | goto fail; |
| 199 | for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) { | 202 | for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) { |
| 200 | if (lock->fl_flags & FL_POSIX) { | 203 | if (lock->fl_flags & FL_POSIX) { |
| 204 | ++seen_fcntl; | ||
| 205 | if (seen_fcntl > num_fcntl_locks) { | ||
| 206 | err = -ENOSPC; | ||
| 207 | goto fail; | ||
| 208 | } | ||
| 201 | err = lock_to_ceph_filelock(lock, &cephlock); | 209 | err = lock_to_ceph_filelock(lock, &cephlock); |
| 202 | if (err) | 210 | if (err) |
| 203 | goto fail; | 211 | goto fail; |
| @@ -213,6 +221,11 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, | |||
| 213 | goto fail; | 221 | goto fail; |
| 214 | for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) { | 222 | for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) { |
| 215 | if (lock->fl_flags & FL_FLOCK) { | 223 | if (lock->fl_flags & FL_FLOCK) { |
| 224 | ++seen_flock; | ||
| 225 | if (seen_flock > num_flock_locks) { | ||
| 226 | err = -ENOSPC; | ||
| 227 | goto fail; | ||
| 228 | } | ||
| 216 | err = lock_to_ceph_filelock(lock, &cephlock); | 229 | err = lock_to_ceph_filelock(lock, &cephlock); |
| 217 | if (err) | 230 | if (err) |
| 218 | goto fail; | 231 | goto fail; |
