3 * This software is licensed under the terms of the GNU General Public
4 * License version 2, as published by the Free Software Foundation, and
5 * may be copied, distributed, and modified under those terms.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
14 #include <linux/exportfs.h>
18 * Look up a directory inode given its starting cluster.
20 static struct inode
*fat_dget(struct super_block
*sb
, int i_logstart
)
22 struct msdos_sb_info
*sbi
= MSDOS_SB(sb
);
23 struct hlist_head
*head
;
24 struct hlist_node
*_p
;
25 struct msdos_inode_info
*i
;
26 struct inode
*inode
= NULL
;
28 head
= sbi
->dir_hashtable
+ fat_dir_hash(i_logstart
);
29 spin_lock(&sbi
->dir_hash_lock
);
30 hlist_for_each_entry(i
, _p
, head
, i_dir_hash
) {
31 BUG_ON(i
->vfs_inode
.i_sb
!= sb
);
32 if (i
->i_logstart
!= i_logstart
)
34 inode
= igrab(&i
->vfs_inode
);
38 spin_unlock(&sbi
->dir_hash_lock
);
42 static struct inode
*fat_nfs_get_inode(struct super_block
*sb
,
43 u64 ino
, u32 generation
)
47 if ((ino
< MSDOS_ROOT_INO
) || (ino
== MSDOS_FSINFO_INO
))
50 inode
= ilookup(sb
, ino
);
51 if (inode
&& generation
&& (inode
->i_generation
!= generation
)) {
60 * Map a NFS file handle to a corresponding dentry.
61 * The dentry may or may not be connected to the filesystem root.
63 struct dentry
*fat_fh_to_dentry(struct super_block
*sb
, struct fid
*fid
,
64 int fh_len
, int fh_type
)
66 return generic_fh_to_dentry(sb
, fid
, fh_len
, fh_type
,
71 * Find the parent for a file specified by NFS handle.
72 * This requires that the handle contain the i_ino of the parent.
74 struct dentry
*fat_fh_to_parent(struct super_block
*sb
, struct fid
*fid
,
75 int fh_len
, int fh_type
)
77 return generic_fh_to_parent(sb
, fid
, fh_len
, fh_type
,
82 * Find the parent for a directory that is not currently connected to
83 * the filesystem root.
85 * On entry, the caller holds child_dir->d_inode->i_mutex.
87 struct dentry
*fat_get_parent(struct dentry
*child_dir
)
89 struct super_block
*sb
= child_dir
->d_sb
;
90 struct buffer_head
*bh
= NULL
;
91 struct msdos_dir_entry
*de
;
92 struct inode
*parent_inode
= NULL
;
94 if (!fat_get_dotdot_entry(child_dir
->d_inode
, &bh
, &de
)) {
95 int parent_logstart
= fat_get_start(MSDOS_SB(sb
), de
);
96 parent_inode
= fat_dget(sb
, parent_logstart
);
100 return d_obtain_alias(parent_inode
);