1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* AFS filesystem directory editing
4 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
8 #include <linux/kernel.h>
10 #include <linux/namei.h>
11 #include <linux/pagemap.h>
12 #include <linux/iversion.h>
17 * Find a number of contiguous clear bits in a directory block bitmask.
19 * There are 64 slots, which means we can load the entire bitmap into a
20 * variable. The first bit doesn't count as it corresponds to the block header
21 * slot. nr_slots is between 1 and 9.
23 static int afs_find_contig_bits(union afs_xdr_dir_block
*block
, unsigned int nr_slots
)
29 bitmap
= (u64
)block
->hdr
.bitmap
[0] << 0 * 8;
30 bitmap
|= (u64
)block
->hdr
.bitmap
[1] << 1 * 8;
31 bitmap
|= (u64
)block
->hdr
.bitmap
[2] << 2 * 8;
32 bitmap
|= (u64
)block
->hdr
.bitmap
[3] << 3 * 8;
33 bitmap
|= (u64
)block
->hdr
.bitmap
[4] << 4 * 8;
34 bitmap
|= (u64
)block
->hdr
.bitmap
[5] << 5 * 8;
35 bitmap
|= (u64
)block
->hdr
.bitmap
[6] << 6 * 8;
36 bitmap
|= (u64
)block
->hdr
.bitmap
[7] << 7 * 8;
37 bitmap
>>= 1; /* The first entry is metadata */
39 mask
= (1 << nr_slots
) - 1;
42 if (sizeof(unsigned long) == 8)
45 n
= ((u32
)bitmap
) != 0 ?
47 ffz((u32
)(bitmap
>> 32)) + 32;
51 if ((bitmap
& mask
) == 0) {
52 if (bit
> 64 - nr_slots
)
66 * Set a number of contiguous bits in the directory block bitmap.
68 static void afs_set_contig_bits(union afs_xdr_dir_block
*block
,
69 int bit
, unsigned int nr_slots
)
73 mask
= (1 << nr_slots
) - 1;
76 block
->hdr
.bitmap
[0] |= (u8
)(mask
>> 0 * 8);
77 block
->hdr
.bitmap
[1] |= (u8
)(mask
>> 1 * 8);
78 block
->hdr
.bitmap
[2] |= (u8
)(mask
>> 2 * 8);
79 block
->hdr
.bitmap
[3] |= (u8
)(mask
>> 3 * 8);
80 block
->hdr
.bitmap
[4] |= (u8
)(mask
>> 4 * 8);
81 block
->hdr
.bitmap
[5] |= (u8
)(mask
>> 5 * 8);
82 block
->hdr
.bitmap
[6] |= (u8
)(mask
>> 6 * 8);
83 block
->hdr
.bitmap
[7] |= (u8
)(mask
>> 7 * 8);
87 * Clear a number of contiguous bits in the directory block bitmap.
89 static void afs_clear_contig_bits(union afs_xdr_dir_block
*block
,
90 int bit
, unsigned int nr_slots
)
94 mask
= (1 << nr_slots
) - 1;
97 block
->hdr
.bitmap
[0] &= ~(u8
)(mask
>> 0 * 8);
98 block
->hdr
.bitmap
[1] &= ~(u8
)(mask
>> 1 * 8);
99 block
->hdr
.bitmap
[2] &= ~(u8
)(mask
>> 2 * 8);
100 block
->hdr
.bitmap
[3] &= ~(u8
)(mask
>> 3 * 8);
101 block
->hdr
.bitmap
[4] &= ~(u8
)(mask
>> 4 * 8);
102 block
->hdr
.bitmap
[5] &= ~(u8
)(mask
>> 5 * 8);
103 block
->hdr
.bitmap
[6] &= ~(u8
)(mask
>> 6 * 8);
104 block
->hdr
.bitmap
[7] &= ~(u8
)(mask
>> 7 * 8);
108 * Scan a directory block looking for a dirent of the right name.
110 static int afs_dir_scan_block(union afs_xdr_dir_block
*block
, struct qstr
*name
,
111 unsigned int blocknum
)
113 union afs_xdr_dirent
*de
;
119 bitmap
= (u64
)block
->hdr
.bitmap
[0] << 0 * 8;
120 bitmap
|= (u64
)block
->hdr
.bitmap
[1] << 1 * 8;
121 bitmap
|= (u64
)block
->hdr
.bitmap
[2] << 2 * 8;
122 bitmap
|= (u64
)block
->hdr
.bitmap
[3] << 3 * 8;
123 bitmap
|= (u64
)block
->hdr
.bitmap
[4] << 4 * 8;
124 bitmap
|= (u64
)block
->hdr
.bitmap
[5] << 5 * 8;
125 bitmap
|= (u64
)block
->hdr
.bitmap
[6] << 6 * 8;
126 bitmap
|= (u64
)block
->hdr
.bitmap
[7] << 7 * 8;
128 for (d
= (blocknum
== 0 ? AFS_DIR_RESV_BLOCKS0
: AFS_DIR_RESV_BLOCKS
);
129 d
< AFS_DIR_SLOTS_PER_BLOCK
;
131 if (!((bitmap
>> d
) & 1))
133 de
= &block
->dirents
[d
];
134 if (de
->u
.valid
!= 1)
137 /* The block was NUL-terminated by afs_dir_check_page(). */
138 len
= strlen(de
->u
.name
);
139 if (len
== name
->len
&&
140 memcmp(de
->u
.name
, name
->name
, name
->len
) == 0)
143 n
= round_up(12 + len
+ 1 + 4, AFS_DIR_DIRENT_SIZE
);
144 n
/= AFS_DIR_DIRENT_SIZE
;
152 * Initialise a new directory block. Note that block 0 is special and contains
153 * some extra metadata.
155 static void afs_edit_init_block(union afs_xdr_dir_block
*meta
,
156 union afs_xdr_dir_block
*block
, int block_num
)
158 memset(block
, 0, sizeof(*block
));
159 block
->hdr
.npages
= htons(1);
160 block
->hdr
.magic
= AFS_DIR_MAGIC
;
161 block
->hdr
.bitmap
[0] = 1;
163 if (block_num
== 0) {
164 block
->hdr
.bitmap
[0] = 0xff;
165 block
->hdr
.bitmap
[1] = 0x1f;
166 memset(block
->meta
.alloc_ctrs
,
167 AFS_DIR_SLOTS_PER_BLOCK
,
168 sizeof(block
->meta
.alloc_ctrs
));
169 meta
->meta
.alloc_ctrs
[0] =
170 AFS_DIR_SLOTS_PER_BLOCK
- AFS_DIR_RESV_BLOCKS0
;
173 if (block_num
< AFS_DIR_BLOCKS_WITH_CTR
)
174 meta
->meta
.alloc_ctrs
[block_num
] =
175 AFS_DIR_SLOTS_PER_BLOCK
- AFS_DIR_RESV_BLOCKS
;
179 * Edit a directory's file data to add a new directory entry. Doing this after
180 * create, mkdir, symlink, link or rename if the data version number is
181 * incremented by exactly one avoids the need to re-download the entire
182 * directory contents.
184 * The caller must hold the inode locked.
186 void afs_edit_dir_add(struct afs_vnode
*vnode
,
187 struct qstr
*name
, struct afs_fid
*new_fid
,
188 enum afs_edit_dir_reason why
)
190 union afs_xdr_dir_block
*meta
, *block
;
191 struct afs_xdr_dir_page
*meta_page
, *dir_page
;
192 union afs_xdr_dirent
*de
;
193 struct page
*page0
, *page
;
194 unsigned int need_slots
, nr_blocks
, b
;
200 _enter(",,{%d,%s},", name
->len
, name
->name
);
202 i_size
= i_size_read(&vnode
->vfs_inode
);
203 if (i_size
> AFS_DIR_BLOCK_SIZE
* AFS_DIR_MAX_BLOCKS
||
204 (i_size
& (AFS_DIR_BLOCK_SIZE
- 1))) {
205 clear_bit(AFS_VNODE_DIR_VALID
, &vnode
->flags
);
209 gfp
= vnode
->vfs_inode
.i_mapping
->gfp_mask
;
210 page0
= find_or_create_page(vnode
->vfs_inode
.i_mapping
, 0, gfp
);
212 clear_bit(AFS_VNODE_DIR_VALID
, &vnode
->flags
);
217 /* Work out how many slots we're going to need. */
218 need_slots
= round_up(12 + name
->len
+ 1 + 4, AFS_DIR_DIRENT_SIZE
);
219 need_slots
/= AFS_DIR_DIRENT_SIZE
;
221 meta_page
= kmap(page0
);
222 meta
= &meta_page
->blocks
[0];
225 nr_blocks
= i_size
/ AFS_DIR_BLOCK_SIZE
;
227 /* Find a block that has sufficient slots available. Each VM page
228 * contains two or more directory blocks.
230 for (b
= 0; b
< nr_blocks
+ 1; b
++) {
231 /* If the directory extended into a new page, then we need to
232 * tack a new page on the end.
234 index
= b
/ AFS_DIR_BLOCKS_PER_PAGE
;
237 dir_page
= meta_page
;
239 if (nr_blocks
>= AFS_DIR_MAX_BLOCKS
)
241 gfp
= vnode
->vfs_inode
.i_mapping
->gfp_mask
;
242 page
= find_or_create_page(vnode
->vfs_inode
.i_mapping
,
246 if (!PagePrivate(page
)) {
247 set_page_private(page
, 1);
248 SetPagePrivate(page
);
250 dir_page
= kmap(page
);
253 /* Abandon the edit if we got a callback break. */
254 if (!test_bit(AFS_VNODE_DIR_VALID
, &vnode
->flags
))
257 block
= &dir_page
->blocks
[b
% AFS_DIR_BLOCKS_PER_PAGE
];
259 _debug("block %u: %2u %3u %u",
261 (b
< AFS_DIR_BLOCKS_WITH_CTR
) ? meta
->meta
.alloc_ctrs
[b
] : 99,
262 ntohs(block
->hdr
.npages
),
263 ntohs(block
->hdr
.magic
));
265 /* Initialise the block if necessary. */
266 if (b
== nr_blocks
) {
267 _debug("init %u", b
);
268 afs_edit_init_block(meta
, block
, b
);
269 i_size_write(&vnode
->vfs_inode
, (b
+ 1) * AFS_DIR_BLOCK_SIZE
);
272 /* Only lower dir pages have a counter in the header. */
273 if (b
>= AFS_DIR_BLOCKS_WITH_CTR
||
274 meta
->meta
.alloc_ctrs
[b
] >= need_slots
) {
275 /* We need to try and find one or more consecutive
276 * slots to hold the entry.
278 slot
= afs_find_contig_bits(block
, need_slots
);
280 _debug("slot %u", slot
);
292 /* There are no spare slots of sufficient size, yet the operation
293 * succeeded. Download the directory again.
295 trace_afs_edit_dir(vnode
, why
, afs_edit_dir_create_nospc
, 0, 0, 0, 0, name
->name
);
296 clear_bit(AFS_VNODE_DIR_VALID
, &vnode
->flags
);
300 afs_edit_init_block(meta
, meta
, 0);
301 i_size
= AFS_DIR_BLOCK_SIZE
;
302 i_size_write(&vnode
->vfs_inode
, i_size
);
303 slot
= AFS_DIR_RESV_BLOCKS0
;
310 /* Set the dirent slot. */
311 trace_afs_edit_dir(vnode
, why
, afs_edit_dir_create
, b
, slot
,
312 new_fid
->vnode
, new_fid
->unique
, name
->name
);
313 de
= &block
->dirents
[slot
];
316 de
->u
.hash_next
= 0; // TODO: Really need to maintain this
317 de
->u
.vnode
= htonl(new_fid
->vnode
);
318 de
->u
.unique
= htonl(new_fid
->unique
);
319 memcpy(de
->u
.name
, name
->name
, name
->len
+ 1);
320 de
->u
.name
[name
->len
] = 0;
322 /* Adjust the bitmap. */
323 afs_set_contig_bits(block
, slot
, need_slots
);
330 /* Adjust the allocation counter. */
331 if (b
< AFS_DIR_BLOCKS_WITH_CTR
)
332 meta
->meta
.alloc_ctrs
[b
] -= need_slots
;
334 inode_inc_iversion_raw(&vnode
->vfs_inode
);
335 afs_stat_v(vnode
, n_dir_cr
);
336 _debug("Insert %s in %u[%u]", name
->name
, b
, slot
);
346 trace_afs_edit_dir(vnode
, why
, afs_edit_dir_create_inval
, 0, 0, 0, 0, name
->name
);
347 clear_bit(AFS_VNODE_DIR_VALID
, &vnode
->flags
);
355 trace_afs_edit_dir(vnode
, why
, afs_edit_dir_create_error
, 0, 0, 0, 0, name
->name
);
356 clear_bit(AFS_VNODE_DIR_VALID
, &vnode
->flags
);
361 * Edit a directory's file data to remove a new directory entry. Doing this
362 * after unlink, rmdir or rename if the data version number is incremented by
363 * exactly one avoids the need to re-download the entire directory contents.
365 * The caller must hold the inode locked.
367 void afs_edit_dir_remove(struct afs_vnode
*vnode
,
368 struct qstr
*name
, enum afs_edit_dir_reason why
)
370 struct afs_xdr_dir_page
*meta_page
, *dir_page
;
371 union afs_xdr_dir_block
*meta
, *block
;
372 union afs_xdr_dirent
*de
;
373 struct page
*page0
, *page
;
374 unsigned int need_slots
, nr_blocks
, b
;
379 _enter(",,{%d,%s},", name
->len
, name
->name
);
381 i_size
= i_size_read(&vnode
->vfs_inode
);
382 if (i_size
< AFS_DIR_BLOCK_SIZE
||
383 i_size
> AFS_DIR_BLOCK_SIZE
* AFS_DIR_MAX_BLOCKS
||
384 (i_size
& (AFS_DIR_BLOCK_SIZE
- 1))) {
385 clear_bit(AFS_VNODE_DIR_VALID
, &vnode
->flags
);
388 nr_blocks
= i_size
/ AFS_DIR_BLOCK_SIZE
;
390 page0
= find_lock_page(vnode
->vfs_inode
.i_mapping
, 0);
392 clear_bit(AFS_VNODE_DIR_VALID
, &vnode
->flags
);
397 /* Work out how many slots we're going to discard. */
398 need_slots
= round_up(12 + name
->len
+ 1 + 4, AFS_DIR_DIRENT_SIZE
);
399 need_slots
/= AFS_DIR_DIRENT_SIZE
;
401 meta_page
= kmap(page0
);
402 meta
= &meta_page
->blocks
[0];
404 /* Find a page that has sufficient slots available. Each VM page
405 * contains two or more directory blocks.
407 for (b
= 0; b
< nr_blocks
; b
++) {
408 index
= b
/ AFS_DIR_BLOCKS_PER_PAGE
;
410 page
= find_lock_page(vnode
->vfs_inode
.i_mapping
, index
);
413 dir_page
= kmap(page
);
416 dir_page
= meta_page
;
419 /* Abandon the edit if we got a callback break. */
420 if (!test_bit(AFS_VNODE_DIR_VALID
, &vnode
->flags
))
423 block
= &dir_page
->blocks
[b
% AFS_DIR_BLOCKS_PER_PAGE
];
425 if (b
> AFS_DIR_BLOCKS_WITH_CTR
||
426 meta
->meta
.alloc_ctrs
[b
] <= AFS_DIR_SLOTS_PER_BLOCK
- 1 - need_slots
) {
427 slot
= afs_dir_scan_block(block
, name
, b
);
439 /* Didn't find the dirent to clobber. Download the directory again. */
440 trace_afs_edit_dir(vnode
, why
, afs_edit_dir_delete_noent
,
441 0, 0, 0, 0, name
->name
);
442 clear_bit(AFS_VNODE_DIR_VALID
, &vnode
->flags
);
446 de
= &block
->dirents
[slot
];
448 trace_afs_edit_dir(vnode
, why
, afs_edit_dir_delete
, b
, slot
,
449 ntohl(de
->u
.vnode
), ntohl(de
->u
.unique
),
452 memset(de
, 0, sizeof(*de
) * need_slots
);
454 /* Adjust the bitmap. */
455 afs_clear_contig_bits(block
, slot
, need_slots
);
462 /* Adjust the allocation counter. */
463 if (b
< AFS_DIR_BLOCKS_WITH_CTR
)
464 meta
->meta
.alloc_ctrs
[b
] += need_slots
;
466 inode_set_iversion_raw(&vnode
->vfs_inode
, vnode
->status
.data_version
);
467 afs_stat_v(vnode
, n_dir_rm
);
468 _debug("Remove %s from %u[%u]", name
->name
, b
, slot
);
478 trace_afs_edit_dir(vnode
, why
, afs_edit_dir_delete_inval
,
479 0, 0, 0, 0, name
->name
);
480 clear_bit(AFS_VNODE_DIR_VALID
, &vnode
->flags
);
489 trace_afs_edit_dir(vnode
, why
, afs_edit_dir_delete_error
,
490 0, 0, 0, 0, name
->name
);
491 clear_bit(AFS_VNODE_DIR_VALID
, &vnode
->flags
);