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