/*
* linux/fs/fat/dir.c
*
* directory handling functions for fat-based filesystems
*
* Written 1992,1993 by Werner Almesberger
*
* Hidden files 1995 by Albert Cahalan <albert@ccs.neu.edu> <adc@coe.neu.edu>
*
* VFAT extensions by Gordon Chaffee <chaffee@plateau.cs.berkeley.edu>
* Merged with msdos fs by Henrik Storner <storner@osiris.ping.dk>
* Rewritten for constant inumbers. Plugged buffer overrun in readdir(). AV
* Short name translation 1999, 2001 by Wolfram Pienkoss <wp@bszh.de>
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/compat.h>
#include <asm/uaccess.h>
#include "fat.h"
static inline loff_t fat_make_i_pos(struct super_block *sb,
struct buffer_head *bh,
struct msdos_dir_entry *de)
{
return ((loff_t)bh->b_blocknr << MSDOS_SB(sb)->dir_per_block_bits)
| (de - (struct msdos_dir_entry *)bh->b_data);
}
static inline void fat_dir_readahead(struct inode *dir, sector_t iblock,
sector_t phys)
{
struct super_block *sb = dir->i_sb;
struct msdos_sb_info *sbi = MSDOS_SB(sb);
struct buffer_head *bh;
int sec;
/* This is not a first sector of cluster, or sec_per_clus == 1 */
if ((iblock & (sbi->sec_per_clus - 1)) || sbi->sec_per_clus == 1)
return;
/* root dir of FAT12/FAT16 */
if ((sbi->fat_bits != 32) && (dir->i_ino == MSDOS_ROOT_INO))
return;
bh = sb_find_get_block(sb, phys);
if (bh == NULL || !buffer_uptodate(bh)) {
for (sec = 0; sec < sbi->sec_per_clus; sec++)
sb_breadahead(sb, phys + sec);
}
brelse(bh);
}
/* Returns the inode number of the directory entry at offset pos. If bh is
non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
returned in bh.
AV. Most often we do it item-by-item. Makes sense to optimize.
AV. OK, there we go: if both bh and de are non-NULL we assume that we just
AV. want the next entry (took one explicit de=NULL in vfat/namei.c).
AV. It's done in fat_get_entry() (inlined), here the slow case lives.
AV. Additionally, when we return -1 (i.e. reached the end of directory)
AV. we make bh NULL.
*/
static int <