Inodes & vnodesWe know that a block on id010e is in trouble. But, we have not yet confirmed that that alone is the reason for the crashes. (Though, yes, it's a pretty safe bet.) Before we declare id010e in need of attention from hardware support, let's look more closely at the stack tracebacks we've been getting from the dumps. First, the routines involved: assfail (a, f, l) pvn_vplist_dirty (vp, off, flags) ufs_putpage (vp, off, len, flags, cred) ufs_l_putpage (vp, off, len, flags, cred) syncip (ip, flags, waitfor) update () ufs_sync (vfsp) The calling parameters listed as vp are vnode pointers. The parameter ip is a pointer to an inode structure. The stack traceback shows that the process that crashed was performing a file system sync. The recently updated inodes were being written back to disk. This process is done inode by inode. The syncip() routine is called by update() for each inode that needs to be sync'ed, in other words, updated on the disk. Before we try to establish which inode syncip() was working with, take a moment to look at the definition of an inode, as described in /usr/include/ufs/inode.h . struct inode { struct inode *i_chain[2]; /* must be first */ struct vnode i_vnode ; /* vnode associated with this inode */ struct vnode *i_devvp; /* vnode for block I/O */ u_short i_flag; dev_t i_dev; /* device where inode resides */ ino_t i_number; /* i number, 1-to-1 with device address */ off_t i_diroff; /* offset in dir, where we found last entry */ struct fs *i_fs; /* file sys associated with this inode */ struct dquot *i_dquot; /* quota structure controlling this file */ long i_owner; /* proc index of process locking inode */ long i_count; /* number of inode locks for i_owner */ union { daddr_t if_nextr; /* next byte read offset (read-ahead) */ struct socket *is_socket; } i_un; struct { struct inode *if_freef; /* free list forward */ struct inode **if_freeb; /* free list back */ } i_fr; struct icommon { u_short ic_mode; /* 0: mode and type of file */ short ic_nlink; /* 2: number of links to file */ uid_t ic_uid; /* 4: owner's user id */ gid_t ic_gid; /* 6: owner's group id */ quad ic_size; /* 8: number of bytes in file */ #ifdef KERNEL struct timeval ic_atime; /* 16: time last accessed */ struct timeval ic_mtime; /* 24: time last modified */ struct timeval ic_ctime; /* 32: last time inode changed */ #else time_t ic_atime; /* 16: time last accessed */ long ic_atspare; time_t ic_mtime; /* 24: time last modified */ long ic_mtspare; time_t ic_ctime; /* 32: last time inode changed */ long ic_ctspare; #endif daddr_t ic_db[NDADDR]; /* 40: disk block addresses */ daddr_t ic_ib[NIADDR]; /* 88: indirect blocks */ long ic_flags; /* 100: status, currently unused */ long ic_blocks; /* 104: blocks actually held */ long ic_gen; /* 108: generation number */ /* * XXX - the disk spares were used to avoid changing * the size of the incore inode in a minor release. * Fix for 5.0 release. * Also remove the code in iget, iupdat that clears them. */ long ic_delaylen; /* 112: delayed writes, units=bytes */ long ic_delayoff; /* 116: where we started delaying */ long ic_nextrio; /* 120: where to start the next clust */ long ic_writes; /* 124: number of outstanding writes */ } i_ic; }; The interesting thing about UFS inodes is that the vnode structure is built into the inode structure. Therefore, let's also look at the vnode structure, as described in /usr/include/sys/vnode.h . enum vtype { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VSOCK, VBAD, VFIFO }; struct vnode { u_short v_flag; /* vnode flags (see below) */ u_short v_count; /* reference count */ u_short v_shlockc; /* count of shared locks */ u_short v_exlockc; /* count of exclusive locks */ struct vfs *v_vfsmountedhere; /* ptr to vfs mounted here */ struct vnodeops *v_op; /* vnode operations */ union { struct socket *v_Socket; /* unix ipc */ struct stdata *v_Stream; /* stream */ struct page *v_Pages; /* vnode pages list */ } v_s; struct vfs *v_vfsp; /* ptr to vfs we are in */ enum vtype v_type; /* vnode type */ dev_t v_rdev; /* device (VCHR, VBLK) */ long *v_filocks; /* File/Record locks ... */ caddr_t v_data; /* private data for fs */ }; Okay, we are now ready to go take a look at the inode in question in the crashes. We will also establish what process was actually running at the time of the crash. |