From 81140ca33c79221f7d594d9825855401fcbcdb9c Mon Sep 17 00:00:00 2001
From: Andrew Morton <akpm@digeo.com>
Date: Sat, 22 Mar 2003 07:33:43 -0800
Subject: [PATCH] [PATCH] remove lock_kernel() from readdir implementations.

Filesystems which are using generic_file_llseek() do not need lock_kernel()
in their readir implementations.  All operations (including llseek) are
serialised by the directory's i_sem.

Just fix ext2 and ext3 for now.  Others may need locking between readdir and
who-knows-what.
---
 fs/ext2/dir.c |  4 +---
 fs/ext3/dir.c | 18 +++++++++---------
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 15aa696f60a6..2cc4c11bcd1a 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -259,8 +259,6 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
 	int need_revalidate = (filp->f_version != inode->i_version);
 	int ret = 0;
 
-	lock_kernel();
-
 	if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
 		goto done;
 
@@ -313,7 +311,6 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
 	filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
 	filp->f_version = inode->i_version;
 	UPDATE_ATIME(inode);
-	unlock_kernel();
 	return 0;
 }
 
@@ -660,6 +657,7 @@ int ext2_empty_dir (struct inode * inode)
 }
 
 struct file_operations ext2_dir_operations = {
+	.llseek		= generic_file_llseek,
 	.read		= generic_read_dir,
 	.readdir	= ext2_readdir,
 	.ioctl		= ext2_ioctl,
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index c92f07826f99..cc27d4082571 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -37,10 +37,11 @@ static int ext3_release_dir (struct inode * inode,
 				struct file * filp);
 
 struct file_operations ext3_dir_operations = {
+	.llseek		= generic_file_llseek,
 	.read		= generic_read_dir,
 	.readdir	= ext3_readdir,		/* we take BKL. needed?*/
 	.ioctl		= ext3_ioctl,		/* BKL held */
-	.fsync		= ext3_sync_file,		/* BKL held */
+	.fsync		= ext3_sync_file,	/* BKL held */
 #ifdef CONFIG_EXT3_INDEX
 	.release	= ext3_release_dir,
 #endif
@@ -98,16 +99,15 @@ static int ext3_readdir(struct file * filp,
 	struct super_block * sb;
 	int err;
 	struct inode *inode = filp->f_dentry->d_inode;
-
-	lock_kernel();
+	int ret = 0;
 
 	sb = inode->i_sb;
 
 	if (is_dx(inode)) {
 		err = ext3_dx_readdir(filp, dirent, filldir);
 		if (err != ERR_BAD_DX_DIR) {
-			unlock_kernel();
-			return err;
+			ret = err;
+			goto out;
 		}
 		/*
 		 * We don't set the inode dirty flag since it's not
@@ -186,8 +186,8 @@ static int ext3_readdir(struct file * filp,
 				filp->f_pos = (filp->f_pos |
 						(sb->s_blocksize - 1)) + 1;
 				brelse (bh);
-				unlock_kernel();
-				return stored;
+				ret = stored;
+				goto out;
 			}
 			offset += le16_to_cpu(de->rec_len);
 			if (le32_to_cpu(de->inode)) {
@@ -217,8 +217,8 @@ static int ext3_readdir(struct file * filp,
 		brelse (bh);
 	}
 	UPDATE_ATIME(inode);
-	unlock_kernel();
-	return 0;
+out:
+	return ret;
 }
 
 #ifdef CONFIG_EXT3_INDEX
-- 
2.30.9