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

TOMOYO Linux Cross Reference
Linux/fs/efs/namei.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  * namei.c
  4  *
  5  * Copyright (c) 1999 Al Smith
  6  *
  7  * Portions derived from work (c) 1995,1996 Christian Vogelgsang.
  8  */
  9 
 10 #include <linux/buffer_head.h>
 11 #include <linux/string.h>
 12 #include <linux/exportfs.h>
 13 #include "efs.h"
 14 
 15 
 16 static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len)
 17 {
 18         struct buffer_head *bh;
 19 
 20         int                     slot, namelen;
 21         char                    *nameptr;
 22         struct efs_dir          *dirblock;
 23         struct efs_dentry       *dirslot;
 24         efs_ino_t               inodenum;
 25         efs_block_t             block;
 26  
 27         if (inode->i_size & (EFS_DIRBSIZE-1))
 28                 pr_warn("%s(): directory size not a multiple of EFS_DIRBSIZE\n",
 29                         __func__);
 30 
 31         for(block = 0; block < inode->i_blocks; block++) {
 32 
 33                 bh = sb_bread(inode->i_sb, efs_bmap(inode, block));
 34                 if (!bh) {
 35                         pr_err("%s(): failed to read dir block %d\n",
 36                                __func__, block);
 37                         return 0;
 38                 }
 39     
 40                 dirblock = (struct efs_dir *) bh->b_data;
 41 
 42                 if (be16_to_cpu(dirblock->magic) != EFS_DIRBLK_MAGIC) {
 43                         pr_err("%s(): invalid directory block\n", __func__);
 44                         brelse(bh);
 45                         return 0;
 46                 }
 47 
 48                 for (slot = 0; slot < dirblock->slots; slot++) {
 49                         dirslot  = (struct efs_dentry *) (((char *) bh->b_data) + EFS_SLOTAT(dirblock, slot));
 50 
 51                         namelen  = dirslot->namelen;
 52                         nameptr  = dirslot->name;
 53 
 54                         if ((namelen == len) && (!memcmp(name, nameptr, len))) {
 55                                 inodenum = be32_to_cpu(dirslot->inode);
 56                                 brelse(bh);
 57                                 return inodenum;
 58                         }
 59                 }
 60                 brelse(bh);
 61         }
 62         return 0;
 63 }
 64 
 65 struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
 66 {
 67         efs_ino_t inodenum;
 68         struct inode *inode = NULL;
 69 
 70         inodenum = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len);
 71         if (inodenum)
 72                 inode = efs_iget(dir->i_sb, inodenum);
 73 
 74         return d_splice_alias(inode, dentry);
 75 }
 76 
 77 static struct inode *efs_nfs_get_inode(struct super_block *sb, u64 ino,
 78                 u32 generation)
 79 {
 80         struct inode *inode;
 81 
 82         if (ino == 0)
 83                 return ERR_PTR(-ESTALE);
 84         inode = efs_iget(sb, ino);
 85         if (IS_ERR(inode))
 86                 return ERR_CAST(inode);
 87 
 88         if (generation && inode->i_generation != generation) {
 89                 iput(inode);
 90                 return ERR_PTR(-ESTALE);
 91         }
 92 
 93         return inode;
 94 }
 95 
 96 struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid,
 97                 int fh_len, int fh_type)
 98 {
 99         return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
100                                     efs_nfs_get_inode);
101 }
102 
103 struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
104                 int fh_len, int fh_type)
105 {
106         return generic_fh_to_parent(sb, fid, fh_len, fh_type,
107                                     efs_nfs_get_inode);
108 }
109 
110 struct dentry *efs_get_parent(struct dentry *child)
111 {
112         struct dentry *parent = ERR_PTR(-ENOENT);
113         efs_ino_t ino;
114 
115         ino = efs_find_entry(d_inode(child), "..", 2);
116         if (ino)
117                 parent = d_obtain_alias(efs_iget(child->d_sb, ino));
118 
119         return parent;
120 }
121 

~ [ 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