diff -urN linux-2.5.3-pre6/Documentation/filesystems/Locking linux/Documentation/filesystems/Locking --- linux-2.5.3-pre6/Documentation/filesystems/Locking Tue Feb 5 17:15:08 2002 +++ linux/Documentation/filesystems/Locking Tue Feb 5 17:19:44 2002 @@ -219,7 +219,7 @@ locking rules: All except ->poll() may block. BKL -llseek: yes +llseek: yes (see below) read: no write: no readdir: yes (see below) @@ -235,6 +235,12 @@ readv: no writev: no +->llseek() locking has moved from llseek to the individual llseek +implementations. If you are not using generic_file_llseek, you +need to acquire and release the appropriate lock in your ->llseek(). +This may or may not be the BKL. Many methods may be safe acquiring +only the inode semaphore. + ->open() locking is in-transit: big lock partially moved into the methods. The only exception is ->open() in the instances of file_operations that never end up in ->i_fop/->proc_fops, i.e. ones that belong to character devices diff -urN linux-2.5.3-pre6/fs/block_dev.c linux/fs/block_dev.c --- linux-2.5.3-pre6/fs/block_dev.c Tue Feb 5 17:14:52 2002 +++ linux/fs/block_dev.c Tue Feb 5 17:20:16 2002 @@ -170,6 +170,7 @@ loff_t size = file->f_dentry->d_inode->i_bdev->bd_inode->i_size; loff_t retval; + lock_kernel(); switch (origin) { case 2: offset += size; @@ -186,6 +187,7 @@ } retval = offset; } + unlock_kernel(); return retval; } diff -urN linux-2.5.3-pre6/fs/hfs/file_cap.c linux/fs/hfs/file_cap.c --- linux-2.5.3-pre6/fs/hfs/file_cap.c Tue Feb 5 17:14:52 2002 +++ linux/fs/hfs/file_cap.c Tue Feb 5 17:28:03 2002 @@ -24,6 +24,7 @@ #include #include #include +#include /*================ Forward declarations ================*/ static loff_t cap_info_llseek(struct file *, loff_t, @@ -91,6 +92,7 @@ { long long retval; + lock_kernel(); switch (origin) { case 2: offset += file->f_dentry->d_inode->i_size; @@ -106,6 +108,7 @@ } retval = offset; } + unlock_kernel(); return retval; } diff -urN linux-2.5.3-pre6/fs/hfs/file_hdr.c linux/fs/hfs/file_hdr.c --- linux-2.5.3-pre6/fs/hfs/file_hdr.c Tue Feb 5 17:14:52 2002 +++ linux/fs/hfs/file_hdr.c Tue Feb 5 17:28:15 2002 @@ -29,6 +29,7 @@ #include #include #include +#include /* prodos types */ #define PRODOSI_FTYPE_DIR 0x0F @@ -347,6 +348,7 @@ { long long retval; + lock_kernel(); switch (origin) { case 2: offset += file->f_dentry->d_inode->i_size; @@ -362,6 +364,7 @@ } retval = offset; } + unlock_kernel(); return retval; } diff -urN linux-2.5.3-pre6/fs/hpfs/dir.c linux/fs/hpfs/dir.c --- linux-2.5.3-pre6/fs/hpfs/dir.c Tue Feb 5 17:14:52 2002 +++ linux/fs/hpfs/dir.c Tue Feb 5 17:22:17 2002 @@ -30,6 +30,7 @@ struct hpfs_inode_info *hpfs_inode = hpfs_i(i); struct super_block *s = i->i_sb; /*printk("dir lseek\n");*/ + lock_kernel(); if (new_off == 0 || new_off == 1 || new_off == 11 || new_off == 12 || new_off == 13) goto ok; hpfs_lock_inode(i); pos = ((loff_t) hpfs_de_as_down_as_possible(s, hpfs_inode->i_dno) << 4) + 1; @@ -40,10 +41,12 @@ } hpfs_unlock_inode(i); ok: + unlock_kernel(); return filp->f_pos = new_off; fail: hpfs_unlock_inode(i); /*printk("illegal lseek: %016llx\n", new_off);*/ + unlock_kernel(); return -ESPIPE; } diff -urN linux-2.5.3-pre6/fs/ncpfs/file.c linux/fs/ncpfs/file.c --- linux-2.5.3-pre6/fs/ncpfs/file.c Tue Feb 5 17:14:52 2002 +++ linux/fs/ncpfs/file.c Tue Feb 5 17:28:33 2002 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "ncplib_kernel.h" diff -urN linux-2.5.3-pre6/fs/proc/generic.c linux/fs/proc/generic.c --- linux-2.5.3-pre6/fs/proc/generic.c Tue Feb 5 17:14:52 2002 +++ linux/fs/proc/generic.c Tue Feb 5 17:24:10 2002 @@ -16,6 +16,7 @@ #include #define __NO_VERSION__ #include +#include #include static ssize_t proc_file_read(struct file * file, char * buf, @@ -140,22 +141,26 @@ static loff_t proc_file_lseek(struct file * file, loff_t offset, int orig) { + lock_kernel(); + switch (orig) { case 0: if (offset < 0) - return -EINVAL; + goto out; file->f_pos = offset; - return(file->f_pos); + goto out; case 1: if (offset + file->f_pos < 0) - return -EINVAL; + goto out; file->f_pos += offset; - return(file->f_pos); + goto out; case 2: - return(-EINVAL); default: - return(-EINVAL); } + +out: + unlock_kernel(); + return -EINVAL; } /* diff -urN linux-2.5.3-pre6/fs/read_write.c linux/fs/read_write.c --- linux-2.5.3-pre6/fs/read_write.c Tue Feb 5 17:14:52 2002 +++ linux/fs/read_write.c Tue Feb 5 17:41:23 2002 @@ -28,23 +28,29 @@ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) { long long retval; + struct inode *inode = file->f_dentry->d_inode->i_mapping->host; + + down(&inode->i_sem); switch (origin) { case 2: - offset += file->f_dentry->d_inode->i_size; + offset += inode->i_size; break; case 1: offset += file->f_pos; } retval = -EINVAL; if (offset>=0 && offset<=file->f_dentry->d_inode->i_sb->s_maxbytes) { - if (offset != file->f_pos) { + if (offset>=0 && offset<=inode->i_sb->s_maxbytes) { file->f_pos = offset; file->f_reada = 0; file->f_version = ++event; } retval = offset; } + + up(&inode->i_sem); + return retval; } @@ -57,6 +63,7 @@ { long long retval; + lock_kernel(); switch (origin) { case 2: offset += file->f_dentry->d_inode->i_size; @@ -73,21 +80,18 @@ } retval = offset; } + unlock_kernel(); return retval; } static inline loff_t llseek(struct file *file, loff_t offset, int origin) { loff_t (*fn)(struct file *, loff_t, int); - loff_t retval; fn = default_llseek; if (file->f_op && file->f_op->llseek) fn = file->f_op->llseek; - lock_kernel(); - retval = fn(file, offset, origin); - unlock_kernel(); - return retval; + return fn(file, offset, origin); } asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin) diff -urN linux-2.5.3-pre6/fs/ufs/file.c linux/fs/ufs/file.c --- linux-2.5.3-pre6/fs/ufs/file.c Tue Feb 5 17:14:52 2002 +++ linux/fs/ufs/file.c Tue Feb 5 17:28:47 2002 @@ -35,6 +35,7 @@ #include #include #include +#include /* * Make sure the offset never goes beyond the 32-bit mark.. @@ -47,6 +48,7 @@ long long retval; struct inode *inode = file->f_dentry->d_inode; + lock_kernel(); switch (origin) { case 2: offset += inode->i_size; @@ -64,6 +66,7 @@ } retval = offset; } + unlock_kernel(); return retval; }