• R/O
  • HTTP
  • SSH
  • HTTPS

linux-2.4.36: Commit

2.4.36-stable kernel tree


Commit MetaInfo

Revisionc30306fb287323591c854a0982d9fa5351859b45 (tree)
Time2008-02-04 00:37:45
Authordann frazier <dannf@debi...>
CommiterWilly Tarreau

Log Message

ext2_readdir() filp->f_pos fix

This is a 2.4 backport of a linux-2.6 change by Jan Blunck
(old-2.6-bkcvs commit 2196b4744393d4f6c06fc4d63b98556d05b90933)

Commit log from 2.6 follows.

[PATCH] ext2_readdir() filp->f_pos fix
If the whole directory is read, ext2_readdir() sets the f_pos to a multiple
of the page size (because of the conditions of the outer for loop). This
sets the wrong f_pos for directory inodes on ext2 partitions with a block
size differing from the page size.

Signed-off-by: dann frazier <dannf@hp.com>

Change Summary

Incremental Difference

--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -240,7 +240,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
240240 loff_t pos = filp->f_pos;
241241 struct inode *inode = filp->f_dentry->d_inode;
242242 struct super_block *sb = inode->i_sb;
243- unsigned offset = pos & ~PAGE_CACHE_MASK;
243+ unsigned int offset = pos & ~PAGE_CACHE_MASK;
244244 unsigned long n = pos >> PAGE_CACHE_SHIFT;
245245 unsigned long npages = dir_pages(inode);
246246 unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
@@ -258,8 +258,13 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
258258 ext2_dirent *de;
259259 struct page *page = ext2_get_page(inode, n);
260260
261- if (IS_ERR(page))
261+ if (IS_ERR(page)) {
262+ ext2_error(sb, __FUNCTION__,
263+ "bad page in #%lu",
264+ inode->i_ino);
265+ filp->f_pos += PAGE_CACHE_SIZE - offset;
262266 continue;
267+ }
263268 kaddr = page_address(page);
264269 if (need_revalidate) {
265270 offset = ext2_validate_entry(kaddr, offset, chunk_mask);
@@ -283,12 +288,12 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
283288 ext2_put_page(page);
284289 goto done;
285290 }
291+ filp->f_pos += le16_to_cpu(de->rec_len);
286292 }
287293 ext2_put_page(page);
288294 }
289295
290296 done:
291- filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
292297 filp->f_version = inode->i_version;
293298 UPDATE_ATIME(inode);
294299 return 0;
Show on old repository browser