fs/: do not fallback to default_llseek() when readdir() uses BKL
authorjan Blunck <jblunck@suse.de>
Wed, 26 May 2010 21:44:53 +0000 (14:44 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 27 May 2010 16:12:56 +0000 (09:12 -0700)
Do not use the fallback default_llseek() if the readdir operation of the
filesystem still uses the big kernel lock.

Since llseek() modifies
file->f_pos of the directory directly it may need locking to not confuse
readdir which usually uses file->f_pos directly as well

Since the special characteristics of the BKL (unlocked on schedule) are
not necessary in this case, the inode mutex can be used for locking as
provided by generic_file_llseek().  This is only possible since all
filesystems, except reiserfs, either use a directory as a flat file or
with disk address offsets.  Reiserfs on the other hand uses a 32bit hash
off the filename as the offset so generic_file_llseek() can get used as
well since the hash is always smaller than sb->s_maxbytes (= (512 << 32) -
blocksize).

Signed-off-by: Jan Blunck <jblunck@suse.de>
Acked-by: Jan Kara <jack@suse.cz>
Acked-by: Anders Larsen <al@alarsen.net>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/autofs/root.c
fs/freevxfs/vxfs_lookup.c
fs/isofs/dir.c
fs/ncpfs/dir.c
fs/qnx4/dir.c
fs/reiserfs/dir.c
fs/smbfs/dir.c
fs/udf/dir.c

index 8713c7cfbc799efe1fa604df04dcbebe3966f225..9a0520b50663b52f9508eb962bd3fbd92f55baa4 100644 (file)
@@ -28,6 +28,7 @@ static int autofs_root_mkdir(struct inode *,struct dentry *,int);
 static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long);
 
 const struct file_operations autofs_root_operations = {
+       .llseek         = generic_file_llseek,
        .read           = generic_read_dir,
        .readdir        = autofs_root_readdir,
        .ioctl          = autofs_root_ioctl,
index aee049cb9f84782640d365a90156f423d2a37b46..0ec7bb2c95c6afd035a9484b0a39347f9f8f61c1 100644 (file)
@@ -57,6 +57,8 @@ const struct inode_operations vxfs_dir_inode_ops = {
 };
 
 const struct file_operations vxfs_dir_operations = {
+       .llseek =               generic_file_llseek,
+       .read =                 generic_read_dir,
        .readdir =              vxfs_readdir,
 };
 
index b9ab69b3a482ce86bcbefd9f7703d0079f516bce..e0aca9a0ac68b9f5a75764a570df2c3d0bd81a72 100644 (file)
@@ -272,6 +272,7 @@ static int isofs_readdir(struct file *filp,
 
 const struct file_operations isofs_dir_operations =
 {
+       .llseek = generic_file_llseek,
        .read = generic_read_dir,
        .readdir = isofs_readdir,
 };
index 92dde6f8d893b51a254e258dfd8942039a95ada6..9578cbe0cd589ad00ce590d60172c2433d16688e 100644 (file)
@@ -49,6 +49,7 @@ extern int ncp_symlink(struct inode *, struct dentry *, const char *);
                      
 const struct file_operations ncp_dir_operations =
 {
+       .llseek         = generic_file_llseek,
        .read           = generic_read_dir,
        .readdir        = ncp_readdir,
        .unlocked_ioctl = ncp_ioctl,
index 6f30c3d5bcbfbfe5923f3cccc3223c9c4d3bba68..3d3fd46921336e7f6b2c73ffc93b64480d24167f 100644 (file)
@@ -77,6 +77,7 @@ out:
 
 const struct file_operations qnx4_dir_operations =
 {
+       .llseek         = generic_file_llseek,
        .read           = generic_read_dir,
        .readdir        = qnx4_readdir,
        .fsync          = simple_fsync,
index 07930449a9583ebee29e5781c3e4dbf9f609aa6f..4455fbe269a31ae341d395b187b3ae5e1f462d10 100644 (file)
@@ -18,6 +18,7 @@ static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry,
                              int datasync);
 
 const struct file_operations reiserfs_dir_operations = {
+       .llseek = generic_file_llseek,
        .read = generic_read_dir,
        .readdir = reiserfs_readdir,
        .fsync = reiserfs_dir_fsync,
index 6c978428892d4de01c406a8abf3d7cc914fe8f5e..00a70cab1f36ea7fc7bd96317d4bccdd8486a736 100644 (file)
@@ -37,6 +37,7 @@ static int smb_link(struct dentry *, struct inode *, struct dentry *);
 
 const struct file_operations smb_dir_operations =
 {
+       .llseek         = generic_file_llseek,
        .read           = generic_read_dir,
        .readdir        = smb_readdir,
        .unlocked_ioctl = smb_ioctl,
index 3a84455c2a7789ef624d7a03b1154b20dbb89d06..1660c81ffa3d6df6dfc816441656279cdc4bcc32 100644 (file)
@@ -207,6 +207,7 @@ static int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
 
 /* readdir and lookup functions */
 const struct file_operations udf_dir_operations = {
+       .llseek                 = generic_file_llseek,
        .read                   = generic_read_dir,
        .readdir                = udf_readdir,
        .unlocked_ioctl         = udf_ioctl,