diff options
-rw-r--r-- | fs/ceph/dir.c | 4 | ||||
-rw-r--r-- | fs/ceph/inode.c | 17 | ||||
-rw-r--r-- | fs/ceph/mds_client.c | 1 | ||||
-rw-r--r-- | fs/ceph/mds_client.h | 3 | ||||
-rw-r--r-- | include/linux/ceph/ceph_fs.h | 2 |
5 files changed, 21 insertions, 6 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 3e9ad501addf..ae61cdf7d489 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -378,7 +378,11 @@ more: | |||
378 | ceph_mdsc_put_request(req); | 378 | ceph_mdsc_put_request(req); |
379 | return -ENOMEM; | 379 | return -ENOMEM; |
380 | } | 380 | } |
381 | } else if (is_hash_order(ctx->pos)) { | ||
382 | req->r_args.readdir.offset_hash = | ||
383 | cpu_to_le32(fpos_hash(ctx->pos)); | ||
381 | } | 384 | } |
385 | |||
382 | req->r_dir_release_cnt = fi->dir_release_count; | 386 | req->r_dir_release_cnt = fi->dir_release_count; |
383 | req->r_dir_ordered_cnt = fi->dir_ordered_count; | 387 | req->r_dir_ordered_cnt = fi->dir_ordered_count; |
384 | req->r_readdir_cache_idx = fi->readdir_cache_idx; | 388 | req->r_readdir_cache_idx = fi->readdir_cache_idx; |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index d3119fe3ab45..dcce79b84406 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -1482,10 +1482,17 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, | |||
1482 | if (test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags)) | 1482 | if (test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags)) |
1483 | return readdir_prepopulate_inodes_only(req, session); | 1483 | return readdir_prepopulate_inodes_only(req, session); |
1484 | 1484 | ||
1485 | if (rinfo->hash_order && req->r_path2) { | 1485 | if (rinfo->hash_order) { |
1486 | last_hash = ceph_str_hash(ci->i_dir_layout.dl_dir_hash, | 1486 | if (req->r_path2) { |
1487 | req->r_path2, strlen(req->r_path2)); | 1487 | last_hash = ceph_str_hash(ci->i_dir_layout.dl_dir_hash, |
1488 | last_hash = ceph_frag_value(last_hash); | 1488 | req->r_path2, |
1489 | strlen(req->r_path2)); | ||
1490 | last_hash = ceph_frag_value(last_hash); | ||
1491 | } else if (rinfo->offset_hash) { | ||
1492 | /* mds understands offset_hash */ | ||
1493 | WARN_ON_ONCE(req->r_readdir_offset != 2); | ||
1494 | last_hash = le32_to_cpu(rhead->args.readdir.offset_hash); | ||
1495 | } | ||
1489 | } | 1496 | } |
1490 | 1497 | ||
1491 | if (rinfo->dir_dir && | 1498 | if (rinfo->dir_dir && |
@@ -1510,7 +1517,7 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req, | |||
1510 | } | 1517 | } |
1511 | 1518 | ||
1512 | if (ceph_frag_is_leftmost(frag) && req->r_readdir_offset == 2 && | 1519 | if (ceph_frag_is_leftmost(frag) && req->r_readdir_offset == 2 && |
1513 | !(rinfo->hash_order && req->r_path2)) { | 1520 | !(rinfo->hash_order && last_hash)) { |
1514 | /* note dir version at start of readdir so we can tell | 1521 | /* note dir version at start of readdir so we can tell |
1515 | * if any dentries get dropped */ | 1522 | * if any dentries get dropped */ |
1516 | req->r_dir_release_cnt = atomic64_read(&ci->i_release_count); | 1523 | req->r_dir_release_cnt = atomic64_read(&ci->i_release_count); |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index a22688873ec3..8cc4d4e8b077 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -189,6 +189,7 @@ static int parse_reply_info_dir(void **p, void *end, | |||
189 | info->dir_end = !!(flags & CEPH_READDIR_FRAG_END); | 189 | info->dir_end = !!(flags & CEPH_READDIR_FRAG_END); |
190 | info->dir_complete = !!(flags & CEPH_READDIR_FRAG_COMPLETE); | 190 | info->dir_complete = !!(flags & CEPH_READDIR_FRAG_COMPLETE); |
191 | info->hash_order = !!(flags & CEPH_READDIR_HASH_ORDER); | 191 | info->hash_order = !!(flags & CEPH_READDIR_HASH_ORDER); |
192 | info->offset_hash = !!(flags & CEPH_READDIR_OFFSET_HASH); | ||
192 | } | 193 | } |
193 | if (num == 0) | 194 | if (num == 0) |
194 | goto done; | 195 | goto done; |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index bbebcd55d79e..3e67dd2169fa 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -83,9 +83,10 @@ struct ceph_mds_reply_info_parsed { | |||
83 | struct ceph_mds_reply_dirfrag *dir_dir; | 83 | struct ceph_mds_reply_dirfrag *dir_dir; |
84 | size_t dir_buf_size; | 84 | size_t dir_buf_size; |
85 | int dir_nr; | 85 | int dir_nr; |
86 | bool dir_complete; | ||
87 | bool dir_end; | 86 | bool dir_end; |
87 | bool dir_complete; | ||
88 | bool hash_order; | 88 | bool hash_order; |
89 | bool offset_hash; | ||
89 | struct ceph_mds_reply_dir_entry *dir_entries; | 90 | struct ceph_mds_reply_dir_entry *dir_entries; |
90 | }; | 91 | }; |
91 | 92 | ||
diff --git a/include/linux/ceph/ceph_fs.h b/include/linux/ceph/ceph_fs.h index f4b2ee18f38c..1787e4a8e251 100644 --- a/include/linux/ceph/ceph_fs.h +++ b/include/linux/ceph/ceph_fs.h | |||
@@ -365,6 +365,7 @@ extern const char *ceph_mds_op_name(int op); | |||
365 | #define CEPH_READDIR_FRAG_END (1<<0) | 365 | #define CEPH_READDIR_FRAG_END (1<<0) |
366 | #define CEPH_READDIR_FRAG_COMPLETE (1<<8) | 366 | #define CEPH_READDIR_FRAG_COMPLETE (1<<8) |
367 | #define CEPH_READDIR_HASH_ORDER (1<<9) | 367 | #define CEPH_READDIR_HASH_ORDER (1<<9) |
368 | #define CEPH_READDIR_OFFSET_HASH (1<<10) | ||
368 | 369 | ||
369 | union ceph_mds_request_args { | 370 | union ceph_mds_request_args { |
370 | struct { | 371 | struct { |
@@ -384,6 +385,7 @@ union ceph_mds_request_args { | |||
384 | __le32 max_entries; /* how many dentries to grab */ | 385 | __le32 max_entries; /* how many dentries to grab */ |
385 | __le32 max_bytes; | 386 | __le32 max_bytes; |
386 | __le16 flags; | 387 | __le16 flags; |
388 | __le32 offset_hash; | ||
387 | } __attribute__ ((packed)) readdir; | 389 | } __attribute__ ((packed)) readdir; |
388 | struct { | 390 | struct { |
389 | __le32 mode; | 391 | __le32 mode; |