Optimise -fstype NOTUSED to -false at -O2.

Optimise -fstype NOTUSED to -false at -O2.
* find/parser.c: Include mountlist.h.
(insert_false): New function, inserts a -false predicate.
(parse_false): Use insert_false.
(is_used_fs_type): New function, determines if any mounted
filesystem is of the named type.
(parse_fstype): At optimisation level 2 and above, -fstpe FOO
is converted to -false if no mounted filesytem is of type FOO.
* find/find.1: Document this optimisation.
* doc/find.texi (Optimisation Options): Likewise.
* NEWS: Mention this change.
This commit is contained in:
James Youngman
2009-07-18 15:15:05 +01:00
parent 64f3d9b616
commit cbdfd2d86f
5 changed files with 103 additions and 14 deletions

View File

@@ -1,5 +1,17 @@
2010-04-01 James Youngman <jay@gnu.org>
Optimise -fstype NOTUSED to -false at -O2.
* find/parser.c: Include mountlist.h.
(insert_false): New function, inserts a -false predicate.
(parse_false): Use insert_false.
(is_used_fs_type): New function, determines if any mounted
filesystem is of the named type.
(parse_fstype): At optimisation level 2 and above, -fstpe FOO
is converted to -false if no mounted filesytem is of type FOO.
* find/find.1: Document this optimisation.
* doc/find.texi (Optimisation Options): Likewise.
* NEWS: Mention this change.
Updated copyright years to add 2010.
* find/find.c: Add 2010.
* find/fstype.c: Add 2010.

7
NEWS
View File

@@ -13,6 +13,13 @@ since it contains Makefiles which are vulnerable to CVE-2009-4029.
patch #4848: Patch - Support for SELinux
** Performance changes
If you use the -fstype FOO predicate and specify a filsystem type FOO
which is not known (e.g. present in /etc/mtab) at the time find
starts, that predicate is now equivalent to -false. This substitution
currently occurs at optimisation level 2 and above.
** Bug Fixes
#29089: SELinux --context and %Z options

View File

@@ -3123,6 +3123,12 @@ information from the inode. On many modern versions of Unix, file
types are returned by @code{readdir()} and so these predicates are
faster to evaluate than predicates which need to stat the file first.
If you use the @samp{-fstype FOO} predicate and specify a filsystem
type @samp{FOO} which is not known (that is, present in
@file{/etc/mtab}) at the time @code{find} starts, that predicate is
equivalent to @samp{-false}.
@item 3
At this optimisation level, the full cost-based query optimiser is
enabled. The order of tests is modified so that cheap (i.e., fast)

View File

@@ -253,6 +253,15 @@ modern versions of Unix, file types are returned by
.B readdir()
and so these predicates are faster to evaluate than predicates which
need to stat the file first.
If you use the
.B \-fstype
.I FOO
predicate and specify a filsystem type
.I FOO
which is not known (that is, present in `/etc/mtab') at the time
.B find
starts, that predicate is equivalent to
.BR \-false .
.IP 3
At this optimisation level, the full cost-based query optimiser is
enabled. The order of tests is modified so that cheap (i.e. fast)

View File

@@ -26,6 +26,7 @@
#include <errno.h>
#include <grp.h>
#include <fnmatch.h>
#include "mountlist.h"
#include "modechange.h"
#include "modetype.h"
#include "xstrtol.h"
@@ -941,20 +942,26 @@ parse_execdir (const struct parser_table* entry, char **argv, int *arg_ptr)
}
static boolean
parse_false (const struct parser_table* entry, char **argv, int *arg_ptr)
insert_false(void)
{
struct predicate *our_pred;
const struct parser_table *entry_false;
(void) argv;
(void) arg_ptr;
our_pred = insert_primary_noarg (entry);
entry_false = find_parser("false");
our_pred = insert_primary_noarg (entry_false);
our_pred->need_stat = our_pred->need_type = false;
our_pred->side_effects = our_pred->no_default_print = false;
our_pred->est_success_rate = 0.0f;
return true;
}
static boolean
parse_false (const struct parser_table* entry, char **argv, int *arg_ptr)
{
return insert_false ();
}
static boolean
insert_fls (const struct parser_table* entry, const char *filename)
{
@@ -1056,22 +1063,70 @@ static float estimate_fstype_success_rate (const char *fsname)
}
static boolean
is_used_fs_type(const char *name)
{
if (0 == strcmp("afs", name))
{
/* I guess AFS may not appear in /etc/mtab (or equivalent) but still be in use,
so assume we always need to check for AFS. */
return true;
}
else
{
const struct mount_entry *entries = read_file_system_list(false);
if (entries)
{
const struct mount_entry *entry;
for (entry = entries; entry; entry = entry->me_next)
{
if (0 == strcmp(name, entry->me_type))
return true;
}
}
else
{
return true;
}
}
return false;
}
static boolean
parse_fstype (const struct parser_table* entry, char **argv, int *arg_ptr)
{
const char *typename;
if (collect_arg (argv, arg_ptr, &typename))
{
struct predicate *our_pred = insert_primary (entry, typename);
our_pred->args.str = typename;
if (options.optimisation_level < 2 || is_used_fs_type (typename))
{
struct predicate *our_pred = insert_primary (entry, typename);
our_pred->args.str = typename;
/* This is an expensive operation, so although there are
* circumstances where it is selective, we ignore this fact
* because we probably don't want to promote this test to the
* front anyway.
*/
our_pred->est_success_rate = estimate_fstype_success_rate (typename);
return true;
/* This is an expensive operation, so although there are
* circumstances where it is selective, we ignore this fact
* because we probably don't want to promote this test to the
* front anyway.
*/
our_pred->est_success_rate = estimate_fstype_success_rate (typename);
return true;
}
else
{
/* This filesystem type is not listed in the mount table.
* Hence this predicate will always return false (with this argument).
* Substitute a predicate with the same effect as -false.
*/
if (options.debug_options & DebugTreeOpt)
{
fprintf (stderr,
"-fstype %s can never succeed, substituting -false\n",
typename);
}
return insert_false ();
}
}
else
{