lkml.org 
[lkml]   [1999]   [Jul]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: Linux 2.2.10ac6


On Thu, 1 Jul 1999, Alan Cox wrote:

> ftp://ftp.*.kernel.org/pub/linux/kernel/alan/...
[snip]

Alan, here is one more patch to FAT/VFAT. It tries to optimize the lookup
time (it does cyclic search from the postition of last hit; in case of
directory change or negative lookup postion is reset to 0, indeed). It
works here and it *does* speed ls -l up (well, actually anything that
does lookups in the order given by readdir - globbing, for one). It's a
BSD thing and they do it on all local filesystems. I didn't want to start
from ext2 ;-/ The thing passes Gordon's testsuite.
Cheers,
Al

diff -urN linux-2.2.10-ac6/fs/fat/dir.c linux-bird.dir/fs/fat/dir.c
--- linux-2.2.10-ac6/fs/fat/dir.c Fri Jul 2 00:39:12 1999
+++ linux-bird.dir/fs/fat/dir.c Fri Jul 2 00:40:11 1999
@@ -137,7 +137,8 @@
char c;
struct buffer_head *bh = NULL;
struct msdos_dir_entry *de;
- loff_t cpos = 0;
+ loff_t cpos = MSDOS_I(dir)->i_last_pos;
+ loff_t barrier = 0;
char bufname[14];
unsigned char long_slots;
int uni_xlate = MSDOS_SB(sb)->options.unicode_xlate;
@@ -147,6 +148,9 @@
int res = 0;

while(1) {
+ if (barrier && cpos>=barrier)
+ goto EODir;
+rescan:
if (fat_get_entry(inode,&cpos,&bh,&de,&ino) == -1)
goto EODir;
parse_record:
@@ -265,11 +269,22 @@
res = long_slots + 1;
*spos = cpos - sizeof(struct msdos_dir_entry);
*lpos = cpos - res*sizeof(struct msdos_dir_entry);
-EODir:
+ MSDOS_I(dir)->i_last_pos = cpos;
+exit:
if (unicode) {
free_page((unsigned long) unicode);
}
return res;
+EODir:
+ if (!MSDOS_I(dir)->i_last_pos)
+ goto exit;
+ if (barrier) {
+ MSDOS_I(dir)->i_last_pos = 0;
+ goto exit;
+ }
+ barrier = MSDOS_I(dir)->i_last_pos;
+ cpos = 0;
+ goto rescan;
}

static int fat_readdirx(
diff -urN linux-2.2.10-ac6/fs/fat/inode.c linux-bird.dir/fs/fat/inode.c
--- linux-2.2.10-ac6/fs/fat/inode.c Fri Jul 2 00:39:12 1999
+++ linux-bird.dir/fs/fat/inode.c Fri Jul 2 00:40:11 1999
@@ -371,6 +371,7 @@
inode->i_uid = MSDOS_SB(sb)->options.fs_uid;
inode->i_gid = MSDOS_SB(sb)->options.fs_gid;
inode->i_version = ++event;
+ MSDOS_I(inode)->i_last_pos = 0;
inode->i_mode = (S_IRWXUGO & ~MSDOS_SB(sb)->options.fs_umask) | S_IFDIR;
inode->i_op = MSDOS_SB(sb)->dir_ops;
if (MSDOS_SB(sb)->fat_bits == 32) {
@@ -760,6 +761,7 @@
inode->i_gid = MSDOS_SB(sb)->options.fs_gid;
inode->i_version = ++event;
if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) {
+ MSDOS_I(inode)->i_last_pos = 0;
inode->i_mode = MSDOS_MKMODE(de->attr,S_IRWXUGO &
~MSDOS_SB(sb)->options.fs_umask) | S_IFDIR;
inode->i_op = MSDOS_SB(inode->i_sb)->dir_ops;
diff -urN linux-2.2.10-ac6/fs/fat/misc.c linux-bird.dir/fs/fat/misc.c
--- linux-2.2.10-ac6/fs/fat/misc.c Fri Jul 2 00:39:12 1999
+++ linux-bird.dir/fs/fat/misc.c Fri Jul 2 00:40:11 1999
@@ -353,8 +353,6 @@
*bh = NULL;
if ((sector = fat_smap(dir,offset >> SECTOR_BITS)) == -1)
return -1;
- PRINTK (("get_entry sector %d %p\n",sector,*bh));
- PRINTK (("get_entry sector apres brelse\n"));
if (!sector)
return -1; /* beyond EOF */
*pos += sizeof(struct msdos_dir_entry);
@@ -362,13 +360,12 @@
printk("Directory sread (sector 0x%x) failed\n",sector);
continue;
}
- PRINTK (("get_entry apres sread\n"));
- *de = (struct msdos_dir_entry *) ((*bh)->b_data+(offset &
- (SECTOR_SIZE-1)));
- *ino = (sector << MSDOS_DPS_BITS)+((offset & (SECTOR_SIZE-1)) >>
- MSDOS_DIR_BITS);
- return 0;
+ break;
}
+ *de = (struct msdos_dir_entry*)((*bh)->b_data+(offset&(SECTOR_SIZE-1)));
+ *ino = (sector << MSDOS_DPS_BITS)+((offset & (SECTOR_SIZE-1)) >>
+ MSDOS_DIR_BITS);
+ return 0;
}


