diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c index eb7de9e2a384e04714dff8a425726dade5fe1601..1f9e31d285cc90f13ea561b168c7f1a5769b18dc 100644 --- a/fs/nilfs2/dir.c +++ b/fs/nilfs2/dir.c @@ -143,6 +143,9 @@ static bool nilfs_check_page(struct page *page) goto Enamelen; if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1)) goto Espan; + if (unlikely(p->inode && + NILFS_PRIVATE_INODE(le64_to_cpu(p->inode)))) + goto Einumber; } if (offs != limit) goto Eend; @@ -168,6 +171,9 @@ static bool nilfs_check_page(struct page *page) goto bad_entry; Espan: error = "directory entry across blocks"; + goto bad_entry; +Einumber: + error = "disallowed inode number"; bad_entry: nilfs_error(sb, "bad entry in directory #%lu: %s - offset=%lu, inode=%lu, rec_len=%d, name_len=%d", diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index a2f247b6a209ec250cb7da2c1cbede10c14cf03f..986620709b9de048f604b15ee35f8ef78998261b 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h @@ -125,6 +125,11 @@ enum { #define NILFS_VALID_INODE(sb, ino) \ ((ino) >= NILFS_FIRST_INO(sb) || (NILFS_SYS_INO_BITS & BIT(ino))) +#define NILFS_PRIVATE_INODE(ino) ({ \ + ino_t __ino = (ino); \ + ((__ino) < NILFS_USER_INO && (__ino) != NILFS_ROOT_INO && \ + (__ino) != NILFS_SKETCH_INO); }) + /** * struct nilfs_transaction_info: context information for synchronization * @ti_magic: Magic number