113 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * This file contians vfs dentry ops for the 9P2000 protocol.4 *5 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>6 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>7 */8 9#include <linux/module.h>10#include <linux/errno.h>11#include <linux/fs.h>12#include <linux/file.h>13#include <linux/pagemap.h>14#include <linux/stat.h>15#include <linux/string.h>16#include <linux/namei.h>17#include <linux/sched.h>18#include <linux/slab.h>19#include <net/9p/9p.h>20#include <net/9p/client.h>21 22#include "v9fs.h"23#include "v9fs_vfs.h"24#include "fid.h"25 26/**27 * v9fs_cached_dentry_delete - called when dentry refcount equals 028 * @dentry: dentry in question29 *30 */31static int v9fs_cached_dentry_delete(const struct dentry *dentry)32{33 p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n",34 dentry, dentry);35 36 /* Don't cache negative dentries */37 if (d_really_is_negative(dentry))38 return 1;39 return 0;40}41 42/**43 * v9fs_dentry_release - called when dentry is going to be freed44 * @dentry: dentry that is being release45 *46 */47 48static void v9fs_dentry_release(struct dentry *dentry)49{50 struct hlist_node *p, *n;51 struct hlist_head head;52 53 p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n",54 dentry, dentry);55 56 spin_lock(&dentry->d_lock);57 hlist_move_list((struct hlist_head *)&dentry->d_fsdata, &head);58 spin_unlock(&dentry->d_lock);59 60 hlist_for_each_safe(p, n, &head)61 p9_fid_put(hlist_entry(p, struct p9_fid, dlist));62}63 64static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)65{66 struct p9_fid *fid;67 struct inode *inode;68 struct v9fs_inode *v9inode;69 70 if (flags & LOOKUP_RCU)71 return -ECHILD;72 73 inode = d_inode(dentry);74 if (!inode)75 goto out_valid;76 77 v9inode = V9FS_I(inode);78 if (v9inode->cache_validity & V9FS_INO_INVALID_ATTR) {79 int retval;80 struct v9fs_session_info *v9ses;81 82 fid = v9fs_fid_lookup(dentry);83 if (IS_ERR(fid))84 return PTR_ERR(fid);85 86 v9ses = v9fs_inode2v9ses(inode);87 if (v9fs_proto_dotl(v9ses))88 retval = v9fs_refresh_inode_dotl(fid, inode);89 else90 retval = v9fs_refresh_inode(fid, inode);91 p9_fid_put(fid);92 93 if (retval == -ENOENT)94 return 0;95 if (retval < 0)96 return retval;97 }98out_valid:99 return 1;100}101 102const struct dentry_operations v9fs_cached_dentry_operations = {103 .d_revalidate = v9fs_lookup_revalidate,104 .d_weak_revalidate = v9fs_lookup_revalidate,105 .d_delete = v9fs_cached_dentry_delete,106 .d_release = v9fs_dentry_release,107};108 109const struct dentry_operations v9fs_dentry_operations = {110 .d_delete = always_delete_dentry,111 .d_release = v9fs_dentry_release,112};113