1/* dir.c: AFS filesystem directory handling
2 *
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/fs.h>
16#include <linux/namei.h>
17#include <linux/pagemap.h>
18#include <linux/ctype.h>
19#include <linux/sched.h>
20#include "internal.h"
21
22static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
23				 unsigned int flags);
24static int afs_dir_open(struct inode *inode, struct file *file);
25static int afs_readdir(struct file *file, struct dir_context *ctx);
26static int afs_d_revalidate(struct dentry *dentry, unsigned int flags);
27static int afs_d_delete(const struct dentry *dentry);
28static void afs_d_release(struct dentry *dentry);
29static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,
30				  loff_t fpos, u64 ino, unsigned dtype);
31static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
32		      bool excl);
33static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
34static int afs_rmdir(struct inode *dir, struct dentry *dentry);
35static int afs_unlink(struct inode *dir, struct dentry *dentry);
36static int afs_link(struct dentry *from, struct inode *dir,
37		    struct dentry *dentry);
38static int afs_symlink(struct inode *dir, struct dentry *dentry,
39		       const char *content);
40static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
41		      struct inode *new_dir, struct dentry *new_dentry);
42
43const struct file_operations afs_dir_file_operations = {
44	.open		= afs_dir_open,
45	.release	= afs_release,
46	.iterate	= afs_readdir,
47	.lock		= afs_lock,
48	.llseek		= generic_file_llseek,
49};
50
51const struct inode_operations afs_dir_inode_operations = {
52	.create		= afs_create,
53	.lookup		= afs_lookup,
54	.link		= afs_link,
55	.unlink		= afs_unlink,
56	.symlink	= afs_symlink,
57	.mkdir		= afs_mkdir,
58	.rmdir		= afs_rmdir,
59	.rename		= afs_rename,
60	.permission	= afs_permission,
61	.getattr	= afs_getattr,
62	.setattr	= afs_setattr,
63};
64
65const struct dentry_operations afs_fs_dentry_operations = {
66	.d_revalidate	= afs_d_revalidate,
67	.d_delete	= afs_d_delete,
68	.d_release	= afs_d_release,
69	.d_automount	= afs_d_automount,
70};
71
72#define AFS_DIR_HASHTBL_SIZE	128
73#define AFS_DIR_DIRENT_SIZE	32
74#define AFS_DIRENT_PER_BLOCK	64
75
76union afs_dirent {
77	struct {
78		uint8_t		valid;
79		uint8_t		unused[1];
80		__be16		hash_next;
81		__be32		vnode;
82		__be32		unique;
83		uint8_t		name[16];
84		uint8_t		overflow[4];	/* if any char of the name (inc
85						 * NUL) reaches here, consume
86						 * the next dirent too */
87	} u;
88	uint8_t	extended_name[32];
89};
90
91/* AFS directory page header (one at the beginning of every 2048-byte chunk) */
92struct afs_dir_pagehdr {
93	__be16		npages;
94	__be16		magic;
95#define AFS_DIR_MAGIC htons(1234)
96	uint8_t		nentries;
97	uint8_t		bitmap[8];
98	uint8_t		pad[19];
99};
100
101/* directory block layout */
102union afs_dir_block {
103
104	struct afs_dir_pagehdr pagehdr;
105
106	struct {
107		struct afs_dir_pagehdr	pagehdr;
108		uint8_t			alloc_ctrs[128];
109		/* dir hash table */
110		uint16_t		hashtable[AFS_DIR_HASHTBL_SIZE];
111	} hdr;
112
113	union afs_dirent dirents[AFS_DIRENT_PER_BLOCK];
114};
115
116/* layout on a linux VM page */
117struct afs_dir_page {
118	union afs_dir_block blocks[PAGE_SIZE / sizeof(union afs_dir_block)];
119};
120
121struct afs_lookup_cookie {
122	struct dir_context ctx;
123	struct afs_fid	fid;
124	struct qstr name;
125	int		found;
126};
127
128/*
129 * check that a directory page is valid
130 */
131static inline void afs_dir_check_page(struct inode *dir, struct page *page)
132{
133	struct afs_dir_page *dbuf;
134	loff_t latter;
135	int tmp, qty;
136
137#if 0
138	/* check the page count */
139	qty = desc.size / sizeof(dbuf->blocks[0]);
140	if (qty == 0)
141		goto error;
142
143	if (page->index == 0 && qty != ntohs(dbuf->blocks[0].pagehdr.npages)) {
144		printk("kAFS: %s(%lu): wrong number of dir blocks %d!=%hu\n",
145		       __func__, dir->i_ino, qty,
146		       ntohs(dbuf->blocks[0].pagehdr.npages));
147		goto error;
148	}
149#endif
150
151	/* determine how many magic numbers there should be in this page */
152	latter = dir->i_size - page_offset(page);
153	if (latter >= PAGE_SIZE)
154		qty = PAGE_SIZE;
155	else
156		qty = latter;
157	qty /= sizeof(union afs_dir_block);
158
159	/* check them */
160	dbuf = page_address(page);
161	for (tmp = 0; tmp < qty; tmp++) {
162		if (dbuf->blocks[tmp].pagehdr.magic != AFS_DIR_MAGIC) {
163			printk("kAFS: %s(%lu): bad magic %d/%d is %04hx\n",
164			       __func__, dir->i_ino, tmp, qty,
165			       ntohs(dbuf->blocks[tmp].pagehdr.magic));
166			goto error;
167		}
168	}
169
170	SetPageChecked(page);
171	return;
172
173error:
174	SetPageChecked(page);
175	SetPageError(page);
176}
177
178/*
179 * discard a page cached in the pagecache
180 */
181static inline void afs_dir_put_page(struct page *page)
182{
183	kunmap(page);
184	page_cache_release(page);
185}
186
187/*
188 * get a page into the pagecache
189 */
190static struct page *afs_dir_get_page(struct inode *dir, unsigned long index,
191				     struct key *key)
192{
193	struct page *page;
194	_enter("{%lu},%lu", dir->i_ino, index);
195
196	page = read_cache_page(dir->i_mapping, index, afs_page_filler, key);
197	if (!IS_ERR(page)) {
198		kmap(page);
199		if (!PageChecked(page))
200			afs_dir_check_page(dir, page);
201		if (PageError(page))
202			goto fail;
203	}
204	return page;
205
206fail:
207	afs_dir_put_page(page);
208	_leave(" = -EIO");
209	return ERR_PTR(-EIO);
210}
211
212/*
213 * open an AFS directory file
214 */
215static int afs_dir_open(struct inode *inode, struct file *file)
216{
217	_enter("{%lu}", inode->i_ino);
218
219	BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048);
220	BUILD_BUG_ON(sizeof(union afs_dirent) != 32);
221
222	if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(inode)->flags))
223		return -ENOENT;
224
225	return afs_open(inode, file);
226}
227
228/*
229 * deal with one block in an AFS directory
230 */
231static int afs_dir_iterate_block(struct dir_context *ctx,
232				 union afs_dir_block *block,
233				 unsigned blkoff)
234{
235	union afs_dirent *dire;
236	unsigned offset, next, curr;
237	size_t nlen;
238	int tmp;
239
240	_enter("%u,%x,%p,,",(unsigned)ctx->pos,blkoff,block);
241
242	curr = (ctx->pos - blkoff) / sizeof(union afs_dirent);
243
244	/* walk through the block, an entry at a time */
245	for (offset = AFS_DIRENT_PER_BLOCK - block->pagehdr.nentries;
246	     offset < AFS_DIRENT_PER_BLOCK;
247	     offset = next
248	     ) {
249		next = offset + 1;
250
251		/* skip entries marked unused in the bitmap */
252		if (!(block->pagehdr.bitmap[offset / 8] &
253		      (1 << (offset % 8)))) {
254			_debug("ENT[%Zu.%u]: unused",
255			       blkoff / sizeof(union afs_dir_block), offset);
256			if (offset >= curr)
257				ctx->pos = blkoff +
258					next * sizeof(union afs_dirent);
259			continue;
260		}
261
262		/* got a valid entry */
263		dire = &block->dirents[offset];
264		nlen = strnlen(dire->u.name,
265			       sizeof(*block) -
266			       offset * sizeof(union afs_dirent));
267
268		_debug("ENT[%Zu.%u]: %s %Zu \"%s\"",
269		       blkoff / sizeof(union afs_dir_block), offset,
270		       (offset < curr ? "skip" : "fill"),
271		       nlen, dire->u.name);
272
273		/* work out where the next possible entry is */
274		for (tmp = nlen; tmp > 15; tmp -= sizeof(union afs_dirent)) {
275			if (next >= AFS_DIRENT_PER_BLOCK) {
276				_debug("ENT[%Zu.%u]:"
277				       " %u travelled beyond end dir block"
278				       " (len %u/%Zu)",
279				       blkoff / sizeof(union afs_dir_block),
280				       offset, next, tmp, nlen);
281				return -EIO;
282			}
283			if (!(block->pagehdr.bitmap[next / 8] &
284			      (1 << (next % 8)))) {
285				_debug("ENT[%Zu.%u]:"
286				       " %u unmarked extension (len %u/%Zu)",
287				       blkoff / sizeof(union afs_dir_block),
288				       offset, next, tmp, nlen);
289				return -EIO;
290			}
291
292			_debug("ENT[%Zu.%u]: ext %u/%Zu",
293			       blkoff / sizeof(union afs_dir_block),
294			       next, tmp, nlen);
295			next++;
296		}
297
298		/* skip if starts before the current position */
299		if (offset < curr)
300			continue;
301
302		/* found the next entry */
303		if (!dir_emit(ctx, dire->u.name, nlen,
304			      ntohl(dire->u.vnode),
305			      ctx->actor == afs_lookup_filldir ?
306			      ntohl(dire->u.unique) : DT_UNKNOWN)) {
307			_leave(" = 0 [full]");
308			return 0;
309		}
310
311		ctx->pos = blkoff + next * sizeof(union afs_dirent);
312	}
313
314	_leave(" = 1 [more]");
315	return 1;
316}
317
318/*
319 * iterate through the data blob that lists the contents of an AFS directory
320 */
321static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx,
322			   struct key *key)
323{
324	union afs_dir_block *dblock;
325	struct afs_dir_page *dbuf;
326	struct page *page;
327	unsigned blkoff, limit;
328	int ret;
329
330	_enter("{%lu},%u,,", dir->i_ino, (unsigned)ctx->pos);
331
332	if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(dir)->flags)) {
333		_leave(" = -ESTALE");
334		return -ESTALE;
335	}
336
337	/* round the file position up to the next entry boundary */
338	ctx->pos += sizeof(union afs_dirent) - 1;
339	ctx->pos &= ~(sizeof(union afs_dirent) - 1);
340
341	/* walk through the blocks in sequence */
342	ret = 0;
343	while (ctx->pos < dir->i_size) {
344		blkoff = ctx->pos & ~(sizeof(union afs_dir_block) - 1);
345
346		/* fetch the appropriate page from the directory */
347		page = afs_dir_get_page(dir, blkoff / PAGE_SIZE, key);
348		if (IS_ERR(page)) {
349			ret = PTR_ERR(page);
350			break;
351		}
352
353		limit = blkoff & ~(PAGE_SIZE - 1);
354
355		dbuf = page_address(page);
356
357		/* deal with the individual blocks stashed on this page */
358		do {
359			dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) /
360					       sizeof(union afs_dir_block)];
361			ret = afs_dir_iterate_block(ctx, dblock, blkoff);
362			if (ret != 1) {
363				afs_dir_put_page(page);
364				goto out;
365			}
366
367			blkoff += sizeof(union afs_dir_block);
368
369		} while (ctx->pos < dir->i_size && blkoff < limit);
370
371		afs_dir_put_page(page);
372		ret = 0;
373	}
374
375out:
376	_leave(" = %d", ret);
377	return ret;
378}
379
380/*
381 * read an AFS directory
382 */
383static int afs_readdir(struct file *file, struct dir_context *ctx)
384{
385	return afs_dir_iterate(file_inode(file),
386			      ctx, file->private_data);
387}
388
389/*
390 * search the directory for a name
391 * - if afs_dir_iterate_block() spots this function, it'll pass the FID
392 *   uniquifier through dtype
393 */
394static int afs_lookup_filldir(struct dir_context *ctx, const char *name,
395			      int nlen, loff_t fpos, u64 ino, unsigned dtype)
396{
397	struct afs_lookup_cookie *cookie =
398		container_of(ctx, struct afs_lookup_cookie, ctx);
399
400	_enter("{%s,%u},%s,%u,,%llu,%u",
401	       cookie->name.name, cookie->name.len, name, nlen,
402	       (unsigned long long) ino, dtype);
403
404	/* insanity checks first */
405	BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048);
406	BUILD_BUG_ON(sizeof(union afs_dirent) != 32);
407
408	if (cookie->name.len != nlen ||
409	    memcmp(cookie->name.name, name, nlen) != 0) {
410		_leave(" = 0 [no]");
411		return 0;
412	}
413
414	cookie->fid.vnode = ino;
415	cookie->fid.unique = dtype;
416	cookie->found = 1;
417
418	_leave(" = -1 [found]");
419	return -1;
420}
421
422/*
423 * do a lookup in a directory
424 * - just returns the FID the dentry name maps to if found
425 */
426static int afs_do_lookup(struct inode *dir, struct dentry *dentry,
427			 struct afs_fid *fid, struct key *key)
428{
429	struct afs_super_info *as = dir->i_sb->s_fs_info;
430	struct afs_lookup_cookie cookie = {
431		.ctx.actor = afs_lookup_filldir,
432		.name = dentry->d_name,
433		.fid.vid = as->volume->vid
434	};
435	int ret;
436
437	_enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry);
438
439	/* search the directory */
440	ret = afs_dir_iterate(dir, &cookie.ctx, key);
441	if (ret < 0) {
442		_leave(" = %d [iter]", ret);
443		return ret;
444	}
445
446	ret = -ENOENT;
447	if (!cookie.found) {
448		_leave(" = -ENOENT [not found]");
449		return -ENOENT;
450	}
451
452	*fid = cookie.fid;
453	_leave(" = 0 { vn=%u u=%u }", fid->vnode, fid->unique);
454	return 0;
455}
456
457/*
458 * Try to auto mount the mountpoint with pseudo directory, if the autocell
459 * operation is setted.
460 */
461static struct inode *afs_try_auto_mntpt(
462	int ret, struct dentry *dentry, struct inode *dir, struct key *key,
463	struct afs_fid *fid)
464{
465	const char *devname = dentry->d_name.name;
466	struct afs_vnode *vnode = AFS_FS_I(dir);
467	struct inode *inode;
468
469	_enter("%d, %p{%pd}, {%x:%u}, %p",
470	       ret, dentry, dentry, vnode->fid.vid, vnode->fid.vnode, key);
471
472	if (ret != -ENOENT ||
473	    !test_bit(AFS_VNODE_AUTOCELL, &vnode->flags))
474		goto out;
475
476	inode = afs_iget_autocell(dir, devname, strlen(devname), key);
477	if (IS_ERR(inode)) {
478		ret = PTR_ERR(inode);
479		goto out;
480	}
481
482	*fid = AFS_FS_I(inode)->fid;
483	_leave("= %p", inode);
484	return inode;
485
486out:
487	_leave("= %d", ret);
488	return ERR_PTR(ret);
489}
490
491/*
492 * look up an entry in a directory
493 */
494static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
495				 unsigned int flags)
496{
497	struct afs_vnode *vnode;
498	struct afs_fid fid;
499	struct inode *inode;
500	struct key *key;
501	int ret;
502
503	vnode = AFS_FS_I(dir);
504
505	_enter("{%x:%u},%p{%pd},",
506	       vnode->fid.vid, vnode->fid.vnode, dentry, dentry);
507
508	ASSERTCMP(d_inode(dentry), ==, NULL);
509
510	if (dentry->d_name.len >= AFSNAMEMAX) {
511		_leave(" = -ENAMETOOLONG");
512		return ERR_PTR(-ENAMETOOLONG);
513	}
514
515	if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
516		_leave(" = -ESTALE");
517		return ERR_PTR(-ESTALE);
518	}
519
520	key = afs_request_key(vnode->volume->cell);
521	if (IS_ERR(key)) {
522		_leave(" = %ld [key]", PTR_ERR(key));
523		return ERR_CAST(key);
524	}
525
526	ret = afs_validate(vnode, key);
527	if (ret < 0) {
528		key_put(key);
529		_leave(" = %d [val]", ret);
530		return ERR_PTR(ret);
531	}
532
533	ret = afs_do_lookup(dir, dentry, &fid, key);
534	if (ret < 0) {
535		inode = afs_try_auto_mntpt(ret, dentry, dir, key, &fid);
536		if (!IS_ERR(inode)) {
537			key_put(key);
538			goto success;
539		}
540
541		ret = PTR_ERR(inode);
542		key_put(key);
543		if (ret == -ENOENT) {
544			d_add(dentry, NULL);
545			_leave(" = NULL [negative]");
546			return NULL;
547		}
548		_leave(" = %d [do]", ret);
549		return ERR_PTR(ret);
550	}
551	dentry->d_fsdata = (void *)(unsigned long) vnode->status.data_version;
552
553	/* instantiate the dentry */
554	inode = afs_iget(dir->i_sb, key, &fid, NULL, NULL);
555	key_put(key);
556	if (IS_ERR(inode)) {
557		_leave(" = %ld", PTR_ERR(inode));
558		return ERR_CAST(inode);
559	}
560
561success:
562	d_add(dentry, inode);
563	_leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%u }",
564	       fid.vnode,
565	       fid.unique,
566	       d_inode(dentry)->i_ino,
567	       d_inode(dentry)->i_generation);
568
569	return NULL;
570}
571
572/*
573 * check that a dentry lookup hit has found a valid entry
574 * - NOTE! the hit can be a negative hit too, so we can't assume we have an
575 *   inode
576 */
577static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
578{
579	struct afs_vnode *vnode, *dir;
580	struct afs_fid uninitialized_var(fid);
581	struct dentry *parent;
582	struct key *key;
583	void *dir_version;
584	int ret;
585
586	if (flags & LOOKUP_RCU)
587		return -ECHILD;
588
589	vnode = AFS_FS_I(d_inode(dentry));
590
591	if (d_really_is_positive(dentry))
592		_enter("{v={%x:%u} n=%pd fl=%lx},",
593		       vnode->fid.vid, vnode->fid.vnode, dentry,
594		       vnode->flags);
595	else
596		_enter("{neg n=%pd}", dentry);
597
598	key = afs_request_key(AFS_FS_S(dentry->d_sb)->volume->cell);
599	if (IS_ERR(key))
600		key = NULL;
601
602	/* lock down the parent dentry so we can peer at it */
603	parent = dget_parent(dentry);
604	dir = AFS_FS_I(d_inode(parent));
605
606	/* validate the parent directory */
607	if (test_bit(AFS_VNODE_MODIFIED, &dir->flags))
608		afs_validate(dir, key);
609
610	if (test_bit(AFS_VNODE_DELETED, &dir->flags)) {
611		_debug("%pd: parent dir deleted", dentry);
612		goto out_bad;
613	}
614
615	dir_version = (void *) (unsigned long) dir->status.data_version;
616	if (dentry->d_fsdata == dir_version)
617		goto out_valid; /* the dir contents are unchanged */
618
619	_debug("dir modified");
620
621	/* search the directory for this vnode */
622	ret = afs_do_lookup(&dir->vfs_inode, dentry, &fid, key);
623	switch (ret) {
624	case 0:
625		/* the filename maps to something */
626		if (d_really_is_negative(dentry))
627			goto out_bad;
628		if (is_bad_inode(d_inode(dentry))) {
629			printk("kAFS: afs_d_revalidate: %pd2 has bad inode\n",
630			       dentry);
631			goto out_bad;
632		}
633
634		/* if the vnode ID has changed, then the dirent points to a
635		 * different file */
636		if (fid.vnode != vnode->fid.vnode) {
637			_debug("%pd: dirent changed [%u != %u]",
638			       dentry, fid.vnode,
639			       vnode->fid.vnode);
640			goto not_found;
641		}
642
643		/* if the vnode ID uniqifier has changed, then the file has
644		 * been deleted and replaced, and the original vnode ID has
645		 * been reused */
646		if (fid.unique != vnode->fid.unique) {
647			_debug("%pd: file deleted (uq %u -> %u I:%u)",
648			       dentry, fid.unique,
649			       vnode->fid.unique,
650			       d_inode(dentry)->i_generation);
651			spin_lock(&vnode->lock);
652			set_bit(AFS_VNODE_DELETED, &vnode->flags);
653			spin_unlock(&vnode->lock);
654			goto not_found;
655		}
656		goto out_valid;
657
658	case -ENOENT:
659		/* the filename is unknown */
660		_debug("%pd: dirent not found", dentry);
661		if (d_really_is_positive(dentry))
662			goto not_found;
663		goto out_valid;
664
665	default:
666		_debug("failed to iterate dir %pd: %d",
667		       parent, ret);
668		goto out_bad;
669	}
670
671out_valid:
672	dentry->d_fsdata = dir_version;
673	dput(parent);
674	key_put(key);
675	_leave(" = 1 [valid]");
676	return 1;
677
678	/* the dirent, if it exists, now points to a different vnode */
679not_found:
680	spin_lock(&dentry->d_lock);
681	dentry->d_flags |= DCACHE_NFSFS_RENAMED;
682	spin_unlock(&dentry->d_lock);
683
684out_bad:
685	_debug("dropping dentry %pd2", dentry);
686	dput(parent);
687	key_put(key);
688
689	_leave(" = 0 [bad]");
690	return 0;
691}
692
693/*
694 * allow the VFS to enquire as to whether a dentry should be unhashed (mustn't
695 * sleep)
696 * - called from dput() when d_count is going to 0.
697 * - return 1 to request dentry be unhashed, 0 otherwise
698 */
699static int afs_d_delete(const struct dentry *dentry)
700{
701	_enter("%pd", dentry);
702
703	if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
704		goto zap;
705
706	if (d_really_is_positive(dentry) &&
707	    (test_bit(AFS_VNODE_DELETED,   &AFS_FS_I(d_inode(dentry))->flags) ||
708	     test_bit(AFS_VNODE_PSEUDODIR, &AFS_FS_I(d_inode(dentry))->flags)))
709		goto zap;
710
711	_leave(" = 0 [keep]");
712	return 0;
713
714zap:
715	_leave(" = 1 [zap]");
716	return 1;
717}
718
719/*
720 * handle dentry release
721 */
722static void afs_d_release(struct dentry *dentry)
723{
724	_enter("%pd", dentry);
725}
726
727/*
728 * create a directory on an AFS filesystem
729 */
730static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
731{
732	struct afs_file_status status;
733	struct afs_callback cb;
734	struct afs_server *server;
735	struct afs_vnode *dvnode, *vnode;
736	struct afs_fid fid;
737	struct inode *inode;
738	struct key *key;
739	int ret;
740
741	dvnode = AFS_FS_I(dir);
742
743	_enter("{%x:%u},{%pd},%ho",
744	       dvnode->fid.vid, dvnode->fid.vnode, dentry, mode);
745
746	key = afs_request_key(dvnode->volume->cell);
747	if (IS_ERR(key)) {
748		ret = PTR_ERR(key);
749		goto error;
750	}
751
752	mode |= S_IFDIR;
753	ret = afs_vnode_create(dvnode, key, dentry->d_name.name,
754			       mode, &fid, &status, &cb, &server);
755	if (ret < 0)
756		goto mkdir_error;
757
758	inode = afs_iget(dir->i_sb, key, &fid, &status, &cb);
759	if (IS_ERR(inode)) {
760		/* ENOMEM at a really inconvenient time - just abandon the new
761		 * directory on the server */
762		ret = PTR_ERR(inode);
763		goto iget_error;
764	}
765
766	/* apply the status report we've got for the new vnode */
767	vnode = AFS_FS_I(inode);
768	spin_lock(&vnode->lock);
769	vnode->update_cnt++;
770	spin_unlock(&vnode->lock);
771	afs_vnode_finalise_status_update(vnode, server);
772	afs_put_server(server);
773
774	d_instantiate(dentry, inode);
775	if (d_unhashed(dentry)) {
776		_debug("not hashed");
777		d_rehash(dentry);
778	}
779	key_put(key);
780	_leave(" = 0");
781	return 0;
782
783iget_error:
784	afs_put_server(server);
785mkdir_error:
786	key_put(key);
787error:
788	d_drop(dentry);
789	_leave(" = %d", ret);
790	return ret;
791}
792
793/*
794 * remove a directory from an AFS filesystem
795 */
796static int afs_rmdir(struct inode *dir, struct dentry *dentry)
797{
798	struct afs_vnode *dvnode, *vnode;
799	struct key *key;
800	int ret;
801
802	dvnode = AFS_FS_I(dir);
803
804	_enter("{%x:%u},{%pd}",
805	       dvnode->fid.vid, dvnode->fid.vnode, dentry);
806
807	key = afs_request_key(dvnode->volume->cell);
808	if (IS_ERR(key)) {
809		ret = PTR_ERR(key);
810		goto error;
811	}
812
813	ret = afs_vnode_remove(dvnode, key, dentry->d_name.name, true);
814	if (ret < 0)
815		goto rmdir_error;
816
817	if (d_really_is_positive(dentry)) {
818		vnode = AFS_FS_I(d_inode(dentry));
819		clear_nlink(&vnode->vfs_inode);
820		set_bit(AFS_VNODE_DELETED, &vnode->flags);
821		afs_discard_callback_on_delete(vnode);
822	}
823
824	key_put(key);
825	_leave(" = 0");
826	return 0;
827
828rmdir_error:
829	key_put(key);
830error:
831	_leave(" = %d", ret);
832	return ret;
833}
834
835/*
836 * remove a file from an AFS filesystem
837 */
838static int afs_unlink(struct inode *dir, struct dentry *dentry)
839{
840	struct afs_vnode *dvnode, *vnode;
841	struct key *key;
842	int ret;
843
844	dvnode = AFS_FS_I(dir);
845
846	_enter("{%x:%u},{%pd}",
847	       dvnode->fid.vid, dvnode->fid.vnode, dentry);
848
849	ret = -ENAMETOOLONG;
850	if (dentry->d_name.len >= AFSNAMEMAX)
851		goto error;
852
853	key = afs_request_key(dvnode->volume->cell);
854	if (IS_ERR(key)) {
855		ret = PTR_ERR(key);
856		goto error;
857	}
858
859	if (d_really_is_positive(dentry)) {
860		vnode = AFS_FS_I(d_inode(dentry));
861
862		/* make sure we have a callback promise on the victim */
863		ret = afs_validate(vnode, key);
864		if (ret < 0)
865			goto error;
866	}
867
868	ret = afs_vnode_remove(dvnode, key, dentry->d_name.name, false);
869	if (ret < 0)
870		goto remove_error;
871
872	if (d_really_is_positive(dentry)) {
873		/* if the file wasn't deleted due to excess hard links, the
874		 * fileserver will break the callback promise on the file - if
875		 * it had one - before it returns to us, and if it was deleted,
876		 * it won't
877		 *
878		 * however, if we didn't have a callback promise outstanding,
879		 * or it was outstanding on a different server, then it won't
880		 * break it either...
881		 */
882		vnode = AFS_FS_I(d_inode(dentry));
883		if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
884			_debug("AFS_VNODE_DELETED");
885		if (test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags))
886			_debug("AFS_VNODE_CB_BROKEN");
887		set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags);
888		ret = afs_validate(vnode, key);
889		_debug("nlink %d [val %d]", vnode->vfs_inode.i_nlink, ret);
890	}
891
892	key_put(key);
893	_leave(" = 0");
894	return 0;
895
896remove_error:
897	key_put(key);
898error:
899	_leave(" = %d", ret);
900	return ret;
901}
902
903/*
904 * create a regular file on an AFS filesystem
905 */
906static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
907		      bool excl)
908{
909	struct afs_file_status status;
910	struct afs_callback cb;
911	struct afs_server *server;
912	struct afs_vnode *dvnode, *vnode;
913	struct afs_fid fid;
914	struct inode *inode;
915	struct key *key;
916	int ret;
917
918	dvnode = AFS_FS_I(dir);
919
920	_enter("{%x:%u},{%pd},%ho,",
921	       dvnode->fid.vid, dvnode->fid.vnode, dentry, mode);
922
923	key = afs_request_key(dvnode->volume->cell);
924	if (IS_ERR(key)) {
925		ret = PTR_ERR(key);
926		goto error;
927	}
928
929	mode |= S_IFREG;
930	ret = afs_vnode_create(dvnode, key, dentry->d_name.name,
931			       mode, &fid, &status, &cb, &server);
932	if (ret < 0)
933		goto create_error;
934
935	inode = afs_iget(dir->i_sb, key, &fid, &status, &cb);
936	if (IS_ERR(inode)) {
937		/* ENOMEM at a really inconvenient time - just abandon the new
938		 * directory on the server */
939		ret = PTR_ERR(inode);
940		goto iget_error;
941	}
942
943	/* apply the status report we've got for the new vnode */
944	vnode = AFS_FS_I(inode);
945	spin_lock(&vnode->lock);
946	vnode->update_cnt++;
947	spin_unlock(&vnode->lock);
948	afs_vnode_finalise_status_update(vnode, server);
949	afs_put_server(server);
950
951	d_instantiate(dentry, inode);
952	if (d_unhashed(dentry)) {
953		_debug("not hashed");
954		d_rehash(dentry);
955	}
956	key_put(key);
957	_leave(" = 0");
958	return 0;
959
960iget_error:
961	afs_put_server(server);
962create_error:
963	key_put(key);
964error:
965	d_drop(dentry);
966	_leave(" = %d", ret);
967	return ret;
968}
969
970/*
971 * create a hard link between files in an AFS filesystem
972 */
973static int afs_link(struct dentry *from, struct inode *dir,
974		    struct dentry *dentry)
975{
976	struct afs_vnode *dvnode, *vnode;
977	struct key *key;
978	int ret;
979
980	vnode = AFS_FS_I(d_inode(from));
981	dvnode = AFS_FS_I(dir);
982
983	_enter("{%x:%u},{%x:%u},{%pd}",
984	       vnode->fid.vid, vnode->fid.vnode,
985	       dvnode->fid.vid, dvnode->fid.vnode,
986	       dentry);
987
988	key = afs_request_key(dvnode->volume->cell);
989	if (IS_ERR(key)) {
990		ret = PTR_ERR(key);
991		goto error;
992	}
993
994	ret = afs_vnode_link(dvnode, vnode, key, dentry->d_name.name);
995	if (ret < 0)
996		goto link_error;
997
998	ihold(&vnode->vfs_inode);
999	d_instantiate(dentry, &vnode->vfs_inode);
1000	key_put(key);
1001	_leave(" = 0");
1002	return 0;
1003
1004link_error:
1005	key_put(key);
1006error:
1007	d_drop(dentry);
1008	_leave(" = %d", ret);
1009	return ret;
1010}
1011
1012/*
1013 * create a symlink in an AFS filesystem
1014 */
1015static int afs_symlink(struct inode *dir, struct dentry *dentry,
1016		       const char *content)
1017{
1018	struct afs_file_status status;
1019	struct afs_server *server;
1020	struct afs_vnode *dvnode, *vnode;
1021	struct afs_fid fid;
1022	struct inode *inode;
1023	struct key *key;
1024	int ret;
1025
1026	dvnode = AFS_FS_I(dir);
1027
1028	_enter("{%x:%u},{%pd},%s",
1029	       dvnode->fid.vid, dvnode->fid.vnode, dentry,
1030	       content);
1031
1032	ret = -EINVAL;
1033	if (strlen(content) >= AFSPATHMAX)
1034		goto error;
1035
1036	key = afs_request_key(dvnode->volume->cell);
1037	if (IS_ERR(key)) {
1038		ret = PTR_ERR(key);
1039		goto error;
1040	}
1041
1042	ret = afs_vnode_symlink(dvnode, key, dentry->d_name.name, content,
1043				&fid, &status, &server);
1044	if (ret < 0)
1045		goto create_error;
1046
1047	inode = afs_iget(dir->i_sb, key, &fid, &status, NULL);
1048	if (IS_ERR(inode)) {
1049		/* ENOMEM at a really inconvenient time - just abandon the new
1050		 * directory on the server */
1051		ret = PTR_ERR(inode);
1052		goto iget_error;
1053	}
1054
1055	/* apply the status report we've got for the new vnode */
1056	vnode = AFS_FS_I(inode);
1057	spin_lock(&vnode->lock);
1058	vnode->update_cnt++;
1059	spin_unlock(&vnode->lock);
1060	afs_vnode_finalise_status_update(vnode, server);
1061	afs_put_server(server);
1062
1063	d_instantiate(dentry, inode);
1064	if (d_unhashed(dentry)) {
1065		_debug("not hashed");
1066		d_rehash(dentry);
1067	}
1068	key_put(key);
1069	_leave(" = 0");
1070	return 0;
1071
1072iget_error:
1073	afs_put_server(server);
1074create_error:
1075	key_put(key);
1076error:
1077	d_drop(dentry);
1078	_leave(" = %d", ret);
1079	return ret;
1080}
1081
1082/*
1083 * rename a file in an AFS filesystem and/or move it between directories
1084 */
1085static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1086		      struct inode *new_dir, struct dentry *new_dentry)
1087{
1088	struct afs_vnode *orig_dvnode, *new_dvnode, *vnode;
1089	struct key *key;
1090	int ret;
1091
1092	vnode = AFS_FS_I(d_inode(old_dentry));
1093	orig_dvnode = AFS_FS_I(old_dir);
1094	new_dvnode = AFS_FS_I(new_dir);
1095
1096	_enter("{%x:%u},{%x:%u},{%x:%u},{%pd}",
1097	       orig_dvnode->fid.vid, orig_dvnode->fid.vnode,
1098	       vnode->fid.vid, vnode->fid.vnode,
1099	       new_dvnode->fid.vid, new_dvnode->fid.vnode,
1100	       new_dentry);
1101
1102	key = afs_request_key(orig_dvnode->volume->cell);
1103	if (IS_ERR(key)) {
1104		ret = PTR_ERR(key);
1105		goto error;
1106	}
1107
1108	ret = afs_vnode_rename(orig_dvnode, new_dvnode, key,
1109			       old_dentry->d_name.name,
1110			       new_dentry->d_name.name);
1111	if (ret < 0)
1112		goto rename_error;
1113	key_put(key);
1114	_leave(" = 0");
1115	return 0;
1116
1117rename_error:
1118	key_put(key);
1119error:
1120	d_drop(new_dentry);
1121	_leave(" = %d", ret);
1122	return ret;
1123}
1124