git: 3eb019000c9e - main - loader: tftp: Add preload method
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 16 Dec 2021 10:53:24 UTC
The branch main has been updated by manu: URL: https://cgit.FreeBSD.org/src/commit/?id=3eb019000c9eba6dafad6741a88f627b4d4fcd8a commit 3eb019000c9eba6dafad6741a88f627b4d4fcd8a Author: Emmanuel Vadot <manu@FreeBSD.org> AuthorDate: 2021-12-10 09:37:01 +0000 Commit: Emmanuel Vadot <manu@FreeBSD.org> CommitDate: 2021-12-16 10:50:41 +0000 loader: tftp: Add preload method The preload method will transfer the whole file in a buffer and cache it so read/lseek operations are faster. Reviewed by: imp, tsoome MFC after: 2 weeks Sponsored by: Beckhoff Automation GmbH & Co. KG Differential Revision: https://reviews.freebsd.org/D33410 --- stand/libsa/tftp.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/stand/libsa/tftp.c b/stand/libsa/tftp.c index dcfce29a9968..9d1c70236925 100644 --- a/stand/libsa/tftp.c +++ b/stand/libsa/tftp.c @@ -73,6 +73,7 @@ static int tftp_read(struct open_file *, void *, size_t, size_t *); static off_t tftp_seek(struct open_file *, off_t, int); static int tftp_set_blksize(struct tftp_handle *, const char *); static int tftp_stat(struct open_file *, struct stat *); +static int tftp_preload(struct open_file *); struct fs_ops tftp_fsops = { .fs_name = "tftp", @@ -82,6 +83,7 @@ struct fs_ops tftp_fsops = { .fo_write = null_write, .fo_seek = tftp_seek, .fo_stat = tftp_stat, + .fo_preload = tftp_preload, .fo_readdir = null_readdir }; @@ -521,6 +523,16 @@ tftp_read(struct open_file *f, void *addr, size_t size, size = tftpfile->tftp_tsize - tftpfile->off; } + if (tftpfile->tftp_cache != NULL) { + bcopy(tftpfile->tftp_cache + tftpfile->off, + addr, size); + + addr = (char *)addr + size; + tftpfile->off += size; + res -= size; + goto out; + } + while (size > 0) { int needblock, count; @@ -586,6 +598,7 @@ tftp_read(struct open_file *f, void *addr, size_t size, } +out: if (resid != NULL) *resid = res; return (rc); @@ -603,6 +616,7 @@ tftp_close(struct open_file *f) if (tftpfile) { free(tftpfile->path); free(tftpfile->pkt); + free(tftpfile->tftp_cache); free(tftpfile); } is_open = 0; @@ -643,6 +657,52 @@ tftp_seek(struct open_file *f, off_t offset, int where) return (tftpfile->off); } +static int +tftp_preload(struct open_file *f) +{ + struct tftp_handle *tftpfile; + char *cache; + int rc; +#ifdef TFTP_DEBUG + time_t start, end; +#endif + + tftpfile = f->f_fsdata; + cache = malloc(sizeof(char) * tftpfile->tftp_tsize); + if (cache == NULL) { + printf("Couldn't allocate %ju bytes for preload caching" + ", disabling caching\n", + (uintmax_t)sizeof(char) * tftpfile->tftp_tsize); + return (-1); + } + +#ifdef TFTP_DEBUG + start = getsecs(); + printf("Preloading %s ", tftpfile->path); +#endif + while (tftpfile->islastblock == 0) { + twiddle(32); + rc = tftp_getnextblock(tftpfile); + if (rc) { + free(cache); + printf("Got TFTP error %d, disabling caching\n", rc); + return (rc); + } + bcopy(tftpfile->tftp_hdr->th_data, + cache + (tftpfile->tftp_blksize * (tftpfile->currblock - 1)), + tftpfile->validsize); + } +#ifdef TFTP_DEBUG + end = getsecs(); + printf("\nPreloaded %s (%ju bytes) during %jd seconds\n", + tftpfile->path, (intmax_t)tftpfile->tftp_tsize, + (intmax_t)end - start); +#endif + + tftpfile->tftp_cache = cache; + return (0); +} + static int tftp_set_blksize(struct tftp_handle *h, const char *str) {