~ubuntu-branches/ubuntu/precise/util-linux/precise-proposed

« back to all changes in this revision

Viewing changes to sys-utils/fstrim.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2011-06-20 22:31:50 UTC
  • mfrom: (1.6.3 upstream) (4.5.1 sid)
  • Revision ID: james.westby@ubuntu.com-20110620223150-lz8wrv0946ihcz3z
Tags: 2.19.1-2ubuntu1
* Merge from Debian unstable, remaining changes:
  - Build for multiarch.
  - Add pre-depends on multiarch-support.
  - configure.ac: don't try to be clever about extracting a path name from
    $libdir to append to /usr in a way that's not overridable; instead,
    reuse the built-in configurable libexecdir.
  - Fix up the .pc.in files to know about libexecdir, so our substitutions
    don't leave us with unusable pkg-config files.
  - Install custom blkid.conf to use /dev/.blkid.tab since we don't
    expect device names to survive a reboot
  - Mention mountall(8) in fstab(5) manpages, along with its special
    options.
  - Since upstart is required in Ubuntu, the hwclock.sh init script is not
    called on startup and the hwclockfirst.sh init script is removed.
  - Drop depends on initscripts for the above.
  - Replace hwclock udev rule with an Upstart job.
  - For the case where mount is called with a directory to mount, look
    that directory up in mountall's /lib/init/fstab if we couldn't find
    it mentioned anywhere else.  This means "mount /proc", "mount /sys",
    etc. work.
  - mount.8 points to the cifs-utils package, not the obsolete smbfs one. 
* Dropped changes:
  - mount.preinst: lsb_release has been fixed in lucid and above to be
    usable without configuration, so we don't have to diverge from Debian
    here anymore.
* Changes merged upstream:
  - sfdisk support for '+' with '-N'
  - mount/umount.c: fix a segfault on umount with empty mtab entry
  - Fix arbitrary unmount with fuse security issue

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * fstrim.c -- discard the part (or whole) of mounted filesystem.
 
3
 *
 
4
 * Copyright (C) 2010 Red Hat, Inc. All rights reserved.
 
5
 * Written by Lukas Czerner <lczerner@redhat.com>
 
6
 *            Karel Zak <kzak@redhat.com>
 
7
 *
 
8
 * This program is free software: you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation, either version 2 of the License, or
 
