root/fs/jfs/jfs_discard.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. jfs_issue_discard
  2. jfs_ioc_trim

   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  */
  32 void 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  */
  65 int 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 = JFS_SBI(ip->i_sb)->bmap;
  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         if (minlen > bmp->db_agsize ||
  87             start >= bmp->db_mapsize ||
  88             range->len < sb->s_blocksize)
  89                 return -EINVAL;
  90 
  91         if (end >= bmp->db_mapsize)
  92                 end = bmp->db_mapsize - 1;
  93 
  94         /**
  95          * we trim all ag's within the range
  96          */
  97         agno = BLKTOAG(start, JFS_SBI(ip->i_sb));
  98         agno_end = BLKTOAG(end, JFS_SBI(ip->i_sb));
  99         while (agno <= agno_end) {
 100                 trimmed += dbDiscardAG(ip, agno, minlen);
 101                 agno++;
 102         }
 103         range->len = trimmed << sb->s_blocksize_bits;
 104 
 105         return 0;
 106 }

/* [<][>][^][v][top][bottom][index][help] */