Messages in this thread Patch in this message | | | Date | Tue, 6 Jul 1999 11:05:04 -0400 (EDT) | From | Simon Kirby <> | Subject | Re: [PATCH] Re: FAT bug in 2.2.10-ac8(was slocate never finishes in ..) |
| |
On Tue, 6 Jul 1999, Alexander Viro wrote: > > Right. You do. It's a combination of my idiocy and idiocy of slocate > authors. Sigh... In case of root directory the second entry (fake "..") > got an d_off (offset of the next entry) equal to 0 *if* there were > additional entries successfully filled by getdents(). My idiocy. > Now, authors of slocate, in their infinite wisdom, decided to do > seekdir after each readdir. Which means that they call getdents (on a > decently-sized buffer) for each bloody offset. It is idiocy. Number of > getdents() calls is 2 orders of magintude higher than it should be. > Combination of those bogosities gave an infinite loop. > Fix for FAT attached (it's against -ac8, with 2.2.9 it will get a > line numbers offset but will apply fine). > > As for slocate... Look for seekdir(recdir, telldir()); and shoot > it. Dunno if the author reads l-k (he didn't leave an address in the > source), but just in case: seekdir() is *NOT* needed if you read > sequentially. Just as fseek(); is not needed for files in the similar > case.
The author works for NetNation (the same company I work for). I will forward this to him.
Simon-
| Simon Kirby | Systems Administration | | mailto:sim@netnation.com | NetNation Communications | | http://www.netnation.com/ | Tech: (604) 684-6892 | --- fs/fat/dir.c Tue Jul 6 01:44:45 1999 +++ fs/fat/dir.c.new Tue Jul 6 01:50:30 1999 @@ -310,6 +310,8 @@ char bufname[14]; char *ptname = bufname; int dotoffset = 0; + unsigned long *furrfu = &lpos; + unsigned long dummy; cpos = filp->f_pos; /* Fake . and .. for the root directory. */ @@ -320,8 +322,11 @@ cpos++; filp->f_pos++; } - if (cpos == 2) + if (cpos == 2) { + dummy = 2; + furrfu = &dummy; cpos = 0; + } } if (cpos & (sizeof(struct msdos_dir_entry)-1)) return -ENOENT; @@ -455,7 +460,7 @@ if (!long_slots||shortnames) { if (both) bufname[i] = '\0'; - if (filldir(dirent, bufname, i, lpos, inum) < 0) + if (filldir(dirent, bufname, i, *furrfu, inum) < 0) goto FillFailed; } else { char longname[275]; @@ -466,11 +471,12 @@ memcpy(&longname[long_len+1], bufname, i); long_len += i; } - if (filldir(dirent, longname, long_len, lpos, inum) < 0) + if (filldir(dirent, longname, long_len, *furrfu, inum) < 0) goto FillFailed; } RecEnd: + furrfu = &lpos; filp->f_pos = cpos; goto GetNew; EODir: | |