~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/orangefs/dcache.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * (C) 2001 Clemson University and The University of Chicago
  4  *
  5  * See COPYING in top-level directory.
  6  */
  7 
  8 /*
  9  *  Implementation of dentry (directory cache) functions.
 10  */
 11 
 12 #include "protocol.h"
 13 #include "orangefs-kernel.h"
 14 
 15 /* Returns 1 if dentry can still be trusted, else 0. */
 16 static int orangefs_revalidate_lookup(struct dentry *dentry)
 17 {
 18         struct dentry *parent_dentry = dget_parent(dentry);
 19         struct inode *parent_inode = parent_dentry->d_inode;
 20         struct orangefs_inode_s *parent = ORANGEFS_I(parent_inode);
 21         struct inode *inode = dentry->d_inode;
 22         struct orangefs_kernel_op_s *new_op;
 23         int ret = 0;
 24         int err = 0;
 25 
 26         gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: attempting lookup.\n", __func__);
 27 
 28         new_op = op_alloc(ORANGEFS_VFS_OP_LOOKUP);
 29         if (!new_op) {
 30                 ret = -ENOMEM;
 31                 goto out_put_parent;
 32         }
 33 
 34         new_op->upcall.req.lookup.sym_follow = ORANGEFS_LOOKUP_LINK_NO_FOLLOW;
 35         new_op->upcall.req.lookup.parent_refn = parent->refn;
 36         strscpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name);
 37 
 38         gossip_debug(GOSSIP_DCACHE_DEBUG,
 39                      "%s:%s:%d interrupt flag [%d]\n",
 40                      __FILE__,
 41                      __func__,
 42                      __LINE__,
 43                      get_interruptible_flag(parent_inode));
 44 
 45         err = service_operation(new_op, "orangefs_lookup",
 46                         get_interruptible_flag(parent_inode));
 47 
 48         /* Positive dentry: reject if error or not the same inode. */
 49         if (inode) {
 50                 if (err) {
 51                         gossip_debug(GOSSIP_DCACHE_DEBUG,
 52                             "%s:%s:%d lookup failure.\n",
 53                             __FILE__, __func__, __LINE__);
 54                         goto out_drop;
 55                 }
 56                 if (!match_handle(new_op->downcall.resp.lookup.refn.khandle,
 57                     inode)) {
 58                         gossip_debug(GOSSIP_DCACHE_DEBUG,
 59                             "%s:%s:%d no match.\n",
 60                             __FILE__, __func__, __LINE__);
 61                         goto out_drop;
 62                 }
 63 
 64         /* Negative dentry: reject if success or error other than ENOENT. */
 65         } else {
 66                 gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: negative dentry.\n",
 67                     __func__);
 68                 if (!err || err != -ENOENT) {
 69                         if (new_op->downcall.status != 0)
 70                                 gossip_debug(GOSSIP_DCACHE_DEBUG,
 71                                     "%s:%s:%d lookup failure.\n",
 72                                     __FILE__, __func__, __LINE__);
 73                         goto out_drop;
 74                 }
 75         }
 76 
 77         orangefs_set_timeout(dentry);
 78         ret = 1;
 79 out_release_op:
 80         op_release(new_op);
 81 out_put_parent:
 82         dput(parent_dentry);
 83         return ret;
 84 out_drop:
 85         gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d revalidate failed\n",
 86             __FILE__, __func__, __LINE__);
 87         goto out_release_op;
 88 }
 89 
 90 /*
 91  * Verify that dentry is valid.
 92  *
 93  * Should return 1 if dentry can still be trusted, else 0.
 94  */
 95 static int orangefs_d_revalidate(struct dentry *dentry, unsigned int flags)
 96 {
 97         int ret;
 98         unsigned long time = (unsigned long) dentry->d_fsdata;
 99 
100         if (time_before(jiffies, time))
101                 return 1;
102 
103         if (flags & LOOKUP_RCU)
104                 return -ECHILD;
105 
106         gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: called on dentry %p.\n",
107                      __func__, dentry);
108 
109         /* skip root handle lookups. */
110         if (dentry->d_inode && is_root_handle(dentry->d_inode))
111                 return 1;
112 
113         /*
114          * If this passes, the positive dentry still exists or the negative
115          * dentry still does not exist.
116          */
117         if (!orangefs_revalidate_lookup(dentry))
118                 return 0;
119 
120         /* We do not need to continue with negative dentries. */
121         if (!dentry->d_inode) {
122                 gossip_debug(GOSSIP_DCACHE_DEBUG,
123                     "%s: negative dentry or positive dentry and inode valid.\n",
124                     __func__);
125                 return 1;
126         }
127 
128         /* Now we must perform a getattr to validate the inode contents. */
129 
130         ret = orangefs_inode_check_changed(dentry->d_inode);
131         if (ret < 0) {
132                 gossip_debug(GOSSIP_DCACHE_DEBUG, "%s:%s:%d getattr failure.\n",
133                     __FILE__, __func__, __LINE__);
134                 return 0;
135         }
136         return !ret;
137 }
138 
139 const struct dentry_operations orangefs_dentry_operations = {
140         .d_revalidate = orangefs_d_revalidate,
141 };
142 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php