Index: findutils-4.2.28/find/parser.c
===================================================================
--- findutils-4.2.28.orig/find/parser.c	2006-11-09 00:44:19.051030424 -0800
+++ findutils-4.2.28/find/parser.c	2006-11-09 00:50:07.350127617 -0800
@@ -134,6 +134,7 @@
 static boolean parse_regextype     PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
 static boolean parse_samefile      PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
 static boolean parse_size          PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
+static boolean parse_sparse        PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
 static boolean parse_true          PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
 static boolean parse_type          PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
 static boolean parse_uid           PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
@@ -270,6 +271,7 @@
   PARSE_OPTION     ("regextype",             regextype),     /* GNU */
   PARSE_TEST       ("samefile",              samefile),	     /* GNU */
   PARSE_TEST       ("size",                  size),
+  PARSE_TEST       ("sparse",                sparse),	     /* GNU */
   PARSE_TEST       ("type",                  type),
   PARSE_TEST       ("uid",                   uid),	     /* GNU */
   PARSE_TEST       ("used",                  used),	     /* GNU */
@@ -1601,6 +1603,15 @@
   return true;
 }
 
+static boolean
+parse_sparse (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+  (void) argv;
+  (void) arg_ptr;
+
+  insert_primary (entry);
+  return true;
+}
 
 static boolean
 parse_true (const struct parser_table* entry, char **argv, int *arg_ptr)
Index: findutils-4.2.28/find/pred.c
===================================================================
--- findutils-4.2.28.orig/find/pred.c	2006-11-09 00:40:54.102242213 -0800
+++ findutils-4.2.28/find/pred.c	2006-11-11 16:39:25.110381238 -0800
@@ -37,6 +37,7 @@
 #include "printquoted.h"
 #include "buildcmd.h"
 #include "yesno.h"
+#include <sys/statvfs.h>
 
 #if ENABLE_NLS
 # include <libintl.h>
@@ -209,6 +210,7 @@
   {pred_regex, "regex   "},
   {pred_samefile,"samefile "},
   {pred_size, "size    "},
+  {pred_sparse, "sparse  "},
   {pred_true, "true    "},
   {pred_type, "type    "},
   {pred_uid, "uid     "},
@@ -1346,6 +1348,28 @@
 }
 
 boolean
+pred_sparse (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+  static dev_t cur_fs_dev = -1;
+  static struct statvfs cur_fs;
+
+  (void) pathname;
+  (void) pred_ptr;
+
+  if (!S_ISREG (stat_buf->st_mode))
+    return false;
+
+  if (stat_buf->st_dev != cur_fs_dev) {
+    if (statvfs(state.rel_pathname, &cur_fs)) {
+      return false;
+    }
+    cur_fs_dev = stat_buf->st_dev;
+  }
+
+  return (stat_buf->st_size > stat_buf->st_blocks * cur_fs.f_bsize);
+}
+
+boolean
 pred_samefile (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
 {
   /* Potential optimisation: because of the loop protection, we always
Index: findutils-4.2.28/find/defs.h
===================================================================
--- findutils-4.2.28.orig/find/defs.h	2006-11-09 00:53:11.220756091 -0800
+++ findutils-4.2.28/find/defs.h	2006-11-09 00:53:23.960817841 -0800
@@ -475,6 +475,7 @@
 boolean pred_regex PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
 boolean pred_samefile PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
 boolean pred_size PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
+boolean pred_sparse PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
 boolean pred_true PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
 boolean pred_type PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
 boolean pred_uid PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
Index: findutils-4.2.28/doc/find.texi
===================================================================
--- findutils-4.2.28.orig/doc/find.texi	2006-11-09 00:55:49.291147085 -0800
+++ findutils-4.2.28/doc/find.texi	2006-11-09 01:05:32.961133296 -0800
@@ -919,6 +919,12 @@
 (@pxref{Single File}).
 @end deffn
 
+@deffn Test -sparse
+True if the file is a regular file and has a size larger than the
+number of blocks allocated multiplied by the blocksize.  This generally
+occurs if the file is sparse.
+@end deffn
+
 @node Type
 @section Type
 
Index: findutils-4.2.28/find/find.1
===================================================================
--- findutils-4.2.28.orig/find/find.1	2006-11-09 00:55:49.103087138 -0800
+++ findutils-4.2.28/find/find.1	2006-11-09 00:59:57.978406247 -0800
@@ -429,6 +429,10 @@
 differently.  The `b' suffix always denotes 512-byte blocks and never
 1 Kilobyte blocks, which is different to the behaviour of \-ls.
 
+.IP \-sparse
+True if the file is a regular file and has a size larger than the
+number of blocks allocated multiplied by the blocksize.  This generally
+occurs if the file is sparse.
 .IP \-true
 Always true.
 .IP "\-type \fIc\fR"
Index: findutils-4.2.28/find/testsuite/find.gnu/sparse.exp
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ findutils-4.2.28/find/testsuite/find.gnu/sparse.exp	2006-11-09 01:16:23.428270215 -0800
@@ -0,0 +1,9 @@
+# tests for -sparse
+exec rm -rf tmp
+exec mkdir tmp
+exec echo hi > tmp/notsparse
+# note that some filesystems (such as XFS) won't create a sparse file when the
+# "holes" are too small.  hopefully this hole is large enough.
+exec dd if=/dev/zero of=tmp/sparse seek=10000 bs=4096 count=1 2>/dev/null
+find_start p { tmp -sparse }
+exec rm -rf tmp
Index: findutils-4.2.28/find/testsuite/find.gnu/sparse.xo
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ findutils-4.2.28/find/testsuite/find.gnu/sparse.xo	2006-11-09 01:03:14.172919476 -0800
@@ -0,0 +1 @@
+tmp/sparse
