Skip to content

Commit 3984ff8

Browse files
committed
hfsuser: use persistent buffer for aligning reads
Prevents the possibility of larger/future block sizes overflowing the previously stack-allocated buffer for this, at the cost of some additional locking for unaligned reads.
1 parent fd91f7f commit 3984ff8

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

lib/libhfsuser/hfsuser.c

+25-5
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ struct hfs_device {
7777
uint16_t default_file_mode, default_dir_mode;
7878
uid_t default_uid;
7979
gid_t default_gid;
80+
void* read_buf;
81+
pthread_mutex_t read_mutex;
8082
#ifdef HAVE_UBLIO
8183
bool use_ublio;
8284
ublio_filehandle_t ubfh;
@@ -608,7 +610,14 @@ int hfs_open(hfs_volume* vol, const char* name, hfs_callback_args* cbargs) {
608610
BAIL(ubmtx_err);
609611
}
610612
}
613+
else
611614
#endif
615+
if(dev->blksize) {
616+
if(!(dev->read_buf = malloc(dev->blksize)))
617+
BAIL(ENOMEM);
618+
if((err = pthread_mutex_init(&dev->read_mutex,NULL)))
619+
goto error;
620+
}
612621

613622
return 0;
614623

@@ -630,6 +639,10 @@ void hfs_close(hfs_volume* vol, hfs_callback_args* cbargs) {
630639
pthread_mutex_destroy(&dev->ubmtx);
631640
}
632641
#endif
642+
if(dev->read_buf) {
643+
free(dev->read_buf);
644+
pthread_mutex_destroy(&dev->read_mutex);
645+
}
633646
if(dev->fd >= 0)
634647
close(dev->fd);
635648
free(dev);
@@ -680,12 +693,15 @@ static inline int hfs_read_pread(struct hfs_device* dev, void* outbytes, uint64_
680693

681694
char* outbuf = outbytes;
682695
uint32_t leading_padding = offset % dev->blksize;
683-
char buf[dev->blksize];
684696
if(leading_padding) {
685-
if(!hfs_preadall(dev->fd,buf,dev->blksize,offset-leading_padding))
697+
pthread_mutex_lock(&dev->read_mutex);
698+
if(!hfs_preadall(dev->fd,dev->read_buf,dev->blksize,offset-leading_padding)) {
699+
pthread_mutex_unlock(&dev->read_mutex);
686700
return -errno;
701+
}
687702
uint32_t leading_bytes = dev->blksize - leading_padding;
688-
memcpy(outbuf,buf+leading_padding,min(leading_bytes,length));
703+
memcpy(outbuf,(char*)dev->read_buf+leading_padding,min(leading_bytes,length));
704+
pthread_mutex_unlock(&dev->read_mutex);
689705
if(leading_bytes >= length)
690706
return 0;
691707
offset += leading_bytes;
@@ -697,9 +713,13 @@ static inline int hfs_read_pread(struct hfs_device* dev, void* outbytes, uint64_
697713
if(length && !hfs_preadall(dev->fd,outbuf,length,offset))
698714
return -errno;
699715
if(trailing_bytes) {
700-
if(!hfs_preadall(dev->fd,buf,dev->blksize,offset+length))
716+
pthread_mutex_lock(&dev->read_mutex);
717+
if(!hfs_preadall(dev->fd,dev->read_buf,dev->blksize,offset+length)) {
718+
pthread_mutex_unlock(&dev->read_mutex);
701719
return -errno;
702-
memcpy(outbuf+length,buf,trailing_bytes);
720+
}
721+
memcpy(outbuf+length,dev->read_buf,trailing_bytes);
722+
pthread_mutex_unlock(&dev->read_mutex);
703723
}
704724
return 0;
705725
}

0 commit comments

Comments
 (0)