Skip to content

Commit

Permalink
Return back checking file for sparseness. Use lseek(SEEK_HOLE) if sup…
Browse files Browse the repository at this point in the history
…ported by the system, otherwise fallback to block check. This allows to workaround bugs with SMB client and not introduce new bugs for filesystems with compression and deduplication.

This has theoretical bug if our collection spans different
filesystems and some filesystems support holes, and some not.
If this ever encountered we should use pathconf(2) and cache
its result for directories.
  • Loading branch information
glebius authored and Justin Maggard committed Jan 17, 2018
1 parent debb502 commit 3e8da9b
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ AC_C_BIGENDIAN
AC_FUNC_FORK
AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
AC_CHECK_FUNCS([gethostname getifaddrs gettimeofday inet_ntoa memmove memset mkdir realpath select sendfile setlocale socket strcasecmp strchr strdup strerror strncasecmp strpbrk strrchr strstr strtol strtoul])
AC_CHECK_DECLS([SEEK_HOLE])

#
# Check for struct ip_mreqn
Expand Down
34 changes: 27 additions & 7 deletions monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
Expand Down Expand Up @@ -471,6 +472,30 @@ monitor_insert_file(const char *name, const char *path)
return depth;
}

static bool
check_notsparse(const char *path)
#if HAVE_DECL_SEEK_HOLE
{
int fd;
bool rv;

if ((fd = open(path, O_RDONLY)) == -1)
return (false);
if (lseek(fd, 0, SEEK_HOLE) == lseek(fd, 0, SEEK_END))
rv = true;
else
rv = false;
close(fd);
return (rv);
}
#else
{
struct stat st;

return (stat(path, &st) == 0 && (st.st_blocks << 9 >= st.st_size));
}
#endif

int
monitor_insert_directory(int fd, char *name, const char * path)
{
Expand All @@ -480,7 +505,6 @@ monitor_insert_directory(int fd, char *name, const char * path)
char path_buf[PATH_MAX];
enum file_types type = TYPE_UNKNOWN;
media_types dir_types;
struct stat st;

if( access(path, R_OK|X_OK) != 0 )
{
Expand Down Expand Up @@ -538,12 +562,8 @@ monitor_insert_directory(int fd, char *name, const char * path)
{
monitor_insert_directory(fd, esc_name, path_buf);
}
else if( type == TYPE_FILE )
{
if( (stat(path_buf, &st) == 0) )
{
monitor_insert_file(esc_name, path_buf);
}
else if( type == TYPE_FILE && check_notsparse(path_buf)) {
monitor_insert_file(esc_name, path_buf);
}
free(esc_name);
}
Expand Down

0 comments on commit 3e8da9b

Please sign in to comment.