Skip to content

Commit

Permalink
hfsuser: use persistent buffer for aligning reads
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
0x09 committed May 5, 2024
1 parent fd91f7f commit 06c945a
Showing 1 changed file with 25 additions and 5 deletions.
30 changes: 25 additions & 5 deletions lib/libhfsuser/hfsuser.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ struct hfs_device {
uint16_t default_file_mode, default_dir_mode;
uid_t default_uid;
gid_t default_gid;
void* read_buf;
pthread_mutex_t read_mutex;
#ifdef HAVE_UBLIO
bool use_ublio;
ublio_filehandle_t ubfh;
Expand Down Expand Up @@ -610,6 +612,13 @@ int hfs_open(hfs_volume* vol, const char* name, hfs_callback_args* cbargs) {
}
#endif

if(!dev->use_ublio && dev->blksize) {
if(!(dev->read_buf = malloc(dev->blksize)))
BAIL(ENOMEM);
if((err = pthread_mutex_init(&dev->read_mutex,NULL)))
goto error;
}

return 0;

error:
Expand All @@ -630,6 +639,10 @@ void hfs_close(hfs_volume* vol, hfs_callback_args* cbargs) {
pthread_mutex_destroy(&dev->ubmtx);
}
#endif
if(dev->read_buf) {
free(dev->read_buf);
pthread_mutex_destroy(&dev->read_mutex);
}
if(dev->fd >= 0)
close(dev->fd);
free(dev);
Expand Down Expand Up @@ -680,12 +693,15 @@ static inline int hfs_read_pread(struct hfs_device* dev, void* outbytes, uint64_

char* outbuf = outbytes;
uint32_t leading_padding = offset % dev->blksize;
char buf[dev->blksize];
if(leading_padding) {
if(!hfs_preadall(dev->fd,buf,dev->blksize,offset-leading_padding))
pthread_mutex_lock(&dev->read_mutex);
if(!hfs_preadall(dev->fd,dev->read_buf,dev->blksize,offset-leading_padding)) {
pthread_mutex_unlock(&dev->read_mutex);
return -errno;
}
uint32_t leading_bytes = dev->blksize - leading_padding;
memcpy(outbuf,buf+leading_padding,min(leading_bytes,length));
memcpy(outbuf,(char*)dev->read_buf+leading_padding,min(leading_bytes,length));
pthread_mutex_unlock(&dev->read_mutex);
if(leading_bytes >= length)
return 0;
offset += leading_bytes;
Expand All @@ -697,9 +713,13 @@ static inline int hfs_read_pread(struct hfs_device* dev, void* outbytes, uint64_
if(length && !hfs_preadall(dev->fd,outbuf,length,offset))
return -errno;
if(trailing_bytes) {
if(!hfs_preadall(dev->fd,buf,dev->blksize,offset+length))
pthread_mutex_lock(&dev->read_mutex);
if(!hfs_preadall(dev->fd,dev->read_buf,dev->blksize,offset+length)) {
pthread_mutex_unlock(&dev->read_mutex);
return -errno;
memcpy(outbuf+length,buf,trailing_bytes);
}
memcpy(outbuf+length,dev->read_buf,trailing_bytes);
pthread_mutex_unlock(&dev->read_mutex);
}
return 0;
}
Expand Down

0 comments on commit 06c945a

Please sign in to comment.