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 "conv.h" 44 #include "fid.h" 45 46 /** 47 * v9fs_dentry_validate - VFS dcache hook to validate cache 48 * @dentry: dentry that is being validated 49 * @nd: path data 50 * 51 * dcache really shouldn't be used for 9P2000 as at all due to 52 * potential attached semantics to directory traversal (walk). 53 * 54 * FUTURE: look into how to use dcache to allow multi-stage 55 * walks in Plan 9 & potential for better dcache operation which 56 * would remain valid for Plan 9 semantics. Older versions 57 * had validation via stat for those interested. However, since 58 * stat has the same approximate overhead as walk there really 59 * is no difference. The only improvement would be from a 60 * time-decay cache like NFS has and that undermines the 61 * synchronous nature of 9P2000. 62 * 63 */ 64 65 static int v9fs_dentry_validate(struct dentry *dentry, struct nameidata *nd) 66 { 67 struct dentry *dc = current->fs->pwd; 68 69 dprintk(DEBUG_VFS, "dentry: %s (%p)\n", dentry->d_iname, dentry); 70 if (v9fs_fid_lookup(dentry)) { 71 dprintk(DEBUG_VFS, "VALID\n"); 72 return 1; 73 } 74 75 while (dc != NULL) { 76 if (dc == dentry) { 77 dprintk(DEBUG_VFS, "VALID\n"); 78 return 1; 79 } 80 if (dc == dc->d_parent) 81 break; 82 83 dc = dc->d_parent; 84 } 85 86 dprintk(DEBUG_VFS, "INVALID\n"); 87 return 0; 88 } 89 90 /** 91 * v9fs_dentry_release - called when dentry is going to be freed 92 * @dentry: dentry that is being release 93 * 94 */ 95 96 void v9fs_dentry_release(struct dentry *dentry) 97 { 98 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); 99 100 if (dentry->d_fsdata != NULL) { 101 struct list_head *fid_list = dentry->d_fsdata; 102 struct v9fs_fid *temp = NULL; 103 struct v9fs_fid *current_fid = NULL; 104 struct v9fs_fcall *fcall = NULL; 105 106 list_for_each_entry_safe(current_fid, temp, fid_list, list) { 107 if (v9fs_t_clunk 108 (current_fid->v9ses, current_fid->fid, &fcall)) 109 dprintk(DEBUG_ERROR, "clunk failed: %s\n", 110 FCALL_ERROR(fcall)); 111 112 v9fs_put_idpool(current_fid->fid, 113 ¤t_fid->v9ses->fidpool); 114 115 kfree(fcall); 116 v9fs_fid_destroy(current_fid); 117 } 118 119 kfree(dentry->d_fsdata); /* free the list_head */ 120 } 121 } 122 123 struct dentry_operations v9fs_dentry_operations = { 124 .d_revalidate = v9fs_dentry_validate, 125 .d_release = v9fs_dentry_release, 126 }; 127