^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* AFS filesystem directory editing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/iversion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "xdr_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Find a number of contiguous clear bits in a directory block bitmask.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * There are 64 slots, which means we can load the entire bitmap into a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * variable. The first bit doesn't count as it corresponds to the block header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * slot. nr_slots is between 1 and 9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static int afs_find_contig_bits(union afs_xdr_dir_block *block, unsigned int nr_slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) u64 bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int bit, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) bitmap = (u64)block->hdr.bitmap[0] << 0 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) bitmap |= (u64)block->hdr.bitmap[1] << 1 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) bitmap |= (u64)block->hdr.bitmap[2] << 2 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) bitmap |= (u64)block->hdr.bitmap[3] << 3 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) bitmap |= (u64)block->hdr.bitmap[4] << 4 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) bitmap |= (u64)block->hdr.bitmap[5] << 5 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) bitmap |= (u64)block->hdr.bitmap[6] << 6 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) bitmap |= (u64)block->hdr.bitmap[7] << 7 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) bitmap >>= 1; /* The first entry is metadata */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) bit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) mask = (1 << nr_slots) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (sizeof(unsigned long) == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) n = ffz(bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) n = ((u32)bitmap) != 0 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) ffz((u32)bitmap) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ffz((u32)(bitmap >> 32)) + 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) bitmap >>= n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) bit += n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if ((bitmap & mask) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (bit > 64 - nr_slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) n = __ffs(bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) bitmap >>= n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) bit += n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) } while (bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * Set a number of contiguous bits in the directory block bitmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static void afs_set_contig_bits(union afs_xdr_dir_block *block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int bit, unsigned int nr_slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) u64 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) mask = (1 << nr_slots) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) mask <<= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) block->hdr.bitmap[0] |= (u8)(mask >> 0 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) block->hdr.bitmap[1] |= (u8)(mask >> 1 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) block->hdr.bitmap[2] |= (u8)(mask >> 2 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) block->hdr.bitmap[3] |= (u8)(mask >> 3 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) block->hdr.bitmap[4] |= (u8)(mask >> 4 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) block->hdr.bitmap[5] |= (u8)(mask >> 5 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) block->hdr.bitmap[6] |= (u8)(mask >> 6 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) block->hdr.bitmap[7] |= (u8)(mask >> 7 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * Clear a number of contiguous bits in the directory block bitmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static void afs_clear_contig_bits(union afs_xdr_dir_block *block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) int bit, unsigned int nr_slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) u64 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) mask = (1 << nr_slots) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) mask <<= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) block->hdr.bitmap[0] &= ~(u8)(mask >> 0 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) block->hdr.bitmap[1] &= ~(u8)(mask >> 1 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) block->hdr.bitmap[2] &= ~(u8)(mask >> 2 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) block->hdr.bitmap[3] &= ~(u8)(mask >> 3 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) block->hdr.bitmap[4] &= ~(u8)(mask >> 4 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) block->hdr.bitmap[5] &= ~(u8)(mask >> 5 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) block->hdr.bitmap[6] &= ~(u8)(mask >> 6 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) block->hdr.bitmap[7] &= ~(u8)(mask >> 7 * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^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) * Scan a directory block looking for a dirent of the right name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static int afs_dir_scan_block(union afs_xdr_dir_block *block, struct qstr *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) unsigned int blocknum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) union afs_xdr_dirent *de;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u64 bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int d, len, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) _enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) bitmap = (u64)block->hdr.bitmap[0] << 0 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) bitmap |= (u64)block->hdr.bitmap[1] << 1 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) bitmap |= (u64)block->hdr.bitmap[2] << 2 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) bitmap |= (u64)block->hdr.bitmap[3] << 3 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) bitmap |= (u64)block->hdr.bitmap[4] << 4 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) bitmap |= (u64)block->hdr.bitmap[5] << 5 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) bitmap |= (u64)block->hdr.bitmap[6] << 6 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) bitmap |= (u64)block->hdr.bitmap[7] << 7 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) for (d = (blocknum == 0 ? AFS_DIR_RESV_BLOCKS0 : AFS_DIR_RESV_BLOCKS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) d < AFS_DIR_SLOTS_PER_BLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) d++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (!((bitmap >> d) & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) de = &block->dirents[d];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (de->u.valid != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* The block was NUL-terminated by afs_dir_check_page(). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) len = strlen(de->u.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (len == name->len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) memcmp(de->u.name, name->name, name->len) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) n = round_up(12 + len + 1 + 4, AFS_DIR_DIRENT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) n /= AFS_DIR_DIRENT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) d += n - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * Initialise a new directory block. Note that block 0 is special and contains
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * some extra metadata.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static void afs_edit_init_block(union afs_xdr_dir_block *meta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) union afs_xdr_dir_block *block, int block_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) memset(block, 0, sizeof(*block));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) block->hdr.npages = htons(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) block->hdr.magic = AFS_DIR_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) block->hdr.bitmap[0] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (block_num == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) block->hdr.bitmap[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) block->hdr.bitmap[1] = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) memset(block->meta.alloc_ctrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) AFS_DIR_SLOTS_PER_BLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) sizeof(block->meta.alloc_ctrs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) meta->meta.alloc_ctrs[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) AFS_DIR_SLOTS_PER_BLOCK - AFS_DIR_RESV_BLOCKS0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (block_num < AFS_DIR_BLOCKS_WITH_CTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) meta->meta.alloc_ctrs[block_num] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) AFS_DIR_SLOTS_PER_BLOCK - AFS_DIR_RESV_BLOCKS;
^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) * Edit a directory's file data to add a new directory entry. Doing this after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * create, mkdir, symlink, link or rename if the data version number is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * incremented by exactly one avoids the need to re-download the entire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * directory contents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * The caller must hold the inode locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) void afs_edit_dir_add(struct afs_vnode *vnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct qstr *name, struct afs_fid *new_fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) enum afs_edit_dir_reason why)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) union afs_xdr_dir_block *meta, *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct afs_xdr_dir_page *meta_page, *dir_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) union afs_xdr_dirent *de;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct page *page0, *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) unsigned int need_slots, nr_blocks, b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) pgoff_t index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) loff_t i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) gfp_t gfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) _enter(",,{%d,%s},", name->len, name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) i_size = i_size_read(&vnode->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (i_size > AFS_DIR_BLOCK_SIZE * AFS_DIR_MAX_BLOCKS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) (i_size & (AFS_DIR_BLOCK_SIZE - 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return;
^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) gfp = vnode->vfs_inode.i_mapping->gfp_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) page0 = find_or_create_page(vnode->vfs_inode.i_mapping, 0, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (!page0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) _leave(" [fgp]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* Work out how many slots we're going to need. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) need_slots = round_up(12 + name->len + 1 + 4, AFS_DIR_DIRENT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) need_slots /= AFS_DIR_DIRENT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) meta_page = kmap(page0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) meta = &meta_page->blocks[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (i_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) goto new_directory;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) nr_blocks = i_size / AFS_DIR_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /* Find a block that has sufficient slots available. Each VM page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * contains two or more directory blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) for (b = 0; b < nr_blocks + 1; b++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* If the directory extended into a new page, then we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * tack a new page on the end.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) index = b / AFS_DIR_BLOCKS_PER_PAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (index == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) page = page0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) dir_page = meta_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (nr_blocks >= AFS_DIR_MAX_BLOCKS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) gfp = vnode->vfs_inode.i_mapping->gfp_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) page = find_or_create_page(vnode->vfs_inode.i_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) index, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (!PagePrivate(page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) attach_page_private(page, (void *)1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) dir_page = kmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /* Abandon the edit if we got a callback break. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) goto invalidated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) block = &dir_page->blocks[b % AFS_DIR_BLOCKS_PER_PAGE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) _debug("block %u: %2u %3u %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) (b < AFS_DIR_BLOCKS_WITH_CTR) ? meta->meta.alloc_ctrs[b] : 99,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ntohs(block->hdr.npages),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) ntohs(block->hdr.magic));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* Initialise the block if necessary. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (b == nr_blocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) _debug("init %u", b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) afs_edit_init_block(meta, block, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) afs_set_i_size(vnode, (b + 1) * AFS_DIR_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* Only lower dir pages have a counter in the header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (b >= AFS_DIR_BLOCKS_WITH_CTR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) meta->meta.alloc_ctrs[b] >= need_slots) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /* We need to try and find one or more consecutive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * slots to hold the entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) slot = afs_find_contig_bits(block, need_slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (slot >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) _debug("slot %u", slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) goto found_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (page != page0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^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) /* There are no spare slots of sufficient size, yet the operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * succeeded. Download the directory again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) trace_afs_edit_dir(vnode, why, afs_edit_dir_create_nospc, 0, 0, 0, 0, name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) new_directory:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) afs_edit_init_block(meta, meta, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) i_size = AFS_DIR_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) afs_set_i_size(vnode, i_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) slot = AFS_DIR_RESV_BLOCKS0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) page = page0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) block = meta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) nr_blocks = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) b = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) found_space:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* Set the dirent slot. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) trace_afs_edit_dir(vnode, why, afs_edit_dir_create, b, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) new_fid->vnode, new_fid->unique, name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) de = &block->dirents[slot];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) de->u.valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) de->u.unused[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) de->u.hash_next = 0; // TODO: Really need to maintain this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) de->u.vnode = htonl(new_fid->vnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) de->u.unique = htonl(new_fid->unique);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) memcpy(de->u.name, name->name, name->len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) de->u.name[name->len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* Adjust the bitmap. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) afs_set_contig_bits(block, slot, need_slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (page != page0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* Adjust the allocation counter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (b < AFS_DIR_BLOCKS_WITH_CTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) meta->meta.alloc_ctrs[b] -= need_slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) inode_inc_iversion_raw(&vnode->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) afs_stat_v(vnode, n_dir_cr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) _debug("Insert %s in %u[%u]", name->name, b, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) out_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) unlock_page(page0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) kunmap(page0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) put_page(page0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) _leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) invalidated:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) trace_afs_edit_dir(vnode, why, afs_edit_dir_create_inval, 0, 0, 0, 0, name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (page != page0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) trace_afs_edit_dir(vnode, why, afs_edit_dir_create_error, 0, 0, 0, 0, name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^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) * Edit a directory's file data to remove a new directory entry. Doing this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * after unlink, rmdir or rename if the data version number is incremented by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * exactly one avoids the need to re-download the entire directory contents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * The caller must hold the inode locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) void afs_edit_dir_remove(struct afs_vnode *vnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct qstr *name, enum afs_edit_dir_reason why)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct afs_xdr_dir_page *meta_page, *dir_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) union afs_xdr_dir_block *meta, *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) union afs_xdr_dirent *de;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct page *page0, *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) unsigned int need_slots, nr_blocks, b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) pgoff_t index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) loff_t i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) _enter(",,{%d,%s},", name->len, name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) i_size = i_size_read(&vnode->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (i_size < AFS_DIR_BLOCK_SIZE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) i_size > AFS_DIR_BLOCK_SIZE * AFS_DIR_MAX_BLOCKS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) (i_size & (AFS_DIR_BLOCK_SIZE - 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) nr_blocks = i_size / AFS_DIR_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) page0 = find_lock_page(vnode->vfs_inode.i_mapping, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (!page0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) _leave(" [fgp]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* Work out how many slots we're going to discard. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) need_slots = round_up(12 + name->len + 1 + 4, AFS_DIR_DIRENT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) need_slots /= AFS_DIR_DIRENT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) meta_page = kmap(page0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) meta = &meta_page->blocks[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* Find a page that has sufficient slots available. Each VM page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * contains two or more directory blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) for (b = 0; b < nr_blocks; b++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) index = b / AFS_DIR_BLOCKS_PER_PAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (index != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) page = find_lock_page(vnode->vfs_inode.i_mapping, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) dir_page = kmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) page = page0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) dir_page = meta_page;
^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) /* Abandon the edit if we got a callback break. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) goto invalidated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) block = &dir_page->blocks[b % AFS_DIR_BLOCKS_PER_PAGE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (b > AFS_DIR_BLOCKS_WITH_CTR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) meta->meta.alloc_ctrs[b] <= AFS_DIR_SLOTS_PER_BLOCK - 1 - need_slots) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) slot = afs_dir_scan_block(block, name, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (slot >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) goto found_dirent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (page != page0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* Didn't find the dirent to clobber. Download the directory again. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) trace_afs_edit_dir(vnode, why, afs_edit_dir_delete_noent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 0, 0, 0, 0, name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) found_dirent:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) de = &block->dirents[slot];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) trace_afs_edit_dir(vnode, why, afs_edit_dir_delete, b, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) ntohl(de->u.vnode), ntohl(de->u.unique),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) memset(de, 0, sizeof(*de) * need_slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /* Adjust the bitmap. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) afs_clear_contig_bits(block, slot, need_slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (page != page0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) put_page(page);
^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) /* Adjust the allocation counter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (b < AFS_DIR_BLOCKS_WITH_CTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) meta->meta.alloc_ctrs[b] += need_slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) inode_set_iversion_raw(&vnode->vfs_inode, vnode->status.data_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) afs_stat_v(vnode, n_dir_rm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) _debug("Remove %s from %u[%u]", name->name, b, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) out_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) unlock_page(page0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) kunmap(page0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) put_page(page0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) _leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) invalidated:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) trace_afs_edit_dir(vnode, why, afs_edit_dir_delete_inval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 0, 0, 0, 0, name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (page != page0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) trace_afs_edit_dir(vnode, why, afs_edit_dir_delete_error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 0, 0, 0, 0, name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }