Revert "blkdiscard: new command"

This was only attempt as alternative implementation, unfortunately
pushed publicly... sorry.

This reverts commit c84ed54cef.
This commit is contained in:
Karel Zak 2012-09-28 01:10:08 +02:00
parent 766d5156c4
commit fce05e9617
4 changed files with 36 additions and 195 deletions

1
.gitignore vendored
View File

@ -65,7 +65,6 @@ tests/run.sh.trs
/addpart
/agetty
/arch
/blkdiscard
/blkid
/blockdev
/cal

View File

@ -51,17 +51,9 @@ fsfreeze_SOURCES = sys-utils/fsfreeze.c
sbin_PROGRAMS += fstrim
dist_man_MANS += sys-utils/fstrim.8
fstrim_SOURCES = sys-utils/fstrim.c lib/blkdev.c
fstrim_SOURCES = sys-utils/fstrim.c
fstrim_LDADD = $(LDADD) libcommon.la
install-exec-hook-blkdiscard:
cd $(DESTDIR)$(sbindir) && ln -sf fstrim blkdiscard
uninstall-hook-blkdiscard:
rm -f $(DESTDIR)$(sbindir)/blkdiscard
INSTALL_EXEC_HOOKS += install-exec-hook-blkdiscard
UNINSTALL_HOOKS += uninstall-hook-blkdiscard
usrbin_exec_PROGRAMS += cytune
dist_man_MANS += sys-utils/cytune.8
cytune_SOURCES = sys-utils/cytune.c sys-utils/cyclades.h

View File

@ -1,66 +0,0 @@
.\" -*- nroff -*-
.TH BLKDISCARD 8 "September 2012" "util-linux" "System Administration"
.SH NAME
blkdiscard \- discard sectors on a device
.SH SYNOPSIS
.B blkdiscard
.RB [ \-o
.IR offset ]
.RB [ \-l
.IR length ]
.RB [ \-s ]
.RB [ \-v ]
.I device
.SH DESCRIPTION
.B blkdiscard
is used to discard device sectors. This is useful for solid-state
drivers (SSDs) and thinly-provisioned storage. Unlike
.BR fstrim (8)
this command is used directly on the block device.
.PP
By default,
.B blkdiscard
will discard all blocks on the device. Options may be used to
modify this behavior based on range or size, as explained below.
.PP
The
.I device
argument is the pathname of the block device.
.B WARNING: All data in the discarded region on the device will be lost!
.SH OPTIONS
The \fIoffset\fR and \fIlength\fR arguments may be
followed by the multiplicative suffixes KiB=1024, MiB=1024*1024, and so on for
GiB, TiB, PiB, EiB, ZiB and YiB (the "iB" is optional, e.g. "K" has the same
meaning as "KiB") or the suffixes KB=1000, MB=1000*1000, and so on for GB, PB,
EB, ZB and YB.
.IP "\fB\-h, \-\-help\fP"
Print help and exit.
.IP "\fB\-o, \-\-offset\fP \fIoffset\fP"
Byte offset in the device from which to discard. Provided value will be
aligned to the device sector size. Default value is zero.
.IP "\fB\-l, \-\-length\fP \fIlength\fP"
Number of bytes after starting point to discard. Provided value will be
aligned to the device sector size. If the specified value extends past the
end of the device,
.B blkdiscard
will stop at the device size boundary. Default value extends to the end
of the device.
.IP "\fB\-s, \-\-secure\fP"
Perform secure discard. Secure discard is the same as regular discard except
all copies of the discarded blocks possibly created by garbage collection must
also be erased. It has to be supported by the device.
.IP "\fB\-v, \-\-verbose\fP"
Print aligned \fIoffset\fR and \fIlength\fR arguments.
.SH AUTHOR
.nf
Lukas Czerner <lczerner@redhat.com>
.fi
.SH SEE ALSO
.BR fstrim (8)
.SH AVAILABILITY
The blkdiscard command is part of the util-linux package and is available
from ftp://ftp.kernel.org/pub/linux/utils/util-linux/.

View File

