mirror of
https://github.com/joel16/android_kernel_sony_msm8994.git
synced 2024-11-24 12:40:24 +00:00
Btrfs: fix key checks and advance in the search ioctl
The search ioctl was working well for finding tree roots, but using it for generic searches requires a few changes to how the keys are advanced. This treats the search control min fields for objectid, type and offset more like a key, where we drop the offset to zero once we bump the type, etc. The downside of this is that we are changing the min_type and min_offset fields during the search, and so the ioctl caller needs extra checks to make sure the keys in the result are the ones it wanted. This also changes key_in_sk to use btrfs_comp_cpu_keys, just to make things more readable. Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
7fde62bffb
commit
abc6e1341b
@ -914,17 +914,23 @@ out:
|
||||
static noinline int key_in_sk(struct btrfs_key *key,
|
||||
struct btrfs_ioctl_search_key *sk)
|
||||
{
|
||||
if (key->objectid < sk->min_objectid)
|
||||
struct btrfs_key test;
|
||||
int ret;
|
||||
|
||||
test.objectid = sk->min_objectid;
|
||||
test.type = sk->min_type;
|
||||
test.offset = sk->min_offset;
|
||||
|
||||
ret = btrfs_comp_cpu_keys(key, &test);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
if (key->offset < sk->min_offset)
|
||||
return 0;
|
||||
if (key->type < sk->min_type)
|
||||
return 0;
|
||||
if (key->objectid > sk->max_objectid)
|
||||
return 0;
|
||||
if (key->type > sk->max_type)
|
||||
return 0;
|
||||
if (key->offset > sk->max_offset)
|
||||
|
||||
test.objectid = sk->max_objectid;
|
||||
test.type = sk->max_type;
|
||||
test.offset = sk->max_offset;
|
||||
|
||||
ret = btrfs_comp_cpu_keys(key, &test);
|
||||
if (ret > 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
@ -998,13 +1004,18 @@ static noinline int copy_to_sk(struct btrfs_root *root,
|
||||
break;
|
||||
}
|
||||
advance_key:
|
||||
if (key->offset < (u64)-1)
|
||||
key->offset++;
|
||||
else if (key->type < (u8)-1)
|
||||
key->type++;
|
||||
else if (key->objectid < (u64)-1)
|
||||
key->objectid++;
|
||||
ret = 0;
|
||||
if (key->offset < (u64)-1 && key->offset < sk->max_offset)
|
||||
key->offset++;
|
||||
else if (key->type < (u8)-1 && key->type < sk->max_type) {
|
||||
key->offset = 0;
|
||||
key->type++;
|
||||
} else if (key->objectid < (u64)-1 && key->objectid < sk->max_objectid) {
|
||||
key->offset = 0;
|
||||
key->type = 0;
|
||||
key->objectid++;
|
||||
} else
|
||||
ret = 1;
|
||||
overflow:
|
||||
*num_found += found;
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user