Index: swapon.c =================================================================== --- swapon.c +++ swapon.c @@ -77,7 +77,7 @@ static enum { SWAPON, SWAPOFF, SWAPCTL } orig_prog, which_prog = SWAPCTL; -static int qflag; +static int Eflag, qflag; int main(int argc, char **argv) @@ -100,7 +100,7 @@ doall = 0; etc_fstab = NULL; - while ((ch = getopt(argc, argv, "AadghklLmqsUF:")) != -1) { + while ((ch = getopt(argc, argv, "AadEghklLmqsUF:")) != -1) { switch(ch) { case 'A': if (which_prog == SWAPCTL) { @@ -121,6 +121,12 @@ else usage(); break; + case 'E': + if (which_prog == SWAPON) + Eflag = 1; + else + usage(); + break; case 'g': hflag = 'G'; break; @@ -182,6 +188,8 @@ strstr(fsp->fs_mntops, "late") == NULL && late != 0) continue; + if (strstr(fsp->fs_mntops, "trimonce") != NULL) + Eflag = 1; swfile = swap_on_off(fsp->fs_spec, 1, fsp->fs_mntops); if (swfile == NULL) { @@ -378,12 +386,19 @@ return (NULL); } } else if (strcmp(token, "notrim") == 0) { + if (Eflag) { + warn("Options \"notrim\" and " + "\"trimonce\" conflict"); + free(ops); + return (NULL); + } Tflag = " -T "; } else if (strcmp(token, "late") == 0) { /* ignore known option */ } else if (strcmp(token, "noauto") == 0) { /* ignore known option */ - } else if (strcmp(token, "sw") != 0) { + } else if (strcmp(token, "sw") != 0 && + strcmp(token, "trimonce") != 0) { warnx("Invalid option: %s", token); free(ops); return (NULL); @@ -721,14 +736,46 @@ return (WEXITSTATUS(status)); } +static void +swap_trim(const char *name) +{ + + struct stat sb; + off_t ioarg[2], sz; + int fd; + + fd = open(name, O_WRONLY); + if (fd < 0) + return; + if (fstat(fd, &sb) >= 0) { + if (S_ISREG(sb.st_mode)) { + sz = sb.st_size; + } else if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) { + if (ioctl(fd, DIOCGMEDIASIZE, &sz) != 0) + err(1, "ioctl(DIOCGMEDIASIZE)"); + } else { + errx(1, "%s has an invalid file type", name); + } + + ioarg[0] = 0; + ioarg[1] = sz; + if (ioctl(fd, DIOCGDELETE, ioarg) != 0) + warn(1, "ioctl(DIOCGDELETE)"); + } + close(fd); +} + static const char * swap_on_off_sfile(const char *name, int doingall) { + int error; - if (which_prog == SWAPON) + if (which_prog == SWAPON) { + if (Eflag) + swap_trim(name); error = swapon(name); - else /* SWAPOFF */ + } else /* SWAPOFF */ error = swapoff(name); if (error == -1) { @@ -759,6 +806,8 @@ fprintf(stderr, "usage: %s ", getprogname()); switch(orig_prog) { case SWAPON: + fprintf(stderr, "[-F fstab] -aLq | [-E] file ...\n"); + break; case SWAPOFF: fprintf(stderr, "[-F fstab] -aLq | file ...\n"); break;