@ -1,7 +1,7 @@
/*
* fstrim.c -- discard the part (or whole) of mounted filesystem.
*
* Copyright (C) 2010,2012 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010 Red Hat, Inc. All rights reserved.
* Written by Lukas Czerner <lczerner@redhat.com>
* Karel Zak <kzak@redhat.com>
*
@ -23,6 +23,7 @@
* online (mounted). You can specify range (start and length) to be
* discarded, or simply discard whole filesystem.
*/
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
@ -40,7 +41,6 @@
#include "strutils.h"
#include "c.h"
#include "closestream.h"
#include "blkdev.h"
#ifndef FITRIM
struct fstrim_range {
@ -48,107 +48,34 @@ struct fstrim_range {
uint64_t len;
uint64_t minlen;
};
# define FITRIM _IOWR('X', 121, struct fstrim_range)
#define FITRIM _IOWR('X', 121, struct fstrim_range)
#endif
#ifndef BLKDISCARD
# define BLKDISCARD _IO(0x12,119)
#endif
#ifndef BLKSECDISCARD
# define BLKSECDISCARD _IO(0x12,125)
#endif
static int is_blk = 0;
static void __attribute__((__noreturn__)) usage(FILE *out)
{
fputs(USAGE_HEADER, out);
if (is_blk) {
fprintf(out, _(" %s [options] <device>\n"), program_invocation_short_name);
fputs(USAGE_OPTIONS, out);
fputs(_(" -s, --secure perform secure discard\n"), out);
} else {
fprintf(out, _(" %s [options] <mountpoint>\n"), program_invocation_short_name);
fputs(USAGE_OPTIONS, out);
fputs(_(" -m, --minimum <num> minimum extent length to discard\n"), out);
}
fprintf(out,
_(" %s [options] <mount point>\n"), program_invocation_short_name);
fputs(USAGE_OPTIONS, out);
fputs(_(" -o, --offset <num> offset in bytes to discard from\n"
" -l, --length <num> length of bytes to discard from the offset\n"
" -m, --minimum <num> minimum extent length to discard\n"
" -v, --verbose print number of discarded bytes\n"), out);
fputs(USAGE_SEPARATOR, out);
fputs(USAGE_HELP, out);
fputs(USAGE_VERSION, out);
fprintf(out, USAGE_MAN_TAIL(is_blk ? "blkdiscard(8)" : "fstrim(8)"));
fprintf(out, USAGE_MAN_TAIL("fstrim(8)"));
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
}
static void do_fstrim(const char *path, uint64_t off, uint64_t len, uint64_t minlen)
{
int fd;
struct stat sb;
struct fstrim_range range;
range.start = off;
range.len = len;
range.minlen = minlen;
fd = open(path, O_RDONLY);
if (fd < 0)
err(EXIT_FAILURE, _("cannot open %s"), path);
if (fstat(fd, &sb) == -1)
err(EXIT_FAILURE, _("stat failed %s"), path);
if (!S_ISDIR(sb.st_mode))
errx(EXIT_FAILURE, _("%s: not a directory"), path);
if (ioctl(fd, FITRIM, &range))
err(EXIT_FAILURE, _("%s: FITRIM ioctl failed"), path);
close(fd);
}
static void do_blkdiscard(const char *path, uint64_t off, uint64_t len, int sec)
{
int fd, secsize;
struct stat sb;
uint64_t blksize, range[2], end;
fd = open(path, O_WRONLY);
if (fd < 0)
err(EXIT_FAILURE, _("cannot open %s"), path);
if (fstat(fd, &sb) == -1)
err(EXIT_FAILURE, _("stat failed %s"), path);
if (!S_ISBLK(sb.st_mode))
errx(EXIT_FAILURE, _("%s: not a block device"), path);
if (blkdev_get_size(fd, (unsigned long long *) &blksize) != 0)
err(EXIT_FAILURE, _("%s: failed to get device size"), path);
if (blkdev_get_sector_size(fd, &secsize) != 0)
err(EXIT_FAILURE, _("%s: failed to get sector size"), path);
/* align range to the sector size */
range[0] = (off + secsize - 1) & ~(secsize - 1);
range[1] = len & ~(secsize - 1);
/* is the range end behind the end of the device ?*/
end = range[0] + range[1];
if (end < range[0] || end > blksize)
range[1] = blksize - range[0];
if (sec) {
if (ioctl(fd, BLKSECDISCARD, &range))
err(EXIT_FAILURE, _("%s: BLKSECDISCARD ioctl failed"), path);
} else {
if (ioctl(fd, BLKDISCARD, &range))
err(EXIT_FAILURE, _("%s: BLKDISCARD ioctl failed"), path);
}
close(fd);
}
int main(int argc, char **argv)
{
char *path;
int c, verbose = 0, secure = 0;
uint64_t len = UINT64_MAX, off = 0, minlen = 0;
int c, fd, verbose = 0;
struct fstrim_range range;
struct stat sb;
static const struct option fs_longopts[] = {
static const struct option longopts[] = {
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'V' },
{ "offset", 1, 0, 'o' },
@ -157,32 +84,16 @@ int main(int argc, char **argv)
{ "verbose", 0, 0, 'v' },
{ NULL, 0, 0, 0 }
};
static const struct option blk_longopts[] = {
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'V' },
{ "offset", 1, 0, 'o' },
{ "length", 1, 0, 'l' },
{ "secure", 0, 0, 's' },
{ "verbose", 0, 0, 'v' },
{ NULL, 0, 0, 0 }
};
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
atexit(close_stdout);
if (strcmp(program_invocation_short_name, "blkdiscard") == 0)
is_blk = 1;
do {
if (is_blk)
c = getopt_long(argc, argv, "hVo:l:sv", blk_longopts, NULL);
else
c = getopt_long(argc, argv, "hVo:l:m:v", fs_longopts, NULL);
if (c == -1)
break;
memset(&range, 0, sizeof(range));
range.len = ULLONG_MAX;
while ((c = getopt_long(argc, argv, "hVo:l:m:v", longopts, NULL)) != -1) {
switch(c) {
case 'h':
usage(stdout);
@ -191,20 +102,17 @@ int main(int argc, char **argv)
printf(UTIL_LINUX_VERSION);
return EXIT_SUCCESS;
case 'l':
len = strtosize_or_err(optarg,
range.len = strtosize_or_err(optarg,
_("failed to parse length"));
break;
case 'o':
off = strtosize_or_err(optarg,
range.start = strtosize_or_err(optarg,
_("failed to parse offset"));
break;
case 'm':
minlen = strtosize_or_err(optarg,
range.minlen = strtosize_or_err(optarg,
_("failed to parse minimum extent length"));
break;
case 's':
secure = 1;
break;
case 'v':
verbose = 1;
break;
@ -212,11 +120,11 @@ int main(int argc, char **argv)
usage(stderr);
break;
}
} while (1);
}
if (optind == argc)
errx(EXIT_FAILURE, is_blk ? _("no device specified.") :
_("no mountpoint specified"));
errx(EXIT_FAILURE, _("no mountpoint specified."));
path = argv[optind++];
if (optind != argc) {
@ -224,14 +132,22 @@ int main(int argc, char **argv)
usage(stderr);
}
if (is_blk)
do_blkdiscard(path, off, len, secure);
else
do_fstrim(path, off, len, minlen);
if (stat(path, &sb) == -1)
err(EXIT_FAILURE, _("stat failed %s"), path);
if (!S_ISDIR(sb.st_mode))
errx(EXIT_FAILURE, _("%s: not a directory"), path);
fd = open(path, O_RDONLY);
if (fd < 0)
err(EXIT_FAILURE, _("cannot open %s"), path);
if (ioctl(fd, FITRIM, &range))
err(EXIT_FAILURE, _("%s: FITRIM ioctl failed"), path);
if (verbose)
/* TRANSLATORS: The standard value here is a very large number. */
printf(_("%s: %" PRIu64 " bytes were trimmed\n"), path, len);
printf(_("%s: %" PRIu64 " bytes were trimmed\n"),
path, (uint64_t) range.len);
close(fd);
return EXIT_SUCCESS;
}