1 /* 2 * linux/fs/9p/vfs_dentry.c 3 * 4 * This file contians vfs dentry ops for the 9P2000 protocol. 5 * 6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to: 21 * Free Software Foundation 22 * 51 Franklin Street, Fifth Floor 23 * Boston, MA 02111-1301 USA 24 * 25 */ 26 27 #include <linux/module.h> 28 #include <linux/errno.h> 29 #include <linux/fs.h> 30 #include <linux/file.h> 31 #include <linux/pagemap.h> 32 #include <linux/stat.h> 33 #include <linux/string.h> 34 #include <linux/smp_lock.h> 35 #include <linux/inet.h> 36 #include <linux/namei.h> 37 #include <linux/idr.h> 38 39 #include "debug.h" 40 #include "v9fs.h" 41 #include "9p.h" 42 #include "v9fs_vfs.h" 43 #include "fid.h" 44 45 /** 46 * v9fs_dentry_validate - VFS dcache hook to validate cache 47 * @dentry: dentry that is being validated 48 * @nd: path data 49 * 50 * dcache really shouldn't be used for 9P2000 as at all due to 51 * potential attached semantics to directory traversal (walk). 52 * 53 * FUTURE: look into how to use dcache to allow multi-stage 54 * walks in Plan 9 & potential for better dcache operation which 55 * would remain valid for Plan 9 semantics. Older versions 56 * had validation via stat for those interested. However, since 57 * stat has the same approximate overhead as walk there really 58 * is no difference. The only improvement would be from a 59 * time-decay cache like NFS has and that undermines the 60 * synchronous nature of 9P2000. 61 * 62 */ 63 64 static int v9fs_dentry_validate(struct dentry *dentry, struct nameidata *nd) 65 { 66 struct dentry *dc = current->fs->pwd; 67 68 dprintk(DEBUG_VFS, "dentry: %s (%p)\n", dentry->d_iname, dentry); 69 if (v9fs_fid_lookup(dentry)) { 70 dprintk(DEBUG_VFS, "VALID\n"); 71 return 1; 72 } 73 74 while (dc != NULL) { 75 if (dc == dentry) { 76 dprintk(DEBUG_VFS, "VALID\n"); 77 return 1; 78 } 79 if (dc == dc->d_parent) 80 break; 81 82 dc = dc->d_parent; 83 } 84 85 dprintk(DEBUG_VFS, "INVALID\n"); 86 return 0; 87 } 88 89 /** 90 * v9fs_dentry_release - called when dentry is going to be freed 91 * @dentry: dentry that is being release 92 * 93 */ 94 95 void v9fs_dentry_release(struct dentry *dentry) 96 { 97 int err; 98 99 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); 100 101 if (dentry->d_fsdata != NULL) { 102 struct list_head *fid_list = dentry->d_fsdata; 103 struct v9fs_fid *temp = NULL; 104 struct v9fs_fid *current_fid = NULL; 105 106 list_for_each_entry_safe(current_fid, temp, fid_list, list) { 107 err = v9fs_t_clunk(current_fid->v9ses, current_fid->fid); 108 109 if (err < 0) 110 dprintk(DEBUG_ERROR, "clunk failed: %d name %s\n", 111 err, dentry->d_iname); 112 113 v9fs_fid_destroy(current_fid); 114 } 115 116 kfree(dentry->d_fsdata); /* free the list_head */ 117 } 118 } 119 120 struct dentry_operations v9fs_dentry_operations = { 121 .d_revalidate = v9fs_dentry_validate, 122 .d_release = v9fs_dentry_release, 123 }; 124