diff options
author | Alex Elder <elder@inktank.com> | 2013-01-30 08:54:34 -0500 |
---|---|---|
committer | Alex Elder <elder@inktank.com> | 2013-01-30 08:54:34 -0500 |
commit | 969e5aa3b0162a02c4f287d48ff58ca2145acf1b (patch) | |
tree | 1af8e8e47e7352c6d3b4abfdb4aea6bd9458666f /fs/ceph | |
parent | 949db153b6466c6f7cad5a427ecea94985927311 (diff) | |
parent | 1ec3911dbd19076bcdfe5540096ff67f91a6ec02 (diff) |
Merge branch 'testing' of github.com:ceph/ceph-client into v3.8-rc5-testing
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/caps.c | 32 | ||||
-rw-r--r-- | fs/ceph/file.c | 6 | ||||
-rw-r--r-- | fs/ceph/ioctl.c | 2 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 33 | ||||
-rw-r--r-- | fs/ceph/mds_client.h | 6 |
5 files changed, 69 insertions, 10 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index a1d9bb30c1bf..1e1e02055a2b 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -611,8 +611,16 @@ retry: | |||
611 | 611 | ||
612 | if (flags & CEPH_CAP_FLAG_AUTH) | 612 | if (flags & CEPH_CAP_FLAG_AUTH) |
613 | ci->i_auth_cap = cap; | 613 | ci->i_auth_cap = cap; |
614 | else if (ci->i_auth_cap == cap) | 614 | else if (ci->i_auth_cap == cap) { |
615 | ci->i_auth_cap = NULL; | 615 | ci->i_auth_cap = NULL; |
616 | spin_lock(&mdsc->cap_dirty_lock); | ||
617 | if (!list_empty(&ci->i_dirty_item)) { | ||
618 | dout(" moving %p to cap_dirty_migrating\n", inode); | ||
619 | list_move(&ci->i_dirty_item, | ||
620 | &mdsc->cap_dirty_migrating); | ||
621 | } | ||
622 | spin_unlock(&mdsc->cap_dirty_lock); | ||
623 | } | ||
616 | 624 | ||
617 | dout("add_cap inode %p (%llx.%llx) cap %p %s now %s seq %d mds%d\n", | 625 | dout("add_cap inode %p (%llx.%llx) cap %p %s now %s seq %d mds%d\n", |
618 | inode, ceph_vinop(inode), cap, ceph_cap_string(issued), | 626 | inode, ceph_vinop(inode), cap, ceph_cap_string(issued), |
@@ -1460,7 +1468,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags, | |||
1460 | struct ceph_mds_client *mdsc = fsc->mdsc; | 1468 | struct ceph_mds_client *mdsc = fsc->mdsc; |
1461 | struct inode *inode = &ci->vfs_inode; | 1469 | struct inode *inode = &ci->vfs_inode; |
1462 | struct ceph_cap *cap; | 1470 | struct ceph_cap *cap; |
1463 | int file_wanted, used; | 1471 | int file_wanted, used, cap_used; |
1464 | int took_snap_rwsem = 0; /* true if mdsc->snap_rwsem held */ | 1472 | int took_snap_rwsem = 0; /* true if mdsc->snap_rwsem held */ |
1465 | int issued, implemented, want, retain, revoking, flushing = 0; | 1473 | int issued, implemented, want, retain, revoking, flushing = 0; |
1466 | int mds = -1; /* keep track of how far we've gone through i_caps list | 1474 | int mds = -1; /* keep track of how far we've gone through i_caps list |
@@ -1563,9 +1571,14 @@ retry_locked: | |||
1563 | 1571 | ||
1564 | /* NOTE: no side-effects allowed, until we take s_mutex */ | 1572 | /* NOTE: no side-effects allowed, until we take s_mutex */ |
1565 | 1573 | ||
1574 | cap_used = used; | ||
1575 | if (ci->i_auth_cap && cap != ci->i_auth_cap) | ||
1576 | cap_used &= ~ci->i_auth_cap->issued; | ||
1577 | |||
1566 | revoking = cap->implemented & ~cap->issued; | 1578 | revoking = cap->implemented & ~cap->issued; |
1567 | dout(" mds%d cap %p issued %s implemented %s revoking %s\n", | 1579 | dout(" mds%d cap %p used %s issued %s implemented %s revoking %s\n", |
1568 | cap->mds, cap, ceph_cap_string(cap->issued), | 1580 | cap->mds, cap, ceph_cap_string(cap->issued), |
1581 | ceph_cap_string(cap_used), | ||
1569 | ceph_cap_string(cap->implemented), | 1582 | ceph_cap_string(cap->implemented), |
1570 | ceph_cap_string(revoking)); | 1583 | ceph_cap_string(revoking)); |
1571 | 1584 | ||
@@ -1593,7 +1606,7 @@ retry_locked: | |||
1593 | } | 1606 | } |
1594 | 1607 | ||
1595 | /* completed revocation? going down and there are no caps? */ | 1608 | /* completed revocation? going down and there are no caps? */ |
1596 | if (revoking && (revoking & used) == 0) { | 1609 | if (revoking && (revoking & cap_used) == 0) { |
1597 | dout("completed revocation of %s\n", | 1610 | dout("completed revocation of %s\n", |
1598 | ceph_cap_string(cap->implemented & ~cap->issued)); | 1611 | ceph_cap_string(cap->implemented & ~cap->issued)); |
1599 | goto ack; | 1612 | goto ack; |
@@ -1670,8 +1683,8 @@ ack: | |||
1670 | sent++; | 1683 | sent++; |
1671 | 1684 | ||
1672 | /* __send_cap drops i_ceph_lock */ | 1685 | /* __send_cap drops i_ceph_lock */ |
1673 | delayed += __send_cap(mdsc, cap, CEPH_CAP_OP_UPDATE, used, want, | 1686 | delayed += __send_cap(mdsc, cap, CEPH_CAP_OP_UPDATE, cap_used, |
1674 | retain, flushing, NULL); | 1687 | want, retain, flushing, NULL); |
1675 | goto retry; /* retake i_ceph_lock and restart our cap scan. */ | 1688 | goto retry; /* retake i_ceph_lock and restart our cap scan. */ |
1676 | } | 1689 | } |
1677 | 1690 | ||
@@ -2416,7 +2429,9 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, | |||
2416 | dout("mds wanted %s -> %s\n", | 2429 | dout("mds wanted %s -> %s\n", |
2417 | ceph_cap_string(le32_to_cpu(grant->wanted)), | 2430 | ceph_cap_string(le32_to_cpu(grant->wanted)), |
2418 | ceph_cap_string(wanted)); | 2431 | ceph_cap_string(wanted)); |
2419 | grant->wanted = cpu_to_le32(wanted); | 2432 | /* imported cap may not have correct mds_wanted */ |
2433 | if (le32_to_cpu(grant->op) == CEPH_CAP_OP_IMPORT) | ||
2434 | check_caps = 1; | ||
2420 | } | 2435 | } |
2421 | 2436 | ||
2422 | cap->seq = seq; | 2437 | cap->seq = seq; |
@@ -2820,6 +2835,9 @@ void ceph_handle_caps(struct ceph_mds_session *session, | |||
2820 | dout(" mds%d seq %lld cap seq %u\n", session->s_mds, session->s_seq, | 2835 | dout(" mds%d seq %lld cap seq %u\n", session->s_mds, session->s_seq, |
2821 | (unsigned)seq); | 2836 | (unsigned)seq); |
2822 | 2837 | ||
2838 | if (op == CEPH_CAP_OP_IMPORT) | ||
2839 | ceph_add_cap_releases(mdsc, session); | ||
2840 | |||
2823 | /* lookup ino */ | 2841 | /* lookup ino */ |
2824 | inode = ceph_find_inode(sb, vino); | 2842 | inode = ceph_find_inode(sb, vino); |
2825 | ci = ceph_inode(inode); | 2843 | ci = ceph_inode(inode); |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index e51558fca3a3..a1e5b81e8118 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -243,6 +243,9 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, | |||
243 | err = ceph_mdsc_do_request(mdsc, | 243 | err = ceph_mdsc_do_request(mdsc, |
244 | (flags & (O_CREAT|O_TRUNC)) ? dir : NULL, | 244 | (flags & (O_CREAT|O_TRUNC)) ? dir : NULL, |
245 | req); | 245 | req); |
246 | if (err) | ||
247 | goto out_err; | ||
248 | |||
246 | err = ceph_handle_snapdir(req, dentry, err); | 249 | err = ceph_handle_snapdir(req, dentry, err); |
247 | if (err == 0 && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry) | 250 | if (err == 0 && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry) |
248 | err = ceph_handle_notrace_create(dir, dentry); | 251 | err = ceph_handle_notrace_create(dir, dentry); |
@@ -263,6 +266,9 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, | |||
263 | err = finish_no_open(file, dn); | 266 | err = finish_no_open(file, dn); |
264 | } else { | 267 | } else { |
265 | dout("atomic_open finish_open on dn %p\n", dn); | 268 | dout("atomic_open finish_open on dn %p\n", dn); |
269 | if (req->r_op == CEPH_MDS_OP_CREATE && req->r_reply_info.has_create_ino) { | ||
270 | *opened |= FILE_CREATED; | ||
271 | } | ||
266 | err = finish_open(file, dentry, ceph_open, opened); | 272 | err = finish_open(file, dentry, ceph_open, opened); |
267 | } | 273 | } |
268 | 274 | ||
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c index 36549a46e311..3b22150d3e19 100644 --- a/fs/ceph/ioctl.c +++ b/fs/ceph/ioctl.c | |||
@@ -194,7 +194,7 @@ static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg) | |||
194 | return -EFAULT; | 194 | return -EFAULT; |
195 | 195 | ||
196 | down_read(&osdc->map_sem); | 196 | down_read(&osdc->map_sem); |
197 | r = ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, &len, | 197 | r = ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, len, |
198 | &dl.object_no, &dl.object_offset, | 198 | &dl.object_no, &dl.object_offset, |
199 | &olen); | 199 | &olen); |
200 | if (r < 0) | 200 | if (r < 0) |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 9165eb8309eb..d95842036c8b 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -233,6 +233,30 @@ bad: | |||
233 | } | 233 | } |
234 | 234 | ||
235 | /* | 235 | /* |
236 | * parse create results | ||
237 | */ | ||
238 | static int parse_reply_info_create(void **p, void *end, | ||
239 | struct ceph_mds_reply_info_parsed *info, | ||
240 | int features) | ||
241 | { | ||
242 | if (features & CEPH_FEATURE_REPLY_CREATE_INODE) { | ||
243 | if (*p == end) { | ||
244 | info->has_create_ino = false; | ||
245 | } else { | ||
246 | info->has_create_ino = true; | ||
247 | info->ino = ceph_decode_64(p); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | if (unlikely(*p != end)) | ||
252 | goto bad; | ||
253 | return 0; | ||
254 | |||
255 | bad: | ||
256 | return -EIO; | ||
257 | } | ||
258 | |||
259 | /* | ||
236 | * parse extra results | 260 | * parse extra results |
237 | */ | 261 | */ |
238 | static int parse_reply_info_extra(void **p, void *end, | 262 | static int parse_reply_info_extra(void **p, void *end, |
@@ -241,8 +265,12 @@ static int parse_reply_info_extra(void **p, void *end, | |||
241 | { | 265 | { |
242 | if (info->head->op == CEPH_MDS_OP_GETFILELOCK) | 266 | if (info->head->op == CEPH_MDS_OP_GETFILELOCK) |
243 | return parse_reply_info_filelock(p, end, info, features); | 267 | return parse_reply_info_filelock(p, end, info, features); |
244 | else | 268 | else if (info->head->op == CEPH_MDS_OP_READDIR) |
245 | return parse_reply_info_dir(p, end, info, features); | 269 | return parse_reply_info_dir(p, end, info, features); |
270 | else if (info->head->op == CEPH_MDS_OP_CREATE) | ||
271 | return parse_reply_info_create(p, end, info, features); | ||
272 | else | ||
273 | return -EIO; | ||
246 | } | 274 | } |
247 | 275 | ||
248 | /* | 276 | /* |
@@ -2170,7 +2198,8 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) | |||
2170 | mutex_lock(&req->r_fill_mutex); | 2198 | mutex_lock(&req->r_fill_mutex); |
2171 | err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session); | 2199 | err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session); |
2172 | if (err == 0) { | 2200 | if (err == 0) { |
2173 | if (result == 0 && req->r_op != CEPH_MDS_OP_GETFILELOCK && | 2201 | if (result == 0 && (req->r_op == CEPH_MDS_OP_READDIR || |
2202 | req->r_op == CEPH_MDS_OP_LSSNAP) && | ||
2174 | rinfo->dir_nr) | 2203 | rinfo->dir_nr) |
2175 | ceph_readdir_prepopulate(req, req->r_session); | 2204 | ceph_readdir_prepopulate(req, req->r_session); |
2176 | ceph_unreserve_caps(mdsc, &req->r_caps_reservation); | 2205 | ceph_unreserve_caps(mdsc, &req->r_caps_reservation); |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index dd26846dd71d..567f7c60354e 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -74,6 +74,12 @@ struct ceph_mds_reply_info_parsed { | |||
74 | struct ceph_mds_reply_info_in *dir_in; | 74 | struct ceph_mds_reply_info_in *dir_in; |
75 | u8 dir_complete, dir_end; | 75 | u8 dir_complete, dir_end; |
76 | }; | 76 | }; |
77 | |||
78 | /* for create results */ | ||
79 | struct { | ||
80 | bool has_create_ino; | ||
81 | u64 ino; | ||
82 | }; | ||
77 | }; | 83 | }; |
78 | 84 | ||
79 | /* encoded blob describing snapshot contexts for certain | 85 | /* encoded blob describing snapshot contexts for certain |