X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fresource.c;h=4a3f5c2d195b3677b595a1f1238539b28ca86a91;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=f7a704e88bd1be85e457cb3c6a1b1f5b1825df3d;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/kernel/resource.c b/kernel/resource.c index f7a704e88..4a3f5c2d1 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -315,11 +315,12 @@ EXPORT_SYMBOL(allocate_resource); */ int insert_resource(struct resource *parent, struct resource *new) { - int result = 0; + int result; struct resource *first, *next; write_lock(&resource_lock); begin: + result = 0; first = __request_resource(parent, new); if (!first) goto out; @@ -328,15 +329,20 @@ int insert_resource(struct resource *parent, struct resource *new) if (first == parent) goto out; - for (next = first; next->sibling; next = next->sibling) + /* Resource fully contained by the clashing resource? Recurse into it */ + if (first->start <= new->start && first->end >= new->end) { + parent = first; + goto begin; + } + + for (next = first; ; next = next->sibling) { + /* Partial overlap? Bad, and unfixable */ + if (next->start < new->start || next->end > new->end) + goto out; + if (!next->sibling) + break; if (next->sibling->start > new->end) break; - - /* existing resource overlaps end of new resource */ - if (next->end > new->end) { - parent = next; - result = 0; - goto begin; } result = 0;