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 | } |