aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/rbd.c65
-rw-r--r--fs/ceph/caps.c9
-rw-r--r--fs/ceph/inode.c9
-rw-r--r--fs/ceph/locks.c177
-rw-r--r--fs/ceph/mds_client.c96
-rw-r--r--fs/ceph/super.c5
-rw-r--r--fs/ceph/super.h4
-rw-r--r--net/ceph/ceph_hash.c12
-rw-r--r--net/ceph/crypto.c4
-rw-r--r--net/ceph/messenger.c1
-rw-r--r--net/ceph/mon_client.c5
11 files changed, 237 insertions, 150 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index adc877dfef5c..38fc5f397fde 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -348,7 +348,6 @@ struct rbd_client_id {
348struct rbd_mapping { 348struct rbd_mapping {
349 u64 size; 349 u64 size;
350 u64 features; 350 u64 features;
351 bool read_only;
352}; 351};
353 352
354/* 353/*
@@ -450,12 +449,11 @@ static DEFINE_IDA(rbd_dev_id_ida);
450static struct workqueue_struct *rbd_wq; 449static struct workqueue_struct *rbd_wq;
451 450
452/* 451/*
453 * Default to false for now, as single-major requires >= 0.75 version of 452 * single-major requires >= 0.75 version of userspace rbd utility.
454 * userspace rbd utility.
455 */ 453 */
456static bool single_major = false; 454static bool single_major = true;
457module_param(single_major, bool, S_IRUGO); 455module_param(single_major, bool, S_IRUGO);
458MODULE_PARM_DESC(single_major, "Use a single major number for all rbd devices (default: false)"); 456MODULE_PARM_DESC(single_major, "Use a single major number for all rbd devices (default: true)");
459 457
460static int rbd_img_request_submit(struct rbd_img_request *img_request); 458static int rbd_img_request_submit(struct rbd_img_request *img_request);
461 459
@@ -608,9 +606,6 @@ static int rbd_open(struct block_device *bdev, fmode_t mode)
608 struct rbd_device *rbd_dev = bdev->bd_disk->private_data; 606 struct rbd_device *rbd_dev = bdev->bd_disk->private_data;
609 bool removing = false; 607 bool removing = false;
610 608
611 if ((mode & FMODE_WRITE) && rbd_dev->mapping.read_only)
612 return -EROFS;
613
614 spin_lock_irq(&rbd_dev->lock); 609 spin_lock_irq(&rbd_dev->lock);
615 if (test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags)) 610 if (test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags))
616 removing = true; 611 removing = true;
@@ -640,46 +635,24 @@ static void rbd_release(struct gendisk *disk, fmode_t mode)
640 635
641static int rbd_ioctl_set_ro(struct rbd_device *rbd_dev, unsigned long arg) 636static int rbd_ioctl_set_ro(struct rbd_device *rbd_dev, unsigned long arg)
642{ 637{
643 int ret = 0; 638 int ro;
644 int val;
645 bool ro;
646 bool ro_changed = false;
647 639
648 /* get_user() may sleep, so call it before taking rbd_dev->lock */ 640 if (get_user(ro, (int __user *)arg))
649 if (get_user(val, (int __user *)(arg)))
650 return -EFAULT; 641 return -EFAULT;
651 642
652 ro = val ? true : false; 643 /* Snapshots can't be marked read-write */
653 /* Snapshot doesn't allow to write*/
654 if (rbd_dev->spec->snap_id != CEPH_NOSNAP && !ro) 644 if (rbd_dev->spec->snap_id != CEPH_NOSNAP && !ro)
655 return -EROFS; 645 return -EROFS;
656 646
657 spin_lock_irq(&rbd_dev->lock); 647 /* Let blkdev_roset() handle it */
658 /* prevent others open this device */ 648 return -ENOTTY;
659 if (rbd_dev->open_count > 1) {
660 ret = -EBUSY;
661 goto out;
662 }
663
664 if (rbd_dev->mapping.read_only != ro) {
665 rbd_dev->mapping.read_only = ro;
666 ro_changed = true;
667 }
668
669out:
670 spin_unlock_irq(&rbd_dev->lock);
671 /* set_disk_ro() may sleep, so call it after releasing rbd_dev->lock */
672 if (ret == 0 && ro_changed)
673 set_disk_ro(rbd_dev->disk, ro ? 1 : 0);
674
675 return ret;
676} 649}
677 650
678static int rbd_ioctl(struct block_device *bdev, fmode_t mode, 651static int rbd_ioctl(struct block_device *bdev, fmode_t mode,
679 unsigned int cmd, unsigned long arg) 652 unsigned int cmd, unsigned long arg)
680{ 653{
681 struct rbd_device *rbd_dev = bdev->bd_disk->private_data; 654 struct rbd_device *rbd_dev = bdev->bd_disk->private_data;
682 int ret = 0; 655 int ret;
683 656
684 switch (cmd) { 657 switch (cmd) {
685 case BLKROSET: 658 case BLKROSET:
@@ -4050,15 +4023,8 @@ static void rbd_queue_workfn(struct work_struct *work)
4050 goto err_rq; 4023 goto err_rq;
4051 } 4024 }
4052 4025
4053 /* Only reads are allowed to a read-only device */ 4026 rbd_assert(op_type == OBJ_OP_READ ||
4054 4027 rbd_dev->spec->snap_id == CEPH_NOSNAP);
4055 if (op_type != OBJ_OP_READ) {
4056 if (rbd_dev->mapping.read_only) {
4057 result = -EROFS;
4058 goto err_rq;
4059 }
4060 rbd_assert(rbd_dev->spec->snap_id == CEPH_NOSNAP);
4061 }
4062 4028
4063 /* 4029 /*
4064 * Quit early if the mapped snapshot no longer exists. It's 4030 * Quit early if the mapped snapshot no longer exists. It's
@@ -4423,7 +4389,6 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
4423 /* enable the discard support */ 4389 /* enable the discard support */
4424 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); 4390 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
4425 q->limits.discard_granularity = segment_size; 4391 q->limits.discard_granularity = segment_size;
4426 q->limits.discard_alignment = segment_size;
4427 blk_queue_max_discard_sectors(q, segment_size / SECTOR_SIZE); 4392 blk_queue_max_discard_sectors(q, segment_size / SECTOR_SIZE);
4428 blk_queue_max_write_zeroes_sectors(q, segment_size / SECTOR_SIZE); 4393 blk_queue_max_write_zeroes_sectors(q, segment_size / SECTOR_SIZE);
4429 4394
@@ -5994,7 +5959,7 @@ static int rbd_dev_device_setup(struct rbd_device *rbd_dev)
5994 goto err_out_disk; 5959 goto err_out_disk;
5995 5960
5996 set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE); 5961 set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE);
5997 set_disk_ro(rbd_dev->disk, rbd_dev->mapping.read_only); 5962 set_disk_ro(rbd_dev->disk, rbd_dev->opts->read_only);
5998 5963
5999 ret = dev_set_name(&rbd_dev->dev, "%d", rbd_dev->dev_id); 5964 ret = dev_set_name(&rbd_dev->dev, "%d", rbd_dev->dev_id);
6000 if (ret) 5965 if (ret)
@@ -6145,7 +6110,6 @@ static ssize_t do_rbd_add(struct bus_type *bus,
6145 struct rbd_options *rbd_opts = NULL; 6110 struct rbd_options *rbd_opts = NULL;
6146 struct rbd_spec *spec = NULL; 6111 struct rbd_spec *spec = NULL;
6147 struct rbd_client *rbdc; 6112 struct rbd_client *rbdc;
6148 bool read_only;
6149 int rc; 6113 int rc;
6150 6114
6151 if (!try_module_get(THIS_MODULE)) 6115 if (!try_module_get(THIS_MODULE))
@@ -6194,11 +6158,8 @@ static ssize_t do_rbd_add(struct bus_type *bus,
6194 } 6158 }
6195 6159
6196 /* If we are mapping a snapshot it must be marked read-only */ 6160 /* If we are mapping a snapshot it must be marked read-only */
6197
6198 read_only = rbd_dev->opts->read_only;
6199 if (rbd_dev->spec->snap_id != CEPH_NOSNAP) 6161 if (rbd_dev->spec->snap_id != CEPH_NOSNAP)
6200 read_only = true; 6162 rbd_dev->opts->read_only = true;
6201 rbd_dev->mapping.read_only = read_only;
6202 6163
6203 rc = rbd_dev_device_setup(rbd_dev); 6164 rc = rbd_dev_device_setup(rbd_dev);
6204 if (rc) 6165 if (rc)
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index ff5d32cf9578..a14b2c974c9e 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1160,7 +1160,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
1160 struct ceph_inode_info *ci = cap->ci; 1160 struct ceph_inode_info *ci = cap->ci;
1161 struct inode *inode = &ci->vfs_inode; 1161 struct inode *inode = &ci->vfs_inode;
1162 struct cap_msg_args arg; 1162 struct cap_msg_args arg;
1163 int held, revoking, dropping; 1163 int held, revoking;
1164 int wake = 0; 1164 int wake = 0;
1165 int delayed = 0; 1165 int delayed = 0;
1166 int ret; 1166 int ret;
@@ -1168,7 +1168,6 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
1168 held = cap->issued | cap->implemented; 1168 held = cap->issued | cap->implemented;
1169 revoking = cap->implemented & ~cap->issued; 1169 revoking = cap->implemented & ~cap->issued;
1170 retain &= ~revoking; 1170 retain &= ~revoking;
1171 dropping = cap->issued & ~retain;
1172 1171
1173 dout("__send_cap %p cap %p session %p %s -> %s (revoking %s)\n", 1172 dout("__send_cap %p cap %p session %p %s -> %s (revoking %s)\n",
1174 inode, cap, cap->session, 1173 inode, cap, cap->session,
@@ -1712,7 +1711,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
1712 1711
1713 /* if we are unmounting, flush any unused caps immediately. */ 1712 /* if we are unmounting, flush any unused caps immediately. */
1714 if (mdsc->stopping) 1713 if (mdsc->stopping)
1715 is_delayed = 1; 1714 is_delayed = true;
1716 1715
1717 spin_lock(&ci->i_ceph_lock); 1716 spin_lock(&ci->i_ceph_lock);
1718 1717
@@ -3189,8 +3188,8 @@ static void handle_cap_flush_ack(struct inode *inode, u64 flush_tid,
3189 int dirty = le32_to_cpu(m->dirty); 3188 int dirty = le32_to_cpu(m->dirty);
3190 int cleaned = 0; 3189 int cleaned = 0;
3191 bool drop = false; 3190 bool drop = false;
3192 bool wake_ci = 0; 3191 bool wake_ci = false;
3193 bool wake_mdsc = 0; 3192 bool wake_mdsc = false;
3194 3193
3195 list_for_each_entry_safe(cf, tmp_cf, &ci->i_cap_flush_list, i_list) { 3194 list_for_each_entry_safe(cf, tmp_cf, &ci->i_cap_flush_list, i_list) {
3196 if (cf->tid == flush_tid) 3195 if (cf->tid == flush_tid)
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index f2550a076edc..ab81652198c4 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -493,6 +493,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
493 ci->i_wb_ref = 0; 493 ci->i_wb_ref = 0;
494 ci->i_wrbuffer_ref = 0; 494 ci->i_wrbuffer_ref = 0;
495 ci->i_wrbuffer_ref_head = 0; 495 ci->i_wrbuffer_ref_head = 0;
496 atomic_set(&ci->i_filelock_ref, 0);
496 ci->i_shared_gen = 0; 497 ci->i_shared_gen = 0;
497 ci->i_rdcache_gen = 0; 498 ci->i_rdcache_gen = 0;
498 ci->i_rdcache_revoking = 0; 499 ci->i_rdcache_revoking = 0;
@@ -786,7 +787,6 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
786 787
787 /* update inode */ 788 /* update inode */
788 ci->i_version = le64_to_cpu(info->version); 789 ci->i_version = le64_to_cpu(info->version);
789 inode->i_version++;
790 inode->i_rdev = le32_to_cpu(info->rdev); 790 inode->i_rdev = le32_to_cpu(info->rdev);
791 inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1; 791 inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
792 792
@@ -1185,6 +1185,7 @@ retry_lookup:
1185 ceph_snap(d_inode(dn)) != tvino.snap)) { 1185 ceph_snap(d_inode(dn)) != tvino.snap)) {
1186 dout(" dn %p points to wrong inode %p\n", 1186 dout(" dn %p points to wrong inode %p\n",
1187 dn, d_inode(dn)); 1187 dn, d_inode(dn));
1188 ceph_dir_clear_ordered(dir);
1188 d_delete(dn); 1189 d_delete(dn);
1189 dput(dn); 1190 dput(dn);
1190 goto retry_lookup; 1191 goto retry_lookup;
@@ -1322,6 +1323,7 @@ retry_lookup:
1322 dout(" %p links to %p %llx.%llx, not %llx.%llx\n", 1323 dout(" %p links to %p %llx.%llx, not %llx.%llx\n",
1323 dn, d_inode(dn), ceph_vinop(d_inode(dn)), 1324 dn, d_inode(dn), ceph_vinop(d_inode(dn)),
1324 ceph_vinop(in)); 1325 ceph_vinop(in));
1326 ceph_dir_clear_ordered(dir);
1325 d_invalidate(dn); 1327 d_invalidate(dn);
1326 have_lease = false; 1328 have_lease = false;
1327 } 1329 }
@@ -1573,6 +1575,7 @@ retry_lookup:
1573 ceph_snap(d_inode(dn)) != tvino.snap)) { 1575 ceph_snap(d_inode(dn)) != tvino.snap)) {
1574 dout(" dn %p points to wrong inode %p\n", 1576 dout(" dn %p points to wrong inode %p\n",
1575 dn, d_inode(dn)); 1577 dn, d_inode(dn));
1578 __ceph_dir_clear_ordered(ci);
1576 d_delete(dn); 1579 d_delete(dn);
1577 dput(dn); 1580 dput(dn);
1578 goto retry_lookup; 1581 goto retry_lookup;
@@ -1597,7 +1600,9 @@ retry_lookup:
1597 &req->r_caps_reservation); 1600 &req->r_caps_reservation);
1598 if (ret < 0) { 1601 if (ret < 0) {
1599 pr_err("fill_inode badness on %p\n", in); 1602 pr_err("fill_inode badness on %p\n", in);
1600 if (d_really_is_negative(dn)) 1603 if (d_really_is_positive(dn))
1604 __ceph_dir_clear_ordered(ci);
1605 else
1601 iput(in); 1606 iput(in);
1602 d_drop(dn); 1607 d_drop(dn);
1603 err = ret; 1608 err = ret;
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c
index e7cce412f2cf..9e66f69ee8a5 100644
--- a/fs/ceph/locks.c
+++ b/fs/ceph/locks.c
@@ -30,19 +30,52 @@ void __init ceph_flock_init(void)
30 get_random_bytes(&lock_secret, sizeof(lock_secret)); 30 get_random_bytes(&lock_secret, sizeof(lock_secret));
31} 31}
32 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 struct ceph_inode_info *ci = ceph_inode(inode);
43 if (atomic_dec_and_test(&ci->i_filelock_ref)) {
44 /* clear error when all locks are released */
45 spin_lock(&ci->i_ceph_lock);
46 ci->i_ceph_flags &= ~CEPH_I_ERROR_FILELOCK;
47 spin_unlock(&ci->i_ceph_lock);
48 }
49}
50
51static const struct file_lock_operations ceph_fl_lock_ops = {
52 .fl_copy_lock = ceph_fl_copy_lock,
53 .fl_release_private = ceph_fl_release_lock,
54};
55
33/** 56/**
34 * Implement fcntl and flock locking functions. 57 * Implement fcntl and flock locking functions.
35 */ 58 */
36static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, 59static int ceph_lock_message(u8 lock_type, u16 operation, struct inode *inode,
37 int cmd, u8 wait, struct file_lock *fl) 60 int cmd, u8 wait, struct file_lock *fl)
38{ 61{
39 struct inode *inode = file_inode(file);
40 struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; 62 struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
41 struct ceph_mds_request *req; 63 struct ceph_mds_request *req;
42 int err; 64 int err;
43 u64 length = 0; 65 u64 length = 0;
44 u64 owner; 66 u64 owner;
45 67
68 if (operation == CEPH_MDS_OP_SETFILELOCK) {
69 /*
70 * increasing i_filelock_ref closes race window between
71 * handling request reply and adding file_lock struct to
72 * inode. Otherwise, auth caps may get trimmed in the
73 * window. Caller function will decrease the counter.
74 */
75 fl->fl_ops = &ceph_fl_lock_ops;
76 atomic_inc(&ceph_inode(inode)->i_filelock_ref);
77 }
78
46 if (operation != CEPH_MDS_OP_SETFILELOCK || cmd == CEPH_LOCK_UNLOCK) 79 if (operation != CEPH_MDS_OP_SETFILELOCK || cmd == CEPH_LOCK_UNLOCK)
47 wait = 0; 80 wait = 0;
48 81
@@ -180,10 +213,12 @@ static int ceph_lock_wait_for_completion(struct ceph_mds_client *mdsc,
180 */ 213 */
181int ceph_lock(struct file *file, int cmd, struct file_lock *fl) 214int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
182{ 215{
183 u8 lock_cmd; 216 struct inode *inode = file_inode(file);
184 int err; 217 struct ceph_inode_info *ci = ceph_inode(inode);
185 u8 wait = 0; 218 int err = 0;
186 u16 op = CEPH_MDS_OP_SETFILELOCK; 219 u16 op = CEPH_MDS_OP_SETFILELOCK;
220 u8 wait = 0;
221 u8 lock_cmd;
187 222
188 if (!(fl->fl_flags & FL_POSIX)) 223 if (!(fl->fl_flags & FL_POSIX))
189 return -ENOLCK; 224 return -ENOLCK;
@@ -199,6 +234,26 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
199 else if (IS_SETLKW(cmd)) 234 else if (IS_SETLKW(cmd))
200 wait = 1; 235 wait = 1;
201 236
237 spin_lock(&ci->i_ceph_lock);
238 if (ci->i_ceph_flags & CEPH_I_ERROR_FILELOCK) {
239 err = -EIO;
240 } else if (op == CEPH_MDS_OP_SETFILELOCK) {
241 /*
242 * increasing i_filelock_ref closes race window between
243 * handling request reply and adding file_lock struct to
244 * inode. Otherwise, i_auth_cap may get trimmed in the
245 * window. Caller function will decrease the counter.
246 */
247 fl->fl_ops = &ceph_fl_lock_ops;
248 atomic_inc(&ci->i_filelock_ref);
249 }
250 spin_unlock(&ci->i_ceph_lock);
251 if (err < 0) {
252 if (op == CEPH_MDS_OP_SETFILELOCK && F_UNLCK == fl->fl_type)
253 posix_lock_file(file, fl, NULL);
254 return err;
255 }
256
202 if (F_RDLCK == fl->fl_type) 257 if (F_RDLCK == fl->fl_type)
203 lock_cmd = CEPH_LOCK_SHARED; 258 lock_cmd = CEPH_LOCK_SHARED;
204 else if (F_WRLCK == fl->fl_type) 259 else if (F_WRLCK == fl->fl_type)
@@ -206,16 +261,16 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
206 else 261 else
207 lock_cmd = CEPH_LOCK_UNLOCK; 262 lock_cmd = CEPH_LOCK_UNLOCK;
208 263
209 err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, lock_cmd, wait, fl); 264 err = ceph_lock_message(CEPH_LOCK_FCNTL, op, inode, lock_cmd, wait, fl);
210 if (!err) { 265 if (!err) {
211 if (op != CEPH_MDS_OP_GETFILELOCK) { 266 if (op == CEPH_MDS_OP_SETFILELOCK) {
212 dout("mds locked, locking locally"); 267 dout("mds locked, locking locally");
213 err = posix_lock_file(file, fl, NULL); 268 err = posix_lock_file(file, fl, NULL);
214 if (err && (CEPH_MDS_OP_SETFILELOCK == op)) { 269 if (err) {
215 /* undo! This should only happen if 270 /* undo! This should only happen if
216 * the kernel detects local 271 * the kernel detects local
217 * deadlock. */ 272 * deadlock. */
218 ceph_lock_message(CEPH_LOCK_FCNTL, op, file, 273 ceph_lock_message(CEPH_LOCK_FCNTL, op, inode,
219 CEPH_LOCK_UNLOCK, 0, fl); 274 CEPH_LOCK_UNLOCK, 0, fl);
220 dout("got %d on posix_lock_file, undid lock", 275 dout("got %d on posix_lock_file, undid lock",
221 err); 276 err);
@@ -227,9 +282,11 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
227 282
228int ceph_flock(struct file *file, int cmd, struct file_lock *fl) 283int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
229{ 284{
230 u8 lock_cmd; 285 struct inode *inode = file_inode(file);
231 int err; 286 struct ceph_inode_info *ci = ceph_inode(inode);
287 int err = 0;
232 u8 wait = 0; 288 u8 wait = 0;
289 u8 lock_cmd;
233 290
234 if (!(fl->fl_flags & FL_FLOCK)) 291 if (!(fl->fl_flags & FL_FLOCK))
235 return -ENOLCK; 292 return -ENOLCK;
@@ -239,6 +296,21 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
239 296
240 dout("ceph_flock, fl_file: %p", fl->fl_file); 297 dout("ceph_flock, fl_file: %p", fl->fl_file);
241 298
299 spin_lock(&ci->i_ceph_lock);
300 if (ci->i_ceph_flags & CEPH_I_ERROR_FILELOCK) {
301 err = -EIO;
302 } else {
303 /* see comment in ceph_lock */
304 fl->fl_ops = &ceph_fl_lock_ops;
305 atomic_inc(&ci->i_filelock_ref);
306 }
307 spin_unlock(&ci->i_ceph_lock);
308 if (err < 0) {
309 if (F_UNLCK == fl->fl_type)
310 locks_lock_file_wait(file, fl);
311 return err;
312 }
313
242 if (IS_SETLKW(cmd)) 314 if (IS_SETLKW(cmd))
243 wait = 1; 315 wait = 1;
244 316
@@ -250,13 +322,13 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
250 lock_cmd = CEPH_LOCK_UNLOCK; 322 lock_cmd = CEPH_LOCK_UNLOCK;
251 323
252 err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK, 324 err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK,
253 file, lock_cmd, wait, fl); 325 inode, lock_cmd, wait, fl);
254 if (!err) { 326 if (!err) {
255 err = locks_lock_file_wait(file, fl); 327 err = locks_lock_file_wait(file, fl);
256 if (err) { 328 if (err) {
257 ceph_lock_message(CEPH_LOCK_FLOCK, 329 ceph_lock_message(CEPH_LOCK_FLOCK,
258 CEPH_MDS_OP_SETFILELOCK, 330 CEPH_MDS_OP_SETFILELOCK,
259 file, CEPH_LOCK_UNLOCK, 0, fl); 331 inode, CEPH_LOCK_UNLOCK, 0, fl);
260 dout("got %d on locks_lock_file_wait, undid lock", err); 332 dout("got %d on locks_lock_file_wait, undid lock", err);
261 } 333 }
262 } 334 }
@@ -288,6 +360,37 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count)
288 *flock_count, *fcntl_count); 360 *flock_count, *fcntl_count);
289} 361}
290 362
363/*
364 * Given a pointer to a lock, convert it to a ceph filelock
365 */
366static int lock_to_ceph_filelock(struct file_lock *lock,
367 struct ceph_filelock *cephlock)
368{
369 int err = 0;
370 cephlock->start = cpu_to_le64(lock->fl_start);
371 cephlock->length = cpu_to_le64(lock->fl_end - lock->fl_start + 1);
372 cephlock->client = cpu_to_le64(0);
373 cephlock->pid = cpu_to_le64((u64)lock->fl_pid);
374 cephlock->owner = cpu_to_le64(secure_addr(lock->fl_owner));
375
376 switch (lock->fl_type) {
377 case F_RDLCK:
378 cephlock->type = CEPH_LOCK_SHARED;
379 break;
380 case F_WRLCK:
381 cephlock->type = CEPH_LOCK_EXCL;
382 break;
383 case F_UNLCK:
384 cephlock->type = CEPH_LOCK_UNLOCK;
385 break;
386 default:
387 dout("Have unknown lock type %d", lock->fl_type);
388 err = -EINVAL;
389 }
390
391 return err;
392}
393
291/** 394/**
292 * Encode the flock and fcntl locks for the given inode into the ceph_filelock 395 * Encode the flock and fcntl locks for the given inode into the ceph_filelock
293 * array. Must be called with inode->i_lock already held. 396 * array. Must be called with inode->i_lock already held.
@@ -356,50 +459,22 @@ int ceph_locks_to_pagelist(struct ceph_filelock *flocks,
356 if (err) 459 if (err)
357 goto out_fail; 460 goto out_fail;
358 461
359 err = ceph_pagelist_append(pagelist, flocks, 462 if (num_fcntl_locks > 0) {
360 num_fcntl_locks * sizeof(*flocks)); 463 err = ceph_pagelist_append(pagelist, flocks,
361 if (err) 464 num_fcntl_locks * sizeof(*flocks));
362 goto out_fail; 465 if (err)
466 goto out_fail;
467 }
363 468
364 nlocks = cpu_to_le32(num_flock_locks); 469 nlocks = cpu_to_le32(num_flock_locks);
365 err = ceph_pagelist_append(pagelist, &nlocks, sizeof(nlocks)); 470 err = ceph_pagelist_append(pagelist, &nlocks, sizeof(nlocks));
366 if (err) 471 if (err)
367 goto out_fail; 472 goto out_fail;
368 473
369 err = ceph_pagelist_append(pagelist, 474 if (num_flock_locks > 0) {
370 &flocks[num_fcntl_locks], 475 err = ceph_pagelist_append(pagelist, &flocks[num_fcntl_locks],
371 num_flock_locks * sizeof(*flocks)); 476 num_flock_locks * sizeof(*flocks));
372out_fail:
373 return err;
374}
375
376/*
377 * Given a pointer to a lock, convert it to a ceph filelock
378 */
379int lock_to_ceph_filelock(struct file_lock *lock,
380 struct ceph_filelock *cephlock)
381{
382 int err = 0;
383 cephlock->start = cpu_to_le64(lock->fl_start);
384 cephlock->length = cpu_to_le64(lock->fl_end - lock->fl_start + 1);
385 cephlock->client = cpu_to_le64(0);
386 cephlock->pid = cpu_to_le64((u64)lock->fl_pid);
387 cephlock->owner = cpu_to_le64(secure_addr(lock->fl_owner));
388
389 switch (lock->fl_type) {
390 case F_RDLCK:
391 cephlock->type = CEPH_LOCK_SHARED;
392 break;
393 case F_WRLCK:
394 cephlock->type = CEPH_LOCK_EXCL;
395 break;
396 case F_UNLCK:
397 cephlock->type = CEPH_LOCK_UNLOCK;
398 break;
399 default:
400 dout("Have unknown lock type %d", lock->fl_type);
401 err = -EINVAL;
402 } 477 }
403 478out_fail:
404 return err; 479 return err;
405} 480}
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 0687ab3c3267..ab69dcb70e8a 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -1039,22 +1039,23 @@ void ceph_mdsc_open_export_target_sessions(struct ceph_mds_client *mdsc,
1039 * session caps 1039 * session caps
1040 */ 1040 */
1041 1041
1042/* caller holds s_cap_lock, we drop it */ 1042static void detach_cap_releases(struct ceph_mds_session *session,
1043static void cleanup_cap_releases(struct ceph_mds_client *mdsc, 1043 struct list_head *target)
1044 struct ceph_mds_session *session)
1045 __releases(session->s_cap_lock)
1046{ 1044{
1047 LIST_HEAD(tmp_list); 1045 lockdep_assert_held(&session->s_cap_lock);
1048 list_splice_init(&session->s_cap_releases, &tmp_list); 1046
1047 list_splice_init(&session->s_cap_releases, target);
1049 session->s_num_cap_releases = 0; 1048 session->s_num_cap_releases = 0;
1050 spin_unlock(&session->s_cap_lock); 1049 dout("dispose_cap_releases mds%d\n", session->s_mds);
1050}
1051 1051
1052 dout("cleanup_cap_releases mds%d\n", session->s_mds); 1052static void dispose_cap_releases(struct ceph_mds_client *mdsc,
1053 while (!list_empty(&tmp_list)) { 1053 struct list_head *dispose)
1054{
1055 while (!list_empty(dispose)) {
1054 struct ceph_cap *cap; 1056 struct ceph_cap *cap;
1055 /* zero out the in-progress message */ 1057 /* zero out the in-progress message */
1056 cap = list_first_entry(&tmp_list, 1058 cap = list_first_entry(dispose, struct ceph_cap, session_caps);
1057 struct ceph_cap, session_caps);
1058 list_del(&cap->session_caps); 1059 list_del(&cap->session_caps);
1059 ceph_put_cap(mdsc, cap); 1060 ceph_put_cap(mdsc, cap);
1060 } 1061 }
@@ -1215,6 +1216,13 @@ static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
1215 } 1216 }
1216 spin_unlock(&mdsc->cap_dirty_lock); 1217 spin_unlock(&mdsc->cap_dirty_lock);
1217 1218
1219 if (atomic_read(&ci->i_filelock_ref) > 0) {
1220 /* make further file lock syscall return -EIO */
1221 ci->i_ceph_flags |= CEPH_I_ERROR_FILELOCK;
1222 pr_warn_ratelimited(" dropping file locks for %p %lld\n",
1223 inode, ceph_ino(inode));
1224 }
1225
1218 if (!ci->i_dirty_caps && ci->i_prealloc_cap_flush) { 1226 if (!ci->i_dirty_caps && ci->i_prealloc_cap_flush) {
1219 list_add(&ci->i_prealloc_cap_flush->i_list, &to_remove); 1227 list_add(&ci->i_prealloc_cap_flush->i_list, &to_remove);
1220 ci->i_prealloc_cap_flush = NULL; 1228 ci->i_prealloc_cap_flush = NULL;
@@ -1244,6 +1252,8 @@ static void remove_session_caps(struct ceph_mds_session *session)
1244{ 1252{
1245 struct ceph_fs_client *fsc = session->s_mdsc->fsc; 1253 struct ceph_fs_client *fsc = session->s_mdsc->fsc;
1246 struct super_block *sb = fsc->sb; 1254 struct super_block *sb = fsc->sb;
1255 LIST_HEAD(dispose);
1256
1247 dout("remove_session_caps on %p\n", session); 1257 dout("remove_session_caps on %p\n", session);
1248 iterate_session_caps(session, remove_session_caps_cb, fsc); 1258 iterate_session_caps(session, remove_session_caps_cb, fsc);
1249 1259
@@ -1278,10 +1288,12 @@ static void remove_session_caps(struct ceph_mds_session *session)
1278 } 1288 }
1279 1289
1280 // drop cap expires and unlock s_cap_lock 1290 // drop cap expires and unlock s_cap_lock
1281 cleanup_cap_releases(session->s_mdsc, session); 1291 detach_cap_releases(session, &dispose);
1282 1292
1283 BUG_ON(session->s_nr_caps > 0); 1293 BUG_ON(session->s_nr_caps > 0);
1284 BUG_ON(!list_empty(&session->s_cap_flushing)); 1294 BUG_ON(!list_empty(&session->s_cap_flushing));
1295 spin_unlock(&session->s_cap_lock);
1296 dispose_cap_releases(session->s_mdsc, &dispose);
1285} 1297}
1286 1298
1287/* 1299/*
@@ -1462,6 +1474,11 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
1462 goto out; 1474 goto out;
1463 if ((used | wanted) & CEPH_CAP_ANY_WR) 1475 if ((used | wanted) & CEPH_CAP_ANY_WR)
1464 goto out; 1476 goto out;
1477 /* Note: it's possible that i_filelock_ref becomes non-zero
1478 * after dropping auth caps. It doesn't hurt because reply
1479 * of lock mds request will re-add auth caps. */
1480 if (atomic_read(&ci->i_filelock_ref) > 0)
1481 goto out;
1465 } 1482 }
1466 /* The inode has cached pages, but it's no longer used. 1483 /* The inode has cached pages, but it's no longer used.
1467 * we can safely drop it */ 1484 * we can safely drop it */
@@ -2827,7 +2844,7 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
2827 struct ceph_mds_cap_reconnect v2; 2844 struct ceph_mds_cap_reconnect v2;
2828 struct ceph_mds_cap_reconnect_v1 v1; 2845 struct ceph_mds_cap_reconnect_v1 v1;
2829 } rec; 2846 } rec;
2830 struct ceph_inode_info *ci; 2847 struct ceph_inode_info *ci = cap->ci;
2831 struct ceph_reconnect_state *recon_state = arg; 2848 struct ceph_reconnect_state *recon_state = arg;
2832 struct ceph_pagelist *pagelist = recon_state->pagelist; 2849 struct ceph_pagelist *pagelist = recon_state->pagelist;
2833 char *path; 2850 char *path;
@@ -2836,8 +2853,6 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
2836 u64 snap_follows; 2853 u64 snap_follows;
2837 struct dentry *dentry; 2854 struct dentry *dentry;
2838 2855
2839 ci = cap->ci;
2840
2841 dout(" adding %p ino %llx.%llx cap %p %lld %s\n", 2856 dout(" adding %p ino %llx.%llx cap %p %lld %s\n",
2842 inode, ceph_vinop(inode), cap, cap->cap_id, 2857 inode, ceph_vinop(inode), cap, cap->cap_id,
2843 ceph_cap_string(cap->issued)); 2858 ceph_cap_string(cap->issued));
@@ -2870,7 +2885,8 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
2870 rec.v2.issued = cpu_to_le32(cap->issued); 2885 rec.v2.issued = cpu_to_le32(cap->issued);
2871 rec.v2.snaprealm = cpu_to_le64(ci->i_snap_realm->ino); 2886 rec.v2.snaprealm = cpu_to_le64(ci->i_snap_realm->ino);
2872 rec.v2.pathbase = cpu_to_le64(pathbase); 2887 rec.v2.pathbase = cpu_to_le64(pathbase);
2873 rec.v2.flock_len = 0; 2888 rec.v2.flock_len = (__force __le32)
2889 ((ci->i_ceph_flags & CEPH_I_ERROR_FILELOCK) ? 0 : 1);
2874 } else { 2890 } else {
2875 rec.v1.cap_id = cpu_to_le64(cap->cap_id); 2891 rec.v1.cap_id = cpu_to_le64(cap->cap_id);
2876 rec.v1.wanted = cpu_to_le32(__ceph_caps_wanted(ci)); 2892 rec.v1.wanted = cpu_to_le32(__ceph_caps_wanted(ci));
@@ -2894,26 +2910,37 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
2894 2910
2895 if (recon_state->msg_version >= 2) { 2911 if (recon_state->msg_version >= 2) {
2896 int num_fcntl_locks, num_flock_locks; 2912 int num_fcntl_locks, num_flock_locks;
2897 struct ceph_filelock *flocks; 2913 struct ceph_filelock *flocks = NULL;
2898 size_t struct_len, total_len = 0; 2914 size_t struct_len, total_len = 0;
2899 u8 struct_v = 0; 2915 u8 struct_v = 0;
2900 2916
2901encode_again: 2917encode_again:
2902 ceph_count_locks(inode, &num_fcntl_locks, &num_flock_locks); 2918 if (rec.v2.flock_len) {
2903 flocks = kmalloc((num_fcntl_locks+num_flock_locks) * 2919 ceph_count_locks(inode, &num_fcntl_locks, &num_flock_locks);
2904 sizeof(struct ceph_filelock), GFP_NOFS); 2920 } else {
2905 if (!flocks) { 2921 num_fcntl_locks = 0;
2906 err = -ENOMEM; 2922 num_flock_locks = 0;
2907 goto out_free;
2908 } 2923 }
2909 err = ceph_encode_locks_to_buffer(inode, flocks, 2924 if (num_fcntl_locks + num_flock_locks > 0) {
2910 num_fcntl_locks, 2925 flocks = kmalloc((num_fcntl_locks + num_flock_locks) *
2911 num_flock_locks); 2926 sizeof(struct ceph_filelock), GFP_NOFS);
2912 if (err) { 2927 if (!flocks) {
2928 err = -ENOMEM;
2929 goto out_free;
2930 }
2931 err = ceph_encode_locks_to_buffer(inode, flocks,
2932 num_fcntl_locks,
2933 num_flock_locks);
2934 if (err) {
2935 kfree(flocks);
2936 flocks = NULL;
2937 if (err == -ENOSPC)
2938 goto encode_again;
2939 goto out_free;
2940 }
2941 } else {
2913 kfree(flocks); 2942 kfree(flocks);
2914 if (err == -ENOSPC) 2943 flocks = NULL;
2915 goto encode_again;
2916 goto out_free;
2917 } 2944 }
2918 2945
2919 if (recon_state->msg_version >= 3) { 2946 if (recon_state->msg_version >= 3) {
@@ -2993,6 +3020,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
2993 int s_nr_caps; 3020 int s_nr_caps;
2994 struct ceph_pagelist *pagelist; 3021 struct ceph_pagelist *pagelist;
2995 struct ceph_reconnect_state recon_state; 3022 struct ceph_reconnect_state recon_state;
3023 LIST_HEAD(dispose);
2996 3024
2997 pr_info("mds%d reconnect start\n", mds); 3025 pr_info("mds%d reconnect start\n", mds);
2998 3026
@@ -3026,7 +3054,9 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc,
3026 */ 3054 */
3027 session->s_cap_reconnect = 1; 3055 session->s_cap_reconnect = 1;
3028 /* drop old cap expires; we're about to reestablish that state */ 3056 /* drop old cap expires; we're about to reestablish that state */
3029 cleanup_cap_releases(mdsc, session); 3057 detach_cap_releases(session, &dispose);
3058 spin_unlock(&session->s_cap_lock);
3059 dispose_cap_releases(mdsc, &dispose);
3030 3060
3031 /* trim unused caps to reduce MDS's cache rejoin time */ 3061 /* trim unused caps to reduce MDS's cache rejoin time */
3032 if (mdsc->fsc->sb->s_root) 3062 if (mdsc->fsc->sb->s_root)
@@ -3857,14 +3887,14 @@ void ceph_mdsc_handle_fsmap(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
3857 goto err_out; 3887 goto err_out;
3858 } 3888 }
3859 return; 3889 return;
3890
3860bad: 3891bad:
3861 pr_err("error decoding fsmap\n"); 3892 pr_err("error decoding fsmap\n");
3862err_out: 3893err_out:
3863 mutex_lock(&mdsc->mutex); 3894 mutex_lock(&mdsc->mutex);
3864 mdsc->mdsmap_err = -ENOENT; 3895 mdsc->mdsmap_err = err;
3865 __wake_requests(mdsc, &mdsc->waiting_for_map); 3896 __wake_requests(mdsc, &mdsc->waiting_for_map);
3866 mutex_unlock(&mdsc->mutex); 3897 mutex_unlock(&mdsc->mutex);
3867 return;
3868} 3898}
3869 3899
3870/* 3900/*
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index e4082afedcb1..fe9fbb3f13f7 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -84,8 +84,9 @@ static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf)
84 buf->f_ffree = -1; 84 buf->f_ffree = -1;
85 buf->f_namelen = NAME_MAX; 85 buf->f_namelen = NAME_MAX;
86 86
87 /* leave fsid little-endian, regardless of host endianness */ 87 /* Must convert the fsid, for consistent values across arches */
88 fsid = *(u64 *)(&monmap->fsid) ^ *((u64 *)&monmap->fsid + 1); 88 fsid = le64_to_cpu(*(__le64 *)(&monmap->fsid)) ^
89 le64_to_cpu(*((__le64 *)&monmap->fsid + 1));
89 buf->f_fsid.val[0] = fsid & 0xffffffff; 90 buf->f_fsid.val[0] = fsid & 0xffffffff;
90 buf->f_fsid.val[1] = fsid >> 32; 91 buf->f_fsid.val[1] = fsid >> 32;
91 92
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 3e27a28aa44a..2beeec07fa76 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -352,6 +352,7 @@ struct ceph_inode_info {
352 int i_pin_ref; 352 int i_pin_ref;
353 int i_rd_ref, i_rdcache_ref, i_wr_ref, i_wb_ref; 353 int i_rd_ref, i_rdcache_ref, i_wr_ref, i_wb_ref;
354 int i_wrbuffer_ref, i_wrbuffer_ref_head; 354 int i_wrbuffer_ref, i_wrbuffer_ref_head;
355 atomic_t i_filelock_ref;
355 u32 i_shared_gen; /* increment each time we get FILE_SHARED */ 356 u32 i_shared_gen; /* increment each time we get FILE_SHARED */
356 u32 i_rdcache_gen; /* incremented each time we get FILE_CACHE. */ 357 u32 i_rdcache_gen; /* incremented each time we get FILE_CACHE. */
357 u32 i_rdcache_revoking; /* RDCACHE gen to async invalidate, if any */ 358 u32 i_rdcache_revoking; /* RDCACHE gen to async invalidate, if any */
@@ -487,6 +488,8 @@ static inline struct inode *ceph_find_inode(struct super_block *sb,
487#define CEPH_I_KICK_FLUSH (1 << 9) /* kick flushing caps */ 488#define CEPH_I_KICK_FLUSH (1 << 9) /* kick flushing caps */
488#define CEPH_I_FLUSH_SNAPS (1 << 10) /* need flush snapss */ 489#define CEPH_I_FLUSH_SNAPS (1 << 10) /* need flush snapss */
489#define CEPH_I_ERROR_WRITE (1 << 11) /* have seen write errors */ 490#define CEPH_I_ERROR_WRITE (1 << 11) /* have seen write errors */
491#define CEPH_I_ERROR_FILELOCK (1 << 12) /* have seen file lock errors */
492
490 493
491/* 494/*
492 * We set the ERROR_WRITE bit when we start seeing write errors on an inode 495 * We set the ERROR_WRITE bit when we start seeing write errors on an inode
@@ -1011,7 +1014,6 @@ extern int ceph_encode_locks_to_buffer(struct inode *inode,
1011extern int ceph_locks_to_pagelist(struct ceph_filelock *flocks, 1014extern int ceph_locks_to_pagelist(struct ceph_filelock *flocks,
1012 struct ceph_pagelist *pagelist, 1015 struct ceph_pagelist *pagelist,
1013 int num_fcntl_locks, int num_flock_locks); 1016 int num_fcntl_locks, int num_flock_locks);
1014extern int lock_to_ceph_filelock(struct file_lock *fl, struct ceph_filelock *c);
1015 1017
1016/* debugfs.c */ 1018/* debugfs.c */
1017extern int ceph_fs_debugfs_init(struct ceph_fs_client *client); 1019extern int ceph_fs_debugfs_init(struct ceph_fs_client *client);
diff --git a/net/ceph/ceph_hash.c b/net/ceph/ceph_hash.c
index 67bb1f11e613..9a5850f264ed 100644
--- a/net/ceph/ceph_hash.c
+++ b/net/ceph/ceph_hash.c
@@ -47,28 +47,38 @@ unsigned int ceph_str_hash_rjenkins(const char *str, unsigned int length)
47 47
48 /* handle the last 11 bytes */ 48 /* handle the last 11 bytes */
49 c = c + length; 49 c = c + length;
50 switch (len) { /* all the case statements fall through */ 50 switch (len) {
51 case 11: 51 case 11:
52 c = c + ((__u32)k[10] << 24); 52 c = c + ((__u32)k[10] << 24);
53 /* fall through */
53 case 10: 54 case 10:
54 c = c + ((__u32)k[9] << 16); 55 c = c + ((__u32)k[9] << 16);
56 /* fall through */
55 case 9: 57 case 9:
56 c = c + ((__u32)k[8] << 8); 58 c = c + ((__u32)k[8] << 8);
57 /* the first byte of c is reserved for the length */ 59 /* the first byte of c is reserved for the length */
60 /* fall through */
58 case 8: 61 case 8:
59 b = b + ((__u32)k[7] << 24); 62 b = b + ((__u32)k[7] << 24);
63 /* fall through */
60 case 7: 64 case 7:
61 b = b + ((__u32)k[6] << 16); 65 b = b + ((__u32)k[6] << 16);
66 /* fall through */
62 case 6: 67 case 6:
63 b = b + ((__u32)k[5] << 8); 68 b = b + ((__u32)k[5] << 8);
69 /* fall through */
64 case 5: 70 case 5:
65 b = b + k[4]; 71 b = b + k[4];
72 /* fall through */
66 case 4: 73 case 4:
67 a = a + ((__u32)k[3] << 24); 74 a = a + ((__u32)k[3] << 24);
75 /* fall through */
68 case 3: 76 case 3:
69 a = a + ((__u32)k[2] << 16); 77 a = a + ((__u32)k[2] << 16);
78 /* fall through */
70 case 2: 79 case 2:
71 a = a + ((__u32)k[1] << 8); 80 a = a + ((__u32)k[1] << 8);
81 /* fall through */
72 case 1: 82 case 1:
73 a = a + k[0]; 83 a = a + k[0];
74 /* case 0: nothing left to add */ 84 /* case 0: nothing left to add */
diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
index 489610ac1cdd..bf9d079cbafd 100644
--- a/net/ceph/crypto.c
+++ b/net/ceph/crypto.c
@@ -37,7 +37,9 @@ static int set_secret(struct ceph_crypto_key *key, void *buf)
37 return -ENOTSUPP; 37 return -ENOTSUPP;
38 } 38 }
39 39
40 WARN_ON(!key->len); 40 if (!key->len)
41 return -EINVAL;
42
41 key->key = kmemdup(buf, key->len, GFP_NOIO); 43 key->key = kmemdup(buf, key->len, GFP_NOIO);
42 if (!key->key) { 44 if (!key->key) {
43 ret = -ENOMEM; 45 ret = -ENOMEM;
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index ad93342c90d7..8a4d3758030b 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -430,6 +430,7 @@ static void ceph_sock_state_change(struct sock *sk)
430 switch (sk->sk_state) { 430 switch (sk->sk_state) {
431 case TCP_CLOSE: 431 case TCP_CLOSE:
432 dout("%s TCP_CLOSE\n", __func__); 432 dout("%s TCP_CLOSE\n", __func__);
433 /* fall through */
433 case TCP_CLOSE_WAIT: 434 case TCP_CLOSE_WAIT:
434 dout("%s TCP_CLOSE_WAIT\n", __func__); 435 dout("%s TCP_CLOSE_WAIT\n", __func__);
435 con_sock_state_closing(con); 436 con_sock_state_closing(con);
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
index 9ae1bab8c05d..1547107f4854 100644
--- a/net/ceph/mon_client.c
+++ b/net/ceph/mon_client.c
@@ -1279,9 +1279,10 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con,
1279 1279
1280 /* 1280 /*
1281 * Older OSDs don't set reply tid even if the orignal 1281 * Older OSDs don't set reply tid even if the orignal
1282 * request had a non-zero tid. Workaround this weirdness 1282 * request had a non-zero tid. Work around this weirdness
1283 * by falling through to the allocate case. 1283 * by allocating a new message.
1284 */ 1284 */
1285 /* fall through */
1285 case CEPH_MSG_MON_MAP: 1286 case CEPH_MSG_MON_MAP:
1286 case CEPH_MSG_MDS_MAP: 1287 case CEPH_MSG_MDS_MAP:
1287 case CEPH_MSG_OSD_MAP: 1288 case CEPH_MSG_OSD_MAP: