[AFS]: Add security support.
[linux-2.6.git] / fs / afs / dir.c
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/slab.h>
16 #include <linux/fs.h>
17 #include <linux/pagemap.h>
18 #include <linux/ctype.h>
19 #include "internal.h"
20
21 static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
22                                      struct nameidata *nd);
23 static int afs_dir_open(struct inode *inode, struct file *file);
24 static int afs_dir_readdir(struct file *file, void *dirent, filldir_t filldir);
25 static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd);
26 static int afs_d_delete(struct dentry *dentry);
27 static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen,
28                                   loff_t fpos, u64 ino, unsigned dtype);
29
30 const struct file_operations afs_dir_file_operations = {
31         .open           = afs_dir_open,
32         .release        = afs_release,
33         .readdir        = afs_dir_readdir,
34 };
35
36 const struct inode_operations afs_dir_inode_operations = {
37         .lookup         = afs_dir_lookup,
38         .permission     = afs_permission,
39         .getattr        = afs_inode_getattr,
40 #if 0 /* TODO */
41         .create         = afs_dir_create,
42         .link           = afs_dir_link,
43         .unlink         = afs_dir_unlink,
44         .symlink        = afs_dir_symlink,
45         .mkdir          = afs_dir_mkdir,
46         .rmdir          = afs_dir_rmdir,
47         .mknod          = afs_dir_mknod,
48         .rename         = afs_dir_rename,
49 #endif
50 };
51
52 static struct dentry_operations afs_fs_dentry_operations = {
53         .d_revalidate   = afs_d_revalidate,
54         .d_delete       = afs_d_delete,
55 };
56
57 #define AFS_DIR_HASHTBL_SIZE    128
58 #define AFS_DIR_DIRENT_SIZE     32
59 #define AFS_DIRENT_PER_BLOCK    64
60
61 union afs_dirent {
62         struct {
63                 uint8_t         valid;
64                 uint8_t         unused[1];
65                 __be16          hash_next;
66                 __be32          vnode;
67                 __be32          unique;
68                 uint8_t         name[16];
69                 uint8_t         overflow[4];    /* if any char of the name (inc
70                                                  * NUL) reaches here, consume
71                                                  * the next dirent too */
72         } u;
73         uint8_t extended_name[32];
74 };
75
76 /* AFS directory page header (one at the beginning of every 2048-byte chunk) */
77 struct afs_dir_pagehdr {
78         __be16          npages;
79         __be16          magic;
80 #define AFS_DIR_MAGIC htons(1234)
81         uint8_t         nentries;
82         uint8_t         bitmap[8];
83         uint8_t         pad[19];
84 };
85
86 /* directory block layout */
87 union afs_dir_block {
88
89         struct afs_dir_pagehdr pagehdr;
90
91         struct {
92                 struct afs_dir_pagehdr  pagehdr;
93                 uint8_t                 alloc_ctrs[128];
94                 /* dir hash table */
95                 uint16_t                hashtable[AFS_DIR_HASHTBL_SIZE];
96         } hdr;
97
98         union afs_dirent dirents[AFS_DIRENT_PER_BLOCK];
99 };
100
101 /* layout on a linux VM page */
102 struct afs_dir_page {
103         union afs_dir_block blocks[PAGE_SIZE / sizeof(union afs_dir_block)];
104 };
105
106 struct afs_dir_lookup_cookie {
107         struct afs_fid  fid;
108         const char      *name;
109         size_t          nlen;
110         int             found;
111 };
112
113 /*
114  * check that a directory page is valid
115  */
116 static inline void afs_dir_check_page(struct inode *dir, struct page *page)
117 {
118         struct afs_dir_page *dbuf;
119         loff_t latter;
120         int tmp, qty;
121
122 #if 0
123         /* check the page count */
124         qty = desc.size / sizeof(dbuf->blocks[0]);
125         if (qty == 0)
126                 goto error;
127
128         if (page->index == 0 && qty != ntohs(dbuf->blocks[0].pagehdr.npages)) {
129                 printk("kAFS: %s(%lu): wrong number of dir blocks %d!=%hu\n",
130                        __FUNCTION__, dir->i_ino, qty,
131                        ntohs(dbuf->blocks[0].pagehdr.npages));
132                 goto error;
133         }
134 #endif
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                                __FUNCTION__, dir->i_ino, tmp, qty,
150                                ntohs(dbuf->blocks[tmp].pagehdr.magic));
151                         goto error;
152                 }
153         }
154
155         SetPageChecked(page);
156         return;
157
158 error:
159         SetPageChecked(page);
160         SetPageError(page);
161 }
162
163 /*
164  * discard a page cached in the pagecache
165  */
166 static 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  */
175 static struct page *afs_dir_get_page(struct inode *dir, unsigned long index,
176                                      struct key *key)
177 {
178         struct page *page;
179         struct file file = {
180                 .private_data = key,
181         };
182
183         _enter("{%lu},%lu", dir->i_ino, index);
184
185         page = read_mapping_page(dir->i_mapping, index, &file);
186         if (!IS_ERR(page)) {
187                 wait_on_page_locked(page);
188                 kmap(page);
189                 if (!PageUptodate(page))
190                         goto fail;
191                 if (!PageChecked(page))
192                         afs_dir_check_page(dir, page);
193                 if (PageError(page))
194                         goto fail;
195         }
196         return page;
197
198 fail:
199         afs_dir_put_page(page);
200         _leave(" = -EIO");
201         return ERR_PTR(-EIO);
202 }
203
204 /*
205  * open an AFS directory file
206  */
207 static int afs_dir_open(struct inode *inode, struct file *file)
208 {
209         _enter("{%lu}", inode->i_ino);
210
211         BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048);
212         BUILD_BUG_ON(sizeof(union afs_dirent) != 32);
213
214         if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(inode)->flags))
215                 return -ENOENT;
216
217         return afs_open(inode, file);
218 }
219
220 /*
221  * deal with one block in an AFS directory
222  */
223 static int afs_dir_iterate_block(unsigned *fpos,
224                                  union afs_dir_block *block,
225                                  unsigned blkoff,
226                                  void *cookie,
227                                  filldir_t filldir)
228 {
229         union afs_dirent *dire;
230         unsigned offset, next, curr;
231         size_t nlen;
232         int tmp, ret;
233
234         _enter("%u,%x,%p,,",*fpos,blkoff,block);
235
236         curr = (*fpos - blkoff) / sizeof(union afs_dirent);
237
238         /* walk through the block, an entry at a time */
239         for (offset = AFS_DIRENT_PER_BLOCK - block->pagehdr.nentries;
240              offset < AFS_DIRENT_PER_BLOCK;
241              offset = next
242              ) {
243                 next = offset + 1;
244
245                 /* skip entries marked unused in the bitmap */
246                 if (!(block->pagehdr.bitmap[offset / 8] &
247                       (1 << (offset % 8)))) {
248                         _debug("ENT[%Zu.%u]: unused",
249                                blkoff / sizeof(union afs_dir_block), offset);
250                         if (offset >= curr)
251                                 *fpos = blkoff +
252                                         next * sizeof(union afs_dirent);
253                         continue;
254                 }
255
256                 /* got a valid entry */
257                 dire = &block->dirents[offset];
258                 nlen = strnlen(dire->u.name,
259                                sizeof(*block) -
260                                offset * sizeof(union afs_dirent));
261
262                 _debug("ENT[%Zu.%u]: %s %Zu \"%s\"",
263                        blkoff / sizeof(union afs_dir_block), offset,
264                        (offset < curr ? "skip" : "fill"),
265                        nlen, dire->u.name);
266
267                 /* work out where the next possible entry is */
268                 for (tmp = nlen; tmp > 15; tmp -= sizeof(union afs_dirent)) {
269                         if (next >= AFS_DIRENT_PER_BLOCK) {
270                                 _debug("ENT[%Zu.%u]:"
271                                        " %u travelled beyond end dir block"
272                                        " (len %u/%Zu)",
273                                        blkoff / sizeof(union afs_dir_block),
274                                        offset, next, tmp, nlen);
275                                 return -EIO;
276                         }
277                         if (!(block->pagehdr.bitmap[next / 8] &
278                               (1 << (next % 8)))) {
279                                 _debug("ENT[%Zu.%u]:"
280                                        " %u unmarked extension (len %u/%Zu)",
281                                        blkoff / sizeof(union afs_dir_block),
282                                        offset, next, tmp, nlen);
283                                 return -EIO;
284                         }
285
286                         _debug("ENT[%Zu.%u]: ext %u/%Zu",
287                                blkoff / sizeof(union afs_dir_block),
288                                next, tmp, nlen);
289                         next++;
290                 }
291
292                 /* skip if starts before the current position */
293                 if (offset < curr)
294                         continue;
295
296                 /* found the next entry */
297                 ret = filldir(cookie,
298                               dire->u.name,
299                               nlen,
300                               blkoff + offset * sizeof(union afs_dirent),
301                               ntohl(dire->u.vnode),
302                               filldir == afs_dir_lookup_filldir ?
303                               ntohl(dire->u.unique) : DT_UNKNOWN);
304                 if (ret < 0) {
305                         _leave(" = 0 [full]");
306                         return 0;
307                 }
308
309                 *fpos = blkoff + next * sizeof(union afs_dirent);
310         }
311
312         _leave(" = 1 [more]");
313         return 1;
314 }
315
316 /*
317  * iterate through the data blob that lists the contents of an AFS directory
318  */
319 static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie,
320                            filldir_t filldir, struct key *key)
321 {
322         union afs_dir_block *dblock;
323         struct afs_dir_page *dbuf;
324         struct page *page;
325         unsigned blkoff, limit;
326         int ret;
327
328         _enter("{%lu},%u,,", dir->i_ino, *fpos);
329
330         if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(dir)->flags)) {
331                 _leave(" = -ESTALE");
332                 return -ESTALE;
333         }
334
335         /* round the file position up to the next entry boundary */
336         *fpos += sizeof(union afs_dirent) - 1;
337         *fpos &= ~(sizeof(union afs_dirent) - 1);
338
339         /* walk through the blocks in sequence */
340         ret = 0;
341         while (*fpos < dir->i_size) {
342                 blkoff = *fpos & ~(sizeof(union afs_dir_block) - 1);
343
344                 /* fetch the appropriate page from the directory */
345                 page = afs_dir_get_page(dir, blkoff / PAGE_SIZE, key);
346                 if (IS_ERR(page)) {
347                         ret = PTR_ERR(page);
348                         break;
349                 }
350
351                 limit = blkoff & ~(PAGE_SIZE - 1);
352
353                 dbuf = page_address(page);
354
355                 /* deal with the individual blocks stashed on this page */
356                 do {
357                         dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) /
358                                                sizeof(union afs_dir_block)];
359                         ret = afs_dir_iterate_block(fpos, dblock, blkoff,
360                                                     cookie, filldir);
361                         if (ret != 1) {
362                                 afs_dir_put_page(page);
363                                 goto out;
364                         }
365
366                         blkoff += sizeof(union afs_dir_block);
367
368                 } while (*fpos < dir->i_size && blkoff < limit);
369
370                 afs_dir_put_page(page);
371                 ret = 0;
372         }
373
374 out:
375         _leave(" = %d", ret);
376         return ret;
377 }
378
379 /*
380  * read an AFS directory
381  */
382 static int afs_dir_readdir(struct file *file, void *cookie, filldir_t filldir)
383 {
384         unsigned fpos;
385         int ret;
386
387         _enter("{%Ld,{%lu}}",
388                file->f_pos, file->f_path.dentry->d_inode->i_ino);
389
390         ASSERT(file->private_data != NULL);
391
392         fpos = file->f_pos;
393         ret = afs_dir_iterate(file->f_path.dentry->d_inode, &fpos,
394                               cookie, filldir, file->private_data);
395         file->f_pos = fpos;
396
397         _leave(" = %d", ret);
398         return ret;
399 }
400
401 /*
402  * search the directory for a name
403  * - if afs_dir_iterate_block() spots this function, it'll pass the FID
404  *   uniquifier through dtype
405  */
406 static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen,
407                                   loff_t fpos, u64 ino, unsigned dtype)
408 {
409         struct afs_dir_lookup_cookie *cookie = _cookie;
410
411         _enter("{%s,%Zu},%s,%u,,%llu,%u",
412                cookie->name, cookie->nlen, name, nlen, ino, dtype);
413
414         /* insanity checks first */
415         BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048);
416         BUILD_BUG_ON(sizeof(union afs_dirent) != 32);
417
418         if (cookie->nlen != nlen || memcmp(cookie->name, name, nlen) != 0) {
419                 _leave(" = 0 [no]");
420                 return 0;
421         }
422
423         cookie->fid.vnode = ino;
424         cookie->fid.unique = dtype;
425         cookie->found = 1;
426
427         _leave(" = -1 [found]");
428         return -1;
429 }
430
431 /*
432  * do a lookup in a directory
433  */
434 static int afs_do_lookup(struct inode *dir, struct dentry *dentry,
435                          struct afs_fid *fid, struct key *key)
436 {
437         struct afs_dir_lookup_cookie cookie;
438         struct afs_super_info *as;
439         unsigned fpos;
440         int ret;
441
442         _enter("{%lu},%p{%s},", dir->i_ino, dentry, dentry->d_name.name);
443
444         as = dir->i_sb->s_fs_info;
445
446         /* search the directory */
447         cookie.name     = dentry->d_name.name;
448         cookie.nlen     = dentry->d_name.len;
449         cookie.fid.vid  = as->volume->vid;
450         cookie.found    = 0;
451
452         fpos = 0;
453         ret = afs_dir_iterate(dir, &fpos, &cookie, afs_dir_lookup_filldir,
454                               key);
455         if (ret < 0) {
456                 _leave(" = %d [iter]", ret);
457                 return ret;
458         }
459
460         ret = -ENOENT;
461         if (!cookie.found) {
462                 _leave(" = -ENOENT [not found]");
463                 return -ENOENT;
464         }
465
466         *fid = cookie.fid;
467         _leave(" = 0 { vn=%u u=%u }", fid->vnode, fid->unique);
468         return 0;
469 }
470
471 /*
472  * look up an entry in a directory
473  */
474 static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
475                                      struct nameidata *nd)
476 {
477         struct afs_vnode *vnode;
478         struct afs_fid fid;
479         struct inode *inode;
480         struct key *key;
481         int ret;
482
483         _enter("{%lu},%p{%s}", dir->i_ino, dentry, dentry->d_name.name);
484
485         if (dentry->d_name.len > 255) {
486                 _leave(" = -ENAMETOOLONG");
487                 return ERR_PTR(-ENAMETOOLONG);
488         }
489
490         vnode = AFS_FS_I(dir);
491         if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
492                 _leave(" = -ESTALE");
493                 return ERR_PTR(-ESTALE);
494         }
495
496         key = afs_request_key(vnode->volume->cell);
497         if (IS_ERR(key)) {
498                 _leave(" = %ld [key]", PTR_ERR(key));
499                 return ERR_PTR(PTR_ERR(key));
500         }
501
502         ret = afs_do_lookup(dir, dentry, &fid, key);
503         if (ret < 0) {
504                 key_put(key);
505                 _leave(" = %d [do]", ret);
506                 return ERR_PTR(ret);
507         }
508
509         /* instantiate the dentry */
510         inode = afs_iget(dir->i_sb, key, &fid);
511         key_put(key);
512         if (IS_ERR(inode)) {
513                 _leave(" = %ld", PTR_ERR(inode));
514                 return ERR_PTR(PTR_ERR(inode));
515         }
516
517         dentry->d_op = &afs_fs_dentry_operations;
518
519         d_add(dentry, inode);
520         _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%lu }",
521                fid.vnode,
522                fid.unique,
523                dentry->d_inode->i_ino,
524                dentry->d_inode->i_version);
525
526         return NULL;
527 }
528
529 /*
530  * propagate changed and modified flags on a directory to all the children of
531  * that directory as they may indicate that the ACL on the dir has changed,
532  * potentially rendering the child inaccessible or that a file has been deleted
533  * or renamed
534  */
535 static void afs_propagate_dir_changes(struct dentry *dir)
536 {
537         struct dentry *child;
538         bool c, m;
539
540         c = test_bit(AFS_VNODE_CHANGED, &AFS_FS_I(dir->d_inode)->flags);
541         m = test_bit(AFS_VNODE_MODIFIED, &AFS_FS_I(dir->d_inode)->flags);
542
543         _enter("{%d,%d}", c, m);
544
545         spin_lock(&dir->d_lock);
546
547         list_for_each_entry(child, &dir->d_subdirs, d_u.d_child) {
548                 if (child->d_inode) {
549                         struct afs_vnode *vnode;
550
551                         _debug("tag %s", child->d_name.name);
552                         vnode = AFS_FS_I(child->d_inode);
553                         if (c)
554                                 set_bit(AFS_VNODE_DIR_CHANGED, &vnode->flags);
555                         if (m)
556                                 set_bit(AFS_VNODE_DIR_MODIFIED, &vnode->flags);
557                 }
558         }
559
560         spin_unlock(&dir->d_lock);
561 }
562
563 /*
564  * check that a dentry lookup hit has found a valid entry
565  * - NOTE! the hit can be a negative hit too, so we can't assume we have an
566  *   inode
567  * - there are several things we need to check
568  *   - parent dir data changes (rm, rmdir, rename, mkdir, create, link,
569  *     symlink)
570  *   - parent dir metadata changed (security changes)
571  *   - dentry data changed (write, truncate)
572  *   - dentry metadata changed (security changes)
573  */
574 static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
575 {
576         struct afs_vnode *vnode;
577         struct afs_fid fid;
578         struct dentry *parent;
579         struct inode *inode, *dir;
580         struct key *key;
581         int ret;
582
583         vnode = AFS_FS_I(dentry->d_inode);
584
585         _enter("{sb=%p n=%s fl=%lx},",
586                dentry->d_sb, dentry->d_name.name, vnode->flags);
587
588         key = afs_request_key(vnode->volume->cell);
589         if (IS_ERR(key))
590                 key = NULL;
591
592         /* lock down the parent dentry so we can peer at it */
593         parent = dget_parent(dentry);
594
595         dir = parent->d_inode;
596         inode = dentry->d_inode;
597
598         /* handle a negative dentry */
599         if (!inode)
600                 goto out_bad;
601
602         /* handle a bad inode */
603         if (is_bad_inode(inode)) {
604                 printk("kAFS: afs_d_revalidate: %s/%s has bad inode\n",
605                        parent->d_name.name, dentry->d_name.name);
606                 goto out_bad;
607         }
608
609         /* check that this dirent still exists if the directory's contents were
610          * modified */
611         if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(dir)->flags)) {
612                 _debug("%s: parent dir deleted", dentry->d_name.name);
613                 goto out_bad;
614         }
615
616         if (test_and_clear_bit(AFS_VNODE_DIR_MODIFIED, &vnode->flags)) {
617                 /* rm/rmdir/rename may have occurred */
618                 _debug("dir modified");
619
620                 /* search the directory for this vnode */
621                 ret = afs_do_lookup(dir, dentry, &fid, key);
622                 if (ret == -ENOENT) {
623                         _debug("%s: dirent not found", dentry->d_name.name);
624                         goto not_found;
625                 }
626                 if (ret < 0) {
627                         _debug("failed to iterate dir %s: %d",
628                                parent->d_name.name, ret);
629                         goto out_bad;
630                 }
631
632                 /* if the vnode ID has changed, then the dirent points to a
633                  * different file */
634                 if (fid.vnode != vnode->fid.vnode) {
635                         _debug("%s: dirent changed [%u != %u]",
636                                dentry->d_name.name, fid.vnode,
637                                vnode->fid.vnode);
638                         goto not_found;
639                 }
640
641                 /* if the vnode ID uniqifier has changed, then the file has
642                  * been deleted */
643                 if (fid.unique != vnode->fid.unique) {
644                         _debug("%s: file deleted (uq %u -> %u I:%lu)",
645                                dentry->d_name.name, fid.unique,
646                                vnode->fid.unique, inode->i_version);
647                         spin_lock(&vnode->lock);
648                         set_bit(AFS_VNODE_DELETED, &vnode->flags);
649                         spin_unlock(&vnode->lock);
650                         invalidate_remote_inode(inode);
651                         goto out_bad;
652                 }
653         }
654
655         /* if the directory's metadata were changed then the security may be
656          * different and we may no longer have access */
657         mutex_lock(&vnode->cb_broken_lock);
658
659         if (test_and_clear_bit(AFS_VNODE_DIR_CHANGED, &vnode->flags) ||
660             test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags)) {
661                 _debug("%s: changed", dentry->d_name.name);
662                 set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags);
663                 if (afs_vnode_fetch_status(vnode, NULL, key) < 0) {
664                         mutex_unlock(&vnode->cb_broken_lock);
665                         goto out_bad;
666                 }
667         }
668
669         if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
670                 _debug("%s: file already deleted", dentry->d_name.name);
671                 mutex_unlock(&vnode->cb_broken_lock);
672                 goto out_bad;
673         }
674
675         /* if the vnode's data version number changed then its contents are
676          * different */
677         if (test_and_clear_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) {
678                 _debug("zap data");
679                 invalidate_remote_inode(inode);
680         }
681
682         if (S_ISDIR(inode->i_mode) &&
683             (test_bit(AFS_VNODE_CHANGED, &vnode->flags) ||
684              test_bit(AFS_VNODE_MODIFIED, &vnode->flags)))
685                 afs_propagate_dir_changes(dentry);
686
687         clear_bit(AFS_VNODE_CHANGED, &vnode->flags);
688         clear_bit(AFS_VNODE_MODIFIED, &vnode->flags);
689         mutex_unlock(&vnode->cb_broken_lock);
690
691 out_valid:
692         dput(parent);
693         key_put(key);
694         _leave(" = 1 [valid]");
695         return 1;
696
697         /* the dirent, if it exists, now points to a different vnode */
698 not_found:
699         spin_lock(&dentry->d_lock);
700         dentry->d_flags |= DCACHE_NFSFS_RENAMED;
701         spin_unlock(&dentry->d_lock);
702
703 out_bad:
704         if (inode) {
705                 /* don't unhash if we have submounts */
706                 if (have_submounts(dentry))
707                         goto out_valid;
708         }
709
710         _debug("dropping dentry %s/%s",
711                parent->d_name.name, dentry->d_name.name);
712         shrink_dcache_parent(dentry);
713         d_drop(dentry);
714         dput(parent);
715         key_put(key);
716
717         _leave(" = 0 [bad]");
718         return 0;
719 }
720
721 /*
722  * allow the VFS to enquire as to whether a dentry should be unhashed (mustn't
723  * sleep)
724  * - called from dput() when d_count is going to 0.
725  * - return 1 to request dentry be unhashed, 0 otherwise
726  */
727 static int afs_d_delete(struct dentry *dentry)
728 {
729         _enter("%s", dentry->d_name.name);
730
731         if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
732                 goto zap;
733
734         if (dentry->d_inode &&
735             test_bit(AFS_VNODE_DELETED, &AFS_FS_I(dentry->d_inode)->flags))
736                         goto zap;
737
738         _leave(" = 0 [keep]");
739         return 0;
740
741 zap:
742         _leave(" = 1 [zap]");
743         return 1;
744 }