^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/buffer_head.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/gfs2_ondisk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/iomap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/ktime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "gfs2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "incore.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "bmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "glock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "meta_io.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "quota.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "rgrp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "super.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "dir.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "util.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "aops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "trace_gfs2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* This doesn't need to be that large as max 64 bit pointers in a 4k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * block is 512, so __u16 is fine for that. It saves stack space to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * keep it small.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct metapath {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct buffer_head *mp_bh[GFS2_MAX_META_HEIGHT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) __u16 mp_list[GFS2_MAX_META_HEIGHT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int mp_fheight; /* find_metapath height */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int mp_aheight; /* actual height (lookup height) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * gfs2_unstuffer_page - unstuff a stuffed inode into a block cached by a page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * @ip: the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * @dibh: the dinode buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * @block: the block number that was allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * @page: The (optional) page. This is looked up if @page is NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Returns: errno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u64 block, struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct inode *inode = &ip->i_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int release = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (!page || page->index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) page = find_or_create_page(inode->i_mapping, 0, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) release = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (!PageUptodate(page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) void *kaddr = kmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) u64 dsize = i_size_read(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (dsize > gfs2_max_stuffed_size(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) dsize = gfs2_max_stuffed_size(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) memset(kaddr + dsize, 0, PAGE_SIZE - dsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) SetPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (gfs2_is_jdata(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!page_has_buffers(page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) create_empty_buffers(page, BIT(inode->i_blkbits),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) BIT(BH_Uptodate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) bh = page_buffers(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (!buffer_mapped(bh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) map_bh(bh, inode->i_sb, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) set_buffer_uptodate(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) gfs2_trans_add_data(ip->i_gl, bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) set_page_dirty(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) gfs2_ordered_add_inode(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (release) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * gfs2_unstuff_dinode - Unstuff a dinode when the data has grown too big
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * @ip: The GFS2 inode to unstuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * @page: The (optional) page. This is looked up if the @page is NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * This routine unstuffs a dinode and returns it to a "normal" state such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * that the height can be grown in the traditional way.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * Returns: errno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct buffer_head *bh, *dibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct gfs2_dinode *di;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u64 block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int isdir = gfs2_is_dir(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) down_write(&ip->i_rw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) error = gfs2_meta_inode_buffer(ip, &dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (i_size_read(&ip->i_inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* Get a free block, fill it with the stuffed data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) and write it out to disk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) unsigned int n = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) error = gfs2_alloc_blocks(ip, &block, &n, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) goto out_brelse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (isdir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) gfs2_trans_remove_revoke(GFS2_SB(&ip->i_inode), block, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) error = gfs2_dir_get_new_buffer(ip, block, &bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) goto out_brelse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) gfs2_buffer_copy_tail(bh, sizeof(struct gfs2_meta_header),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) dibh, sizeof(struct gfs2_dinode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) error = gfs2_unstuffer_page(ip, dibh, block, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) goto out_brelse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* Set up the pointer to the new block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) gfs2_trans_add_meta(ip->i_gl, dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) di = (struct gfs2_dinode *)dibh->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (i_size_read(&ip->i_inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) *(__be64 *)(di + 1) = cpu_to_be64(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) gfs2_add_inode_blocks(&ip->i_inode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ip->i_height = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) di->di_height = cpu_to_be16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) out_brelse:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) brelse(dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) up_write(&ip->i_rw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * find_metapath - Find path through the metadata tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * @sdp: The superblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * @block: The disk block to look up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * @mp: The metapath to return the result in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * @height: The pre-calculated height of the metadata tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * This routine returns a struct metapath structure that defines a path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * through the metadata of inode "ip" to get to block "block".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * Example:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * Given: "ip" is a height 3 file, "offset" is 101342453, and this is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * filesystem with a blocksize of 4096.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * find_metapath() would return a struct metapath structure set to:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * mp_fheight = 3, mp_list[0] = 0, mp_list[1] = 48, and mp_list[2] = 165.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * That means that in order to get to the block containing the byte at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * offset 101342453, we would load the indirect block pointed to by pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * 0 in the dinode. We would then load the indirect block pointed to by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * pointer 48 in that indirect block. We would then load the data block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * pointed to by pointer 165 in that indirect block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * ----------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * | Dinode | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * | | 4|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * | |0 1 2 3 4 5 9|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * | | 6|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * ----------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * ----------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * | Indirect Block |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * | 5|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * | 4 4 4 4 4 5 5 1|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * |0 5 6 7 8 9 0 1 2|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * ----------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * ----------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * | Indirect Block |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * | 1 1 1 1 1 5|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * | 6 6 6 6 6 1|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * |0 3 4 5 6 7 2|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * ----------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * ----------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * | Data block containing offset |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * | 101342453 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * ----------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static void find_metapath(const struct gfs2_sbd *sdp, u64 block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct metapath *mp, unsigned int height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) mp->mp_fheight = height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) for (i = height; i--;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) mp->mp_list[i] = do_div(block, sdp->sd_inptrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static inline unsigned int metapath_branch_start(const struct metapath *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (mp->mp_list[0] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * metaptr1 - Return the first possible metadata pointer in a metapath buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * @height: The metadata height (0 = dinode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * @mp: The metapath
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static inline __be64 *metaptr1(unsigned int height, const struct metapath *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct buffer_head *bh = mp->mp_bh[height];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (height == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return ((__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return ((__be64 *)(bh->b_data + sizeof(struct gfs2_meta_header)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * metapointer - Return pointer to start of metadata in a buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * @height: The metadata height (0 = dinode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * @mp: The metapath
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * Return a pointer to the block number of the next height of the metadata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * tree given a buffer containing the pointer to the current height of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * metadata tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static inline __be64 *metapointer(unsigned int height, const struct metapath *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) __be64 *p = metaptr1(height, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return p + mp->mp_list[height];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static inline const __be64 *metaend(unsigned int height, const struct metapath *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) const struct buffer_head *bh = mp->mp_bh[height];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return (const __be64 *)(bh->b_data + bh->b_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static void clone_metapath(struct metapath *clone, struct metapath *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) unsigned int hgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) *clone = *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) for (hgt = 0; hgt < mp->mp_aheight; hgt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) get_bh(clone->mp_bh[hgt]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static void gfs2_metapath_ra(struct gfs2_glock *gl, __be64 *start, __be64 *end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) const __be64 *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) for (t = start; t < end; t++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct buffer_head *rabh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (!*t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) rabh = gfs2_getbuf(gl, be64_to_cpu(*t), CREATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (trylock_buffer(rabh)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!buffer_uptodate(rabh)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) rabh->b_end_io = end_buffer_read_sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) submit_bh(REQ_OP_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) REQ_RAHEAD | REQ_META | REQ_PRIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) rabh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) unlock_buffer(rabh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) brelse(rabh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static int __fillup_metapath(struct gfs2_inode *ip, struct metapath *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) unsigned int x, unsigned int h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) for (; x < h; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) __be64 *ptr = metapointer(x, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) u64 dblock = be64_to_cpu(*ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (!dblock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) ret = gfs2_meta_indirect_buffer(ip, x + 1, dblock, &mp->mp_bh[x + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) mp->mp_aheight = x + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * lookup_metapath - Walk the metadata tree to a specific point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * @ip: The inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * @mp: The metapath
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * Assumes that the inode's buffer has already been looked up and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * hooked onto mp->mp_bh[0] and that the metapath has been initialised
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * by find_metapath().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * If this function encounters part of the tree which has not been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * allocated, it returns the current height of the tree at the point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * at which it found the unallocated block. Blocks which are found are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * added to the mp->mp_bh[] list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * Returns: error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static int lookup_metapath(struct gfs2_inode *ip, struct metapath *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return __fillup_metapath(ip, mp, 0, ip->i_height - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * fillup_metapath - fill up buffers for the metadata path to a specific height
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * @ip: The inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * @mp: The metapath
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * @h: The height to which it should be mapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * Similar to lookup_metapath, but does lookups for a range of heights
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * Returns: error or the number of buffers filled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static int fillup_metapath(struct gfs2_inode *ip, struct metapath *mp, int h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) unsigned int x = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (h) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /* find the first buffer we need to look up. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) for (x = h - 1; x > 0; x--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (mp->mp_bh[x])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) ret = __fillup_metapath(ip, mp, x, h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return mp->mp_aheight - x - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static sector_t metapath_to_block(struct gfs2_sbd *sdp, struct metapath *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) sector_t factor = 1, block = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) int hgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) for (hgt = mp->mp_fheight - 1; hgt >= 0; hgt--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (hgt < mp->mp_aheight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) block += mp->mp_list[hgt] * factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) factor *= sdp->sd_inptrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static void release_metapath(struct metapath *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) for (i = 0; i < GFS2_MAX_META_HEIGHT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (mp->mp_bh[i] == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) brelse(mp->mp_bh[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) mp->mp_bh[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * gfs2_extent_length - Returns length of an extent of blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * @bh: The metadata block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * @ptr: Current position in @bh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * @limit: Max extent length to return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * @eob: Set to 1 if we hit "end of block"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * Returns: The length of the extent (minimum of one block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static inline unsigned int gfs2_extent_length(struct buffer_head *bh, __be64 *ptr, size_t limit, int *eob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) const __be64 *end = (__be64 *)(bh->b_data + bh->b_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) const __be64 *first = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) u64 d = be64_to_cpu(*ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) *eob = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (ptr >= end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) d++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) } while(be64_to_cpu(*ptr) == d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (ptr >= end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) *eob = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return ptr - first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) enum walker_status { WALK_STOP, WALK_FOLLOW, WALK_CONTINUE };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * gfs2_metadata_walker - walk an indirect block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * @mp: Metapath to indirect block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * @ptrs: Number of pointers to look at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * When returning WALK_FOLLOW, the walker must update @mp to point at the right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * indirect block to follow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) typedef enum walker_status (*gfs2_metadata_walker)(struct metapath *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) unsigned int ptrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * gfs2_walk_metadata - walk a tree of indirect blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * @inode: The inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * @mp: Starting point of walk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * @max_len: Maximum number of blocks to walk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * @walker: Called during the walk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * Returns 1 if the walk was stopped by @walker, 0 if we went past @max_len or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * past the end of metadata, and a negative error code otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static int gfs2_walk_metadata(struct inode *inode, struct metapath *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) u64 max_len, gfs2_metadata_walker walker)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) u64 factor = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) unsigned int hgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * The walk starts in the lowest allocated indirect block, which may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * before the position indicated by @mp. Adjust @max_len accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * to avoid a short walk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) for (hgt = mp->mp_fheight - 1; hgt >= mp->mp_aheight; hgt--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) max_len += mp->mp_list[hgt] * factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) mp->mp_list[hgt] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) factor *= sdp->sd_inptrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) u16 start = mp->mp_list[hgt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) enum walker_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) unsigned int ptrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) u64 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /* Walk indirect block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ptrs = (hgt >= 1 ? sdp->sd_inptrs : sdp->sd_diptrs) - start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) len = ptrs * factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (len > max_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ptrs = DIV_ROUND_UP_ULL(max_len, factor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) status = walker(mp, ptrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) case WALK_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) case WALK_FOLLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) BUG_ON(mp->mp_aheight == mp->mp_fheight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ptrs = mp->mp_list[hgt] - start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) len = ptrs * factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) case WALK_CONTINUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (len >= max_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) max_len -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (status == WALK_FOLLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) goto fill_up_metapath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) lower_metapath:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* Decrease height of metapath. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) brelse(mp->mp_bh[hgt]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) mp->mp_bh[hgt] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) mp->mp_list[hgt] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (!hgt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) hgt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) factor *= sdp->sd_inptrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /* Advance in metadata tree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) (mp->mp_list[hgt])++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (hgt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (mp->mp_list[hgt] >= sdp->sd_inptrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) goto lower_metapath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (mp->mp_list[hgt] >= sdp->sd_diptrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) fill_up_metapath:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /* Increase height of metapath. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) ret = fillup_metapath(ip, mp, ip->i_height - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) hgt += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) for (; ret; ret--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) do_div(factor, sdp->sd_inptrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) mp->mp_aheight = hgt + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static enum walker_status gfs2_hole_walker(struct metapath *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) unsigned int ptrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) const __be64 *start, *ptr, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) unsigned int hgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) hgt = mp->mp_aheight - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) start = metapointer(hgt, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) end = start + ptrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) for (ptr = start; ptr < end; ptr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (*ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) mp->mp_list[hgt] += ptr - start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (mp->mp_aheight == mp->mp_fheight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return WALK_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return WALK_FOLLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return WALK_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * gfs2_hole_size - figure out the size of a hole
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * @inode: The inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * @lblock: The logical starting block number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * @len: How far to look (in blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * @mp: The metapath at lblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * @iomap: The iomap to store the hole size in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * This function modifies @mp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * Returns: errno on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static int gfs2_hole_size(struct inode *inode, sector_t lblock, u64 len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct metapath *mp, struct iomap *iomap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct metapath clone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) u64 hole_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) clone_metapath(&clone, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ret = gfs2_walk_metadata(inode, &clone, len, gfs2_hole_walker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (ret == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) hole_size = metapath_to_block(GFS2_SB(inode), &clone) - lblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) hole_size = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) iomap->length = hole_size << inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) release_metapath(&clone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static inline __be64 *gfs2_indirect_init(struct metapath *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct gfs2_glock *gl, unsigned int i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) unsigned offset, u64 bn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) __be64 *ptr = (__be64 *)(mp->mp_bh[i - 1]->b_data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) ((i > 1) ? sizeof(struct gfs2_meta_header) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) sizeof(struct gfs2_dinode)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) BUG_ON(i < 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) BUG_ON(mp->mp_bh[i] != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) mp->mp_bh[i] = gfs2_meta_new(gl, bn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) gfs2_trans_add_meta(gl, mp->mp_bh[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) gfs2_metatype_set(mp->mp_bh[i], GFS2_METATYPE_IN, GFS2_FORMAT_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) gfs2_buffer_clear_tail(mp->mp_bh[i], sizeof(struct gfs2_meta_header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) ptr += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) *ptr = cpu_to_be64(bn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) enum alloc_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) ALLOC_DATA = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) ALLOC_GROW_DEPTH = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ALLOC_GROW_HEIGHT = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /* ALLOC_UNSTUFF = 3, TBD and rather complicated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * gfs2_iomap_alloc - Build a metadata tree of the requested height
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * @inode: The GFS2 inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * @iomap: The iomap structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) * @mp: The metapath, with proper height information calculated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) * In this routine we may have to alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * i) Indirect blocks to grow the metadata tree height
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * ii) Indirect blocks to fill in lower part of the metadata tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * iii) Data blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * This function is called after gfs2_iomap_get, which works out the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * total number of blocks which we need via gfs2_alloc_size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * We then do the actual allocation asking for an extent at a time (if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * enough contiguous free blocks are available, there will only be one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * allocation request per call) and uses the state machine to initialise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * the blocks in order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * Right now, this function will allocate at most one indirect block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * worth of data -- with a default block size of 4K, that's slightly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * less than 2M. If this limitation is ever removed to allow huge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * allocations, we would probably still want to limit the iomap size we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * return to avoid stalling other tasks during huge writes; the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * iomap iteration would then find the blocks already allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * Returns: errno on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static int gfs2_iomap_alloc(struct inode *inode, struct iomap *iomap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct metapath *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct buffer_head *dibh = mp->mp_bh[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) u64 bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) size_t dblks = iomap->length >> inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) const unsigned end_of_metadata = mp->mp_fheight - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) enum alloc_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) __be64 *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) __be64 zero_bn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) BUG_ON(mp->mp_aheight < 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) BUG_ON(dibh == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) BUG_ON(dblks < 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) gfs2_trans_add_meta(ip->i_gl, dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) down_write(&ip->i_rw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (mp->mp_fheight == mp->mp_aheight) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) /* Bottom indirect block exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) state = ALLOC_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) /* Need to allocate indirect blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (mp->mp_fheight == ip->i_height) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /* Writing into existing tree, extend tree down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) iblks = mp->mp_fheight - mp->mp_aheight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) state = ALLOC_GROW_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /* Building up tree height */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) state = ALLOC_GROW_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) iblks = mp->mp_fheight - ip->i_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) branch_start = metapath_branch_start(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) iblks += (mp->mp_fheight - branch_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) /* start of the second part of the function (state machine) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) blks = dblks + iblks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) i = mp->mp_aheight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) n = blks - alloced;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) ret = gfs2_alloc_blocks(ip, &bn, &n, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) alloced += n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (state != ALLOC_DATA || gfs2_is_jdata(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) gfs2_trans_remove_revoke(sdp, bn, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /* Growing height of tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) case ALLOC_GROW_HEIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (i == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) ptr = (__be64 *)(dibh->b_data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) sizeof(struct gfs2_dinode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) zero_bn = *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) for (; i - 1 < mp->mp_fheight - ip->i_height && n > 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) i++, n--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) gfs2_indirect_init(mp, ip->i_gl, i, 0, bn++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (i - 1 == mp->mp_fheight - ip->i_height) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) gfs2_buffer_copy_tail(mp->mp_bh[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) sizeof(struct gfs2_meta_header),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) dibh, sizeof(struct gfs2_dinode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) gfs2_buffer_clear_tail(dibh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) sizeof(struct gfs2_dinode) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) sizeof(__be64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) ptr = (__be64 *)(mp->mp_bh[i]->b_data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) sizeof(struct gfs2_meta_header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) *ptr = zero_bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) state = ALLOC_GROW_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) for(i = branch_start; i < mp->mp_fheight; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (mp->mp_bh[i] == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) brelse(mp->mp_bh[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) mp->mp_bh[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) i = branch_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (n == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) fallthrough; /* To branching from existing tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) case ALLOC_GROW_DEPTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (i > 1 && i < mp->mp_fheight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) gfs2_trans_add_meta(ip->i_gl, mp->mp_bh[i-1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) for (; i < mp->mp_fheight && n > 0; i++, n--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) gfs2_indirect_init(mp, ip->i_gl, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) mp->mp_list[i-1], bn++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (i == mp->mp_fheight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) state = ALLOC_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (n == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) fallthrough; /* To tree complete, adding data blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) case ALLOC_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) BUG_ON(n > dblks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) BUG_ON(mp->mp_bh[end_of_metadata] == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) gfs2_trans_add_meta(ip->i_gl, mp->mp_bh[end_of_metadata]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) dblks = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ptr = metapointer(end_of_metadata, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) iomap->addr = bn << inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) iomap->flags |= IOMAP_F_MERGED | IOMAP_F_NEW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) while (n-- > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) *ptr++ = cpu_to_be64(bn++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) } while (iomap->addr == IOMAP_NULL_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) iomap->type = IOMAP_MAPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) iomap->length = (u64)dblks << inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) ip->i_height = mp->mp_fheight;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) gfs2_add_inode_blocks(&ip->i_inode, alloced);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) gfs2_dinode_out(ip, dibh->b_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) up_write(&ip->i_rw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) #define IOMAP_F_GFS2_BOUNDARY IOMAP_F_PRIVATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * gfs2_alloc_size - Compute the maximum allocation size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) * @inode: The inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * @mp: The metapath
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * @size: Requested size in blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) * Compute the maximum size of the next allocation at @mp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * Returns: size in blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) static u64 gfs2_alloc_size(struct inode *inode, struct metapath *mp, u64 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) const __be64 *first, *ptr, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * For writes to stuffed files, this function is called twice via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * gfs2_iomap_get, before and after unstuffing. The size we return the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) * first time needs to be large enough to get the reservation and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * allocation sizes right. The size we return the second time must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * be exact or else gfs2_iomap_alloc won't do the right thing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (gfs2_is_stuffed(ip) || mp->mp_fheight != mp->mp_aheight) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) unsigned int maxsize = mp->mp_fheight > 1 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) sdp->sd_inptrs : sdp->sd_diptrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) maxsize -= mp->mp_list[mp->mp_fheight - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (size > maxsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) size = maxsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) first = metapointer(ip->i_height - 1, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) end = metaend(ip->i_height - 1, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (end - first > size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) end = first + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) for (ptr = first; ptr < end; ptr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (*ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return ptr - first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * gfs2_iomap_get - Map blocks from an inode to disk blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * @inode: The inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * @pos: Starting position in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * @length: Length to map, in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * @flags: iomap flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * @iomap: The iomap structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * @mp: The metapath
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * Returns: errno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static int gfs2_iomap_get(struct inode *inode, loff_t pos, loff_t length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) unsigned flags, struct iomap *iomap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) struct metapath *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) loff_t size = i_size_read(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) __be64 *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) sector_t lblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) sector_t lblock_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) int eob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) u64 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) struct buffer_head *dibh = NULL, *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) u8 height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (!length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) down_read(&ip->i_rw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) ret = gfs2_meta_inode_buffer(ip, &dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) mp->mp_bh[0] = dibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (gfs2_is_stuffed(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (flags & IOMAP_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) loff_t max_size = gfs2_max_stuffed_size(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (pos + length > max_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) goto unstuff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) iomap->length = max_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (pos >= size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (flags & IOMAP_REPORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) iomap->offset = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) iomap->length = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) goto hole_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) iomap->length = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) iomap->addr = (ip->i_no_addr << inode->i_blkbits) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) sizeof(struct gfs2_dinode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) iomap->type = IOMAP_INLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) iomap->inline_data = dibh->b_data + sizeof(struct gfs2_dinode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) unstuff:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) lblock = pos >> inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) iomap->offset = lblock << inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) lblock_stop = (pos + length - 1) >> inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) len = lblock_stop - lblock + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) iomap->length = len << inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) height = ip->i_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) while ((lblock + 1) * sdp->sd_sb.sb_bsize > sdp->sd_heightsize[height])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) height++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) find_metapath(sdp, lblock, mp, height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (height > ip->i_height || gfs2_is_stuffed(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) goto do_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) ret = lookup_metapath(ip, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (mp->mp_aheight != ip->i_height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) goto do_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) ptr = metapointer(ip->i_height - 1, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (*ptr == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) goto do_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) bh = mp->mp_bh[ip->i_height - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) len = gfs2_extent_length(bh, ptr, len, &eob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) iomap->addr = be64_to_cpu(*ptr) << inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) iomap->length = len << inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) iomap->type = IOMAP_MAPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) iomap->flags |= IOMAP_F_MERGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (eob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) iomap->flags |= IOMAP_F_GFS2_BOUNDARY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) iomap->bdev = inode->i_sb->s_bdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) up_read(&ip->i_rw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) do_alloc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (flags & IOMAP_REPORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (pos >= size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) else if (height == ip->i_height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) ret = gfs2_hole_size(inode, lblock, len, mp, iomap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) iomap->length = size - iomap->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) } else if (flags & IOMAP_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) u64 alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (flags & IOMAP_DIRECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) goto out; /* (see gfs2_file_direct_write) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) len = gfs2_alloc_size(inode, mp, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) alloc_size = len << inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (alloc_size < iomap->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) iomap->length = alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) if (pos < size && height == ip->i_height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) ret = gfs2_hole_size(inode, lblock, len, mp, iomap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) hole_found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) iomap->addr = IOMAP_NULL_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) iomap->type = IOMAP_HOLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * gfs2_lblk_to_dblk - convert logical block to disk block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * @inode: the inode of the file we're mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) * @lblock: the block relative to the start of the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) * @dblock: the returned dblock, if no error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) * This function maps a single block from a file logical block (relative to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) * the start of the file) to a file system absolute block using iomap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) * Returns: the absolute file system block, or an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) int gfs2_lblk_to_dblk(struct inode *inode, u32 lblock, u64 *dblock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) struct iomap iomap = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) struct metapath mp = { .mp_aheight = 1, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) loff_t pos = (loff_t)lblock << inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) ret = gfs2_iomap_get(inode, pos, i_blocksize(inode), 0, &iomap, &mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) release_metapath(&mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) *dblock = iomap.addr >> inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) static int gfs2_write_lock(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) error = gfs2_glock_nq(&ip->i_gh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) goto out_uninit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (&ip->i_inode == sdp->sd_rindex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) GL_NOCACHE, &m_ip->i_gh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) gfs2_glock_dq(&ip->i_gh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) out_uninit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) gfs2_holder_uninit(&ip->i_gh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static void gfs2_write_unlock(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (&ip->i_inode == sdp->sd_rindex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) gfs2_glock_dq_uninit(&m_ip->i_gh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) gfs2_glock_dq_uninit(&ip->i_gh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) static int gfs2_iomap_page_prepare(struct inode *inode, loff_t pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) unsigned len, struct iomap *iomap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) unsigned int blockmask = i_blocksize(inode) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) unsigned int blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) blocks = ((pos & blockmask) + len + blockmask) >> inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return gfs2_trans_begin(sdp, RES_DINODE + blocks, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) static void gfs2_iomap_page_done(struct inode *inode, loff_t pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) unsigned copied, struct page *page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct iomap *iomap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) struct gfs2_trans *tr = current->journal_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (page && !gfs2_is_stuffed(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) gfs2_page_add_databufs(ip, page, offset_in_page(pos), copied);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (tr->tr_num_buf_new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) gfs2_trans_end(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) static const struct iomap_page_ops gfs2_iomap_page_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) .page_prepare = gfs2_iomap_page_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) .page_done = gfs2_iomap_page_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) loff_t length, unsigned flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct iomap *iomap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct metapath *mp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) bool unstuff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) unstuff = gfs2_is_stuffed(ip) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) pos + length > gfs2_max_stuffed_size(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (unstuff || iomap->type == IOMAP_HOLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) unsigned int data_blocks, ind_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) struct gfs2_alloc_parms ap = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) unsigned int rblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) struct gfs2_trans *tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) gfs2_write_calc_reserv(ip, iomap->length, &data_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) &ind_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) ap.target = data_blocks + ind_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) ret = gfs2_quota_lock_check(ip, &ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) ret = gfs2_inplace_reserve(ip, &ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) goto out_qunlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) rblocks = RES_DINODE + ind_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (gfs2_is_jdata(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) rblocks += data_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (ind_blocks || data_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) rblocks += RES_STATFS + RES_QUOTA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) if (inode == sdp->sd_rindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) rblocks += 2 * RES_STATFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) rblocks += gfs2_rg_blocks(ip, data_blocks + ind_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) ret = gfs2_trans_begin(sdp, rblocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) iomap->length >> inode->i_blkbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) goto out_trans_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (unstuff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) ret = gfs2_unstuff_dinode(ip, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) goto out_trans_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) release_metapath(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) ret = gfs2_iomap_get(inode, iomap->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) iomap->length, flags, iomap, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) goto out_trans_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (iomap->type == IOMAP_HOLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) ret = gfs2_iomap_alloc(inode, iomap, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) gfs2_trans_end(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) gfs2_inplace_release(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) punch_hole(ip, iomap->offset, iomap->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) goto out_qunlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) tr = current->journal_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if (tr->tr_num_buf_new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) gfs2_trans_end(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (gfs2_is_stuffed(ip) || gfs2_is_jdata(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) iomap->page_ops = &gfs2_iomap_page_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) out_trans_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) gfs2_trans_end(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) out_trans_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) gfs2_inplace_release(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) out_qunlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) gfs2_quota_unlock(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) static inline bool gfs2_iomap_need_write_lock(unsigned flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) return (flags & IOMAP_WRITE) && !(flags & IOMAP_DIRECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) unsigned flags, struct iomap *iomap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) struct iomap *srcmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) struct metapath mp = { .mp_aheight = 1, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (gfs2_is_jdata(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) iomap->flags |= IOMAP_F_BUFFER_HEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) trace_gfs2_iomap_start(ip, pos, length, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (gfs2_iomap_need_write_lock(flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) ret = gfs2_write_lock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) ret = gfs2_iomap_get(inode, pos, length, flags, iomap, &mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) switch(flags & (IOMAP_WRITE | IOMAP_ZERO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) case IOMAP_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (flags & IOMAP_DIRECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) * Silently fall back to buffered I/O for stuffed files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) * or if we've got a hole (see gfs2_file_direct_write).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (iomap->type != IOMAP_MAPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) ret = -ENOTBLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) case IOMAP_ZERO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (iomap->type == IOMAP_HOLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) ret = gfs2_iomap_begin_write(inode, pos, length, flags, iomap, &mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (ret && gfs2_iomap_need_write_lock(flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) gfs2_write_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) release_metapath(&mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) trace_gfs2_iomap_end(ip, iomap, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) ssize_t written, unsigned flags, struct iomap *iomap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) switch (flags & (IOMAP_WRITE | IOMAP_ZERO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) case IOMAP_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) if (flags & IOMAP_DIRECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) case IOMAP_ZERO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (iomap->type == IOMAP_HOLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (!gfs2_is_stuffed(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) gfs2_ordered_add_inode(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (inode == sdp->sd_rindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) adjust_fs_space(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) gfs2_inplace_release(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (ip->i_qadata && ip->i_qadata->qa_qd_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) gfs2_quota_unlock(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (length != written && (iomap->flags & IOMAP_F_NEW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) /* Deallocate blocks that were just allocated. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) loff_t blockmask = i_blocksize(inode) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) loff_t end = (pos + length) & ~blockmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) pos = (pos + written + blockmask) & ~blockmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (pos < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) truncate_pagecache_range(inode, pos, end - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) punch_hole(ip, pos, end - pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (unlikely(!written))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) if (iomap->flags & IOMAP_F_SIZE_CHANGED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) set_bit(GLF_DIRTY, &ip->i_gl->gl_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (gfs2_iomap_need_write_lock(flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) gfs2_write_unlock(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) const struct iomap_ops gfs2_iomap_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) .iomap_begin = gfs2_iomap_begin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) .iomap_end = gfs2_iomap_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) * gfs2_block_map - Map one or more blocks of an inode to a disk block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) * @inode: The inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) * @lblock: The logical block number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) * @bh_map: The bh to be mapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) * @create: True if its ok to alloc blocks to satify the request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) * The size of the requested mapping is defined in bh_map->b_size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) * Clears buffer_mapped(bh_map) and leaves bh_map->b_size unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) * when @lblock is not mapped. Sets buffer_mapped(bh_map) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) * bh_map->b_size to indicate the size of the mapping when @lblock and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) * successive blocks are mapped, up to the requested size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) * Sets buffer_boundary() if a read of metadata will be required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) * before the next block can be mapped. Sets buffer_new() if new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) * blocks were allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) * Returns: errno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) int gfs2_block_map(struct inode *inode, sector_t lblock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) struct buffer_head *bh_map, int create)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) loff_t pos = (loff_t)lblock << inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) loff_t length = bh_map->b_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) struct metapath mp = { .mp_aheight = 1, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) struct iomap iomap = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) int flags = create ? IOMAP_WRITE : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) clear_buffer_mapped(bh_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) clear_buffer_new(bh_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) clear_buffer_boundary(bh_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) trace_gfs2_bmap(ip, bh_map, lblock, create, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) ret = gfs2_iomap_get(inode, pos, length, flags, &iomap, &mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) if (create && !ret && iomap.type == IOMAP_HOLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) ret = gfs2_iomap_alloc(inode, &iomap, &mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) release_metapath(&mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (iomap.length > bh_map->b_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) iomap.length = bh_map->b_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) iomap.flags &= ~IOMAP_F_GFS2_BOUNDARY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) if (iomap.addr != IOMAP_NULL_ADDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) map_bh(bh_map, inode->i_sb, iomap.addr >> inode->i_blkbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) bh_map->b_size = iomap.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (iomap.flags & IOMAP_F_GFS2_BOUNDARY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) set_buffer_boundary(bh_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (iomap.flags & IOMAP_F_NEW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) set_buffer_new(bh_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) trace_gfs2_bmap(ip, bh_map, lblock, create, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) * Deprecated: do not use in new code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) struct buffer_head bh = { .b_state = 0, .b_blocknr = 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) int create = *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) BUG_ON(!extlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) BUG_ON(!dblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) BUG_ON(!new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) bh.b_size = BIT(inode->i_blkbits + (create ? 0 : 5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) ret = gfs2_block_map(inode, lblock, &bh, create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) *extlen = bh.b_size >> inode->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) *dblock = bh.b_blocknr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) if (buffer_new(&bh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) *new = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) *new = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) * NOTE: Never call gfs2_block_zero_range with an open transaction because it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) * uses iomap write to perform its actions, which begin their own transactions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) * (iomap_begin, page_prepare, etc.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) static int gfs2_block_zero_range(struct inode *inode, loff_t from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) unsigned int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) BUG_ON(current->journal_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) return iomap_zero_range(inode, from, length, NULL, &gfs2_iomap_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) #define GFS2_JTRUNC_REVOKES 8192
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * gfs2_journaled_truncate - Wrapper for truncate_pagecache for jdata files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) * @inode: The inode being truncated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) * @oldsize: The original (larger) size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) * @newsize: The new smaller size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) * With jdata files, we have to journal a revoke for each block which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) * truncated. As a result, we need to split this into separate transactions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) * if the number of pages being truncated gets too large.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) static int gfs2_journaled_truncate(struct inode *inode, u64 oldsize, u64 newsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) u64 max_chunk = GFS2_JTRUNC_REVOKES * sdp->sd_vfs->s_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) u64 chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) while (oldsize != newsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) struct gfs2_trans *tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) unsigned int offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) chunk = oldsize - newsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) if (chunk > max_chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) chunk = max_chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) offs = oldsize & ~PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (offs && chunk > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) chunk = offs + ((chunk - offs) & PAGE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) truncate_pagecache(inode, oldsize - chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) oldsize -= chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) tr = current->journal_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) if (!test_bit(TR_TOUCHED, &tr->tr_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) gfs2_trans_end(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) error = gfs2_trans_begin(sdp, RES_DINODE, GFS2_JTRUNC_REVOKES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) static int trunc_start(struct inode *inode, u64 newsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) struct buffer_head *dibh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) int journaled = gfs2_is_jdata(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) u64 oldsize = inode->i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (!gfs2_is_stuffed(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) unsigned int blocksize = i_blocksize(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) unsigned int offs = newsize & (blocksize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) if (offs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) error = gfs2_block_zero_range(inode, newsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) blocksize - offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (journaled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) error = gfs2_trans_begin(sdp, RES_DINODE + RES_JDATA, GFS2_JTRUNC_REVOKES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) error = gfs2_trans_begin(sdp, RES_DINODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) error = gfs2_meta_inode_buffer(ip, &dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) gfs2_trans_add_meta(ip->i_gl, dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) if (gfs2_is_stuffed(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + newsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) ip->i_diskflags |= GFS2_DIF_TRUNC_IN_PROG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) i_size_write(inode, newsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) ip->i_inode.i_mtime = ip->i_inode.i_ctime = current_time(&ip->i_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) gfs2_dinode_out(ip, dibh->b_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) if (journaled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) error = gfs2_journaled_truncate(inode, oldsize, newsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) truncate_pagecache(inode, newsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) brelse(dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (current->journal_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) gfs2_trans_end(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) int gfs2_iomap_get_alloc(struct inode *inode, loff_t pos, loff_t length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) struct iomap *iomap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) struct metapath mp = { .mp_aheight = 1, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) ret = gfs2_iomap_get(inode, pos, length, IOMAP_WRITE, iomap, &mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) if (!ret && iomap->type == IOMAP_HOLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) ret = gfs2_iomap_alloc(inode, iomap, &mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) release_metapath(&mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) * sweep_bh_for_rgrps - find an rgrp in a meta buffer and free blocks therein
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) * @ip: inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) * @rg_gh: holder of resource group glock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) * @bh: buffer head to sweep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) * @start: starting point in bh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) * @end: end point in bh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) * @meta: true if bh points to metadata (rather than data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) * @btotal: place to keep count of total blocks freed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) * We sweep a metadata buffer (provided by the metapath) for blocks we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) * free, and free them all. However, we do it one rgrp at a time. If this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) * block has references to multiple rgrps, we break it into individual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) * transactions. This allows other processes to use the rgrps while we're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) * focused on a single one, for better concurrency / performance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) * At every transaction boundary, we rewrite the inode into the journal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) * That way the bitmaps are kept consistent with the inode and we can recover
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) * if we're interrupted by power-outages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) * Returns: 0, or return code if an error occurred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) * *btotal has the total number of blocks freed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) static int sweep_bh_for_rgrps(struct gfs2_inode *ip, struct gfs2_holder *rd_gh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) struct buffer_head *bh, __be64 *start, __be64 *end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) bool meta, u32 *btotal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) struct gfs2_rgrpd *rgd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) struct gfs2_trans *tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) __be64 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) int blks_outside_rgrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) u64 bn, bstart, isize_blks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) s64 blen; /* needs to be s64 or gfs2_add_inode_blocks breaks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) bool buf_in_tr = false; /* buffer was added to transaction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) more_rgrps:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) rgd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) if (gfs2_holder_initialized(rd_gh)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) rgd = gfs2_glock2rgrp(rd_gh->gh_gl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) gfs2_assert_withdraw(sdp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) gfs2_glock_is_locked_by_me(rd_gh->gh_gl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) blks_outside_rgrp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) bstart = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) blen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) for (p = start; p < end; p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (!*p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) bn = be64_to_cpu(*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) if (rgd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) if (!rgrp_contains_block(rgd, bn)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) blks_outside_rgrp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) rgd = gfs2_blk2rgrpd(sdp, bn, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) if (unlikely(!rgd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) ret = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 0, rd_gh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) /* Must be done with the rgrp glock held: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) if (gfs2_rs_active(&ip->i_res) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) rgd == ip->i_res.rs_rbm.rgd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) gfs2_rs_deltree(&ip->i_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) /* The size of our transactions will be unknown until we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) actually process all the metadata blocks that relate to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) the rgrp. So we estimate. We know it can't be more than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) the dinode's i_blocks and we don't want to exceed the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) journal flush threshold, sd_log_thresh2. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) if (current->journal_info == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) unsigned int jblocks_rqsted, revokes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) jblocks_rqsted = rgd->rd_length + RES_DINODE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) RES_INDIRECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) isize_blks = gfs2_get_inode_blocks(&ip->i_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) if (isize_blks > atomic_read(&sdp->sd_log_thresh2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) jblocks_rqsted +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) atomic_read(&sdp->sd_log_thresh2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) jblocks_rqsted += isize_blks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) revokes = jblocks_rqsted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) if (meta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) revokes += end - start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) else if (ip->i_depth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) revokes += sdp->sd_inptrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) ret = gfs2_trans_begin(sdp, jblocks_rqsted, revokes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) down_write(&ip->i_rw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) /* check if we will exceed the transaction blocks requested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) tr = current->journal_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) if (tr->tr_num_buf_new + RES_STATFS +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) RES_QUOTA >= atomic_read(&sdp->sd_log_thresh2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) /* We set blks_outside_rgrp to ensure the loop will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) be repeated for the same rgrp, but with a new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) transaction. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) blks_outside_rgrp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) /* This next part is tricky. If the buffer was added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) to the transaction, we've already set some block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) pointers to 0, so we better follow through and free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) them, or we will introduce corruption (so break).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) This may be impossible, or at least rare, but I
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) decided to cover the case regardless.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) If the buffer was not added to the transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) (this call), doing so would exceed our transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) size, so we need to end the transaction and start a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) new one (so goto). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) if (buf_in_tr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) gfs2_trans_add_meta(ip->i_gl, bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) buf_in_tr = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) *p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (bstart + blen == bn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) blen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) if (bstart) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) __gfs2_free_blocks(ip, rgd, bstart, (u32)blen, meta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) (*btotal) += blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) gfs2_add_inode_blocks(&ip->i_inode, -blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) bstart = bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) blen = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (bstart) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) __gfs2_free_blocks(ip, rgd, bstart, (u32)blen, meta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) (*btotal) += blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) gfs2_add_inode_blocks(&ip->i_inode, -blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (!ret && blks_outside_rgrp) { /* If buffer still has non-zero blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) outside the rgrp we just processed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) do it all over again. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) if (current->journal_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) struct buffer_head *dibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) ret = gfs2_meta_inode_buffer(ip, &dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) /* Every transaction boundary, we rewrite the dinode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) to keep its di_blocks current in case of failure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) ip->i_inode.i_mtime = ip->i_inode.i_ctime =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) current_time(&ip->i_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) gfs2_trans_add_meta(ip->i_gl, dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) gfs2_dinode_out(ip, dibh->b_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) brelse(dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) up_write(&ip->i_rw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) gfs2_trans_end(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) buf_in_tr = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) gfs2_glock_dq_uninit(rd_gh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) goto more_rgrps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) static bool mp_eq_to_hgt(struct metapath *mp, __u16 *list, unsigned int h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) if (memcmp(mp->mp_list, list, h * sizeof(mp->mp_list[0])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) * find_nonnull_ptr - find a non-null pointer given a metapath and height
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) * @mp: starting metapath
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) * @h: desired height to search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) * Assumes the metapath is valid (with buffers) out to height h.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) * Returns: true if a non-null pointer was found in the metapath buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) * false if all remaining pointers are NULL in the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) static bool find_nonnull_ptr(struct gfs2_sbd *sdp, struct metapath *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) unsigned int h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) __u16 *end_list, unsigned int end_aligned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) struct buffer_head *bh = mp->mp_bh[h];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) __be64 *first, *ptr, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) first = metaptr1(h, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) ptr = first + mp->mp_list[h];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) end = (__be64 *)(bh->b_data + bh->b_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) if (end_list && mp_eq_to_hgt(mp, end_list, h)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) bool keep_end = h < end_aligned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) end = first + end_list[h] + keep_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) while (ptr < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) if (*ptr) { /* if we have a non-null pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) mp->mp_list[h] = ptr - first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) h++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) if (h < GFS2_MAX_META_HEIGHT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) mp->mp_list[h] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) enum dealloc_states {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) DEALLOC_MP_FULL = 0, /* Strip a metapath with all buffers read in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) DEALLOC_MP_LOWER = 1, /* lower the metapath strip height */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) DEALLOC_FILL_MP = 2, /* Fill in the metapath to the given height. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) DEALLOC_DONE = 3, /* process complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) metapointer_range(struct metapath *mp, int height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) __u16 *start_list, unsigned int start_aligned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) __u16 *end_list, unsigned int end_aligned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) __be64 **start, __be64 **end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) struct buffer_head *bh = mp->mp_bh[height];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) __be64 *first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) first = metaptr1(height, mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) *start = first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) if (mp_eq_to_hgt(mp, start_list, height)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) bool keep_start = height < start_aligned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) *start = first + start_list[height] + keep_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) *end = (__be64 *)(bh->b_data + bh->b_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) if (end_list && mp_eq_to_hgt(mp, end_list, height)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) bool keep_end = height < end_aligned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) *end = first + end_list[height] + keep_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) static inline bool walk_done(struct gfs2_sbd *sdp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) struct metapath *mp, int height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) __u16 *end_list, unsigned int end_aligned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) __u16 end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) if (end_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) bool keep_end = height < end_aligned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (!mp_eq_to_hgt(mp, end_list, height))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) end = end_list[height] + keep_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) end = (height > 0) ? sdp->sd_inptrs : sdp->sd_diptrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) return mp->mp_list[height] >= end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) * punch_hole - deallocate blocks in a file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) * @ip: inode to truncate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) * @offset: the start of the hole
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) * @length: the size of the hole (or 0 for truncate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) * Punch a hole into a file or truncate a file at a given position. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) * function operates in whole blocks (@offset and @length are rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) * accordingly); partially filled blocks must be cleared otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) * This function works from the bottom up, and from the right to the left. In
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) * other words, it strips off the highest layer (data) before stripping any of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) * the metadata. Doing it this way is best in case the operation is interrupted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) * by power failure, etc. The dinode is rewritten in every transaction to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) * guarantee integrity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) u64 maxsize = sdp->sd_heightsize[ip->i_height];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) struct metapath mp = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) struct buffer_head *dibh, *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) struct gfs2_holder rd_gh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) unsigned int bsize_shift = sdp->sd_sb.sb_bsize_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) u64 lblock = (offset + (1 << bsize_shift) - 1) >> bsize_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) __u16 start_list[GFS2_MAX_META_HEIGHT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) __u16 __end_list[GFS2_MAX_META_HEIGHT], *end_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) unsigned int start_aligned, end_aligned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) unsigned int strip_h = ip->i_height - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) u32 btotal = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) int ret, state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) int mp_h; /* metapath buffers are read in to this height */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) u64 prev_bnr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) __be64 *start, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) if (offset >= maxsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) * The starting point lies beyond the allocated meta-data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) * there are no blocks do deallocate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) * The start position of the hole is defined by lblock, start_list, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) * start_aligned. The end position of the hole is defined by lend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) * end_list, and end_aligned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) * start_aligned and end_aligned define down to which height the start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) * and end positions are aligned to the metadata tree (i.e., the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) * position is a multiple of the metadata granularity at the height
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) * above). This determines at which heights additional meta pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) * needs to be preserved for the remaining data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) if (length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) u64 end_offset = offset + length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) u64 lend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) * Clip the end at the maximum file size for the given height:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) * that's how far the metadata goes; files bigger than that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) * will have additional layers of indirection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) if (end_offset > maxsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) end_offset = maxsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) lend = end_offset >> bsize_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) if (lblock >= lend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) find_metapath(sdp, lend, &mp, ip->i_height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) end_list = __end_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) memcpy(end_list, mp.mp_list, sizeof(mp.mp_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) for (mp_h = ip->i_height - 1; mp_h > 0; mp_h--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) if (end_list[mp_h])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) end_aligned = mp_h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) find_metapath(sdp, lblock, &mp, ip->i_height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) memcpy(start_list, mp.mp_list, sizeof(start_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) for (mp_h = ip->i_height - 1; mp_h > 0; mp_h--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) if (start_list[mp_h])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) start_aligned = mp_h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) ret = gfs2_meta_inode_buffer(ip, &dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) mp.mp_bh[0] = dibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) ret = lookup_metapath(ip, &mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) goto out_metapath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) /* issue read-ahead on metadata */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) for (mp_h = 0; mp_h < mp.mp_aheight - 1; mp_h++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) metapointer_range(&mp, mp_h, start_list, start_aligned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) end_list, end_aligned, &start, &end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) gfs2_metapath_ra(ip->i_gl, start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) if (mp.mp_aheight == ip->i_height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) state = DEALLOC_MP_FULL; /* We have a complete metapath */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) state = DEALLOC_FILL_MP; /* deal with partial metapath */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) ret = gfs2_rindex_update(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) goto out_metapath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) ret = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) goto out_metapath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) gfs2_holder_mark_uninitialized(&rd_gh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) mp_h = strip_h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) while (state != DEALLOC_DONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) /* Truncate a full metapath at the given strip height.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) * Note that strip_h == mp_h in order to be in this state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) case DEALLOC_MP_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) bh = mp.mp_bh[mp_h];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) gfs2_assert_withdraw(sdp, bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) if (gfs2_assert_withdraw(sdp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) prev_bnr != bh->b_blocknr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) fs_emerg(sdp, "inode %llu, block:%llu, i_h:%u,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) "s_h:%u, mp_h:%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) (unsigned long long)ip->i_no_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) prev_bnr, ip->i_height, strip_h, mp_h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) prev_bnr = bh->b_blocknr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) if (gfs2_metatype_check(sdp, bh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) (mp_h ? GFS2_METATYPE_IN :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) GFS2_METATYPE_DI))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) * Below, passing end_aligned as 0 gives us the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) * metapointer range excluding the end point: the end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) * point is the first metapath we must not deallocate!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) metapointer_range(&mp, mp_h, start_list, start_aligned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) end_list, 0 /* end_aligned */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) &start, &end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) ret = sweep_bh_for_rgrps(ip, &rd_gh, mp.mp_bh[mp_h],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) start, end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) mp_h != ip->i_height - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) &btotal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) /* If we hit an error or just swept dinode buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) just exit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) if (ret || !mp_h) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) state = DEALLOC_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) state = DEALLOC_MP_LOWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) /* lower the metapath strip height */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) case DEALLOC_MP_LOWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) /* We're done with the current buffer, so release it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) unless it's the dinode buffer. Then back up to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) previous pointer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) if (mp_h) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) brelse(mp.mp_bh[mp_h]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) mp.mp_bh[mp_h] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) /* If we can't get any lower in height, we've stripped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) off all we can. Next step is to back up and start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) stripping the previous level of metadata. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) if (mp_h == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) strip_h--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) memcpy(mp.mp_list, start_list, sizeof(start_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) mp_h = strip_h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) state = DEALLOC_FILL_MP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) mp.mp_list[mp_h] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) mp_h--; /* search one metadata height down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) mp.mp_list[mp_h]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) if (walk_done(sdp, &mp, mp_h, end_list, end_aligned))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) /* Here we've found a part of the metapath that is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) * allocated. We need to search at that height for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) * next non-null pointer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) if (find_nonnull_ptr(sdp, &mp, mp_h, end_list, end_aligned)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) state = DEALLOC_FILL_MP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) mp_h++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) /* No more non-null pointers at this height. Back up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) to the previous height and try again. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) break; /* loop around in the same state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) /* Fill the metapath with buffers to the given height. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) case DEALLOC_FILL_MP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) /* Fill the buffers out to the current height. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) ret = fillup_metapath(ip, &mp, mp_h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) /* On the first pass, issue read-ahead on metadata. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) if (mp.mp_aheight > 1 && strip_h == ip->i_height - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) unsigned int height = mp.mp_aheight - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) /* No read-ahead for data blocks. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) if (mp.mp_aheight - 1 == strip_h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) height--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) for (; height >= mp.mp_aheight - ret; height--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) metapointer_range(&mp, height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) start_list, start_aligned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) end_list, end_aligned,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) &start, &end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) gfs2_metapath_ra(ip->i_gl, start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) /* If buffers found for the entire strip height */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) if (mp.mp_aheight - 1 == strip_h) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) state = DEALLOC_MP_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) if (mp.mp_aheight < ip->i_height) /* We have a partial height */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) mp_h = mp.mp_aheight - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) /* If we find a non-null block pointer, crawl a bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) higher up in the metapath and try again, otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) we need to look lower for a new starting point. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) if (find_nonnull_ptr(sdp, &mp, mp_h, end_list, end_aligned))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) mp_h++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) state = DEALLOC_MP_LOWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) if (btotal) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) if (current->journal_info == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) ret = gfs2_trans_begin(sdp, RES_DINODE + RES_STATFS +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) RES_QUOTA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) down_write(&ip->i_rw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) gfs2_statfs_change(sdp, 0, +btotal, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) gfs2_quota_change(ip, -(s64)btotal, ip->i_inode.i_uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) ip->i_inode.i_gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) ip->i_inode.i_mtime = ip->i_inode.i_ctime = current_time(&ip->i_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) gfs2_trans_add_meta(ip->i_gl, dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) gfs2_dinode_out(ip, dibh->b_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) up_write(&ip->i_rw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) gfs2_trans_end(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) if (gfs2_holder_initialized(&rd_gh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) gfs2_glock_dq_uninit(&rd_gh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) if (current->journal_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) up_write(&ip->i_rw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) gfs2_trans_end(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) gfs2_quota_unhold(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) out_metapath:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) release_metapath(&mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) static int trunc_end(struct gfs2_inode *ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) struct buffer_head *dibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) error = gfs2_trans_begin(sdp, RES_DINODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) down_write(&ip->i_rw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) error = gfs2_meta_inode_buffer(ip, &dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) if (!i_size_read(&ip->i_inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) ip->i_height = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) ip->i_goal = ip->i_no_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) gfs2_ordered_del_inode(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) ip->i_inode.i_mtime = ip->i_inode.i_ctime = current_time(&ip->i_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) ip->i_diskflags &= ~GFS2_DIF_TRUNC_IN_PROG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) gfs2_trans_add_meta(ip->i_gl, dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) gfs2_dinode_out(ip, dibh->b_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) brelse(dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) up_write(&ip->i_rw_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) gfs2_trans_end(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) * do_shrink - make a file smaller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) * @inode: the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) * @newsize: the size to make the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) * Called with an exclusive lock on @inode. The @size must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) * be equal to or smaller than the current inode size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) * Returns: errno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) static int do_shrink(struct inode *inode, u64 newsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) error = trunc_start(inode, newsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) if (gfs2_is_stuffed(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) error = punch_hole(ip, newsize, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) if (error == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) error = trunc_end(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) void gfs2_trim_blocks(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) ret = do_shrink(inode, inode->i_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) WARN_ON(ret != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) * do_grow - Touch and update inode size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) * @inode: The inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) * @size: The new size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) * This function updates the timestamps on the inode and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) * may also increase the size of the inode. This function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) * must not be called with @size any smaller than the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) * inode size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) * Although it is not strictly required to unstuff files here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) * earlier versions of GFS2 have a bug in the stuffed file reading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) * code which will result in a buffer overrun if the size is larger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) * than the max stuffed file size. In order to prevent this from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) * occurring, such files are unstuffed, but in other cases we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) * just update the inode size directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) * Returns: 0 on success, or -ve on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) static int do_grow(struct inode *inode, u64 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) struct gfs2_alloc_parms ap = { .target = 1, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) struct buffer_head *dibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) int unstuff = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) if (gfs2_is_stuffed(ip) && size > gfs2_max_stuffed_size(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) error = gfs2_quota_lock_check(ip, &ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) error = gfs2_inplace_reserve(ip, &ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) goto do_grow_qunlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) unstuff = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) error = gfs2_trans_begin(sdp, RES_DINODE + RES_STATFS + RES_RG_BIT +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) (unstuff &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) gfs2_is_jdata(ip) ? RES_JDATA : 0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 0 : RES_QUOTA), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) goto do_grow_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) if (unstuff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) error = gfs2_unstuff_dinode(ip, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) goto do_end_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) error = gfs2_meta_inode_buffer(ip, &dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) goto do_end_trans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) truncate_setsize(inode, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) ip->i_inode.i_mtime = ip->i_inode.i_ctime = current_time(&ip->i_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) gfs2_trans_add_meta(ip->i_gl, dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) gfs2_dinode_out(ip, dibh->b_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) brelse(dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) do_end_trans:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) gfs2_trans_end(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) do_grow_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) if (unstuff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) gfs2_inplace_release(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) do_grow_qunlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) gfs2_quota_unlock(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) * gfs2_setattr_size - make a file a given size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) * @inode: the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) * @newsize: the size to make the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) * The file size can grow, shrink, or stay the same size. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) * is called holding i_rwsem and an exclusive glock on the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) * in question.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) * Returns: errno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) int gfs2_setattr_size(struct inode *inode, u64 newsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) BUG_ON(!S_ISREG(inode->i_mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) ret = inode_newsize_ok(inode, newsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) inode_dio_wait(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) ret = gfs2_qa_get(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) if (newsize >= inode->i_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) ret = do_grow(inode, newsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) ret = do_shrink(inode, newsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) gfs2_rs_delete(ip, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) gfs2_qa_put(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) int gfs2_truncatei_resume(struct gfs2_inode *ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) error = punch_hole(ip, i_size_read(&ip->i_inode), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) error = trunc_end(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) int gfs2_file_dealloc(struct gfs2_inode *ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) return punch_hole(ip, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) * gfs2_free_journal_extents - Free cached journal bmap info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) * @jd: The journal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) void gfs2_free_journal_extents(struct gfs2_jdesc *jd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) struct gfs2_journal_extent *jext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) while(!list_empty(&jd->extent_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) jext = list_first_entry(&jd->extent_list, struct gfs2_journal_extent, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) list_del(&jext->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) kfree(jext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) * gfs2_add_jextent - Add or merge a new extent to extent cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) * @jd: The journal descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) * @lblock: The logical block at start of new extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) * @dblock: The physical block at start of new extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) * @blocks: Size of extent in fs blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) * Returns: 0 on success or -ENOMEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) static int gfs2_add_jextent(struct gfs2_jdesc *jd, u64 lblock, u64 dblock, u64 blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) struct gfs2_journal_extent *jext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) if (!list_empty(&jd->extent_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) jext = list_last_entry(&jd->extent_list, struct gfs2_journal_extent, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) if ((jext->dblock + jext->blocks) == dblock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) jext->blocks += blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) jext = kzalloc(sizeof(struct gfs2_journal_extent), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) if (jext == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) jext->dblock = dblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) jext->lblock = lblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) jext->blocks = blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) list_add_tail(&jext->list, &jd->extent_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) jd->nr_extents++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) * gfs2_map_journal_extents - Cache journal bmap info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) * @sdp: The super block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) * @jd: The journal to map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) * Create a reusable "extent" mapping from all logical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) * blocks to all physical blocks for the given journal. This will save
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) * us time when writing journal blocks. Most journals will have only one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) * extent that maps all their logical blocks. That's because gfs2.mkfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) * arranges the journal blocks sequentially to maximize performance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) * So the extent would map the first block for the entire file length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) * However, gfs2_jadd can happen while file activity is happening, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) * those journals may not be sequential. Less likely is the case where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) * the users created their own journals by mounting the metafs and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) * laying it out. But it's still possible. These journals might have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) * several extents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) * Returns: 0 on success, or error on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) int gfs2_map_journal_extents(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) u64 lblock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) u64 lblock_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) struct buffer_head bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) unsigned int shift = sdp->sd_sb.sb_bsize_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) u64 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) ktime_t start, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) start = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) lblock_stop = i_size_read(jd->jd_inode) >> shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) size = (lblock_stop - lblock) << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) jd->nr_extents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) WARN_ON(!list_empty(&jd->extent_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) bh.b_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) bh.b_blocknr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) bh.b_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) rc = gfs2_block_map(jd->jd_inode, lblock, &bh, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) if (rc || !buffer_mapped(&bh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) rc = gfs2_add_jextent(jd, lblock, bh.b_blocknr, bh.b_size >> shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) size -= bh.b_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) lblock += (bh.b_size >> ip->i_inode.i_blkbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) } while(size > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) end = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) fs_info(sdp, "journal %d mapped with %u extents in %lldms\n", jd->jd_jid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) jd->nr_extents, ktime_ms_delta(end, start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) fs_warn(sdp, "error %d mapping journal %u at offset %llu (extent %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) rc, jd->jd_jid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) (unsigned long long)(i_size_read(jd->jd_inode) - size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) jd->nr_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) fs_warn(sdp, "bmap=%d lblock=%llu block=%llu, state=0x%08lx, size=%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) rc, (unsigned long long)lblock, (unsigned long long)bh.b_blocknr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) bh.b_state, (unsigned long long)bh.b_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) gfs2_free_journal_extents(jd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) * gfs2_write_alloc_required - figure out if a write will require an allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) * @ip: the file being written to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) * @offset: the offset to write to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) * @len: the number of bytes being written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) * Returns: 1 if an alloc is required, 0 otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) struct buffer_head bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) unsigned int shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) u64 lblock, lblock_stop, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) u64 end_of_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) if (gfs2_is_stuffed(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) if (offset + len > gfs2_max_stuffed_size(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) shift = sdp->sd_sb.sb_bsize_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) BUG_ON(gfs2_is_dir(ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) end_of_file = (i_size_read(&ip->i_inode) + sdp->sd_sb.sb_bsize - 1) >> shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) lblock = offset >> shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) if (lblock_stop > end_of_file && ip != GFS2_I(sdp->sd_rindex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) size = (lblock_stop - lblock) << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) bh.b_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) bh.b_size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) gfs2_block_map(&ip->i_inode, lblock, &bh, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) if (!buffer_mapped(&bh))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) size -= bh.b_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) lblock += (bh.b_size >> ip->i_inode.i_blkbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) } while(size > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) static int stuffed_zero_range(struct inode *inode, loff_t offset, loff_t length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) struct buffer_head *dibh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) if (offset >= inode->i_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) if (offset + length > inode->i_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) length = inode->i_size - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) error = gfs2_meta_inode_buffer(ip, &dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) gfs2_trans_add_meta(ip->i_gl, dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) memset(dibh->b_data + sizeof(struct gfs2_dinode) + offset, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) brelse(dibh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) static int gfs2_journaled_truncate_range(struct inode *inode, loff_t offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) loff_t length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) loff_t max_chunk = GFS2_JTRUNC_REVOKES * sdp->sd_vfs->s_blocksize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) while (length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) struct gfs2_trans *tr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) loff_t chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) unsigned int offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) chunk = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) if (chunk > max_chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) chunk = max_chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) offs = offset & ~PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) if (offs && chunk > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) chunk = offs + ((chunk - offs) & PAGE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) truncate_pagecache_range(inode, offset, chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) offset += chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) length -= chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) tr = current->journal_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) if (!test_bit(TR_TOUCHED, &tr->tr_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) gfs2_trans_end(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) error = gfs2_trans_begin(sdp, RES_DINODE, GFS2_JTRUNC_REVOKES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) struct gfs2_inode *ip = GFS2_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) struct gfs2_sbd *sdp = GFS2_SB(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) unsigned int blocksize = i_blocksize(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) loff_t start, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) if (!gfs2_is_stuffed(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) unsigned int start_off, end_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) start_off = offset & (blocksize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) end_len = (offset + length) & (blocksize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) if (start_off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) unsigned int len = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) if (length > blocksize - start_off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) len = blocksize - start_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) error = gfs2_block_zero_range(inode, offset, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) if (start_off + length < blocksize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) end_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) if (end_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) error = gfs2_block_zero_range(inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) offset + length - end_len, end_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) start = round_down(offset, blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) end = round_up(offset + length, blocksize) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) error = filemap_write_and_wait_range(inode->i_mapping, start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) if (gfs2_is_jdata(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_JDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) GFS2_JTRUNC_REVOKES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) error = gfs2_trans_begin(sdp, RES_DINODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) if (gfs2_is_stuffed(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) error = stuffed_zero_range(inode, offset, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) if (gfs2_is_jdata(ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) BUG_ON(!current->journal_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) gfs2_journaled_truncate_range(inode, offset, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) truncate_pagecache_range(inode, offset, offset + length - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) file_update_time(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) if (current->journal_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) gfs2_trans_end(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) if (!gfs2_is_stuffed(ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) error = punch_hole(ip, offset, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) if (current->journal_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) gfs2_trans_end(sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) static int gfs2_map_blocks(struct iomap_writepage_ctx *wpc, struct inode *inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) loff_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) struct metapath mp = { .mp_aheight = 1, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) if (WARN_ON_ONCE(gfs2_is_stuffed(GFS2_I(inode))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) if (offset >= wpc->iomap.offset &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) offset < wpc->iomap.offset + wpc->iomap.length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) memset(&wpc->iomap, 0, sizeof(wpc->iomap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) ret = gfs2_iomap_get(inode, offset, INT_MAX, 0, &wpc->iomap, &mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) release_metapath(&mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) const struct iomap_writeback_ops gfs2_writeback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) .map_blocks = gfs2_map_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) };