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 msdos_inode_info
*i
;
25 struct inode
*inode
= NULL
;
27 head
= sbi
->dir_hashtable
+ fat_dir_hash(i_logstart
);
28 spin_lock(&sbi
->dir_hash_lock
);
29 hlist_for_each_entry(i
, head
, i_dir_hash
) {
30 BUG_ON(i
->vfs_inode
.i_sb
!= sb
);
31 if (i
->i_logstart
!= i_logstart
)
33 inode
= igrab(&i
->vfs_inode
);
37 spin_unlock(&sbi
->dir_hash_lock
);
41 static struct inode
*fat_nfs_get_inode(struct super_block
*sb
,
42 u64 ino
, u32 generation
)
46 if ((ino
< MSDOS_ROOT_INO
) || (ino
== MSDOS_FSINFO_INO
))
49 inode
= ilookup(sb
, ino
);
50 if (inode
&& generation
&& (inode
->i_generation
!= generation
)) {
59 * Map a NFS file handle to a corresponding dentry.
60 * The dentry may or may not be connected to the filesystem root.
62 struct dentry
*fat_fh_to_dentry(struct super_block
*sb
, struct fid
*fid
,
63 int fh_len
, int fh_type
)
65 return generic_fh_to_dentry(sb
, fid
, fh_len
, fh_type
,
70 * Find the parent for a file specified by NFS handle.
71 * This requires that the handle contain the i_ino of the parent.
73 struct dentry
*fat_fh_to_parent(struct super_block
*sb
, struct fid
*fid
,
74 int fh_len
, int fh_type
)
76 return generic_fh_to_parent(sb
, fid
, fh_len
, fh_type
,
81 * Find the parent for a directory that is not currently connected to
82 * the filesystem root.
84 * On entry, the caller holds child_dir->d_inode->i_mutex.
86 struct dentry
*fat_get_parent(struct dentry
*child_dir
)
88 struct super_block
*sb
= child_dir
->d_sb
;
89 struct buffer_head
*bh
= NULL
;
90 struct msdos_dir_entry
*de
;
91 struct inode
*parent_inode
= NULL
;
93 if (!fat_get_dotdot_entry(child_dir
->d_inode
, &bh
, &de
)) {
94 int parent_logstart
= fat_get_start(MSDOS_SB(sb
), de
);
95 parent_inode
= fat_dget(sb
, parent_logstart
);
99 return d_obtain_alias(parent_inode
);