From 9e7184e2a6c0b9f995083ac698e10d991e35dcdf Mon Sep 17 00:00:00 2001 From: Erik Larsson Date: Fri, 18 Apr 2014 11:54:54 +0200 Subject: [PATCH] Fix readdir I/O error on file names larger than 255 bytes in Solaris. If a readdir operation returned a file name larger than 255 bytes, Solaris/Illumos would return I/O error from the readdir operation. Fixed by truncating the file name returned in the readdir operation. --- src/lowntfs-3g.c | 24 ++++++++++++++++++++++-- src/ntfs-3g.c | 24 ++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/lowntfs-3g.c b/src/lowntfs-3g.c index a7852a99..546ab69f 100644 --- a/src/lowntfs-3g.c +++ b/src/lowntfs-3g.c @@ -79,7 +79,9 @@ #if defined(__APPLE__) || defined(__DARWIN__) #include -#endif /* defined(__APPLE__) || defined(__DARWIN__) */ +#elif defined(__sun) && defined (__SVR4) +#include +#endif /* defined(__APPLE__) || defined(__DARWIN__), ... */ #include "compat.h" #include "attrib.h" @@ -1020,7 +1022,25 @@ static int ntfs_fuse_filler(ntfs_fuse_fill_context_t *fill_ctx, memset(filename + MAXNAMLEN, 0, filenamelen - MAXNAMLEN); ntfs_log_debug(" after: '%s'\n", filename); } -#endif /* defined(__APPLE__) || defined(__DARWIN__) */ +#elif defined(__sun) && defined (__SVR4) + /* + * Returning file names larger than MAXNAMELEN (256) bytes + * causes Solaris/Illumos to return an I/O error from the system + * call. + * However we also need space for a terminating NULL, or user + * space tools will bug out since they expect a NULL terminator. + * Effectively the maximum length of a file name is MAXNAMELEN - + * 1 (255). + */ + if (filenamelen > (MAXNAMELEN - 1)) { + ntfs_log_debug("Truncating %d byte filename to %d " + "bytes.\n", filenamelen, MAXNAMELEN - 1); + ntfs_log_debug(" before: '%s'\n", filename); + memset(&filename[MAXNAMELEN - 1], 0, + filenamelen - (MAXNAMELEN - 1)); + ntfs_log_debug(" after: '%s'\n", filename); + } +#endif /* defined(__APPLE__) || defined(__DARWIN__), ... */ current = fill_ctx->last; sz = fuse_add_direntry(fill_ctx->req, diff --git a/src/ntfs-3g.c b/src/ntfs-3g.c index 166ef727..51cb0cc1 100644 --- a/src/ntfs-3g.c +++ b/src/ntfs-3g.c @@ -78,7 +78,9 @@ #if defined(__APPLE__) || defined(__DARWIN__) #include -#endif /* defined(__APPLE__) || defined(__DARWIN__) */ +#elif defined(__sun) && defined (__SVR4) +#include +#endif /* defined(__APPLE__) || defined(__DARWIN__), ... */ #include "compat.h" #include "attrib.h" @@ -1057,7 +1059,25 @@ static int ntfs_fuse_filler(ntfs_fuse_fill_context_t *fill_ctx, memset(filename + MAXNAMLEN, 0, filenamelen - MAXNAMLEN); ntfs_log_debug(" after: '%s'\n", filename); } -#endif /* defined(__APPLE__) || defined(__DARWIN__) */ +#elif defined(__sun) && defined (__SVR4) + /* + * Returning file names larger than MAXNAMELEN (256) bytes + * causes Solaris/Illumos to return an I/O error from the system + * call. + * However we also need space for a terminating NULL, or user + * space tools will bug out since they expect a NULL terminator. + * Effectively the maximum length of a file name is MAXNAMELEN - + * 1 (255). + */ + if (filenamelen > (MAXNAMELEN - 1)) { + ntfs_log_debug("Truncating %d byte filename to %d " + "bytes.\n", filenamelen, MAXNAMELEN - 1); + ntfs_log_debug(" before: '%s'\n", filename); + memset(&filename[MAXNAMELEN - 1], 0, + filenamelen - (MAXNAMELEN - 1)); + ntfs_log_debug(" after: '%s'\n", filename); + } +#endif /* defined(__APPLE__) || defined(__DARWIN__), ... */ ret = fill_ctx->filler(fill_ctx->buf, filename, &st, 0); }