Module Name: src Committed By: dholland Date: Tue Sep 15 15:00:49 UTC 2015
Modified Files: src/sys/ufs/lfs: ulfs_lookup.c Log Message: Tidy up ulfs_direnter: don't malloc a temporary struct lfs_direct and double-copy it. Just write to the destination buffer. To generate a diff of this commit: cvs rdiff -u -r1.28 -r1.29 src/sys/ufs/lfs/ulfs_lookup.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/ufs/lfs/ulfs_lookup.c diff -u src/sys/ufs/lfs/ulfs_lookup.c:1.28 src/sys/ufs/lfs/ulfs_lookup.c:1.29 --- src/sys/ufs/lfs/ulfs_lookup.c:1.28 Tue Sep 15 15:00:32 2015 +++ src/sys/ufs/lfs/ulfs_lookup.c Tue Sep 15 15:00:49 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: ulfs_lookup.c,v 1.28 2015/09/15 15:00:32 dholland Exp $ */ +/* $NetBSD: ulfs_lookup.c,v 1.29 2015/09/15 15:00:49 dholland Exp $ */ /* from NetBSD: ufs_lookup.c,v 1.122 2013/01/22 09:39:18 dholland Exp */ /* @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ulfs_lookup.c,v 1.28 2015/09/15 15:00:32 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ulfs_lookup.c,v 1.29 2015/09/15 15:00:49 dholland Exp $"); #ifdef _KERNEL_OPT #include "opt_lfs.h" @@ -696,26 +696,29 @@ bad: } /* - * Construct a new directory entry after a call to namei, using the - * name in the componentname argument cnp. The new directory entry - * will refer to inode INUM which has type (directory-level type) - * DTYPE. If adding a reference to an already-created or - * already-extant inode, these values are retrieved with: - * ip->i_number - * LFS_IFTODT(ip->i_mode) - * (The latter should be tidier. XXX) + * Assign the contents of directory entry DIRP, on volume FS. + * + * NAME/NAMLEN is the name, which is not necessarily null terminated. + * INUM is the inode number, and DTYPE is the type code (LFS_DT_*). + * + * Note that these values typically come from: + * cnp->cn_nameptr + * cnp->cn_namelen + * ip->i_number + * LFS_IFTODT(ip->i_mode) * * Does not set d_reclen. */ static void -ulfs_makedirentry_tmp(struct lfs *fs, struct componentname *cnp, - ino_t inum, unsigned dtype, struct lfs_direct *newdirp) +ulfs_direntry_assign(struct lfs *fs, struct lfs_direct *dirp, + const char *name, size_t namlen, + ino_t inum, unsigned dtype) { - lfs_dir_setino(fs, newdirp, inum); - memcpy(newdirp->d_name, cnp->cn_nameptr, (size_t)cnp->cn_namelen); - newdirp->d_name[cnp->cn_namelen] = '\0'; - lfs_dir_setnamlen(fs, newdirp, cnp->cn_namelen); - lfs_dir_settype(fs, newdirp, dtype); + lfs_dir_setino(fs, dirp, inum); + lfs_dir_setnamlen(fs, dirp, namlen); + lfs_dir_settype(fs, dirp, dtype); + memcpy(dirp->d_name, name, namlen); + dirp->d_name[namlen] = '\0'; } /* @@ -766,16 +769,19 @@ ulfs_direnter(struct vnode *dvp, const s struct ulfsmount *ump = VFSTOULFS(dvp->v_mount); struct lfs *fs = ump->um_lfs; int dirblksiz = fs->um_dirblksiz; - struct lfs_direct *dirp; - - dirp = pool_cache_get(ulfs_direct_cache, PR_WAITOK); - ulfs_makedirentry_tmp(fs, cnp, inum, dtype, dirp); + const char *name; + unsigned namlen, reclen; +#ifdef LFS_DIRHASH + int dohashadd; +#endif error = 0; + name = cnp->cn_nameptr; /* note: not null-terminated */ + namlen = cnp->cn_namelen; cr = cnp->cn_cred; dp = VTOI(dvp); - newentrysize = LFS_DIRSIZ(fs, dirp); + newentrysize = LFS_DIRECTSIZ(namlen); if (ulr->ulr_count == 0) { /* @@ -788,7 +794,6 @@ ulfs_direnter(struct vnode *dvp, const s panic("ulfs_direnter: newblk"); if ((error = lfs_balloc(dvp, (off_t)ulr->ulr_offset, dirblksiz, cr, B_CLRBUF | B_SYNC, &bp)) != 0) { - pool_cache_put(ulfs_direct_cache, dirp); return (error); } dp->i_size = ulr->ulr_offset + dirblksiz; @@ -796,11 +801,13 @@ ulfs_direnter(struct vnode *dvp, const s dp->i_flag |= IN_CHANGE | IN_UPDATE; uvm_vnp_setsize(dvp, dp->i_size); lfs_blkoff = ulr->ulr_offset & (ump->um_mountp->mnt_stat.f_iosize - 1); - memcpy((char *)bp->b_data + lfs_blkoff, dirp, newentrysize); + ep = (struct lfs_direct *)((char *)bp->b_data + lfs_blkoff); + ulfs_direntry_assign(fs, ep, name, namlen, inum, dtype); + lfs_dir_setreclen(fs, ep, dirblksiz); #ifdef LFS_DIRHASH if (dp->i_dirhash != NULL) { ulfsdirhash_newblk(dp, ulr->ulr_offset); - ulfsdirhash_add(dp, dirp, ulr->ulr_offset); + ulfsdirhash_add(dp, ep, ulr->ulr_offset); ulfsdirhash_checkblock(dp, (char *)bp->b_data + lfs_blkoff, ulr->ulr_offset); } @@ -808,7 +815,6 @@ ulfs_direnter(struct vnode *dvp, const s error = VOP_BWRITE(bp->b_vp, bp); vfs_timestamp(&ts); ret = lfs_update(dvp, &ts, &ts, UPDATE_DIROP); - pool_cache_put(ulfs_direct_cache, dirp); if (error == 0) return (ret); return (error); @@ -844,7 +850,6 @@ ulfs_direnter(struct vnode *dvp, const s */ error = ulfs_blkatoff(dvp, (off_t)ulr->ulr_offset, &dirbuf, &bp, true); if (error) { - pool_cache_put(ulfs_direct_cache, dirp); return (error); } /* @@ -857,8 +862,6 @@ ulfs_direnter(struct vnode *dvp, const s dsize = (lfs_dir_getino(fs, ep) != 0) ? LFS_DIRSIZ(fs, ep) : 0; spacefree = lfs_dir_getreclen(fs, ep) - dsize; for (loc = lfs_dir_getreclen(fs, ep); loc < ulr->ulr_count; ) { - uint16_t reclen; - nep = (struct lfs_direct *)(dirbuf + loc); /* Trim the existing slot (NB: dsize may be zero). */ @@ -902,25 +905,29 @@ ulfs_direnter(struct vnode *dvp, const s */ if (lfs_dir_getino(fs, ep) == 0 || (lfs_dir_getino(fs, ep) == ULFS_WINO && - memcmp(ep->d_name, dirp->d_name, lfs_dir_getnamlen(fs, dirp)) == 0)) { + memcmp(ep->d_name, name, namlen) == 0)) { if (spacefree + dsize < newentrysize) panic("ulfs_direnter: compact1"); - lfs_dir_setreclen(fs, dirp, spacefree + dsize); + reclen = spacefree + dsize; +#ifdef LFS_DIRHASH + dohashadd = (lfs_dir_getino(fs, ep) == 0); +#endif } else { if (spacefree < newentrysize) panic("ulfs_direnter: compact2"); - lfs_dir_setreclen(fs, dirp, spacefree); + reclen = spacefree; lfs_dir_setreclen(fs, ep, dsize); ep = LFS_NEXTDIR(fs, ep); - } - #ifdef LFS_DIRHASH - if (dp->i_dirhash != NULL && (lfs_dir_getino(fs, ep) == 0 || - lfs_dir_getreclen(fs, dirp) == spacefree)) - ulfsdirhash_add(dp, dirp, ulr->ulr_offset + ((char *)ep - dirbuf)); + dohashadd = 1; #endif - memcpy((void *)ep, (void *)dirp, (u_int)newentrysize); + } + + ulfs_direntry_assign(fs, ep, name, namlen, inum, dtype); + lfs_dir_setreclen(fs, ep, reclen); #ifdef LFS_DIRHASH + if (dp->i_dirhash != NULL && dohashadd) + ulfsdirhash_add(dp, ep, ulr->ulr_offset + ((char *)ep - dirbuf)); if (dp->i_dirhash != NULL) ulfsdirhash_checkblock(dp, dirbuf - (ulr->ulr_offset & (dirblksiz - 1)), @@ -942,7 +949,6 @@ ulfs_direnter(struct vnode *dvp, const s #endif (void) lfs_truncate(dvp, (off_t)ulr->ulr_endoff, IO_SYNC, cr); } - pool_cache_put(ulfs_direct_cache, dirp); return (error); }