diff --git a/common/uimage.c b/common/uimage.c index 28a25bb..b6f0f10 100644 --- a/common/uimage.c +++ b/common/uimage.c @@ -111,9 +111,9 @@ /* * Hack around tftp fs. We need lseek for uImage support, but * this cannot be implemented in tftp fs, so we detect this - * by doing a test lseek and copy the file to ram if it fails + * and copy the file to ram if it fails */ - if (IS_BUILTIN(CONFIG_FS_TFTP) && lseek(fd, 0, SEEK_SET)) { + if (IS_BUILTIN(CONFIG_FS_TFTP) && !can_lseek_backward(fd)) { close(fd); ret = copy_file(filename, uimage_tmp, 0); if (ret) diff --git a/fs/uimagefs.c b/fs/uimagefs.c index 13c1fba..c0c5750 100644 --- a/fs/uimagefs.c +++ b/fs/uimagefs.c @@ -374,9 +374,9 @@ /* * Hack around tftp fs. We need lseek for uImage support, but * this cannot be implemented in tftp fs, so we detect this - * by doing a test lseek and copy the file to ram if it fails + * and copy the file to ram if it fails */ - if (IS_BUILTIN(CONFIG_FS_TFTP) && lseek(fd, 0, SEEK_SET)) { + if (IS_BUILTIN(CONFIG_FS_TFTP) && !can_lseek_backward(fd)) { close(fd); ret = copy_file(priv->filename, priv->tmp, 0); if (ret) diff --git a/include/fs.h b/include/fs.h index d7fa771..f8a3b8b 100644 --- a/include/fs.h +++ b/include/fs.h @@ -100,6 +100,26 @@ char *linux_rootarg; }; +/* + * Some filesystems i.e. tftpfs only support lseek into one direction. + * To detect this limited functionality we add this extra function. + * Additionaly we also return 0 if we even can not seek forward. + */ +static inline int can_lseek_backward(int fd) +{ + int ret; + + ret = lseek(fd, 1, SEEK_SET); + if (ret < 0) + return 0; + + ret = lseek(fd, 0, SEEK_SET); + if (ret < 0) + return 0; + + return ret; +} + #define drv_to_fs_driver(d) container_of(d, struct fs_driver_d, drv) int flush(int fd);