Blame view

fs/efs/namei.c 2.67 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
  /*
   * namei.c
   *
   * Copyright (c) 1999 Al Smith
   *
   * Portions derived from work (c) 1995,1996 Christian Vogelgsang.
   */
  
  #include <linux/buffer_head.h>
  #include <linux/string.h>
05da08048   Christoph Hellwig   efs: new export ops
11
  #include <linux/exportfs.h>
45254b4fb   Christoph Hellwig   efs: move headers...
12
  #include "efs.h"
05da08048   Christoph Hellwig   efs: new export ops
13

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  
  static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) {
  	struct buffer_head *bh;
  
  	int			slot, namelen;
  	char			*nameptr;
  	struct efs_dir		*dirblock;
  	struct efs_dentry	*dirslot;
  	efs_ino_t		inodenum;
  	efs_block_t		block;
   
  	if (inode->i_size & (EFS_DIRBSIZE-1))
  		printk(KERN_WARNING "EFS: WARNING: find_entry(): directory size not a multiple of EFS_DIRBSIZE
  ");
  
  	for(block = 0; block < inode->i_blocks; block++) {
  
  		bh = sb_bread(inode->i_sb, efs_bmap(inode, block));
  		if (!bh) {
  			printk(KERN_ERR "EFS: find_entry(): failed to read dir block %d
  ", block);
  			return 0;
  		}
      
  		dirblock = (struct efs_dir *) bh->b_data;
  
  		if (be16_to_cpu(dirblock->magic) != EFS_DIRBLK_MAGIC) {
  			printk(KERN_ERR "EFS: find_entry(): invalid directory block
  ");
  			brelse(bh);
  			return(0);
  		}
  
  		for(slot = 0; slot < dirblock->slots; slot++) {
  			dirslot  = (struct efs_dentry *) (((char *) bh->b_data) + EFS_SLOTAT(dirblock, slot));
  
  			namelen  = dirslot->namelen;
  			nameptr  = dirslot->name;
  
  			if ((namelen == len) && (!memcmp(name, nameptr, len))) {
  				inodenum = be32_to_cpu(dirslot->inode);
  				brelse(bh);
  				return(inodenum);
  			}
  		}
  		brelse(bh);
  	}
  	return(0);
  }
  
  struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) {
  	efs_ino_t inodenum;
a9049376e   Al Viro   make d_splice_ali...
66
  	struct inode *inode = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
  	inodenum = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len);
a9049376e   Al Viro   make d_splice_ali...
69
  	if (inodenum)
298384cd7   David Howells   iget: stop EFS fr...
70
  		inode = efs_iget(dir->i_sb, inodenum);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71

2d8a10cd1   Al Viro   [PATCH] fix efs_l...
72
  	return d_splice_alias(inode, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
  }
05da08048   Christoph Hellwig   efs: new export ops
74
75
  static struct inode *efs_nfs_get_inode(struct super_block *sb, u64 ino,
  		u32 generation)
5ca296073   Christoph Hellwig   knfsd: exportfs: ...
76
  {
5ca296073   Christoph Hellwig   knfsd: exportfs: ...
77
  	struct inode *inode;
5ca296073   Christoph Hellwig   knfsd: exportfs: ...
78
79
80
  
  	if (ino == 0)
  		return ERR_PTR(-ESTALE);
298384cd7   David Howells   iget: stop EFS fr...
81
82
83
  	inode = efs_iget(sb, ino);
  	if (IS_ERR(inode))
  		return ERR_CAST(inode);
5ca296073   Christoph Hellwig   knfsd: exportfs: ...
84

298384cd7   David Howells   iget: stop EFS fr...
85
  	if (generation && inode->i_generation != generation) {
05da08048   Christoph Hellwig   efs: new export ops
86
87
  		iput(inode);
  		return ERR_PTR(-ESTALE);
5ca296073   Christoph Hellwig   knfsd: exportfs: ...
88
  	}
05da08048   Christoph Hellwig   efs: new export ops
89
90
  	return inode;
  }
5ca296073   Christoph Hellwig   knfsd: exportfs: ...
91

05da08048   Christoph Hellwig   efs: new export ops
92
93
94
95
96
97
98
99
100
101
102
103
  struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid,
  		int fh_len, int fh_type)
  {
  	return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
  				    efs_nfs_get_inode);
  }
  
  struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
  		int fh_len, int fh_type)
  {
  	return generic_fh_to_parent(sb, fid, fh_len, fh_type,
  				    efs_nfs_get_inode);
5ca296073   Christoph Hellwig   knfsd: exportfs: ...
104
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105
106
  struct dentry *efs_get_parent(struct dentry *child)
  {
440037287   Christoph Hellwig   [PATCH] switch al...
107
  	struct dentry *parent = ERR_PTR(-ENOENT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
  	efs_ino_t ino;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
  	ino = efs_find_entry(child->d_inode, "..", 2);
440037287   Christoph Hellwig   [PATCH] switch al...
111
112
  	if (ino)
  		parent = d_obtain_alias(efs_iget(child->d_inode->i_sb, ino));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113

440037287   Christoph Hellwig   [PATCH] switch al...
114
  	return parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
115
  }