[patch-2.3.43-pre5] optimized fsync(2)/fdatasync(2)

From: Tigran Aivazian (tigran@ocston.org)
Date: Wed Feb 09 2000 - 16:27:37 EST


Hi Linus,

I have removed lock/unlock_kernel() from fsync(2)/fdatasyn(2) system
calls. Obviously, I had to go through each filesystem's f_op->fsync()
implementation ensuring that it is SMP-safe. This is the resulting
patch:

    http://www.ocston.org/~tigran/patches/fsync-2.3.43-p5.patch

As I only modified filesystems that are in the kernel tree, the
authors of filesystems maintained outside the official kernel should
do something similar for their own filesystems (hence
cc:linux-fsdevel).

Please consider this patch.

Regards,
Tigran.

diff -urN -X dontdiff linux/fs/buffer.c linux-fsync/fs/buffer.c
--- linux/fs/buffer.c Wed Feb 9 19:34:50 2000
+++ linux-fsync/fs/buffer.c Wed Feb 9 21:24:56 2000
@@ -323,7 +323,9 @@
         struct inode * inode = dentry->d_inode;
         struct super_block * sb;
         kdev_t dev;
+ int ret;
 
+ lock_kernel();
         /* sync the inode to buffers */
         write_inode_now(inode);
 
@@ -335,7 +337,9 @@
 
         /* .. finally sync the buffers to disk */
         dev = inode->i_dev;
- return sync_buffers(dev, 1);
+ ret = sync_buffers(dev, 1);
+ unlock_kernel();
+ return ret;
 }
 
 asmlinkage long sys_fsync(unsigned int fd)
@@ -345,7 +349,6 @@
         struct inode * inode;
         int err;
 
- lock_kernel();
         err = -EBADF;
         file = fget(fd);
         if (!file)
@@ -371,7 +374,6 @@
 out_putf:
         fput(file);
 out:
- unlock_kernel();
         return err;
 }
 
@@ -382,7 +384,6 @@
         struct inode * inode;
         int err;
 
- lock_kernel();
         err = -EBADF;
         file = fget(fd);
         if (!file)
@@ -408,7 +409,6 @@
 out_putf:
         fput(file);
 out:
- unlock_kernel();
         return err;
 }
 
diff -urN -X dontdiff linux/fs/coda/file.c linux-fsync/fs/coda/file.c
--- linux/fs/coda/file.c Thu Jan 13 21:21:07 2000
+++ linux-fsync/fs/coda/file.c Wed Feb 9 20:19:26 2000
@@ -213,12 +213,14 @@
               S_ISLNK(coda_inode->i_mode)))
                 return -EINVAL;
 
+ lock_kernel();
         cnp = ITOC(coda_inode);
         CHECK_CNODE(cnp);
 
         cont_inode = cnp->c_ovp;
         if ( cont_inode == NULL ) {
                 printk("coda_file_write: cached inode is 0!\n");
+ unlock_kernel();
                 return -1;
         }
 
@@ -235,6 +237,7 @@
         up(&cont_inode->i_sem);
 
         coda_restore_codafile(coda_inode, coda_file, cont_inode, &cont_file);
