aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-05-01 13:43:03 -0400
committerAlex Elder <elder@inktank.com>2013-05-02 12:58:17 -0400
commit30d1cff817808fca9801c743d2de4c61f3f38e15 (patch)
treeb6944042ba2919676bd13ebf84c412b04854f00e /drivers/block
parent15228ede7d9437b0dcfe9331c9830b3646fdadf7 (diff)
rbd: use binary search for snapshot lookup
Use bsearch(3) to make snapshot lookup by id more efficient. (There could be thousands of snapshots, and conceivably many more.) Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/rbd.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 3f58aba6461f..82d9586a4172 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -33,6 +33,7 @@
33#include <linux/ceph/mon_client.h> 33#include <linux/ceph/mon_client.h>
34#include <linux/ceph/decode.h> 34#include <linux/ceph/decode.h>
35#include <linux/parser.h> 35#include <linux/parser.h>
36#include <linux/bsearch.h>
36 37
37#include <linux/kernel.h> 38#include <linux/kernel.h>
38#include <linux/device.h> 39#include <linux/device.h>
@@ -819,16 +820,39 @@ static const char *_rbd_dev_v1_snap_name(struct rbd_device *rbd_dev, u32 which)
819 return kstrdup(snap_name, GFP_KERNEL); 820 return kstrdup(snap_name, GFP_KERNEL);
820} 821}
821 822
823/*
824 * Snapshot id comparison function for use with qsort()/bsearch().
825 * Note that result is for snapshots in *descending* order.
826 */
827static int snapid_compare_reverse(const void *s1, const void *s2)
828{
829 u64 snap_id1 = *(u64 *)s1;
830 u64 snap_id2 = *(u64 *)s2;
831
832 if (snap_id1 < snap_id2)
833 return 1;
834 return snap_id1 == snap_id2 ? 0 : -1;
835}
836
837/*
838 * Search a snapshot context to see if the given snapshot id is
839 * present.
840 *
841 * Returns the position of the snapshot id in the array if it's found,
842 * or BAD_SNAP_INDEX otherwise.
843 *
844 * Note: The snapshot array is in kept sorted (by the osd) in
845 * reverse order, highest snapshot id first.
846 */
822static u32 rbd_dev_snap_index(struct rbd_device *rbd_dev, u64 snap_id) 847static u32 rbd_dev_snap_index(struct rbd_device *rbd_dev, u64 snap_id)
823{ 848{
824 struct ceph_snap_context *snapc = rbd_dev->header.snapc; 849 struct ceph_snap_context *snapc = rbd_dev->header.snapc;
825 u32 which; 850 u64 *found;
826 851
827 for (which = 0; which < snapc->num_snaps; which++) 852 found = bsearch(&snap_id, &snapc->snaps, snapc->num_snaps,
828 if (snapc->snaps[which] == snap_id) 853 sizeof (snap_id), snapid_compare_reverse);
829 return which;
830 854
831 return BAD_SNAP_INDEX; 855 return found ? (u32)(found - &snapc->snaps[0]) : BAD_SNAP_INDEX;
832} 856}
833 857
834static const char *rbd_dev_v1_snap_name(struct rbd_device *rbd_dev, 858static const char *rbd_dev_v1_snap_name(struct rbd_device *rbd_dev,