245 lines
10 KiB
Plaintext
Executable File
245 lines
10 KiB
Plaintext
Executable File
The Ultra Defragmenter for Linux
|
|
================================
|
|
|
|
UltraDefrag was originally developed for Windows. Porting to Linux
|
|
implied replacing calls to Windows services by calls to services provided
|
|
by Linux, and specifically using services provided by libntfs-3g, a
|
|
library providing access to NTFS partitions. This work is still in
|
|
progress, but restricted features in terminal mode are available.
|
|
|
|
For more information on UltraDefrag and ntfs-3g see their respective
|
|
home pages :
|
|
|
|
http://ultradefrag.sourceforge.net
|
|
http://www.tuxera.com/community/ntfs-3g-download/
|
|
|
|
Copyright (c) 2007-2011 UltraDefrag Development Team.
|
|
Copyright (c) 2011 Jean-Pierre Andre for the Linux version
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
This is an initial version released for tests only. DO NOT USE IT
|
|
ON PARTITIONS WITH VALUABLE DATA, WITHOUT DOING A FULL BACKUP. YOU HAVE
|
|
BEEN WARNED. Only the console mode is supported (no GUI !)
|
|
|
|
Compiling
|
|
=========
|
|
|
|
To use UltraDefrag on Linux, you first need to have ntfs-3g installed
|
|
and you need to have the libntfs-3g headers from a matching development
|
|
version.
|
|
|
|
There is currently no "configure" script to build Makefile's tailored for
|
|
your environment. You may have to build your own "Makefile"s, though the
|
|
standard Makefile's provided will do in most cases, after adapting the
|
|
locations of the header files and shared object of libntfs-3g. Also check
|
|
whether the "compiler.h" header file has appropriate definitions for your
|
|
computer and compiler.
|
|
|
|
Currently only configurations for X86-32, X86-64, M68k, Sparc and PowerPC
|
|
have been tested on Linux, and a configuration for Windows in 32-bit mode
|
|
has also been tested. Specific Makefiles for the above mentioned test
|
|
configurations may also be a good base for deriving your own.
|
|
|
|
Usage
|
|
=====
|
|
|
|
After having successfully compiled, and made a backup of your important
|
|
files, you can start the defragmenter by issuing in a terminal windows the
|
|
command :
|
|
|
|
udefrag [options] <device>
|
|
|
|
Where <device> is an unmounted partition, such as "/dev/sdb1" (quotes
|
|
not required). UltraDefrag will start and display the file is is currently
|
|
defragmenting. After it finishes, a report is stored in the file "fraglist.txt"
|
|
within the defragmented partition. Currently, a single partition may be
|
|
selected, and the options to request or deny specific files are not
|
|
available.
|
|
|
|
The only options currently available are :
|
|
|
|
-f n, --min-fragments=n :
|
|
Only defragment files with more than n fragments (n being a
|
|
decimal number)
|
|
-h, --help :
|
|
Display basic usage information
|
|
-m, --show-cluster-map :
|
|
Display a rough map of used space. The characters displayed show
|
|
what the space is used for. If the option is not selected, an
|
|
indication of the file being defragmented is displayed.
|
|
-n, --dry-run, --do_nothing :
|
|
Do not make any modification to the file system.
|
|
-o, --optimize :
|
|
Optimize volume space (instead of default : defragment files)
|
|
-s n, --max-size==n :
|
|
Only defragment files bigger than n bytes (n being a decimal
|
|
number with an optional suffix K, M, G or T)
|
|
-t, --trace :
|
|
Output debugging information to stderr. More information may be
|
|
obtained by setting the option twice.
|
|
--map-rows=n :
|
|
Number of rows to display the cluster map on screen
|
|
--map-symbols-per-line=n
|
|
Number of columns to display the cluster map on screen
|
|
|
|
DO NOT STOP A DEFRAGMENTATION in progress by killing the process or
|
|
shutting down the computer. You may however stop it safely by hitting
|
|
Ctrl-C.
|
|
|
|
Defragmentation generally creates contiguous free space which provides
|
|
opportunity for further defragmentation, so restarting udefrag may yield
|
|
a better defragmentation.
|
|
|
|
Developer's corner
|
|
==================
|
|
|
|
If you want to dig into the code, below are the changes which had to
|
|
be done for porting from Windows. Improvements and bug fixes complying
|
|
with these rules are welcome.
|
|
|
|
Variables
|
|
=========
|
|
|
|
The usual types for integers of mandatory sizes defined in windows.h
|
|
(such as SHORT, WORD or ULONG) are defined on Linux with the same size,
|
|
however their endianness is the one generally used in the architecture.
|
|
|
|
When a variable defined with a mandatory size is to be formatted using
|
|
a printf-type function, it has to be cast to a basic C type to get
|
|
independence from the architecture. A variable defined as ULONG (32 bits)
|
|
is printed wrongly with the format "%lu" on computers using 64 bits for
|
|
an unsigned long. Similarly, sizeof() or strlen() may return 64-bit
|
|
values badly printed with "%u".
|
|
|
|
Formating a 64-bit integer requires a format "%I64d" or "%lld", so the
|
|
macro LL64 is defined to mean "I64" or "ll" as appropriate. The
|
|
corresponding expression must be cast to 64 bits, typically by as cast
|
|
to ULONGLONG.
|
|
|
|
Note : make sure that LONGLONG and the QuadPart of a LARGE_INTEGER are
|
|
declared as a 64-bit signed integer and not as a double (as may be the
|
|
case in old winnt.h). As a workaround SLONGLONG has been defined as a
|
|
64-bit signed integer in compiler.h and LARGE_INTEGER has been defined
|
|
accordingly in ntndk.h.
|
|
|
|
Of course, Ultradefrag is about defragging file systems which have an
|
|
internal little endian data representation (even on big endian computers).
|
|
The types LESHORT, LELONG and LELONGLONG are used to identify integers
|
|
which are little endian on any computer. These types are the same as
|
|
USHORT, ULONG and ULONGLONG on little endian computers. They can be
|
|
assigned and compared for equality provided they have the same size,
|
|
but for other operations they have to be converted to "cpu-endian". A
|
|
few macroes have been defined for these conversions on computer which
|
|
need them.
|
|
|
|
Character strings
|
|
=================
|
|
|
|
Windows and Linux usually use different representation of characters.
|
|
|
|
Windows uses two bytes per character from the basic Unicode set (the
|
|
extended set requiring surrogate pairs is rarely used). The
|
|
less significant byte comes first (little-endian representation),
|
|
so this is the UTF-16LE encoding of Unicode characters. C compiler
|
|
environments define the type wchar_t as a two-byte unsigned integer,
|
|
thus restricting the character set to the basic one, and the L"string"
|
|
constructs mean a sequence of such wchar_t's.
|
|
|
|
Linux uses one to three bytes per character from the basic Unicode set
|
|
(four bytes for the extended set). This is the UTF-8 encoding. C compiler
|
|
environments define wchar_t as a four-byte signed integer with the
|
|
natural endianness of the CPU used. The L"string" constructs mean
|
|
a sequence of such wchar_t's, not UTF-8 encoded.
|
|
|
|
In order to maximally share the code between Windows and Linux, and
|
|
minimize translations between representations, we use the following
|
|
conventions :
|
|
|
|
In most situations, the Unicode characters are encoded according to
|
|
the traditions of each OS : UTF-16LE for Windows, and UTF-8 for Linux.
|
|
The type utf_t defines a unit of storage for such a string : unsigned
|
|
short on Windows, and char for Linux. String litterals must be defined
|
|
by using the macro UTF("string") which translates to a wide character
|
|
string on Windows and to a plain character string on Linux.
|
|
|
|
Example :
|
|
const utf_t name[] = UTF("my name");
|
|
Which the C preprocessor translates on Windows as :
|
|
const w_char name[] = L"my name";
|
|
and on Linux as :
|
|
const char name[] = "my name";
|
|
|
|
Similarly usual string functions are described with the prefix utf
|
|
to mean an action on w_chars on Windows and an action on chars on Linux :
|
|
|
|
utflen() means wcslen() or strlen()
|
|
utfchr() wcschr() strchr()
|
|
utfrchr() wcsrchr() strrchr()
|
|
utfstr() wcsstr() strstr()
|
|
utfcpy() wcscpy() strcpy()
|
|
utfncpy() wcsncpy() strncpy()
|
|
|
|
Of course, Ultradefrag has to deal with UTF-16LE strings for file names
|
|
and attribute names. In such a situation a character is described by
|
|
the type utf16_t, which is always a two-byte unsigned little endian integer.
|
|
|
|
An extra set of functions has to be used for these strings : utf16len(),
|
|
utf16chr(), etc. They are defined the same as wcs-type functions on Windows,
|
|
but they have to be developed for Linux, even on little endian computers.
|
|
|
|
Windows System calls
|
|
====================
|
|
|
|
Obviously Windows system calls are specific to Windows. When possible
|
|
the needed system calls are emulated on Linux using the same name and
|
|
arguments, either relying on Linux system calls (thread creation, memory
|
|
allocation) or using the ntfs-3g library for NTFS file systems actions.
|
|
|
|
When this is not possible, code sequences may be skipped or redefined
|
|
through preprocessor commands (#ifdef LINUX).
|
|
|
|
Volume letters
|
|
==============
|
|
|
|
Windows generally uses volume letters to designate a specific volume,
|
|
whereas Linux uses device patch. Defining a specific type to mean either
|
|
a volume letter or a device path would cause a lot of modifications to
|
|
the code, so artificial volume letters are kept on Linux and used as
|
|
indexes to an array of volume paths to access to volume when needed.
|
|
This may have to be changed later if code parts are to be linked
|
|
dynamically.
|
|
|
|
Impact on existing code
|
|
=======================
|
|
|
|
Each source code file has begin with a #include "compiler.h" to identify
|
|
the target environment and define macroes to be used on Windows or Linux
|
|
for each function implemented according the the OS. The standard include
|
|
file "windows.h" has to made conditional and replaced by "linux.h" to
|
|
import definitions specific to Linux.
|
|
|
|
Most of the changes to the code are related to character strings. They
|
|
generally have to be defined as utf_t and string functions have to be
|
|
replaced by macroes. Constant wide-strings (L"string") have also to be
|
|
defined through a macro.
|
|
|
|
Little-endian-only variables are apparently only found in ntfs.h and
|
|
ftw_ntfs.c and need more changes.
|
|
|
|
Two new source files have to be added for Linux only. The first one
|
|
emulates the Windows system calls, and the second one makes the needed
|
|
calls to the ntfs-3g driver.
|