Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * This file contians vfs dentry ops for the 9P2000 protocol.
0004  *
0005  *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
0006  *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
0007  */
0008 
0009 #include <linux/module.h>
0010 #include <linux/errno.h>
0011 #include <linux/fs.h>
0012 #include <linux/file.h>
0013 #include <linux/pagemap.h>
0014 #include <linux/stat.h>
0015 #include <linux/string.h>
0016 #include <linux/inet.h>
0017 #include <linux/namei.h>
0018 #include <linux/idr.h>
0019 #include <linux/sched.h>
0020 #include <linux/slab.h>
0021 #include <net/9p/9p.h>
0022 #include <net/9p/client.h>
0023 
0024 #include "v9fs.h"
0025 #include "v9fs_vfs.h"
0026 #include "fid.h"
0027 
0028 /**
0029  * v9fs_cached_dentry_delete - called when dentry refcount equals 0
0030  * @dentry:  dentry in question
0031  *
0032  */
0033 static int v9fs_cached_dentry_delete(const struct dentry *dentry)
0034 {
0035     p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n",
0036          dentry, dentry);
0037 
0038     /* Don't cache negative dentries */
0039     if (d_really_is_negative(dentry))
0040         return 1;
0041     return 0;
0042 }
0043 
0044 /**
0045  * v9fs_dentry_release - called when dentry is going to be freed
0046  * @dentry:  dentry that is being release
0047  *
0048  */
0049 
0050 static void v9fs_dentry_release(struct dentry *dentry)
0051 {
0052     struct hlist_node *p, *n;
0053 
0054     p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n",
0055          dentry, dentry);
0056     hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata)
0057         p9_fid_put(hlist_entry(p, struct p9_fid, dlist));
0058     dentry->d_fsdata = NULL;
0059 }
0060 
0061 static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
0062 {
0063     struct p9_fid *fid;
0064     struct inode *inode;
0065     struct v9fs_inode *v9inode;
0066 
0067     if (flags & LOOKUP_RCU)
0068         return -ECHILD;
0069 
0070     inode = d_inode(dentry);
0071     if (!inode)
0072         goto out_valid;
0073 
0074     v9inode = V9FS_I(inode);
0075     if (v9inode->cache_validity & V9FS_INO_INVALID_ATTR) {
0076         int retval;
0077         struct v9fs_session_info *v9ses;
0078 
0079         fid = v9fs_fid_lookup(dentry);
0080         if (IS_ERR(fid))
0081             return PTR_ERR(fid);
0082 
0083         v9ses = v9fs_inode2v9ses(inode);
0084         if (v9fs_proto_dotl(v9ses))
0085             retval = v9fs_refresh_inode_dotl(fid, inode);
0086         else
0087             retval = v9fs_refresh_inode(fid, inode);
0088         p9_fid_put(fid);
0089 
0090         if (retval == -ENOENT)
0091             return 0;
0092         if (retval < 0)
0093             return retval;
0094     }
0095 out_valid:
0096     return 1;
0097 }
0098 
0099 const struct dentry_operations v9fs_cached_dentry_operations = {
0100     .d_revalidate = v9fs_lookup_revalidate,
0101     .d_weak_revalidate = v9fs_lookup_revalidate,
0102     .d_delete = v9fs_cached_dentry_delete,
0103     .d_release = v9fs_dentry_release,
0104 };
0105 
0106 const struct dentry_operations v9fs_dentry_operations = {
0107     .d_delete = always_delete_dentry,
0108     .d_release = v9fs_dentry_release,
0109 };