Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hfsplus: emit proper file type from readdir

hfsplus_readdir() incorrectly returned DT_REG for symbolic links and
special files. Return DT_REG, DT_LNK, DT_FIFO, DT_CHR, DT_BLK, DT_SOCK,
or DT_UNKNOWN according to mode field in catalog record. Programs
relying on information from readdir will now work correctly with HFS+.

Signed-off-by: Sergei Antonov <saproj@gmail.com>
Cc: Anton Altaparmakov <aia21@cam.ac.uk>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Vyacheslav Dubeyko <slava@dubeyko.com>
Cc: Hin-Tak Leung <htl10@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Sergei Antonov and committed by
Linus Torvalds
97a62eae 7f2fc81e

+19 -1
+19 -1
fs/hfsplus/dir.c
··· 218 218 be32_to_cpu(entry.folder.id), DT_DIR)) 219 219 break; 220 220 } else if (type == HFSPLUS_FILE) { 221 + u16 mode; 222 + unsigned type = DT_UNKNOWN; 223 + 221 224 if (fd.entrylength < sizeof(struct hfsplus_cat_file)) { 222 225 pr_err("small file entry\n"); 223 226 err = -EIO; 224 227 goto out; 225 228 } 229 + 230 + mode = be16_to_cpu(entry.file.permissions.mode); 231 + if (S_ISREG(mode)) 232 + type = DT_REG; 233 + else if (S_ISLNK(mode)) 234 + type = DT_LNK; 235 + else if (S_ISFIFO(mode)) 236 + type = DT_FIFO; 237 + else if (S_ISCHR(mode)) 238 + type = DT_CHR; 239 + else if (S_ISBLK(mode)) 240 + type = DT_BLK; 241 + else if (S_ISSOCK(mode)) 242 + type = DT_SOCK; 243 + 226 244 if (!dir_emit(ctx, strbuf, len, 227 - be32_to_cpu(entry.file.id), DT_REG)) 245 + be32_to_cpu(entry.file.id), type)) 228 246 break; 229 247 } else { 230 248 pr_err("bad catalog entry type\n");