1e69e7fe5SEric Van Hensbergen /* 2e69e7fe5SEric Van Hensbergen * linux/fs/9p/vfs_dentry.c 3e69e7fe5SEric Van Hensbergen * 4e69e7fe5SEric Van Hensbergen * This file contians vfs dentry ops for the 9P2000 protocol. 5e69e7fe5SEric Van Hensbergen * 6e69e7fe5SEric Van Hensbergen * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 7e69e7fe5SEric Van Hensbergen * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8e69e7fe5SEric Van Hensbergen * 9e69e7fe5SEric Van Hensbergen * This program is free software; you can redistribute it and/or modify 1042e8c509SEric Van Hensbergen * it under the terms of the GNU General Public License version 2 1142e8c509SEric Van Hensbergen * as published by the Free Software Foundation. 12e69e7fe5SEric Van Hensbergen * 13e69e7fe5SEric Van Hensbergen * This program is distributed in the hope that it will be useful, 14e69e7fe5SEric Van Hensbergen * but WITHOUT ANY WARRANTY; without even the implied warranty of 15e69e7fe5SEric Van Hensbergen * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16e69e7fe5SEric Van Hensbergen * GNU General Public License for more details. 17e69e7fe5SEric Van Hensbergen * 18e69e7fe5SEric Van Hensbergen * You should have received a copy of the GNU General Public License 19e69e7fe5SEric Van Hensbergen * along with this program; if not, write to: 20e69e7fe5SEric Van Hensbergen * Free Software Foundation 21e69e7fe5SEric Van Hensbergen * 51 Franklin Street, Fifth Floor 22e69e7fe5SEric Van Hensbergen * Boston, MA 02111-1301 USA 23e69e7fe5SEric Van Hensbergen * 24e69e7fe5SEric Van Hensbergen */ 25e69e7fe5SEric Van Hensbergen 26e69e7fe5SEric Van Hensbergen #include <linux/module.h> 27e69e7fe5SEric Van Hensbergen #include <linux/errno.h> 28e69e7fe5SEric Van Hensbergen #include <linux/fs.h> 29e69e7fe5SEric Van Hensbergen #include <linux/file.h> 30e69e7fe5SEric Van Hensbergen #include <linux/pagemap.h> 31e69e7fe5SEric Van Hensbergen #include <linux/stat.h> 32e69e7fe5SEric Van Hensbergen #include <linux/string.h> 33e69e7fe5SEric Van Hensbergen #include <linux/inet.h> 34e69e7fe5SEric Van Hensbergen #include <linux/namei.h> 35e69e7fe5SEric Van Hensbergen #include <linux/idr.h> 36e8edc6e0SAlexey Dobriyan #include <linux/sched.h> 375a0e3ad6STejun Heo #include <linux/slab.h> 38bd238fb4SLatchesar Ionkov #include <net/9p/9p.h> 39bd238fb4SLatchesar Ionkov #include <net/9p/client.h> 40e69e7fe5SEric Van Hensbergen 41e69e7fe5SEric Van Hensbergen #include "v9fs.h" 42e69e7fe5SEric Van Hensbergen #include "v9fs_vfs.h" 43e69e7fe5SEric Van Hensbergen #include "fid.h" 44e69e7fe5SEric Van Hensbergen 45e69e7fe5SEric Van Hensbergen /** 46e03abc0cSEric Van Hensbergen * v9fs_cached_dentry_delete - called when dentry refcount equals 0 47e03abc0cSEric Van Hensbergen * @dentry: dentry in question 48e03abc0cSEric Van Hensbergen * 49e03abc0cSEric Van Hensbergen */ 50fe15ce44SNick Piggin static int v9fs_cached_dentry_delete(const struct dentry *dentry) 51e03abc0cSEric Van Hensbergen { 52*4b8e9923SAl Viro p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n", 53*4b8e9923SAl Viro dentry, dentry); 54e03abc0cSEric Van Hensbergen 55a950a652SAneesh Kumar K.V /* Don't cache negative dentries */ 56a950a652SAneesh Kumar K.V if (!dentry->d_inode) 57e03abc0cSEric Van Hensbergen return 1; 58e03abc0cSEric Van Hensbergen return 0; 59e03abc0cSEric Van Hensbergen } 60e03abc0cSEric Van Hensbergen 61e03abc0cSEric Van Hensbergen /** 62e69e7fe5SEric Van Hensbergen * v9fs_dentry_release - called when dentry is going to be freed 63e69e7fe5SEric Van Hensbergen * @dentry: dentry that is being release 64e69e7fe5SEric Van Hensbergen * 65e69e7fe5SEric Van Hensbergen */ 66e69e7fe5SEric Van Hensbergen 6798cd3fb0SAl Viro static void v9fs_dentry_release(struct dentry *dentry) 68e69e7fe5SEric Van Hensbergen { 69aaeb7ecfSAl Viro struct hlist_node *p, *n; 70*4b8e9923SAl Viro p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n", 71*4b8e9923SAl Viro dentry, dentry); 72aaeb7ecfSAl Viro hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata) 73c4d30967SAl Viro p9_client_clunk(hlist_entry(p, struct p9_fid, dlist)); 74bd238fb4SLatchesar Ionkov dentry->d_fsdata = NULL; 75e69e7fe5SEric Van Hensbergen } 76e69e7fe5SEric Van Hensbergen 770b728e19SAl Viro static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags) 78b3cbea03SAneesh Kumar K.V { 79b3cbea03SAneesh Kumar K.V struct p9_fid *fid; 80b3cbea03SAneesh Kumar K.V struct inode *inode; 81b3cbea03SAneesh Kumar K.V struct v9fs_inode *v9inode; 82b3cbea03SAneesh Kumar K.V 830b728e19SAl Viro if (flags & LOOKUP_RCU) 84b3cbea03SAneesh Kumar K.V return -ECHILD; 85b3cbea03SAneesh Kumar K.V 86b3cbea03SAneesh Kumar K.V inode = dentry->d_inode; 87b3cbea03SAneesh Kumar K.V if (!inode) 88b3cbea03SAneesh Kumar K.V goto out_valid; 89b3cbea03SAneesh Kumar K.V 90b3cbea03SAneesh Kumar K.V v9inode = V9FS_I(inode); 91b3cbea03SAneesh Kumar K.V if (v9inode->cache_validity & V9FS_INO_INVALID_ATTR) { 92b3cbea03SAneesh Kumar K.V int retval; 93b3cbea03SAneesh Kumar K.V struct v9fs_session_info *v9ses; 94b3cbea03SAneesh Kumar K.V fid = v9fs_fid_lookup(dentry); 95b3cbea03SAneesh Kumar K.V if (IS_ERR(fid)) 96b3cbea03SAneesh Kumar K.V return PTR_ERR(fid); 97b3cbea03SAneesh Kumar K.V 98b3cbea03SAneesh Kumar K.V v9ses = v9fs_inode2v9ses(inode); 99b3cbea03SAneesh Kumar K.V if (v9fs_proto_dotl(v9ses)) 100b3cbea03SAneesh Kumar K.V retval = v9fs_refresh_inode_dotl(fid, inode); 101b3cbea03SAneesh Kumar K.V else 102b3cbea03SAneesh Kumar K.V retval = v9fs_refresh_inode(fid, inode); 103f2eda2c6SAneesh Kumar K.V if (retval == -ENOENT) 104f2eda2c6SAneesh Kumar K.V return 0; 105f2eda2c6SAneesh Kumar K.V if (retval < 0) 106b3cbea03SAneesh Kumar K.V return retval; 107b3cbea03SAneesh Kumar K.V } 108b3cbea03SAneesh Kumar K.V out_valid: 109b3cbea03SAneesh Kumar K.V return 1; 110b3cbea03SAneesh Kumar K.V } 111b3cbea03SAneesh Kumar K.V 112a488257cSAl Viro const struct dentry_operations v9fs_cached_dentry_operations = { 113b3cbea03SAneesh Kumar K.V .d_revalidate = v9fs_lookup_revalidate, 114ecf3d1f1SJeff Layton .d_weak_revalidate = v9fs_lookup_revalidate, 115e03abc0cSEric Van Hensbergen .d_delete = v9fs_cached_dentry_delete, 116e03abc0cSEric Van Hensbergen .d_release = v9fs_dentry_release, 117e03abc0cSEric Van Hensbergen }; 118e03abc0cSEric Van Hensbergen 119a488257cSAl Viro const struct dentry_operations v9fs_dentry_operations = { 120b26d4cd3SAl Viro .d_delete = always_delete_dentry, 121e69e7fe5SEric Van Hensbergen .d_release = v9fs_dentry_release, 122e69e7fe5SEric Van Hensbergen }; 123