summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/uimage.c4
-rw-r--r--fs/uimagefs.c4
-rw-r--r--include/fs.h20
3 files changed, 24 insertions, 4 deletions
diff --git a/common/uimage.c b/common/uimage.c
index 28a25bba2d..b6f0f109ca 100644
--- a/common/uimage.c
+++ b/common/uimage.c
@@ -111,9 +111,9 @@ again:
/*
* 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 13c1fbac05..c0c5750c2c 100644
--- a/fs/uimagefs.c
+++ b/fs/uimagefs.c
@@ -374,9 +374,9 @@ again:
/*
* 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 d7fa7714b4..f8a3b8bda4 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -100,6 +100,26 @@ struct fs_device_d {
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);