11
 * (at your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 * GNU General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
 *
 
21
 *
 
22
 * This program uses FITRIM ioctl to discard parts or the whole filesystem
 
23
 * online (mounted). You can specify range (start and length) to be
 
24
 * discarded, or simply discard whole filesystem.
 
25
 */
 
26
 
 
27
#include <string.h>
 
28
#include <unistd.h>
 
29
#include <stdlib.h>
 
30
#include <stdio.h>
 
31
#include <stdint.h>
 
32
#include <fcntl.h>
 
33
#include <limits.h>
 
34
#include <getopt.h>
 
35
#include <err.h>
 
36
#include <error.h>
 
37
#include <errno.h>
 
38
 
 
39
#include <sys/ioctl.h>
 
40
#include <sys/stat.h>
 
41
#include <linux/fs.h>
 
42
 
 
43
#include "nls.h"
 
44
#include "strutils.h"
 
45
 
 
46
#ifndef FITRIM
 
47
struct fstrim_range {
 
48
        uint64_t start;
 
49
        uint64_t len;
 
50
        uint64_t minlen;
 
51
};
 
52
#define FITRIM          _IOWR('X', 121, struct fstrim_range)
 
53
#endif
 
54
 
 
55
static void __attribute__((__noreturn__)) usage(FILE *out)
 
56
{
 
57
        fprintf(out, _("Usage: %s [options] <mount point>\n\nOptions:\n"),
 
58
                        program_invocation_short_name);
 
59
 
 
60
        fprintf(out, _(
 
61
                " -h, --help          this help\n"
 
62
                " -o, --offset <num>  offset in bytes to discard from\n"
 
63
                " -l, --length <num>  length of bytes to discard from the offset\n"
 
64
                " -m, --minimum <num> minimum extent length to discard\n"
 
65
                " -v, --verbose       print number of discarded bytes\n"));
 
66
 
 
67
        fprintf(out, _("\nFor more information see fstrim(1).\n"));
 
68
 
 
69
        exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
 
70
}
 
71
 
 
72
int main(int argc, char **argv)
 
73
{
 
74
        char *path;
 
75
        int c, fd, verbose = 0;
 
76
        struct fstrim_range range;
 
77
        struct stat sb;
 
78
 
 
79
        struct option longopts[] = {
 
80
            { "help",      0, 0, 'h' },
 
81
            { "offset",    1, 0, 'o' },
 
82
            { "length",    1, 0, 'l' },
 
83
            { "minimum",   1, 0, 'm' },
 
84
            { "verbose",   0, 0, 'v' },
 
85
            { NULL,        0, 0, 0 }
 
86
        };
 
87
 
 
88
        setlocale(LC_ALL, "");
 
89
        bindtextdomain(PACKAGE, LOCALEDIR);
 
90
        textdomain(PACKAGE);
 
91
 
 
92
        memset(&range, 0, sizeof(range));
 
93
        range.len = ULLONG_MAX;
 
94
 
 
95
        while ((c = getopt_long(argc, argv, "ho:l:m:v", longopts, NULL)) != -1) {
 
96
                switch(c) {
 
97
                case 'h':
 
98
                        usage(stdout);
 
99
                        break;
 
100
                case 'l':
 
101
                        if (strtosize(optarg, &range.len))
 
102
                                errx(EXIT_FAILURE,
 
103
                                     _("failed to parse length: %s"), optarg);
 
104
                        break;
 
105
                case 'o':
 
106
                        if (strtosize(optarg, &range.start))
 
107
                                errx(EXIT_FAILURE,
 
108
                                     _("failed to parse offset: %s"), optarg);
 
109
                        break;
 
110
                case 'm':
 
111
                        if (strtosize(optarg, &range.minlen))
 
112
                                errx(EXIT_FAILURE,
 
113
                                     _("failed to parse minimal extend length: %s"),
 
114
                                     optarg);
 
115
                        break;
 
116
                case 'v':
 
117
                        verbose = 1;
 
118
                        break;
 
119
                default:
 
120
                        usage(stderr);
 
121
                        break;
 
122
                }
 
123
        }
 
124
 
 
125
        if (optind == argc)
 
126
                errx(EXIT_FAILURE, _("no mountpoint specified."));
 
127
 
 
128
        path = argv[optind++];
 
129
 
 
130
        if (optind != argc) {
 
131
                warnx(_("unexpected number of arguments"));
 
132
                usage(stderr);
 
133
        }
 
134
 
 
135
        if (stat(path, &sb) == -1)
 
136
                err(EXIT_FAILURE, _("%s: stat failed"), path);
 
137
        if (!S_ISDIR(sb.st_mode))
 
138
                errx(EXIT_FAILURE, _("%s: not a directory"), path);
 
139
 
 
140
        fd = open(path, O_RDONLY);
 
141
        if (fd < 0)
 
142
                err(EXIT_FAILURE, _("%s: open failed"), path);
 
143
 
 
144
        if (ioctl(fd, FITRIM, &range)) {
 
145
                int errsv = errno;
 
146
                close(fd);
 
147
                error(EXIT_FAILURE, errsv, _("%s: FITRIM ioctl failed"), path);
 
148
        }
 
149
        if (verbose)
 
150
                printf(_("%s: %" PRIu64 " bytes was trimmed\n"),
 
151
                                                path, range.len);
 
152
        close(fd);
 
153
        return EXIT_SUCCESS;
 
154
}