diff -urN linux-2.2.10-ac6/fs/vfat/namei.c linux-bird.dir/fs/vfat/namei.c
--- linux-2.2.10-ac6/fs/vfat/namei.c Fri Jul 2 00:39:14 1999
+++ linux-bird.dir/fs/vfat/namei.c Fri Jul 2 00:40:11 1999
@@ -977,6 +977,7 @@
mark_inode_dirty(inode);
inode->i_version = ++event;
dir->i_version = event;
+ MSDOS_I(dir)->i_last_pos = 0;
dentry->d_time = dentry->d_parent->d_inode->i_version;
d_instantiate(dentry,inode);
return 0;
@@ -1022,6 +1023,7 @@
dir->i_mtime = CURRENT_TIME;
dir->i_atime = CURRENT_TIME;
dir->i_version = ++event;
+ MSDOS_I(dir)->i_last_pos = 0;
mark_inode_dirty(dir);
de->name[0] = DELETED_FLAG;
fat_mark_buffer_dirty(sb, bh, 1);
@@ -1108,6 +1110,7 @@
mark_inode_dirty(inode);
inode->i_version = ++event;
dir->i_version = event;
+ MSDOS_I(dir)->i_last_pos = 0;
dir->i_nlink++;
inode->i_nlink = 2; /* no need to mark them dirty */

@@ -1179,6 +1182,7 @@
}

new_dir->i_version = ++event;
+ MSDOS_I(new_dir)->i_last_pos = 0;

/* releases old_bh */
vfat_remove_entry(old_dir,&old_sinfo,old_bh,old_de);
diff -urN linux-2.2.10-ac6/include/linux/msdos_fs_i.h linux-bird.dir/include/linux/msdos_fs_i.h
--- linux-2.2.10-ac6/include/linux/msdos_fs_i.h Fri Jul 2 00:39:17 1999
+++ linux-bird.dir/include/linux/msdos_fs_i.h Fri Jul 2 00:40:11 1999
@@ -29,12 +29,11 @@
int i_logstart; /* logical first cluster */
int i_attrs; /* unused attribute bits */
int i_ctime_ms; /* unused change time in milliseconds */
- int i_busy; /* file is either deleted but still open, or
- inconsistent (mkdir) */
int i_binary; /* file contains non-text data */
int i_location; /* on-disk position of directory entry or 0 */
struct inode *i_fat_inode; /* struct inode of this one */
struct list_head i_fat_hash; /* hash by i_location */
+ off_t i_last_pos;/* position of last lookup */
};

#endif
\
 
 \ /
  Last update: 2005-03-22 13:52    [W:0.844 / U:0.388 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site