155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o/* 255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o * region.c --- code which manages allocations within a region. 3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o * Copyright (C) 2001 Theodore Ts'o. 555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o * 655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o * %Begin-Header% 755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o * This file may be redistributed under the terms of the GNU Public 855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o * License. 955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o * %End-Header% 1055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o */ 1155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 1255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o#if HAVE_UNISTD_H 1355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o#include <unistd.h> 1455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o#endif 1555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o#include <string.h> 1655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 170eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o#ifdef TEST_PROGRAM 180eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o#undef ENABLE_NLS 190eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o#endif 2055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o#include "e2fsck.h" 2155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 2255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'ostruct region_el { 2355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o region_addr_t start; 2455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o region_addr_t end; 2555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o struct region_el *next; 2655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o}; 2755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 2855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'ostruct region_struct { 2955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o region_addr_t min; 3055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o region_addr_t max; 3155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o struct region_el *allocated; 3255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o}; 3355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 3455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'oregion_t region_create(region_addr_t min, region_addr_t max) 3555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o{ 3655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o region_t region; 3755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 3855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o region = malloc(sizeof(struct region_struct)); 3955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o if (!region) 4055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o return NULL; 4155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o memset(region, 0, sizeof(struct region_struct)); 4255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o region->min = min; 4355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o region->max = max; 4455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o return region; 4555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o} 4655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 4755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'ovoid region_free(region_t region) 4855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o{ 4955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o struct region_el *r, *next; 5055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 5155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o for (r = region->allocated; r; r = next) { 5255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o next = r->next; 5355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o free(r); 5455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o } 5555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o memset(region, 0, sizeof(struct region_struct)); 5655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o free(region); 5755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o} 5855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 5955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'oint region_allocate(region_t region, region_addr_t start, int n) 6055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o{ 6155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o struct region_el *r, *new_region, *prev, *next; 6255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o region_addr_t end; 6355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 6455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o end = start+n; 6555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o if ((start < region->min) || (end > region->max)) 6655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o return -1; 6755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o if (n == 0) 6855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o return 1; 6955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 7055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o /* 7155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o * Search through the linked list. If we find that it 7255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o * conflicts witih something that's already allocated, return 7355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o * 1; if we can find an existing region which we can grow, do 7455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o * so. Otherwise, stop when we find the appropriate place 7555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o * insert a new region element into the linked list. 7655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o */ 7755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) { 7855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o if (((start >= r->start) && (start < r->end)) || 7955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o ((end > r->start) && (end <= r->end)) || 8055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o ((start <= r->start) && (end >= r->end))) 8155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o return 1; 8255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o if (end == r->start) { 8355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o r->start = start; 8455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o return 0; 8555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o } 8655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o if (start == r->end) { 8755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o if ((next = r->next)) { 8855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o if (end > next->start) 8955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o return 1; 9055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o if (end == next->start) { 9155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o r->end = next->end; 9255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o r->next = next->next; 9355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o free(next); 9455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o return 0; 9555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o } 9655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o } 9755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o r->end = end; 9855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o return 0; 9955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o } 10055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o if (start < r->start) 10155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o break; 10255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o } 10355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o /* 10455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o * Insert a new region element structure into the linked list 10555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o */ 10655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o new_region = malloc(sizeof(struct region_el)); 10755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o if (!new_region) 10855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o return -1; 10955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o new_region->start = start; 11055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o new_region->end = start + n; 11155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o new_region->next = r; 11255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o if (prev) 11355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o prev->next = new_region; 11455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o else 11555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o region->allocated = new_region; 11655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o return 0; 11755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o} 11855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 11955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o#ifdef TEST_PROGRAM 12055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o#include <stdio.h> 12155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 12255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o#define BCODE_END 0 12355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o#define BCODE_CREATE 1 12455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o#define BCODE_FREE 2 12555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o#define BCODE_ALLOCATE 3 12655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o#define BCODE_PRINT 4 12755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 12855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'oint bcode_program[] = { 12955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_CREATE, 1, 1001, 13055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_PRINT, 13155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_ALLOCATE, 10, 10, 13255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_ALLOCATE, 30, 10, 13355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_PRINT, 13455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_ALLOCATE, 1, 15, 13555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_ALLOCATE, 15, 8, 13655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_ALLOCATE, 1, 20, 13755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_ALLOCATE, 1, 8, 13855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_PRINT, 13955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_ALLOCATE, 40, 10, 14055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_PRINT, 14155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_ALLOCATE, 22, 5, 14255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_PRINT, 14355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_ALLOCATE, 27, 3, 14455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_PRINT, 14555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_ALLOCATE, 20, 2, 14655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_PRINT, 14755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_ALLOCATE, 49, 1, 14855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_ALLOCATE, 50, 5, 14955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_ALLOCATE, 9, 2, 15055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_ALLOCATE, 9, 1, 15155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_PRINT, 15255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_FREE, 15355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o BCODE_END 15455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o}; 15555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 15655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'ovoid region_print(region_t region, FILE *f) 15755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o{ 15855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o struct region_el *r; 15955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o int i = 0; 160efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 16155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o fprintf(f, "Printing region (min=%d. max=%d)\n\t", region->min, 16255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o region->max); 16355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o for (r = region->allocated; r; r = r->next) { 16455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o fprintf(f, "(%d, %d) ", r->start, r->end); 16555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o if (++i >= 8) 16655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o fprintf(f, "\n\t"); 16755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o } 16855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o fprintf(f, "\n"); 16955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o} 17055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 17155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'oint main(int argc, char **argv) 17255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o{ 173e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall region_t r = NULL; 17455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o int pc = 0, ret; 175e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall region_addr_t start, end; 17655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 177efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 17855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o while (1) { 17955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o switch (bcode_program[pc++]) { 18055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o case BCODE_END: 18155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o exit(0); 18255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o case BCODE_CREATE: 18355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o start = bcode_program[pc++]; 18455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o end = bcode_program[pc++]; 18555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o printf("Creating region with args(%d, %d)\n", 18655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o start, end); 18755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o r = region_create(start, end); 18855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o if (!r) { 18955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o fprintf(stderr, "Couldn't create region.\n"); 19055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o exit(1); 19155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o } 19255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o break; 19355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o case BCODE_ALLOCATE: 19455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o start = bcode_program[pc++]; 19555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o end = bcode_program[pc++]; 19655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o ret = region_allocate(r, start, end); 19755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o printf("Region_allocate(%d, %d) returns %d\n", 19855fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o start, end, ret); 19955fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o break; 20055fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o case BCODE_PRINT: 20155fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o region_print(r, stdout); 20255fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o break; 20355fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o } 20455fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o } 20555fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o} 20655fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o 20755fd07ed0a5f4ed3dcc770526ee1ad3be967ac98Theodore Ts'o#endif /* TEST_PROGRAM */ 208