xref: /linux/fs/afs/dir_edit.c (revision ca56a74a31e26d81a481304ed2f631e65883372b)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* AFS filesystem directory editing
3  *
4  * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
5  * Written by David Howells (dhowells@redhat.com)
6  */
7 
8 #include <linux/kernel.h>
9 #include <linux/fs.h>
10 #include <linux/namei.h>
11 #include <linux/pagemap.h>
12 #include <linux/iversion.h>
13 #include <linux/folio_queue.h>
14 #include "internal.h"
15 #include "xdr_fs.h"
16 
17 /*
18  * Find a number of contiguous clear bits in a directory block bitmask.
19  *
20  * There are 64 slots, which means we can load the entire bitmap into a
21  * variable.  The first bit doesn't count as it corresponds to the block header
22  * slot.  nr_slots is between 1 and 9.
23  */
afs_find_contig_bits(union afs_xdr_dir_block * block,unsigned int nr_slots)24 static int afs_find_contig_bits(union afs_xdr_dir_block *block, unsigned int nr_slots)
25 {
26 	u64 bitmap;
27 	u32 mask;
28 	int bit, n;
29 
30 	bitmap  = (u64)block->hdr.bitmap[0] << 0 * 8;
31 	bitmap |= (u64)block->hdr.bitmap[1] << 1 * 8;
32 	bitmap |= (u64)block->hdr.bitmap[2] << 2 * 8;
33 	bitmap |= (u64)block->hdr.bitmap[3] << 3 * 8;
34 	bitmap |= (u64)block->hdr.bitmap[4] << 4 * 8;
35 	bitmap |= (u64)block->hdr.bitmap[5] << 5 * 8;
36 	bitmap |= (u64)block->hdr.bitmap[6] << 6 * 8;
37 	bitmap |= (u64)block->hdr.bitmap[7] << 7 * 8;
38 	bitmap >>= 1; /* The first entry is metadata */
39 	bit = 1;
40 	mask = (1 << nr_slots) - 1;
41 
42 	do {
43 		if (sizeof(unsigned long) == 8)
44 			n = ffz(bitmap);
45 		else
46 			n = ((u32)bitmap) != 0 ?
47 				ffz((u32)bitmap) :
48 				ffz((u32)(bitmap >> 32)) + 32;
49 		bitmap >>= n;
50 		bit += n;
51 
52 		if ((bitmap & mask) == 0) {
53 			if (bit > 64 - nr_slots)
54 				return -1;
55 			return bit;
56 		}
57 
58 		n = __ffs(bitmap);
59 		bitmap >>= n;
60 		bit += n;
61 	} while (bitmap);
62 
63 	return -1;
64 }
65 
66 /*
67  * Set a number of contiguous bits in the directory block bitmap.
68  */
afs_set_contig_bits(union afs_xdr_dir_block * block,int bit,unsigned int nr_slots)69 static void afs_set_contig_bits(union afs_xdr_dir_block *block,
70 				int bit, unsigned int nr_slots)
71 {
72 	u64 mask;
73 
74 	mask = (1 << nr_slots) - 1;
75 	mask <<= bit;
76 
77 	block->hdr.bitmap[0] |= (u8)(mask >> 0 * 8);
78 	block->hdr.bitmap[1] |= (u8)(mask >> 1 * 8);
79 	block->hdr.bitmap[2] |= (u8)(mask >> 2 * 8);
80 	block->hdr.bitmap[3] |= (u8)(mask >> 3 * 8);
81 	block->hdr.bitmap[4] |= (u8)(mask >> 4 * 8);
82 	block->hdr.bitmap[5] |= (u8)(mask >> 5 * 8);
83 	block->hdr.bitmap[6] |= (u8)(mask >> 6 * 8);
84 	block->hdr.bitmap[7] |= (u8)(mask >> 7 * 8);
85 }
86 
87 /*
88  * Clear a number of contiguous bits in the directory block bitmap.
89  */
afs_clear_contig_bits(union afs_xdr_dir_block * block,int bit,unsigned int nr_slots)90 static void afs_clear_contig_bits(union afs_xdr_dir_block *block,
91 				  int bit, unsigned int nr_slots)
92 {
93 	u64 mask;
94 
95 	mask = (1 << nr_slots) - 1;
96 	mask <<= bit;
97 
98 	block->hdr.bitmap[0] &= ~(u8)(mask >> 0 * 8);
99 	block->hdr.bitmap[1] &= ~(u8)(mask >> 1 * 8);
100 	block->hdr.bitmap[2] &= ~(u8)(mask >> 2 * 8);
101 	block->hdr.bitmap[3] &= ~(u8)(mask >> 3 * 8);
102 	block->hdr.bitmap[4] &= ~(u8)(mask >> 4 * 8);
103 	block->hdr.bitmap[5] &= ~(u8)(mask >> 5 * 8);
104 	block->hdr.bitmap[6] &= ~(u8)(mask >> 6 * 8);
105 	block->hdr.bitmap[7] &= ~(u8)(mask >> 7 * 8);
106 }
107 
108 /*
109  * Get a specific block, extending the directory storage to cover it as needed.
110  */
afs_dir_get_block(struct afs_dir_iter * iter,size_t block)111 static union afs_xdr_dir_block *afs_dir_get_block(struct afs_dir_iter *iter, size_t block)
112 {
113 	struct folio_queue *fq;
114 	struct afs_vnode *dvnode = iter->dvnode;
115 	struct folio *folio;
116 	size_t blpos = block * AFS_DIR_BLOCK_SIZE;
117 	size_t blend = (block + 1) * AFS_DIR_BLOCK_SIZE, fpos = iter->fpos;
118 	int ret;
119 
120 	if (dvnode->directory_size < blend) {
121 		size_t cur_size = dvnode->directory_size;
122 
123 		ret = netfs_alloc_folioq_buffer(
124 			NULL, &dvnode->directory, &cur_size, blend,
125 			mapping_gfp_mask(dvnode->netfs.inode.i_mapping));
126 		dvnode->directory_size = cur_size;
127 		if (ret < 0)
128 			goto fail;
129 	}
130 
131 	fq = iter->fq;
132 	if (!fq)
133 		fq = dvnode->directory;
134 
135 	/* Search the folio queue for the folio containing the block... */
136 	for (; fq; fq = fq->next) {
137 		for (int s = iter->fq_slot; s < folioq_count(fq); s++) {
138 			size_t fsize = folioq_folio_size(fq, s);
139 
140 			if (blend <= fpos + fsize) {
141 				/* ... and then return the mapped block. */
142 				folio = folioq_folio(fq, s);
143 				if (WARN_ON_ONCE(folio_pos(folio) != fpos))
144 					goto fail;
145 				iter->fq = fq;
146 				iter->fq_slot = s;
147 				iter->fpos = fpos;
148 				return kmap_local_folio(folio, blpos - fpos);
149 			}
150 			fpos += fsize;
151 		}
152 		iter->fq_slot = 0;
153 	}
154 
155 fail:
156 	iter->fq = NULL;
157 	iter->fq_slot = 0;
158 	afs_invalidate_dir(dvnode, afs_dir_invalid_edit_get_block);
159 	return NULL;
160 }
161 
162 /*
163  * Scan a directory block looking for a dirent of the right name.
164  */
afs_dir_scan_block(const union afs_xdr_dir_block * block,const struct qstr * name,unsigned int blocknum)165 static int afs_dir_scan_block(const union afs_xdr_dir_block *block, const struct qstr *name,
166 			      unsigned int blocknum)
167 {
168 	const union afs_xdr_dirent *de;
169 	u64 bitmap;
170 	int d, len, n;
171 
172 	_enter("");
173 
174 	bitmap  = (u64)block->hdr.bitmap[0] << 0 * 8;
175 	bitmap |= (u64)block->hdr.bitmap[1] << 1 * 8;
176 	bitmap |= (u64)block->hdr.bitmap[2] << 2 * 8;
177 	bitmap |= (u64)block->hdr.bitmap[3] << 3 * 8;
178 	bitmap |= (u64)block->hdr.bitmap[4] << 4 * 8;
179 	bitmap |= (u64)block->hdr.bitmap[5] << 5 * 8;
180 	bitmap |= (u64)block->hdr.bitmap[6] << 6 * 8;
181 	bitmap |= (u64)block->hdr.bitmap[7] << 7 * 8;
182 
183 	for (d = (blocknum == 0 ? AFS_DIR_RESV_BLOCKS0 : AFS_DIR_RESV_BLOCKS);
184 	     d < AFS_DIR_SLOTS_PER_BLOCK;
185 	     d++) {
186 		if (!((bitmap >> d) & 1))
187 			continue;
188 		de = &block->dirents[d];
189 		if (de->u.valid != 1)
190 			continue;
191 
192 		/* The block was NUL-terminated by afs_dir_check_page(). */
193 		len = strlen(de->u.name);
194 		if (len == name->len &&
195 		    memcmp(de->u.name, name->name, name->len) == 0)
196 			return d;
197 
198 		n = round_up(12 + len + 1 + 4, AFS_DIR_DIRENT_SIZE);
199 		n /= AFS_DIR_DIRENT_SIZE;
200 		d += n - 1;
201 	}
202 
203 	return -1;
204 }
205 
206 /*
207  * Initialise a new directory block.  Note that block 0 is special and contains
208  * some extra metadata.
209  */
afs_edit_init_block(union afs_xdr_dir_block * meta,union afs_xdr_dir_block * block,int block_num)210 static void afs_edit_init_block(union afs_xdr_dir_block *meta,
211 				union afs_xdr_dir_block *block, int block_num)
212 {
213 	memset(block, 0, sizeof(*block));
214 	block->hdr.npages = htons(1);
215 	block->hdr.magic = AFS_DIR_MAGIC;
216 	block->hdr.bitmap[0] = 1;
217 
218 	if (block_num == 0) {
219 		block->hdr.bitmap[0] = 0xff;
220 		block->hdr.bitmap[1] = 0x1f;
221 		memset(block->meta.alloc_ctrs,
222 		       AFS_DIR_SLOTS_PER_BLOCK,
223 		       sizeof(block->meta.alloc_ctrs));
224 		meta->meta.alloc_ctrs[0] =
225 			AFS_DIR_SLOTS_PER_BLOCK - AFS_DIR_RESV_BLOCKS0;
226 	}
227 
228 	if (block_num < AFS_DIR_BLOCKS_WITH_CTR)
229 		meta->meta.alloc_ctrs[block_num] =
230 			AFS_DIR_SLOTS_PER_BLOCK - AFS_DIR_RESV_BLOCKS;
231 }
232 
233 /*
234  * Edit a directory's file data to add a new directory entry.  Doing this after
235  * create, mkdir, symlink, link or rename if the data version number is
236  * incremented by exactly one avoids the need to re-download the entire
237  * directory contents.
238  *
239  * The caller must hold the inode locked.
240  */
afs_edit_dir_add(struct afs_vnode * vnode,struct qstr * name,struct afs_fid * new_fid,enum afs_edit_dir_reason why)241 void afs_edit_dir_add(struct afs_vnode *vnode,
242 		      struct qstr *name, struct afs_fid *new_fid,
243 		      enum afs_edit_dir_reason why)
244 {
245 	union afs_xdr_dir_block *meta, *block;
246 	union afs_xdr_dirent *de;
247 	struct afs_dir_iter iter = { .dvnode = vnode };
248 	unsigned int nr_blocks, b, entry;
249 	loff_t i_size;
250 	int slot;
251 
252 	_enter(",,{%d,%s},", name->len, name->name);
253 
254 	i_size = i_size_read(&vnode->netfs.inode);
255 	if (i_size > AFS_DIR_BLOCK_SIZE * AFS_DIR_MAX_BLOCKS ||
256 	    (i_size & (AFS_DIR_BLOCK_SIZE - 1))) {
257 		afs_invalidate_dir(vnode, afs_dir_invalid_edit_add_bad_size);
258 		return;
259 	}
260 
261 	meta = afs_dir_get_block(&iter, 0);
262 	if (!meta)
263 		return;
264 
265 	/* Work out how many slots we're going to need. */
266 	iter.nr_slots = afs_dir_calc_slots(name->len);
267 
268 	if (i_size == 0)
269 		goto new_directory;
270 	nr_blocks = i_size / AFS_DIR_BLOCK_SIZE;
271 
272 	/* Find a block that has sufficient slots available.  Each folio
273 	 * contains two or more directory blocks.
274 	 */
275 	for (b = 0; b < nr_blocks + 1; b++) {
276 		/* If the directory extended into a new folio, then we need to
277 		 * tack a new folio on the end.
278 		 */
279 		if (nr_blocks >= AFS_DIR_MAX_BLOCKS)
280 			goto error_too_many_blocks;
281 
282 		/* Lower dir blocks have a counter in the header we can check. */
283 		if (b < AFS_DIR_BLOCKS_WITH_CTR &&
284 		    meta->meta.alloc_ctrs[b] < iter.nr_slots)
285 			continue;
286 
287 		block = afs_dir_get_block(&iter, b);
288 		if (!block)
289 			goto error;
290 
291 		/* Abandon the edit if we got a callback break. */
292 		if (!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
293 			goto already_invalidated;
294 
295 		_debug("block %u: %2u %3u %u",
296 		       b,
297 		       (b < AFS_DIR_BLOCKS_WITH_CTR) ? meta->meta.alloc_ctrs[b] : 99,
298 		       ntohs(block->hdr.npages),
299 		       ntohs(block->hdr.magic));
300 
301 		/* Initialise the block if necessary. */
302 		if (b == nr_blocks) {
303 			_debug("init %u", b);
304 			afs_edit_init_block(meta, block, b);
305 			afs_set_i_size(vnode, (b + 1) * AFS_DIR_BLOCK_SIZE);
306 		}
307 
308 		/* We need to try and find one or more consecutive slots to
309 		 * hold the entry.
310 		 */
311 		slot = afs_find_contig_bits(block, iter.nr_slots);
312 		if (slot >= 0) {
313 			_debug("slot %u", slot);
314 			goto found_space;
315 		}
316 
317 		kunmap_local(block);
318 	}
319 
320 	/* There are no spare slots of sufficient size, yet the operation
321 	 * succeeded.  Download the directory again.
322 	 */
323 	trace_afs_edit_dir(vnode, why, afs_edit_dir_create_nospc, 0, 0, 0, 0, name->name);
324 	afs_invalidate_dir(vnode, afs_dir_invalid_edit_add_no_slots);
325 	goto out_unmap;
326 
327 new_directory:
328 	afs_edit_init_block(meta, meta, 0);
329 	i_size = AFS_DIR_BLOCK_SIZE;
330 	afs_set_i_size(vnode, i_size);
331 	slot = AFS_DIR_RESV_BLOCKS0;
332 	block = afs_dir_get_block(&iter, 0);
333 	nr_blocks = 1;
334 	b = 0;
335 
336 found_space:
337 	/* Set the dirent slot. */
338 	trace_afs_edit_dir(vnode, why, afs_edit_dir_create, b, slot,
339 			   new_fid->vnode, new_fid->unique, name->name);
340 	de = &block->dirents[slot];
341 	de->u.valid	= 1;
342 	de->u.unused[0]	= 0;
343 	de->u.hash_next	= 0; // TODO: Really need to maintain this
344 	de->u.vnode	= htonl(new_fid->vnode);
345 	de->u.unique	= htonl(new_fid->unique);
346 	memcpy(de->u.name, name->name, name->len + 1);
347 	de->u.name[name->len] = 0;
348 
349 	/* Adjust the bitmap. */
350 	afs_set_contig_bits(block, slot, iter.nr_slots);
351 
352 	/* Adjust the allocation counter. */
353 	if (b < AFS_DIR_BLOCKS_WITH_CTR)
354 		meta->meta.alloc_ctrs[b] -= iter.nr_slots;
355 
356 	/* Adjust the hash chain. */
357 	entry = b * AFS_DIR_SLOTS_PER_BLOCK + slot;
358 	iter.bucket = afs_dir_hash_name(name);
359 	de->u.hash_next = meta->meta.hashtable[iter.bucket];
360 	meta->meta.hashtable[iter.bucket] = htons(entry);
361 	kunmap_local(block);
362 
363 	inode_inc_iversion_raw(&vnode->netfs.inode);
364 	afs_stat_v(vnode, n_dir_cr);
365 	_debug("Insert %s in %u[%u]", name->name, b, slot);
366 
367 	netfs_single_mark_inode_dirty(&vnode->netfs.inode);
368 
369 out_unmap:
370 	kunmap_local(meta);
371 	_leave("");
372 	return;
373 
374 already_invalidated:
375 	trace_afs_edit_dir(vnode, why, afs_edit_dir_create_inval, 0, 0, 0, 0, name->name);
376 	kunmap_local(block);
377 	goto out_unmap;
378 
379 error_too_many_blocks:
380 	afs_invalidate_dir(vnode, afs_dir_invalid_edit_add_too_many_blocks);
381 error:
382 	trace_afs_edit_dir(vnode, why, afs_edit_dir_create_error, 0, 0, 0, 0, name->name);
383 	goto out_unmap;
384 }
385 
386 /*
387  * Edit a directory's file data to remove a new directory entry.  Doing this
388  * after unlink, rmdir or rename if the data version number is incremented by
389  * exactly one avoids the need to re-download the entire directory contents.
390  *
391  * The caller must hold the inode locked.
392  */
afs_edit_dir_remove(struct afs_vnode * vnode,struct qstr * name,enum afs_edit_dir_reason why)393 void afs_edit_dir_remove(struct afs_vnode *vnode,
394 			 struct qstr *name, enum afs_edit_dir_reason why)
395 {
396 	union afs_xdr_dir_block *meta, *block, *pblock;
397 	union afs_xdr_dirent *de, *pde;
398 	struct afs_dir_iter iter = { .dvnode = vnode };
399 	struct afs_fid fid;
400 	unsigned int b, slot, entry;
401 	loff_t i_size;
402 	__be16 next;
403 	int found;
404 
405 	_enter(",,{%d,%s},", name->len, name->name);
406 
407 	i_size = i_size_read(&vnode->netfs.inode);
408 	if (i_size < AFS_DIR_BLOCK_SIZE ||
409 	    i_size > AFS_DIR_BLOCK_SIZE * AFS_DIR_MAX_BLOCKS ||
410 	    (i_size & (AFS_DIR_BLOCK_SIZE - 1))) {
411 		afs_invalidate_dir(vnode, afs_dir_invalid_edit_rem_bad_size);
412 		return;
413 	}
414 
415 	if (!afs_dir_init_iter(&iter, name))
416 		return;
417 
418 	meta = afs_dir_find_block(&iter, 0);
419 	if (!meta)
420 		return;
421 
422 	/* Find the entry in the blob. */
423 	found = afs_dir_search_bucket(&iter, name, &fid);
424 	if (found < 0) {
425 		/* Didn't find the dirent to clobber.  Re-download. */
426 		trace_afs_edit_dir(vnode, why, afs_edit_dir_delete_noent,
427 				   0, 0, 0, 0, name->name);
428 		afs_invalidate_dir(vnode, afs_dir_invalid_edit_rem_wrong_name);
429 		goto out_unmap;
430 	}
431 
432 	entry = found;
433 	b    = entry / AFS_DIR_SLOTS_PER_BLOCK;
434 	slot = entry % AFS_DIR_SLOTS_PER_BLOCK;
435 
436 	block = afs_dir_find_block(&iter, b);
437 	if (!block)
438 		goto error;
439 	if (!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
440 		goto already_invalidated;
441 
442 	/* Check and clear the entry. */
443 	de = &block->dirents[slot];
444 	if (de->u.valid != 1)
445 		goto error_unmap;
446 
447 	trace_afs_edit_dir(vnode, why, afs_edit_dir_delete, b, slot,
448 			   ntohl(de->u.vnode), ntohl(de->u.unique),
449 			   name->name);
450 
451 	/* Adjust the bitmap. */
452 	afs_clear_contig_bits(block, slot, iter.nr_slots);
453 
454 	/* Adjust the allocation counter. */
455 	if (b < AFS_DIR_BLOCKS_WITH_CTR)
456 		meta->meta.alloc_ctrs[b] += iter.nr_slots;
457 
458 	/* Clear the constituent entries. */
459 	next = de->u.hash_next;
460 	memset(de, 0, sizeof(*de) * iter.nr_slots);
461 	kunmap_local(block);
462 
463 	/* Adjust the hash chain: if iter->prev_entry is 0, the hashtable head
464 	 * index is previous; otherwise it's slot number of the previous entry.
465 	 */
466 	if (!iter.prev_entry) {
467 		__be16 prev_next = meta->meta.hashtable[iter.bucket];
468 
469 		if (unlikely(prev_next != htons(entry))) {
470 			pr_warn("%llx:%llx:%x: not head of chain b=%x p=%x,%x e=%x %*s",
471 				vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique,
472 				iter.bucket, iter.prev_entry, prev_next, entry,
473 				name->len, name->name);
474 			goto error;
475 		}
476 		meta->meta.hashtable[iter.bucket] = next;
477 	} else {
478 		unsigned int pb = iter.prev_entry / AFS_DIR_SLOTS_PER_BLOCK;
479 		unsigned int ps = iter.prev_entry % AFS_DIR_SLOTS_PER_BLOCK;
480 		__be16 prev_next;
481 
482 		pblock = afs_dir_find_block(&iter, pb);
483 		if (!pblock)
484 			goto error;
485 		pde = &pblock->dirents[ps];
486 		prev_next = pde->u.hash_next;
487 		if (prev_next != htons(entry)) {
488 			kunmap_local(pblock);
489 			pr_warn("%llx:%llx:%x: not prev in chain b=%x p=%x,%x e=%x %*s",
490 				vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique,
491 				iter.bucket, iter.prev_entry, prev_next, entry,
492 				name->len, name->name);
493 			goto error;
494 		}
495 		pde->u.hash_next = next;
496 		kunmap_local(pblock);
497 	}
498 
499 	netfs_single_mark_inode_dirty(&vnode->netfs.inode);
500 
501 	inode_set_iversion_raw(&vnode->netfs.inode, vnode->status.data_version);
502 	afs_stat_v(vnode, n_dir_rm);
503 	_debug("Remove %s from %u[%u]", name->name, b, slot);
504 
505 out_unmap:
506 	kunmap_local(meta);
507 	_leave("");
508 	return;
509 
510 already_invalidated:
511 	kunmap_local(block);
512 	trace_afs_edit_dir(vnode, why, afs_edit_dir_delete_inval,
513 			   0, 0, 0, 0, name->name);
514 	goto out_unmap;
515 
516 error_unmap:
517 	kunmap_local(block);
518 error:
519 	trace_afs_edit_dir(vnode, why, afs_edit_dir_delete_error,
520 			   0, 0, 0, 0, name->name);
521 	goto out_unmap;
522 }
523 
524 /*
525  * Edit a subdirectory that has been moved between directories to update the
526  * ".." entry.
527  */
afs_edit_dir_update_dotdot(struct afs_vnode * vnode,struct afs_vnode * new_dvnode,enum afs_edit_dir_reason why)528 void afs_edit_dir_update_dotdot(struct afs_vnode *vnode, struct afs_vnode *new_dvnode,
529 				enum afs_edit_dir_reason why)
530 {
531 	union afs_xdr_dir_block *block;
532 	union afs_xdr_dirent *de;
533 	struct afs_dir_iter iter = { .dvnode = vnode };
534 	unsigned int nr_blocks, b;
535 	loff_t i_size;
536 	int slot;
537 
538 	_enter("");
539 
540 	i_size = i_size_read(&vnode->netfs.inode);
541 	if (i_size < AFS_DIR_BLOCK_SIZE) {
542 		afs_invalidate_dir(vnode, afs_dir_invalid_edit_upd_bad_size);
543 		return;
544 	}
545 
546 	nr_blocks = i_size / AFS_DIR_BLOCK_SIZE;
547 
548 	/* Find a block that has sufficient slots available.  Each folio
549 	 * contains two or more directory blocks.
550 	 */
551 	for (b = 0; b < nr_blocks; b++) {
552 		block = afs_dir_get_block(&iter, b);
553 		if (!block)
554 			goto error;
555 
556 		/* Abandon the edit if we got a callback break. */
557 		if (!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
558 			goto already_invalidated;
559 
560 		slot = afs_dir_scan_block(block, &dotdot_name, b);
561 		if (slot >= 0)
562 			goto found_dirent;
563 
564 		kunmap_local(block);
565 	}
566 
567 	/* Didn't find the dirent to clobber.  Download the directory again. */
568 	trace_afs_edit_dir(vnode, why, afs_edit_dir_update_nodd,
569 			   0, 0, 0, 0, "..");
570 	afs_invalidate_dir(vnode, afs_dir_invalid_edit_upd_no_dd);
571 	goto out;
572 
573 found_dirent:
574 	de = &block->dirents[slot];
575 	de->u.vnode  = htonl(new_dvnode->fid.vnode);
576 	de->u.unique = htonl(new_dvnode->fid.unique);
577 
578 	trace_afs_edit_dir(vnode, why, afs_edit_dir_update_dd, b, slot,
579 			   ntohl(de->u.vnode), ntohl(de->u.unique), "..");
580 
581 	kunmap_local(block);
582 	netfs_single_mark_inode_dirty(&vnode->netfs.inode);
583 	inode_set_iversion_raw(&vnode->netfs.inode, vnode->status.data_version);
584 
585 out:
586 	_leave("");
587 	return;
588 
589 already_invalidated:
590 	kunmap_local(block);
591 	trace_afs_edit_dir(vnode, why, afs_edit_dir_update_inval,
592 			   0, 0, 0, 0, "..");
593 	goto out;
594 
595 error:
596 	trace_afs_edit_dir(vnode, why, afs_edit_dir_update_error,
597 			   0, 0, 0, 0, "..");
598 	goto out;
599 }
600 
601 /*
602  * Initialise a new directory.  We need to fill in the "." and ".." entries.
603  */
afs_mkdir_init_dir(struct afs_vnode * dvnode,struct afs_vnode * parent_dvnode)604 void afs_mkdir_init_dir(struct afs_vnode *dvnode, struct afs_vnode *parent_dvnode)
605 {
606 	union afs_xdr_dir_block *meta;
607 	struct afs_dir_iter iter = { .dvnode = dvnode };
608 	union afs_xdr_dirent *de;
609 	unsigned int slot = AFS_DIR_RESV_BLOCKS0;
610 	loff_t i_size;
611 
612 	i_size = i_size_read(&dvnode->netfs.inode);
613 	if (i_size != AFS_DIR_BLOCK_SIZE) {
614 		afs_invalidate_dir(dvnode, afs_dir_invalid_edit_add_bad_size);
615 		return;
616 	}
617 
618 	meta = afs_dir_get_block(&iter, 0);
619 	if (!meta)
620 		return;
621 
622 	afs_edit_init_block(meta, meta, 0);
623 
624 	de = &meta->dirents[slot];
625 	de->u.valid  = 1;
626 	de->u.vnode  = htonl(dvnode->fid.vnode);
627 	de->u.unique = htonl(dvnode->fid.unique);
628 	memcpy(de->u.name, ".", 2);
629 	trace_afs_edit_dir(dvnode, afs_edit_dir_for_mkdir, afs_edit_dir_mkdir, 0, slot,
630 			   dvnode->fid.vnode, dvnode->fid.unique, ".");
631 	slot++;
632 
633 	de = &meta->dirents[slot];
634 	de->u.valid  = 1;
635 	de->u.vnode  = htonl(parent_dvnode->fid.vnode);
636 	de->u.unique = htonl(parent_dvnode->fid.unique);
637 	memcpy(de->u.name, "..", 3);
638 	trace_afs_edit_dir(dvnode, afs_edit_dir_for_mkdir, afs_edit_dir_mkdir, 0, slot,
639 			   parent_dvnode->fid.vnode, parent_dvnode->fid.unique, "..");
640 
641 	afs_set_contig_bits(meta, AFS_DIR_RESV_BLOCKS0, 2);
642 	meta->meta.alloc_ctrs[0] -= 2;
643 	kunmap_local(meta);
644 
645 	netfs_single_mark_inode_dirty(&dvnode->netfs.inode);
646 	set_bit(AFS_VNODE_DIR_VALID, &dvnode->flags);
647 	set_bit(AFS_VNODE_DIR_READ, &dvnode->flags);
648 }
649