pxar: fuse: avoid possible hash collision in lookup by additional checking against filename
The hash of the filename in the goodbye table items allows to quickly compare to a hashed filename. Unfortunately, a matching hash is no garantee for matching filenames as hash collisions are possible. This patch fixes such possible collisions by further checking the filenames once a matching hash has been found. This introduces no significant extra cost (except for the filename comparison) for cases with matching hashes, as the lookup call has to seek and read the file attributes (including the filename) anyway. In cases with hash collision, the next matching item is read and treaded analogously (what means we need at least one extra seek). As collisions should be not that frequent, this should be an acceptable penalty. Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
committed by
Dietmar Maurer
parent
ba5e67475a
commit
0e20b336e1
@ -289,7 +289,7 @@ impl<R: Read + Seek, F: Fn(&Path) -> Result<(), Error>> Decoder<R, F> {
|
||||
/// directories `PXAR_GOODBYE_TAIL_MARKER`. This is not mandatory and it can
|
||||
/// also directly point to its `PXAR_FILENAME` or `PXAR_ENTRY`, thereby
|
||||
/// avoiding an additional seek.
|
||||
pub fn attributes(&mut self, offset: u64) -> Result<(PxarEntry, PxarAttributes, u64), Error> {
|
||||
pub fn attributes(&mut self, offset: u64) -> Result<(OsString, PxarEntry, PxarAttributes, u64), Error> {
|
||||
self.seek(SeekFrom::Start(offset))?;
|
||||
|
||||
let mut marker: u64 = self.inner.read_item()?;
|
||||
@ -301,11 +301,14 @@ impl<R: Read + Seek, F: Fn(&Path) -> Result<(), Error>> Decoder<R, F> {
|
||||
marker = self.inner.read_item()?;
|
||||
}
|
||||
|
||||
if marker == PXAR_FILENAME {
|
||||
let filename = if marker == PXAR_FILENAME {
|
||||
let size: u64 = self.inner.read_item()?;
|
||||
let _filename = self.inner.read_filename(size)?;
|
||||
let filename = self.inner.read_filename(size)?;
|
||||
marker = self.inner.read_item()?;
|
||||
}
|
||||
filename
|
||||
} else {
|
||||
OsString::new()
|
||||
};
|
||||
|
||||
if marker == PXAR_FORMAT_HARDLINK {
|
||||
let size: u64 = self.inner.read_item()?;
|
||||
@ -324,12 +327,12 @@ impl<R: Read + Seek, F: Fn(&Path) -> Result<(), Error>> Decoder<R, F> {
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
Ok((entry, xattr, file_size))
|
||||
Ok((filename, entry, xattr, file_size))
|
||||
}
|
||||
|
||||
/// Opens the file by validating the given `offset` and returning its attrs,
|
||||
/// xattrs and size.
|
||||
pub fn open(&mut self, offset: u64) -> Result<(PxarEntry, PxarAttributes, u64), Error> {
|
||||
pub fn open(&mut self, offset: u64) -> Result<(OsString, PxarEntry, PxarAttributes, u64), Error> {
|
||||
self.attributes(offset)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user