From 726f69e29ca9d4842f3acb20fffd2466fda62c09 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 7 Dec 2006 00:25:33 +0100 Subject: Imported from util-linux-2.5 tarball. --- disk-utils/mkswap.c | 69 +++++++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 31 deletions(-) (limited to 'disk-utils/mkswap.c') diff --git a/disk-utils/mkswap.c b/disk-utils/mkswap.c index bb4e2249e..fe3f04c11 100644 --- a/disk-utils/mkswap.c +++ b/disk-utils/mkswap.c @@ -28,12 +28,8 @@ #include -#ifndef __GNUC__ -#error "needs gcc for the bitop-__asm__'s" -#endif - #ifndef __linux__ -#define volatile +# define volatile #endif #define TEST_BUFFER_PAGES 8 @@ -45,21 +41,29 @@ static long PAGES = 0; static int check = 0; static int badpages = 0; -static char signature_page[PAGE_SIZE]; +static int signature_page[PAGE_SIZE/sizeof(int)]; -#define bitop(name,op) \ -static inline int name(char * addr,unsigned int nr) \ -{ \ -int __res; \ -__asm__ __volatile__("bt" op " %1,%2; adcl $0,%0" \ -:"=g" (__res) \ -:"r" (nr),"m" (*(addr)),"0" (0)); \ -return __res; \ +static long bit_test_and_set (unsigned int *addr, unsigned int nr) +{ + unsigned int r, m; + + addr += nr / (8 * sizeof(int)); + r = *addr; + m = 1 << (nr & (8 * sizeof(int) - 1)); + *addr = r | m; + return (r & m) != 0; } -bitop(bit,"") -bitop(setbit,"s") -bitop(clrbit,"r") +static bit_test_and_clear (unsigned int *addr, unsigned int nr) +{ + unsigned int r, m; + + addr += nr / (8 * sizeof(int)); + r = *addr; + m = 1 << (nr & (8 * sizeof(int) - 1)); + *addr = r & ~m; + return (r & m) != 0; +} /* * Volatile to let gcc know that this doesn't return. When trying @@ -84,18 +88,18 @@ void check_blocks(void) current_page = 0; while (current_page < PAGES) { if (!check) { - setbit(signature_page,current_page++); + bit_test_and_set(signature_page,current_page++); continue; } if (do_seek && lseek(DEV,current_page*PAGE_SIZE,SEEK_SET) != current_page*PAGE_SIZE) die("seek failed in check_blocks"); if (do_seek = (PAGE_SIZE != read(DEV, buffer, PAGE_SIZE))) { - clrbit(signature_page,current_page++); + bit_test_and_clear(signature_page,current_page++); badpages++; continue; } - setbit(signature_page,current_page++); + bit_test_and_set(signature_page,current_page++); } if (badpages) printf("%d bad page%s\n",badpages,(badpages>1)?"s":""); @@ -165,7 +169,7 @@ int main(int argc, char ** argv) argv++; if (argv[0][0] != '-') if (device_name) { - PAGES = strtol(argv[0],&tmp,0)>>2; + PAGES = strtol(argv[0],&tmp,0)>>(PAGE_SHIFT-10); if (*tmp) usage(); } else @@ -179,14 +183,17 @@ int main(int argc, char ** argv) if (device_name && !PAGES) { PAGES = get_size(device_name) / PAGE_SIZE; } - if (!device_name || PAGES<10) + if (!device_name || PAGES<10) { + fprintf(stderr, + "%s: error: swap area needs to be at least %ldkB\n", + program_name, 10 * PAGE_SIZE / 1024); usage(); - if (PAGES > 32688) /* 130752 blocks */ - PAGES=32688; -#if 0 - if (PAGES > 32768) - PAGES=32768; -#endif + } + if (PAGES > 8 * (PAGE_SIZE - 10)) { + PAGES = 8 * (PAGE_SIZE - 10); + fprintf(stderr, "%s: warning: truncating swap area to %ldkB\n", + program_name, PAGES * PAGE_SIZE / 1024); + } DEV = open(device_name,O_RDWR); if (DEV < 0 || fstat(DEV, &statbuf) < 0) { perror(device_name); @@ -197,13 +204,13 @@ int main(int argc, char ** argv) else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340) die("Will not try to make swapdevice on '%s'"); check_blocks(); - if (!clrbit(signature_page,0)) + if (!bit_test_and_clear(signature_page,0)) die("fatal: first page unreadable"); goodpages = PAGES - badpages - 1; - if (!goodpages) + if (goodpages <= 0) die("Unable to set up swap-space: unreadable"); printf("Setting up swapspace, size = %d bytes\n",goodpages*PAGE_SIZE); - strncpy(signature_page+PAGE_SIZE-10,"SWAP-SPACE",10); + strncpy((char*)signature_page+PAGE_SIZE-10,"SWAP-SPACE",10); if (lseek(DEV, 0, SEEK_SET)) die("unable to rewind swap-device"); if (PAGE_SIZE != write(DEV, signature_page, PAGE_SIZE)) -- cgit v1.2.3-55-g7522