+ unlock_kernel();
         return result;
 }
 /*
diff -urN -X dontdiff linux/fs/ext2/fsync.c linux-fsync/fs/ext2/fsync.c
--- linux/fs/ext2/fsync.c Thu Jan 13 21:21:37 2000
+++ linux-fsync/fs/ext2/fsync.c Wed Feb 9 20:23:26 2000
@@ -24,8 +24,7 @@
 
 #include <linux/fs.h>
 #include <linux/locks.h>
-
-
+#include <linux/smp_lock.h>
 
 
 #define blocksize (EXT2_BLOCK_SIZE(inode->i_sb))
@@ -130,6 +129,7 @@
         int wait, err = 0;
         struct inode *inode = dentry->d_inode;
 
+ lock_kernel();
         if (S_ISLNK(inode->i_mode) && !(inode->i_blocks))
                 /*
                  * Don't sync fast links!
@@ -152,5 +152,6 @@
         }
 skip:
         err |= ext2_sync_inode (inode);
+ unlock_kernel();
         return err ? -EIO : 0;
 }
diff -urN -X dontdiff linux/fs/minix/fsync.c linux-fsync/fs/minix/fsync.c
--- linux/fs/minix/fsync.c Tue Jun 29 17:22:08 1999
+++ linux-fsync/fs/minix/fsync.c Wed Feb 9 20:16:06 2000
@@ -148,10 +148,7 @@
 {
         int wait, err = 0;
         
- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
- S_ISLNK(inode->i_mode)))
- return -EINVAL;
-
+ lock_kernel();
         for (wait=0; wait<=1; wait++)
         {
                 err |= V1_sync_direct(inode, wait);
@@ -159,6 +156,7 @@
                 err |= V1_sync_dindirect(inode, inode->u.minix_i.u.i1_data + 8, wait);
         }
         err |= minix_sync_inode (inode);
+ unlock_kernel();
         return (err < 0) ? -EIO : 0;
 }
 
@@ -309,10 +307,7 @@
 {
         int wait, err = 0;
         
- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
- S_ISLNK(inode->i_mode)))
- return -EINVAL;
-
+ lock_kernel();
         for (wait=0; wait<=1; wait++)
         {
                 err |= V2_sync_direct(inode, wait);
@@ -324,6 +319,7 @@
                       (unsigned long *) inode->u.minix_i.u.i2_data + 9, wait);
         }
         err |= minix_sync_inode (inode);
+ unlock_kernel();
         return (err < 0) ? -EIO : 0;
 }
 
@@ -336,6 +332,10 @@
 {
         struct inode *inode = dentry->d_inode;
         
+ if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+ S_ISLNK(inode->i_mode)))
+ return -EINVAL;
+
         if (INODE_VERSION(inode) == MINIX_V1)
                 return V1_minix_sync_file(inode, file);
         else
diff -urN -X dontdiff linux/fs/nfs/file.c linux-fsync/fs/nfs/file.c
--- linux/fs/nfs/file.c Thu Jan 13 21:21:07 2000
+++ linux-fsync/fs/nfs/file.c Wed Feb 9 20:16:32 2000
@@ -146,11 +146,13 @@
 
         dfprintk(VFS, "nfs: fsync(%x/%ld)\n", inode->i_dev, inode->i_ino);
 
+ lock_kernel();
         status = nfs_wb_file(inode, file);
         if (!status) {
                 status = file->f_error;
                 file->f_error = 0;
         }
+ unlock_kernel();
         return status;
 }
 
diff -urN -X dontdiff linux/fs/qnx4/fsync.c linux-fsync/fs/qnx4/fsync.c
--- linux/fs/qnx4/fsync.c Tue Jun 29 17:22:08 1999
+++ linux-fsync/fs/qnx4/fsync.c Wed Feb 9 20:18:16 2000
@@ -156,10 +156,12 @@
               S_ISLNK(inode->i_mode)))
                 return -EINVAL;
 
+ lock_kernel();
         for (wait = 0; wait <= 1; wait++) {
                 err |= sync_direct(inode, wait);
         }
         err |= qnx4_sync_inode(inode);
+ unlock_kernel();
         return (err < 0) ? -EIO : 0;
 }
 
diff -urN -X dontdiff linux/fs/sysv/fsync.c linux-fsync/fs/sysv/fsync.c
--- linux/fs/sysv/fsync.c Tue Jun 29 17:22:08 1999
+++ linux-fsync/fs/sysv/fsync.c Wed Feb 9 20:17:15 2000
@@ -187,6 +187,7 @@
              S_ISLNK(inode->i_mode)))
                 return -EINVAL;
 
+ lock_kernel();
         for (wait=0; wait<=1; wait++) {
                 err |= sync_direct(inode, wait);
                 err |= sync_indirect(inode, inode->u.sysv_i.i_data+10, 0, wait);
@@ -194,5 +195,6 @@
                 err |= sync_tindirect(inode, inode->u.sysv_i.i_data+12, 0, wait);
         }
         err |= sysv_sync_inode (inode);
+ unlock_kernel();
         return (err < 0) ? -EIO : 0;
 }
diff -urN -X dontdiff linux/fs/udf/fsync.c linux-fsync/fs/udf/fsync.c
--- linux/fs/udf/fsync.c Sat Jan 29 12:11:53 2000
+++ linux-fsync/fs/udf/fsync.c Wed Feb 9 20:21:15 2000
@@ -100,6 +100,7 @@
         int wait, err = 0;
         struct inode *inode = dentry->d_inode;
 
+ lock_kernel();
         if (S_ISLNK(inode->i_mode) && !(inode->i_blocks))
         {
                 /*
@@ -116,10 +117,16 @@
         }
 skip:
         err |= udf_sync_inode (inode);
+ unlock_kernel();
         return err ? -EIO : 0;
 }
 
 int udf_sync_file_adinicb(struct file * file, struct dentry *dentry)
 {
- return udf_sync_inode(dentry->d_inode) ? -EIO : 0;
+ int ret;
+
+ lock_kernel();
+ ret = udf_sync_inode(dentry->d_inode) ? -EIO : 0;
+ unlock_kernel();
+ return ret;
 }

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Feb 15 2000 - 21:00:16 EST