Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/ext2fs/ext2_lookup.c
Show First 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | |||||
#include <sys/namei.h> | #include <sys/namei.h> | ||||
#include <sys/bio.h> | #include <sys/bio.h> | ||||
#include <sys/buf.h> | #include <sys/buf.h> | ||||
#include <sys/endian.h> | #include <sys/endian.h> | ||||
#include <sys/mount.h> | #include <sys/mount.h> | ||||
#include <sys/vnode.h> | #include <sys/vnode.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/dirent.h> | #include <sys/dirent.h> | ||||
#include <sys/sdt.h> | |||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <ufs/ufs/dir.h> | #include <ufs/ufs/dir.h> | ||||
#include <fs/ext2fs/fs.h> | #include <fs/ext2fs/fs.h> | ||||
#include <fs/ext2fs/inode.h> | #include <fs/ext2fs/inode.h> | ||||
#include <fs/ext2fs/ext2_mount.h> | #include <fs/ext2fs/ext2_mount.h> | ||||
#include <fs/ext2fs/ext2fs.h> | #include <fs/ext2fs/ext2fs.h> | ||||
#include <fs/ext2fs/ext2_dinode.h> | #include <fs/ext2fs/ext2_dinode.h> | ||||
#include <fs/ext2fs/ext2_dir.h> | #include <fs/ext2fs/ext2_dir.h> | ||||
#include <fs/ext2fs/ext2_extern.h> | #include <fs/ext2fs/ext2_extern.h> | ||||
#include <fs/ext2fs/fs.h> | #include <fs/ext2fs/fs.h> | ||||
SDT_PROVIDER_DECLARE(ext2fs); | |||||
/* | |||||
* ext2fs trace probe: | |||||
* arg0: verbosity. Higher numbers give more verbose messages | |||||
* arg1: Textual message | |||||
*/ | |||||
SDT_PROBE_DEFINE2(ext2fs, , lookup, trace, "int", "char*"); | |||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
static int dirchk = 1; | static int dirchk = 1; | ||||
#else | #else | ||||
static int dirchk = 0; | static int dirchk = 0; | ||||
#endif | #endif | ||||
static SYSCTL_NODE(_vfs, OID_AUTO, e2fs, CTLFLAG_RD, 0, "EXT2FS filesystem"); | static SYSCTL_NODE(_vfs, OID_AUTO, e2fs, CTLFLAG_RD, 0, "EXT2FS filesystem"); | ||||
SYSCTL_INT(_vfs_e2fs, OID_AUTO, dircheck, CTLFLAG_RW, &dirchk, 0, ""); | SYSCTL_INT(_vfs_e2fs, OID_AUTO, dircheck, CTLFLAG_RW, &dirchk, 0, ""); | ||||
▲ Show 20 Lines • Show All 717 Lines • ▼ Show 20 Lines | while (ep < top) { | ||||
* Get pointer to the next entry. | * Get pointer to the next entry. | ||||
*/ | */ | ||||
ep = (struct ext2fs_direct_2 *)((char *)data + offset); | ep = (struct ext2fs_direct_2 *)((char *)data + offset); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
SDT_PROBE_DEFINE4(ext2fs, , trace, ext2_dirbad_error, | |||||
"char*", "ino_t", "doff_t", "char*"); | |||||
void | void | ||||
ext2_dirbad(struct inode *ip, doff_t offset, char *how) | ext2_dirbad(struct inode *ip, doff_t offset, char *how) | ||||
{ | { | ||||
struct mount *mp; | struct mount *mp; | ||||
mp = ITOV(ip)->v_mount; | mp = ITOV(ip)->v_mount; | ||||
if ((mp->mnt_flag & MNT_RDONLY) == 0) | if ((mp->mnt_flag & MNT_RDONLY) == 0) | ||||
panic("ext2_dirbad: %s: bad dir ino %ju at offset %ld: %s\n", | panic("ext2_dirbad: %s: bad dir ino %ju at offset %ld: %s\n", | ||||
mp->mnt_stat.f_mntonname, (uintmax_t)ip->i_number, | mp->mnt_stat.f_mntonname, (uintmax_t)ip->i_number, | ||||
(long)offset, how); | (long)offset, how); | ||||
else | else | ||||
(void)printf("%s: bad dir ino %ju at offset %ld: %s\n", | SDT_PROBE4(ext2fs, , trace, ext2_dirbad_error, | ||||
mp->mnt_stat.f_mntonname, (uintmax_t)ip->i_number, | mp->mnt_stat.f_mntonname, ip->i_number, offset, how); | ||||
(long)offset, how); | |||||
} | } | ||||
SDT_PROBE_DEFINE5(ext2fs, , trace, ext2_dirbadentry_error, | |||||
"char*", "int", "uint32_t", "uint16_t", "uint8_t"); | |||||
/* | /* | ||||
* Do consistency checking on a directory entry: | * Do consistency checking on a directory entry: | ||||
* record length must be multiple of 4 | * record length must be multiple of 4 | ||||
* entry must fit in rest of its DIRBLKSIZ block | * entry must fit in rest of its DIRBLKSIZ block | ||||
* record must be large enough to contain entry | * record must be large enough to contain entry | ||||
* name is not longer than MAXNAMLEN | * name is not longer than MAXNAMLEN | ||||
* name must be as long as advertised, and null terminated | * name must be as long as advertised, and null terminated | ||||
*/ | */ | ||||
Show All 17 Lines | ext2_dirbadentry(struct vnode *dp, struct ext2fs_direct_2 *de, | ||||
else if (entryoffsetinblock + de->e2d_reclen > DIRBLKSIZ) | else if (entryoffsetinblock + de->e2d_reclen > DIRBLKSIZ) | ||||
error_msg = "directory entry across blocks"; | error_msg = "directory entry across blocks"; | ||||
/* else LATER | /* else LATER | ||||
if (de->inode > dir->i_sb->u.ext2_sb.s_es->s_inodes_count) | if (de->inode > dir->i_sb->u.ext2_sb.s_es->s_inodes_count) | ||||
error_msg = "inode out of bounds"; | error_msg = "inode out of bounds"; | ||||
*/ | */ | ||||
if (error_msg != NULL) { | if (error_msg != NULL) { | ||||
printf("bad directory entry: %s\n", error_msg); | SDT_PROBE5(ext2fs, , trace, ext2_dirbadentry_error, | ||||
printf("offset=%d, inode=%lu, rec_len=%u, name_len=%u\n", | error_msg, entryoffsetinblock, | ||||
entryoffsetinblock, (unsigned long)de->e2d_ino, | de->e2d_ino, de->e2d_reclen, de->e2d_namlen); | ||||
de->e2d_reclen, de->e2d_namlen); | |||||
} | } | ||||
return error_msg == NULL ? 0 : 1; | return error_msg == NULL ? 0 : 1; | ||||
} | } | ||||
/* | /* | ||||
* Insert an entry into the fresh directory block. | * Insert an entry into the fresh directory block. | ||||
* Initialize entry tail if the metadata_csum feature is turned on. | * Initialize entry tail if the metadata_csum feature is turned on. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 407 Lines • ▼ Show 20 Lines | if ((error = VFS_VGET(vp->v_mount, dirbuf.dotdot_ino, | ||||
LK_EXCLUSIVE, &vp)) != 0) { | LK_EXCLUSIVE, &vp)) != 0) { | ||||
vp = NULL; | vp = NULL; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
out: | out: | ||||
if (error == ENOTDIR) | if (error == ENOTDIR) | ||||
printf("checkpath: .. not a directory\n"); | SDT_PROBE2(ext2fs, , lookup, trace, 1, | ||||
"checkpath: .. not a directory"); | |||||
if (vp != NULL) | if (vp != NULL) | ||||
vput(vp); | vput(vp); | ||||
return (error); | return (error); | ||||
} | } |