TRIM Patch
Link to this paste: http://bugs.dragonflybsd.org/pastes/419
Added by bissont 7 months ago.
Syntax: Diff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
atg-s-optimus /export_fs/DragonFlyBSD/ $ git show commit 410618f1f07446cef84f23b3a7aa66d676d9f37f Author: Tim Bisson <bissont@mac.com> Date: Fri Oct 12 09:14:18 2012 -0700 Fix TRIM: * Only enable TRIM if DRAT (Deterministic Read After TRIM) is supported * if trim is on as a option, display that when typing "mount" * make sure TRIM occurs with UFS when it is enabled. using ip->i_devvp->v_mount->mnt_flag doesn't have mount options. ** when softupdates is enabled, struct freeblocks doesn't pass the vnode to to the temporary inode pointer. Adding vnode to freeblocks so we can get the mountp that has the TRIM flag enabled. * change post trim ffs_blkfree_cg() to use taskqueue_swi_mp and get mp token when modifying freemapw diff --git a/sys/dev/disk/ahci/ahci_cam.c b/sys/dev/disk/ahci/ahci_cam.c index 3b5d857..f0a41fa 100644 --- a/sys/dev/disk/ahci/ahci_cam.c +++ b/sys/dev/disk/ahci/ahci_cam.c @@ -1095,7 +1095,8 @@ ahci_xpt_scsi_disk_io(struct ahci_port *ap, struct ata_port *atx, */ if (at->at_identify.support_dsm) { rdata->inquiry_data.vendor_specific1[0] = - at->at_identify.support_dsm &ATA_SUPPORT_DSM_TRIM; + (at->at_identify.support_dsm & ATA_SUPPORT_DSM_TRIM) && + (at->at_identify.support3 & ATA_SUPPORT_DRAT); rdata->inquiry_data.vendor_specific1[1] = at->at_identify.max_dsm_blocks; } diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index e6a0024..a3b2035 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1835,6 +1835,7 @@ vfs_flagstostr(int flags, const struct mountctl_opt *optp, { MNT_SUIDDIR, "suiddir" }, { MNT_SOFTDEP, "soft-updates" }, { MNT_IGNORE, "ignore" }, + { MNT_TRIM, "trim" }, { 0, NULL} }; int bwritten; diff --git a/sys/vfs/ufs/ffs_alloc.c b/sys/vfs/ufs/ffs_alloc.c index afcde72..9a26f1a 100644 --- a/sys/vfs/ufs/ffs_alloc.c +++ b/sys/vfs/ufs/ffs_alloc.c @@ -1627,8 +1627,10 @@ ffs_blkfree_trim_task(void *ctx, int pending) struct ffs_blkfree_trim_params *tp; tp = ctx; + lwkt_gettoken(&tp->i_devvp->v_mount->mnt_token); ffs_blkfree_cg(tp->i_fs, tp->i_devvp, tp->i_dev, tp->i_number, tp->i_din_uid, tp->bno, tp->size); + lwkt_reltoken(&tp->i_devvp->v_mount->mnt_token); kfree(tp, M_TEMP); } @@ -1643,7 +1645,7 @@ ffs_blkfree_trim_completed(struct bio *biop) tp = bp->b_bio1.bio_caller_info1.ptr; TASK_INIT(&tp->task, 0, ffs_blkfree_trim_task, tp); tp = biop->bio_caller_info1.ptr; - taskqueue_enqueue(taskqueue_swi, &tp->task); + taskqueue_enqueue(taskqueue_swi_mp, &tp->task); biodone(biop); } @@ -1658,7 +1660,7 @@ ffs_blkfree_trim_completed(struct bio *biop) void ffs_blkfree(struct inode *ip, ufs_daddr_t bno, long size) { - struct mount *mp = ip->i_devvp->v_mount; + struct mount *mp = ip->i_vnode->v_mount; struct ffs_blkfree_trim_params *tp; if (!(mp->mnt_flag & MNT_TRIM)) { diff --git a/sys/vfs/ufs/ffs_softdep.c b/sys/vfs/ufs/ffs_softdep.c index b6a8cbf..9f0a3a6 100644 --- a/sys/vfs/ufs/ffs_softdep.c +++ b/sys/vfs/ufs/ffs_softdep.c @@ -1740,6 +1740,7 @@ softdep_setup_freeblocks(struct inode *ip, off_t length) freeblks->fb_uid = ip->i_uid; freeblks->fb_previousinum = ip->i_number; freeblks->fb_devvp = ip->i_devvp; + freeblks->fb_vp = ITOV(ip); freeblks->fb_fs = fs; freeblks->fb_oldsize = ip->i_size; freeblks->fb_newsize = length; @@ -2130,6 +2131,7 @@ handle_workitem_freeblocks(struct freeblks *freeblks) ufs_lbn_t baselbns[NIADDR], tmpval; tip.i_number = freeblks->fb_previousinum; + tip.i_vnode = freeblks->fb_vp; tip.i_devvp = freeblks->fb_devvp; tip.i_dev = freeblks->fb_devvp->v_rdev; tip.i_fs = freeblks->fb_fs; diff --git a/sys/vfs/ufs/softdep.h b/sys/vfs/ufs/softdep.h index c99396a..80a5d2a 100644 --- a/sys/vfs/ufs/softdep.h +++ b/sys/vfs/ufs/softdep.h @@ -401,6 +401,7 @@ struct freeblks { ino_t fb_previousinum; /* inode of previous owner of blocks */ struct vnode *fb_devvp; /* filesystem device vnode */ struct fs *fb_fs; /* addr of superblock */ + struct vnode *fb_vp; /* vnodeip*/ off_t fb_oldsize; /* previous file size */ off_t fb_newsize; /* new file size */ int fb_chkcnt; /* used to check cnt of blks released */ |