File Index
Files and directories
Sign in
FILE

jfs_discard.c

File preview with syntax highlighting.

linux-6.19.14/fs/jfs/jfs_discard.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 *   Copyright (C) Tino Reichardt, 2012
  4 */
  5
  6#include <linux/fs.h>
  7#include <linux/slab.h>
  8#include <linux/blkdev.h>
  9
 10#include "jfs_incore.h"
 11#include "jfs_superblock.h"
 12#include "jfs_discard.h"
 13#include "jfs_dmap.h"
 14#include "jfs_debug.h"
 15
 16
 17/*
 18 * NAME:	jfs_issue_discard()
 19 *
 20 * FUNCTION:	TRIM the specified block range on device, if supported
 21 *
 22 * PARAMETERS:
 23 *	ip	- pointer to in-core inode
 24 *	blkno	- starting block number to be trimmed (0..N)
 25 *	nblocks	- number of blocks to be trimmed
 26 *
 27 * RETURN VALUES:
 28 *	none
 29 *
 30 * serialization: IREAD_LOCK(ipbmap) held on entry/exit;
 31 */
 32void jfs_issue_discard(struct inode *ip, u64 blkno, u64 nblocks)
 33{
 34	struct super_block *sb = ip->i_sb;
 35	int r = 0;
 36
 37	r = sb_issue_discard(sb, blkno, nblocks, GFP_NOFS, 0);
 38	if (unlikely(r != 0)) {
 39		jfs_err("JFS: sb_issue_discard(%p, %llu, %llu, GFP_NOFS, 0) = %d => failed!",
 40			sb, (unsigned long long)blkno,
 41			(unsigned long long)nblocks, r);
 42	}
 43
 44	jfs_info("JFS: sb_issue_discard(%p, %llu, %llu, GFP_NOFS, 0) = %d",
 45		sb, (unsigned long long)blkno,
 46		(unsigned long long)nblocks, r);
 47
 48	return;
 49}
 50
 51/*
 52 * NAME:	jfs_ioc_trim()
 53 *
 54 * FUNCTION:	attempt to discard (TRIM) all free blocks from the
 55 *              filesystem.
 56 *
 57 * PARAMETERS:
 58 *	ip	- pointer to in-core inode;
 59 *	range	- the range, given by user space
 60 *
 61 * RETURN VALUES:
 62 *	0	- success
 63 *	-EIO	- i/o error
 64 */
 65int jfs_ioc_trim(struct inode *ip, struct fstrim_range *range)
 66{
 67	struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
 68	struct bmap *bmp;
 69	struct super_block *sb = ipbmap->i_sb;
 70	int agno, agno_end;
 71	u64 start, end, minlen;
 72	u64 trimmed = 0;
 73
 74	/**
 75	 * convert byte values to block size of filesystem:
 76	 * start:	First Byte to trim
 77	 * len:		number of Bytes to trim from start
 78	 * minlen:	minimum extent length in Bytes
 79	 */
 80	start = range->start >> sb->s_blocksize_bits;
 81	end = start + (range->len >> sb->s_blocksize_bits) - 1;
 82	minlen = range->minlen >> sb->s_blocksize_bits;
 83	if (minlen == 0)
 84		minlen = 1;
 85
 86	down_read(&sb->s_umount);
 87	bmp = JFS_SBI(ip->i_sb)->bmap;
 88
 89	if (bmp == NULL ||
 90	    minlen > bmp->db_agsize ||
 91	    start >= bmp->db_mapsize ||
 92	    range->len < sb->s_blocksize) {
 93		up_read(&sb->s_umount);
 94		return -EINVAL;
 95	}
 96
 97	if (end >= bmp->db_mapsize)
 98		end = bmp->db_mapsize - 1;
 99
100	/**
101	 * we trim all ag's within the range
102	 */
103	agno = BLKTOAG(start, JFS_SBI(ip->i_sb));
104	agno_end = BLKTOAG(end, JFS_SBI(ip->i_sb));
105	while (agno <= agno_end) {
106		trimmed += dbDiscardAG(ip, agno, minlen);
107		agno++;
108	}
109
110	up_read(&sb->s_umount);
111	range->len = trimmed << sb->s_blocksize_bits;
112
113	return 0;
114}
~/ Read-only file preview.