diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-13 14:21:50 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-13 14:21:50 -0400 |
| commit | ffdb8f1bfbd9cef1394f5d3c4a774015d4ac0f97 (patch) | |
| tree | 4c7b06a4df4e3fc18e63df33230080a419f7c606 | |
| parent | 80dadf86d607bc5f25cc384ac590ef8b49ae523a (diff) | |
| parent | 0c1f91f27140cf3b6e38dc4e892adac241c73a20 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
ceph: unwind canceled flock state
ceph: fix ENOENT logic in striped_read
ceph: fix short sync reads from the OSD
ceph: fix sync vs canceled write
ceph: use ihold when we already have an inode ref
| -rw-r--r-- | fs/ceph/addr.c | 2 | ||||
| -rw-r--r-- | fs/ceph/caps.c | 10 | ||||
| -rw-r--r-- | fs/ceph/dir.c | 11 | ||||
| -rw-r--r-- | fs/ceph/export.c | 4 | ||||
| -rw-r--r-- | fs/ceph/file.c | 35 | ||||
| -rw-r--r-- | fs/ceph/inode.c | 18 | ||||
| -rw-r--r-- | fs/ceph/ioctl.c | 6 | ||||
| -rw-r--r-- | fs/ceph/locks.c | 29 | ||||
| -rw-r--r-- | fs/ceph/snap.c | 2 | ||||
| -rw-r--r-- | fs/ceph/xattr.c | 6 | ||||
| -rw-r--r-- | net/ceph/osd_client.c | 15 |
11 files changed, 80 insertions, 58 deletions
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 33da49dc3cc6..5a3953db8118 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
| @@ -453,7 +453,7 @@ static int ceph_writepage(struct page *page, struct writeback_control *wbc) | |||
| 453 | int err; | 453 | int err; |
| 454 | struct inode *inode = page->mapping->host; | 454 | struct inode *inode = page->mapping->host; |
| 455 | BUG_ON(!inode); | 455 | BUG_ON(!inode); |
| 456 | igrab(inode); | 456 | ihold(inode); |
| 457 | err = writepage_nounlock(page, wbc); | 457 | err = writepage_nounlock(page, wbc); |
| 458 | unlock_page(page); | 458 | unlock_page(page); |
| 459 | iput(inode); | 459 | iput(inode); |
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 1f72b00447c4..f605753c8fe9 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
| @@ -2940,14 +2940,12 @@ void ceph_flush_dirty_caps(struct ceph_mds_client *mdsc) | |||
| 2940 | while (!list_empty(&mdsc->cap_dirty)) { | 2940 | while (!list_empty(&mdsc->cap_dirty)) { |
| 2941 | ci = list_first_entry(&mdsc->cap_dirty, struct ceph_inode_info, | 2941 | ci = list_first_entry(&mdsc->cap_dirty, struct ceph_inode_info, |
| 2942 | i_dirty_item); | 2942 | i_dirty_item); |
| 2943 | inode = igrab(&ci->vfs_inode); | 2943 | inode = &ci->vfs_inode; |
| 2944 | ihold(inode); | ||
| 2944 | dout("flush_dirty_caps %p\n", inode); | 2945 | dout("flush_dirty_caps %p\n", inode); |
| 2945 | spin_unlock(&mdsc->cap_dirty_lock); | 2946 | spin_unlock(&mdsc->cap_dirty_lock); |
| 2946 | if (inode) { | 2947 | ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH, NULL); |
| 2947 | ceph_check_caps(ci, CHECK_CAPS_NODELAY|CHECK_CAPS_FLUSH, | 2948 | iput(inode); |
| 2948 | NULL); | ||
| 2949 | iput(inode); | ||
| 2950 | } | ||
| 2951 | spin_lock(&mdsc->cap_dirty_lock); | 2949 | spin_lock(&mdsc->cap_dirty_lock); |
| 2952 | } | 2950 | } |
| 2953 | spin_unlock(&mdsc->cap_dirty_lock); | 2951 | spin_unlock(&mdsc->cap_dirty_lock); |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 33729e822bb9..ef8f08c343e8 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
| @@ -308,7 +308,8 @@ more: | |||
| 308 | req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); | 308 | req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS); |
| 309 | if (IS_ERR(req)) | 309 | if (IS_ERR(req)) |
| 310 | return PTR_ERR(req); | 310 | return PTR_ERR(req); |
| 311 | req->r_inode = igrab(inode); | 311 | req->r_inode = inode; |
| 312 | ihold(inode); | ||
| 312 | req->r_dentry = dget(filp->f_dentry); | 313 | req->r_dentry = dget(filp->f_dentry); |
| 313 | /* hints to request -> mds selection code */ | 314 | /* hints to request -> mds selection code */ |
| 314 | req->r_direct_mode = USE_AUTH_MDS; | 315 | req->r_direct_mode = USE_AUTH_MDS; |
| @@ -787,10 +788,12 @@ static int ceph_link(struct dentry *old_dentry, struct inode *dir, | |||
| 787 | req->r_dentry_drop = CEPH_CAP_FILE_SHARED; | 788 | req->r_dentry_drop = CEPH_CAP_FILE_SHARED; |
| 788 | req->r_dentry_unless = CEPH_CAP_FILE_EXCL; | 789 | req->r_dentry_unless = CEPH_CAP_FILE_EXCL; |
| 789 | err = ceph_mdsc_do_request(mdsc, dir, req); | 790 | err = ceph_mdsc_do_request(mdsc, dir, req); |
| 790 | if (err) | 791 | if (err) { |
| 791 | d_drop(dentry); | 792 | d_drop(dentry); |
| 792 | else if (!req->r_reply_info.head->is_dentry) | 793 | } else if (!req->r_reply_info.head->is_dentry) { |
| 793 | d_instantiate(dentry, igrab(old_dentry->d_inode)); | 794 | ihold(old_dentry->d_inode); |
| 795 | d_instantiate(dentry, old_dentry->d_inode); | ||
| 796 | } | ||
| 794 | ceph_mdsc_put_request(req); | 797 | ceph_mdsc_put_request(req); |
| 795 | return err; | 798 | return err; |
| 796 | } | 799 | } |
diff --git a/fs/ceph/export.c b/fs/ceph/export.c index a610d3d67488..f67b687550de 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c | |||
| @@ -109,7 +109,7 @@ static struct dentry *__fh_to_dentry(struct super_block *sb, | |||
| 109 | err = ceph_mdsc_do_request(mdsc, NULL, req); | 109 | err = ceph_mdsc_do_request(mdsc, NULL, req); |
| 110 | inode = req->r_target_inode; | 110 | inode = req->r_target_inode; |
| 111 | if (inode) | 111 | if (inode) |
| 112 | igrab(inode); | 112 | ihold(inode); |
| 113 | ceph_mdsc_put_request(req); | 113 | ceph_mdsc_put_request(req); |
| 114 | if (!inode) | 114 | if (!inode) |
| 115 | return ERR_PTR(-ESTALE); | 115 | return ERR_PTR(-ESTALE); |
| @@ -167,7 +167,7 @@ static struct dentry *__cfh_to_dentry(struct super_block *sb, | |||
| 167 | err = ceph_mdsc_do_request(mdsc, NULL, req); | 167 | err = ceph_mdsc_do_request(mdsc, NULL, req); |
| 168 | inode = req->r_target_inode; | 168 | inode = req->r_target_inode; |
| 169 | if (inode) | 169 | if (inode) |
| 170 | igrab(inode); | 170 | ihold(inode); |
| 171 | ceph_mdsc_put_request(req); | 171 | ceph_mdsc_put_request(req); |
| 172 | if (!inode) | 172 | if (!inode) |
| 173 | return ERR_PTR(err ? err : -ESTALE); | 173 | return ERR_PTR(err ? err : -ESTALE); |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 203252d88d9f..9542f07d0b93 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
| @@ -191,7 +191,8 @@ int ceph_open(struct inode *inode, struct file *file) | |||
| 191 | err = PTR_ERR(req); | 191 | err = PTR_ERR(req); |
| 192 | goto out; | 192 | goto out; |
| 193 | } | 193 | } |
| 194 | req->r_inode = igrab(inode); | 194 | req->r_inode = inode; |
| 195 | ihold(inode); | ||
| 195 | req->r_num_caps = 1; | 196 | req->r_num_caps = 1; |
| 196 | err = ceph_mdsc_do_request(mdsc, parent_inode, req); | 197 | err = ceph_mdsc_do_request(mdsc, parent_inode, req); |
| 197 | if (!err) | 198 | if (!err) |
| @@ -282,7 +283,7 @@ int ceph_release(struct inode *inode, struct file *file) | |||
| 282 | static int striped_read(struct inode *inode, | 283 | static int striped_read(struct inode *inode, |
| 283 | u64 off, u64 len, | 284 | u64 off, u64 len, |
| 284 | struct page **pages, int num_pages, | 285 | struct page **pages, int num_pages, |
| 285 | int *checkeof, bool align_to_pages, | 286 | int *checkeof, bool o_direct, |
| 286 | unsigned long buf_align) | 287 | unsigned long buf_align) |
| 287 | { | 288 | { |
| 288 | struct ceph_fs_client *fsc = ceph_inode_to_client(inode); | 289 | struct ceph_fs_client *fsc = ceph_inode_to_client(inode); |
| @@ -307,7 +308,7 @@ static int striped_read(struct inode *inode, | |||
| 307 | io_align = off & ~PAGE_MASK; | 308 | io_align = off & ~PAGE_MASK; |
| 308 | 309 | ||
| 309 | more: | 310 | more: |
| 310 | if (align_to_pages) | 311 | if (o_direct) |
| 311 | page_align = (pos - io_align + buf_align) & ~PAGE_MASK; | 312 | page_align = (pos - io_align + buf_align) & ~PAGE_MASK; |
| 312 | else | 313 | else |
| 313 | page_align = pos & ~PAGE_MASK; | 314 | page_align = pos & ~PAGE_MASK; |
| @@ -317,10 +318,10 @@ more: | |||
| 317 | ci->i_truncate_seq, | 318 | ci->i_truncate_seq, |
| 318 | ci->i_truncate_size, | 319 | ci->i_truncate_size, |
| 319 | page_pos, pages_left, page_align); | 320 | page_pos, pages_left, page_align); |
| 320 | hit_stripe = this_len < left; | ||
| 321 | was_short = ret >= 0 && ret < this_len; | ||
| 322 | if (ret == -ENOENT) | 321 | if (ret == -ENOENT) |
| 323 | ret = 0; | 322 | ret = 0; |
| 323 | hit_stripe = this_len < left; | ||
| 324 | was_short = ret >= 0 && ret < this_len; | ||
| 324 | dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read, | 325 | dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read, |
| 325 | ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : ""); | 326 | ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : ""); |
| 326 | 327 | ||
| @@ -345,20 +346,22 @@ more: | |||
| 345 | } | 346 | } |
| 346 | 347 | ||
| 347 | if (was_short) { | 348 | if (was_short) { |
| 348 | /* was original extent fully inside i_size? */ | 349 | /* did we bounce off eof? */ |
| 349 | if (pos + left <= inode->i_size) { | 350 | if (pos + left > inode->i_size) |
| 350 | dout("zero tail\n"); | 351 | *checkeof = 1; |
| 351 | ceph_zero_page_vector_range(page_off + read, len - read, | 352 | |
| 353 | /* zero trailing bytes (inside i_size) */ | ||
| 354 | if (left > 0 && pos < inode->i_size) { | ||
| 355 | if (pos + left > inode->i_size) | ||
| 356 | left = inode->i_size - pos; | ||
| 357 | |||
| 358 | dout("zero tail %d\n", left); | ||
| 359 | ceph_zero_page_vector_range(page_off + read, left, | ||
| 352 | pages); | 360 | pages); |
| 353 | read = len; | 361 | read += left; |
| 354 | goto out; | ||
| 355 | } | 362 | } |
| 356 | |||
| 357 | /* check i_size */ | ||
| 358 | *checkeof = 1; | ||
| 359 | } | 363 | } |
| 360 | 364 | ||
| 361 | out: | ||
| 362 | if (ret >= 0) | 365 | if (ret >= 0) |
| 363 | ret = read; | 366 | ret = read; |
| 364 | dout("striped_read returns %d\n", ret); | 367 | dout("striped_read returns %d\n", ret); |
| @@ -658,7 +661,7 @@ out: | |||
| 658 | 661 | ||
| 659 | /* hit EOF or hole? */ | 662 | /* hit EOF or hole? */ |
| 660 | if (statret == 0 && *ppos < inode->i_size) { | 663 | if (statret == 0 && *ppos < inode->i_size) { |
| 661 | dout("aio_read sync_read hit hole, reading more\n"); | 664 | dout("aio_read sync_read hit hole, ppos %lld < size %lld, reading more\n", *ppos, inode->i_size); |
| 662 | read += ret; | 665 | read += ret; |
| 663 | base += ret; | 666 | base += ret; |
| 664 | len -= ret; | 667 | len -= ret; |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 70b6a4839c38..d8858e96ab18 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
| @@ -1101,10 +1101,10 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
| 1101 | goto done; | 1101 | goto done; |
| 1102 | } | 1102 | } |
| 1103 | req->r_dentry = dn; /* may have spliced */ | 1103 | req->r_dentry = dn; /* may have spliced */ |
| 1104 | igrab(in); | 1104 | ihold(in); |
| 1105 | } else if (ceph_ino(in) == vino.ino && | 1105 | } else if (ceph_ino(in) == vino.ino && |
| 1106 | ceph_snap(in) == vino.snap) { | 1106 | ceph_snap(in) == vino.snap) { |
| 1107 | igrab(in); | 1107 | ihold(in); |
| 1108 | } else { | 1108 | } else { |
| 1109 | dout(" %p links to %p %llx.%llx, not %llx.%llx\n", | 1109 | dout(" %p links to %p %llx.%llx, not %llx.%llx\n", |
| 1110 | dn, in, ceph_ino(in), ceph_snap(in), | 1110 | dn, in, ceph_ino(in), ceph_snap(in), |
| @@ -1144,7 +1144,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
| 1144 | goto done; | 1144 | goto done; |
| 1145 | } | 1145 | } |
| 1146 | req->r_dentry = dn; /* may have spliced */ | 1146 | req->r_dentry = dn; /* may have spliced */ |
| 1147 | igrab(in); | 1147 | ihold(in); |
| 1148 | rinfo->head->is_dentry = 1; /* fool notrace handlers */ | 1148 | rinfo->head->is_dentry = 1; /* fool notrace handlers */ |
| 1149 | } | 1149 | } |
| 1150 | 1150 | ||
| @@ -1328,7 +1328,7 @@ void ceph_queue_writeback(struct inode *inode) | |||
| 1328 | if (queue_work(ceph_inode_to_client(inode)->wb_wq, | 1328 | if (queue_work(ceph_inode_to_client(inode)->wb_wq, |
| 1329 | &ceph_inode(inode)->i_wb_work)) { | 1329 | &ceph_inode(inode)->i_wb_work)) { |
| 1330 | dout("ceph_queue_writeback %p\n", inode); | 1330 | dout("ceph_queue_writeback %p\n", inode); |
| 1331 | igrab(inode); | 1331 | ihold(inode); |
| 1332 | } else { | 1332 | } else { |
| 1333 | dout("ceph_queue_writeback %p failed\n", inode); | 1333 | dout("ceph_queue_writeback %p failed\n", inode); |
| 1334 | } | 1334 | } |
| @@ -1353,7 +1353,7 @@ void ceph_queue_invalidate(struct inode *inode) | |||
| 1353 | if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq, | 1353 | if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq, |
| 1354 | &ceph_inode(inode)->i_pg_inv_work)) { | 1354 | &ceph_inode(inode)->i_pg_inv_work)) { |
| 1355 | dout("ceph_queue_invalidate %p\n", inode); | 1355 | dout("ceph_queue_invalidate %p\n", inode); |
| 1356 | igrab(inode); | 1356 | ihold(inode); |
| 1357 | } else { | 1357 | } else { |
| 1358 | dout("ceph_queue_invalidate %p failed\n", inode); | 1358 | dout("ceph_queue_invalidate %p failed\n", inode); |
| 1359 | } | 1359 | } |
| @@ -1477,7 +1477,7 @@ void ceph_queue_vmtruncate(struct inode *inode) | |||
| 1477 | if (queue_work(ceph_sb_to_client(inode->i_sb)->trunc_wq, | 1477 | if (queue_work(ceph_sb_to_client(inode->i_sb)->trunc_wq, |
| 1478 | &ci->i_vmtruncate_work)) { | 1478 | &ci->i_vmtruncate_work)) { |
| 1479 | dout("ceph_queue_vmtruncate %p\n", inode); | 1479 | dout("ceph_queue_vmtruncate %p\n", inode); |
| 1480 | igrab(inode); | 1480 | ihold(inode); |
| 1481 | } else { | 1481 | } else { |
| 1482 | dout("ceph_queue_vmtruncate %p failed, pending=%d\n", | 1482 | dout("ceph_queue_vmtruncate %p failed, pending=%d\n", |
| 1483 | inode, ci->i_truncate_pending); | 1483 | inode, ci->i_truncate_pending); |
| @@ -1738,7 +1738,8 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 1738 | __mark_inode_dirty(inode, inode_dirty_flags); | 1738 | __mark_inode_dirty(inode, inode_dirty_flags); |
| 1739 | 1739 | ||
| 1740 | if (mask) { | 1740 | if (mask) { |
| 1741 | req->r_inode = igrab(inode); | 1741 | req->r_inode = inode; |
| 1742 | ihold(inode); | ||
| 1742 | req->r_inode_drop = release; | 1743 | req->r_inode_drop = release; |
| 1743 | req->r_args.setattr.mask = cpu_to_le32(mask); | 1744 | req->r_args.setattr.mask = cpu_to_le32(mask); |
| 1744 | req->r_num_caps = 1; | 1745 | req->r_num_caps = 1; |
| @@ -1779,7 +1780,8 @@ int ceph_do_getattr(struct inode *inode, int mask) | |||
| 1779 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS); | 1780 | req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_GETATTR, USE_ANY_MDS); |
| 1780 | if (IS_ERR(req)) | 1781 | if (IS_ERR(req)) |
| 1781 | return PTR_ERR(req); | 1782 | return PTR_ERR(req); |
| 1782 | req->r_inode = igrab(inode); | 1783 | req->r_inode = inode; |
| 1784 | ihold(inode); | ||
| 1783 | req->r_num_caps = 1; | 1785 | req->r_num_caps = 1; |
| 1784 | req->r_args.getattr.mask = cpu_to_le32(mask); | 1786 | req->r_args.getattr.mask = cpu_to_le32(mask); |
| 1785 | err = ceph_mdsc_do_request(mdsc, NULL, req); | 1787 | err = ceph_mdsc_do_request(mdsc, NULL, req); |
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c index 8888c9ba68db..ef0b5f48e13a 100644 --- a/fs/ceph/ioctl.c +++ b/fs/ceph/ioctl.c | |||
| @@ -73,7 +73,8 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg) | |||
| 73 | USE_AUTH_MDS); | 73 | USE_AUTH_MDS); |
| 74 | if (IS_ERR(req)) | 74 | if (IS_ERR(req)) |
| 75 | return PTR_ERR(req); | 75 | return PTR_ERR(req); |
| 76 | req->r_inode = igrab(inode); | 76 | req->r_inode = inode; |
| 77 | ihold(inode); | ||
| 77 | req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL; | 78 | req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL; |
| 78 | 79 | ||
| 79 | req->r_args.setlayout.layout.fl_stripe_unit = | 80 | req->r_args.setlayout.layout.fl_stripe_unit = |
| @@ -135,7 +136,8 @@ static long ceph_ioctl_set_layout_policy (struct file *file, void __user *arg) | |||
| 135 | 136 | ||
| 136 | if (IS_ERR(req)) | 137 | if (IS_ERR(req)) |
| 137 | return PTR_ERR(req); | 138 | return PTR_ERR(req); |
| 138 | req->r_inode = igrab(inode); | 139 | req->r_inode = inode; |
| 140 | ihold(inode); | ||
| 139 | 141 | ||
| 140 | req->r_args.setlayout.layout.fl_stripe_unit = | 142 | req->r_args.setlayout.layout.fl_stripe_unit = |
| 141 | cpu_to_le32(l.stripe_unit); | 143 | cpu_to_le32(l.stripe_unit); |
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index 476b329867d4..80576d05d687 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
| @@ -23,7 +23,8 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | |||
| 23 | req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS); | 23 | req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS); |
| 24 | if (IS_ERR(req)) | 24 | if (IS_ERR(req)) |
| 25 | return PTR_ERR(req); | 25 | return PTR_ERR(req); |
| 26 | req->r_inode = igrab(inode); | 26 | req->r_inode = inode; |
| 27 | ihold(inode); | ||
| 27 | 28 | ||
| 28 | /* mds requires start and length rather than start and end */ | 29 | /* mds requires start and length rather than start and end */ |
| 29 | if (LLONG_MAX == fl->fl_end) | 30 | if (LLONG_MAX == fl->fl_end) |
| @@ -32,11 +33,10 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | |||
| 32 | length = fl->fl_end - fl->fl_start + 1; | 33 | length = fl->fl_end - fl->fl_start + 1; |
| 33 | 34 | ||
| 34 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " | 35 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " |
| 35 | "length: %llu, wait: %d, type`: %d", (int)lock_type, | 36 | "length: %llu, wait: %d, type: %d", (int)lock_type, |
| 36 | (int)operation, (u64)fl->fl_pid, fl->fl_start, | 37 | (int)operation, (u64)fl->fl_pid, fl->fl_start, |
| 37 | length, wait, fl->fl_type); | 38 | length, wait, fl->fl_type); |
| 38 | 39 | ||
| 39 | |||
| 40 | req->r_args.filelock_change.rule = lock_type; | 40 | req->r_args.filelock_change.rule = lock_type; |
| 41 | req->r_args.filelock_change.type = cmd; | 41 | req->r_args.filelock_change.type = cmd; |
| 42 | req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid); | 42 | req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid); |
| @@ -70,7 +70,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | |||
| 70 | } | 70 | } |
| 71 | ceph_mdsc_put_request(req); | 71 | ceph_mdsc_put_request(req); |
| 72 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " | 72 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " |
| 73 | "length: %llu, wait: %d, type`: %d, err code %d", (int)lock_type, | 73 | "length: %llu, wait: %d, type: %d, err code %d", (int)lock_type, |
| 74 | (int)operation, (u64)fl->fl_pid, fl->fl_start, | 74 | (int)operation, (u64)fl->fl_pid, fl->fl_start, |
| 75 | length, wait, fl->fl_type, err); | 75 | length, wait, fl->fl_type, err); |
| 76 | return err; | 76 | return err; |
| @@ -109,16 +109,20 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) | |||
| 109 | dout("mds locked, locking locally"); | 109 | dout("mds locked, locking locally"); |
| 110 | err = posix_lock_file(file, fl, NULL); | 110 | err = posix_lock_file(file, fl, NULL); |
| 111 | if (err && (CEPH_MDS_OP_SETFILELOCK == op)) { | 111 | if (err && (CEPH_MDS_OP_SETFILELOCK == op)) { |
| 112 | /* undo! This should only happen if the kernel detects | 112 | /* undo! This should only happen if |
| 113 | * local deadlock. */ | 113 | * the kernel detects local |
| 114 | * deadlock. */ | ||
| 114 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, | 115 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, |
| 115 | CEPH_LOCK_UNLOCK, 0, fl); | 116 | CEPH_LOCK_UNLOCK, 0, fl); |
| 116 | dout("got %d on posix_lock_file, undid lock", err); | 117 | dout("got %d on posix_lock_file, undid lock", |
| 118 | err); | ||
| 117 | } | 119 | } |
| 118 | } | 120 | } |
| 119 | 121 | ||
| 120 | } else { | 122 | } else if (err == -ERESTARTSYS) { |
| 121 | dout("mds returned error code %d", err); | 123 | dout("undoing lock\n"); |
| 124 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, | ||
| 125 | CEPH_LOCK_UNLOCK, 0, fl); | ||
| 122 | } | 126 | } |
| 123 | return err; | 127 | return err; |
| 124 | } | 128 | } |
| @@ -155,8 +159,11 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) | |||
| 155 | file, CEPH_LOCK_UNLOCK, 0, fl); | 159 | file, CEPH_LOCK_UNLOCK, 0, fl); |
| 156 | dout("got %d on flock_lock_file_wait, undid lock", err); | 160 | dout("got %d on flock_lock_file_wait, undid lock", err); |
| 157 | } | 161 | } |
| 158 | } else { | 162 | } else if (err == -ERESTARTSYS) { |
| 159 | dout("mds error code %d", err); | 163 | dout("undoing lock\n"); |
| 164 | ceph_lock_message(CEPH_LOCK_FLOCK, | ||
| 165 | CEPH_MDS_OP_SETFILELOCK, | ||
| 166 | file, CEPH_LOCK_UNLOCK, 0, fl); | ||
| 160 | } | 167 | } |
| 161 | return err; | 168 | return err; |
| 162 | } | 169 | } |
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 24067d68a554..54b14de2e729 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c | |||
| @@ -722,7 +722,7 @@ static void flush_snaps(struct ceph_mds_client *mdsc) | |||
| 722 | ci = list_first_entry(&mdsc->snap_flush_list, | 722 | ci = list_first_entry(&mdsc->snap_flush_list, |
| 723 | struct ceph_inode_info, i_snap_flush_item); | 723 | struct ceph_inode_info, i_snap_flush_item); |
| 724 | inode = &ci->vfs_inode; | 724 | inode = &ci->vfs_inode; |
| 725 | igrab(inode); | 725 | ihold(inode); |
| 726 | spin_unlock(&mdsc->snap_flush_lock); | 726 | spin_unlock(&mdsc->snap_flush_lock); |
| 727 | spin_lock(&inode->i_lock); | 727 | spin_lock(&inode->i_lock); |
| 728 | __ceph_flush_snaps(ci, &session, 0); | 728 | __ceph_flush_snaps(ci, &session, 0); |
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index f2b628696180..f42d730f1b66 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
| @@ -665,7 +665,8 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name, | |||
| 665 | err = PTR_ERR(req); | 665 | err = PTR_ERR(req); |
| 666 | goto out; | 666 | goto out; |
| 667 | } | 667 | } |
| 668 | req->r_inode = igrab(inode); | 668 | req->r_inode = inode; |
| 669 | ihold(inode); | ||
| 669 | req->r_inode_drop = CEPH_CAP_XATTR_SHARED; | 670 | req->r_inode_drop = CEPH_CAP_XATTR_SHARED; |
| 670 | req->r_num_caps = 1; | 671 | req->r_num_caps = 1; |
| 671 | req->r_args.setxattr.flags = cpu_to_le32(flags); | 672 | req->r_args.setxattr.flags = cpu_to_le32(flags); |
| @@ -795,7 +796,8 @@ static int ceph_send_removexattr(struct dentry *dentry, const char *name) | |||
| 795 | USE_AUTH_MDS); | 796 | USE_AUTH_MDS); |
| 796 | if (IS_ERR(req)) | 797 | if (IS_ERR(req)) |
| 797 | return PTR_ERR(req); | 798 | return PTR_ERR(req); |
| 798 | req->r_inode = igrab(inode); | 799 | req->r_inode = inode; |
| 800 | ihold(inode); | ||
| 799 | req->r_inode_drop = CEPH_CAP_XATTR_SHARED; | 801 | req->r_inode_drop = CEPH_CAP_XATTR_SHARED; |
| 800 | req->r_num_caps = 1; | 802 | req->r_num_caps = 1; |
| 801 | req->r_path2 = kstrdup(name, GFP_NOFS); | 803 | req->r_path2 = kstrdup(name, GFP_NOFS); |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 6ea2b892f44b..9cb627a4073a 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
| @@ -1144,6 +1144,13 @@ static void handle_osds_timeout(struct work_struct *work) | |||
| 1144 | round_jiffies_relative(delay)); | 1144 | round_jiffies_relative(delay)); |
| 1145 | } | 1145 | } |
| 1146 | 1146 | ||
| 1147 | static void complete_request(struct ceph_osd_request *req) | ||
| 1148 | { | ||
| 1149 | if (req->r_safe_callback) | ||
| 1150 | req->r_safe_callback(req, NULL); | ||
| 1151 | complete_all(&req->r_safe_completion); /* fsync waiter */ | ||
| 1152 | } | ||
| 1153 | |||
| 1147 | /* | 1154 | /* |
| 1148 | * handle osd op reply. either call the callback if it is specified, | 1155 | * handle osd op reply. either call the callback if it is specified, |
| 1149 | * or do the completion to wake up the waiting thread. | 1156 | * or do the completion to wake up the waiting thread. |
| @@ -1226,11 +1233,8 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, | |||
| 1226 | else | 1233 | else |
| 1227 | complete_all(&req->r_completion); | 1234 | complete_all(&req->r_completion); |
| 1228 | 1235 | ||
| 1229 | if (flags & CEPH_OSD_FLAG_ONDISK) { | 1236 | if (flags & CEPH_OSD_FLAG_ONDISK) |
| 1230 | if (req->r_safe_callback) | 1237 | complete_request(req); |
| 1231 | req->r_safe_callback(req, msg); | ||
| 1232 | complete_all(&req->r_safe_completion); /* fsync waiter */ | ||
| 1233 | } | ||
| 1234 | 1238 | ||
| 1235 | done: | 1239 | done: |
| 1236 | dout("req=%p req->r_linger=%d\n", req, req->r_linger); | 1240 | dout("req=%p req->r_linger=%d\n", req, req->r_linger); |
| @@ -1732,6 +1736,7 @@ int ceph_osdc_wait_request(struct ceph_osd_client *osdc, | |||
| 1732 | __cancel_request(req); | 1736 | __cancel_request(req); |
| 1733 | __unregister_request(osdc, req); | 1737 | __unregister_request(osdc, req); |
| 1734 | mutex_unlock(&osdc->request_mutex); | 1738 | mutex_unlock(&osdc->request_mutex); |
| 1739 | complete_request(req); | ||
| 1735 | dout("wait_request tid %llu canceled/timed out\n", req->r_tid); | 1740 | dout("wait_request tid %llu canceled/timed out\n", req->r_tid); |
| 1736 | return rc; | 1741 | return rc; |
| 1737 | } | 1742 | } |
