// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright ( C ) Tino Reichardt , 2012
*/
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
#include "jfs_incore.h"
#include "jfs_superblock.h"
#include "jfs_discard.h"
#include "jfs_dmap.h"
#include "jfs_debug.h"
/*
* NAME : jfs_issue_discard ( )
*
* FUNCTION : TRIM the specified block range on device , if supported
*
* PARAMETERS :
* ip - pointer to in - core inode
* blkno - starting block number to be trimmed ( 0 . . N )
* nblocks - number of blocks to be trimmed
*
* RETURN VALUES :
* none
*
* serialization : IREAD_LOCK ( ipbmap ) held on entry / exit ;
*/
void jfs_issue_discard(struct inode *ip, u64 blkno, u64 nblocks)
{
struct super_block *sb = ip->i_sb;
int r = 0 ;
r = sb_issue_discard(sb, blkno, nblocks, GFP_NOFS, 0 );
if (unlikely(r != 0 )) {
jfs_err("JFS: sb_issue_discard(%p, %llu, %llu, GFP_NOFS, 0) = %d => failed!" ,
sb, (unsigned long long )blkno,
(unsigned long long )nblocks, r);
}
jfs_info("JFS: sb_issue_discard(%p, %llu, %llu, GFP_NOFS, 0) = %d" ,
sb, (unsigned long long )blkno,
(unsigned long long )nblocks, r);
return ;
}
/*
* NAME : jfs_ioc_trim ( )
*
* FUNCTION : attempt to discard ( TRIM ) all free blocks from the
* filesystem .
*
* PARAMETERS :
* ip - pointer to in - core inode ;
* range - the range , given by user space
*
* RETURN VALUES :
* 0 - success
* - EIO - i / o error
*/
int jfs_ioc_trim(struct inode *ip, struct fstrim_range *range)
{
struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
struct bmap *bmp;
struct super_block *sb = ipbmap->i_sb;
int agno, agno_end;
u64 start, end, minlen;
u64 trimmed = 0 ;
/**
* convert byte values to block size of filesystem :
* start : First Byte to trim
* len : number of Bytes to trim from start
* minlen : minimum extent length in Bytes
*/
start = range->start >> sb->s_blocksize_bits;
end = start + (range->len >> sb->s_blocksize_bits) - 1 ;
minlen = range->minlen >> sb->s_blocksize_bits;
if (minlen == 0 )
minlen = 1 ;
down_read(&sb->s_umount);
bmp = JFS_SBI(ip->i_sb)->bmap;
if (bmp == NULL ||
minlen > bmp->db_agsize ||
start >= bmp->db_mapsize ||
range->len < sb->s_blocksize) {
up_read(&sb->s_umount);
return -EINVAL;
}
if (end >= bmp->db_mapsize)
end = bmp->db_mapsize - 1 ;
/**
* we trim all ag ' s within the range
*/
agno = BLKTOAG(start, JFS_SBI(ip->i_sb));
agno_end = BLKTOAG(end, JFS_SBI(ip->i_sb));
while (agno <= agno_end) {
trimmed += dbDiscardAG(ip, agno, minlen);
agno++;
}
up_read(&sb->s_umount);
range->len = trimmed << sb->s_blocksize_bits;
return 0 ;
}
Messung V0.5 in Prozent C=95 H=94 G=94
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-09-27)
¤
*© Formatika GbR, Deutschland