Patches contributed by Eötvös Lorand University


commit f3111502c065d32dcb021f55e30398aaebd8fb0f
Author: Ingo Molnar <mingo@elte.hu>
Date:   Fri Apr 28 15:30:03 2006 -0700

    [XFRM]: fix incorrect xfrm_state_afinfo_lock use
    
    xfrm_state_afinfo_lock can be read-locked from bh context, so take it
    in a bh-safe manner in xfrm_state_register_afinfo() and
    xfrm_state_unregister_afinfo(). Found by the lock validator.
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: David S. Miller <davem@davemloft.net>

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 3dc3e1f3b7aa..93a2f36ad3db 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1061,7 +1061,7 @@ int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo)
 		return -EINVAL;
 	if (unlikely(afinfo->family >= NPROTO))
 		return -EAFNOSUPPORT;
-	write_lock(&xfrm_state_afinfo_lock);
+	write_lock_bh(&xfrm_state_afinfo_lock);
 	if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL))
 		err = -ENOBUFS;
 	else {
@@ -1069,7 +1069,7 @@ int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo)
 		afinfo->state_byspi = xfrm_state_byspi;
 		xfrm_state_afinfo[afinfo->family] = afinfo;
 	}
-	write_unlock(&xfrm_state_afinfo_lock);
+	write_unlock_bh(&xfrm_state_afinfo_lock);
 	return err;
 }
 EXPORT_SYMBOL(xfrm_state_register_afinfo);
@@ -1081,7 +1081,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
 		return -EINVAL;
 	if (unlikely(afinfo->family >= NPROTO))
 		return -EAFNOSUPPORT;
-	write_lock(&xfrm_state_afinfo_lock);
+	write_lock_bh(&xfrm_state_afinfo_lock);
 	if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) {
 		if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo))
 			err = -EINVAL;
@@ -1091,7 +1091,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
 			afinfo->state_bydst = NULL;
 		}
 	}
-	write_unlock(&xfrm_state_afinfo_lock);
+	write_unlock_bh(&xfrm_state_afinfo_lock);
 	return err;
 }
 EXPORT_SYMBOL(xfrm_state_unregister_afinfo);

commit 8dff7c29707b7514043539f5ab5e0a6eb7bd9dcd
Author: Ingo Molnar <mingo@elte.hu>
Date:   Fri Apr 28 15:23:59 2006 -0700

    [XFRM]: fix softirq-unsafe xfrm typemap->lock use
    
    xfrm typemap->lock may be used in softirq context, so all write_lock()
    uses must be softirq-safe.
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: David S. Miller <davem@davemloft.net>

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index c3725fe2a8fb..e5b0afc94f1e 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -57,12 +57,12 @@ int xfrm_register_type(struct xfrm_type *type, unsigned short family)
 		return -EAFNOSUPPORT;
 	typemap = afinfo->type_map;
 
-	write_lock(&typemap->lock);
+	write_lock_bh(&typemap->lock);
 	if (likely(typemap->map[type->proto] == NULL))
 		typemap->map[type->proto] = type;
 	else
 		err = -EEXIST;
-	write_unlock(&typemap->lock);
+	write_unlock_bh(&typemap->lock);
 	xfrm_policy_put_afinfo(afinfo);
 	return err;
 }
@@ -78,12 +78,12 @@ int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
 		return -EAFNOSUPPORT;
 	typemap = afinfo->type_map;
 
-	write_lock(&typemap->lock);
+	write_lock_bh(&typemap->lock);
 	if (unlikely(typemap->map[type->proto] != type))
 		err = -ENOENT;
 	else
 		typemap->map[type->proto] = NULL;
-	write_unlock(&typemap->lock);
+	write_unlock_bh(&typemap->lock);
 	xfrm_policy_put_afinfo(afinfo);
 	return err;
 }

commit 5dc5cf7dd2723430b6df3d91c5b22af49e063622
Author: Ingo Molnar <mingo@elte.hu>
Date:   Thu Apr 20 02:43:23 2006 -0700

    [PATCH] md: locking fix
    
    - fix mddev_lock() usage bugs in md_attr_show() and md_attr_store().
      [they did not anticipate the possibility of getting a signal]
    
    - remove mddev_lock_uninterruptible() [unused]
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Acked-by: Neil Brown <neilb@suse.de>
    Signed-off-by: Andrew Morton <akpm@osdl.org>
    Signed-off-by: Linus Torvalds <torvalds@osdl.org>

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 434ca39d19c1..d7316b829a62 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -279,11 +279,6 @@ static inline int mddev_lock(mddev_t * mddev)
 	return mutex_lock_interruptible(&mddev->reconfig_mutex);
 }
 
-static inline void mddev_lock_uninterruptible(mddev_t * mddev)
-{
-	mutex_lock(&mddev->reconfig_mutex);
-}
-
 static inline int mddev_trylock(mddev_t * mddev)
 {
 	return mutex_trylock(&mddev->reconfig_mutex);
@@ -2458,9 +2453,11 @@ md_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
 
 	if (!entry->show)
 		return -EIO;
-	mddev_lock(mddev);
-	rv = entry->show(mddev, page);
-	mddev_unlock(mddev);
+	rv = mddev_lock(mddev);
+	if (!rv) {
+		rv = entry->show(mddev, page);
+		mddev_unlock(mddev);
+	}
 	return rv;
 }
 
@@ -2474,9 +2471,11 @@ md_attr_store(struct kobject *kobj, struct attribute *attr,
 
 	if (!entry->store)
 		return -EIO;
-	mddev_lock(mddev);
-	rv = entry->store(mddev, page, length);
-	mddev_unlock(mddev);
+	rv = mddev_lock(mddev);
+	if (!rv) {
+		rv = entry->store(mddev, page, length);
+		mddev_unlock(mddev);
+	}
 	return rv;
 }
 
@@ -4341,8 +4340,9 @@ static int md_seq_show(struct seq_file *seq, void *v)
 		return 0;
 	}
 
-	if (mddev_lock(mddev)!=0) 
+	if (mddev_lock(mddev) < 0)
 		return -EINTR;
+
 	if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) {
 		seq_printf(seq, "%s : %sactive", mdname(mddev),
 						mddev->pers ? "" : "in");

commit 341b446bc5aa36d1d5b8159c1e66716b5d89024d
Author: Ingo Molnar <mingo@elte.hu>
Date:   Tue Apr 11 13:57:45 2006 +0200

    [PATCH] another round of fs/pipe.c cleanups
    
    make pipe.c a bit more readable and hackable.
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: Jens Axboe <axboe@suse.de>

diff --git a/fs/pipe.c b/fs/pipe.c
index b941e1951eac..e984beb93a0e 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -44,7 +44,8 @@ void pipe_wait(struct pipe_inode_info *pipe)
 	 * Pipes are system-local resources, so sleeping on them
 	 * is considered a noninteractive wait:
 	 */
-	prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
+	prepare_to_wait(&pipe->wait, &wait,
+			TASK_INTERRUPTIBLE | TASK_NONINTERACTIVE);
 	if (pipe->inode)
 		mutex_unlock(&pipe->inode->i_mutex);
 	schedule();
@@ -93,7 +94,8 @@ pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len)
 	return 0;
 }
 
-static void anon_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
+static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
+				  struct pipe_buffer *buf)
 {
 	struct page *page = buf->page;
 
@@ -102,25 +104,22 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buff
 	/*
 	 * If nobody else uses this page, and we don't already have a
 	 * temporary page, let's keep track of it as a one-deep
-	 * allocation cache
+	 * allocation cache. (Otherwise just release our reference to it)
 	 */
-	if (page_count(page) == 1 && !pipe->tmp_page) {
+	if (page_count(page) == 1 && !pipe->tmp_page)
 		pipe->tmp_page = page;
-		return;
-	}
-
-	/*
-	 * Otherwise just release our reference to it
-	 */
-	page_cache_release(page);
+	else
+		page_cache_release(page);
 }
 
-static void *anon_pipe_buf_map(struct file *file, struct pipe_inode_info *pipe, struct pipe_buffer *buf)
+static void * anon_pipe_buf_map(struct file *file, struct pipe_inode_info *pipe,
+				struct pipe_buffer *buf)
 {
 	return kmap(buf->page);
 }
 
-static void anon_pipe_buf_unmap(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
+static void anon_pipe_buf_unmap(struct pipe_inode_info *pipe,
+				struct pipe_buffer *buf)
 {
 	kunmap(buf->page);
 }
@@ -182,7 +181,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
 			error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars);
 			ops->unmap(pipe, buf);
 			if (unlikely(error)) {
-				if (!ret) ret = -EFAULT;
+				if (!ret)
+					ret = -EFAULT;
 				break;
 			}
 			ret += chars;
@@ -218,7 +218,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
 			}
 		}
 		if (signal_pending(current)) {
-			if (!ret) ret = -ERESTARTSYS;
+			if (!ret)
+				ret = -ERESTARTSYS;
 			break;
 		}
 		if (do_wakeup) {
@@ -228,7 +229,8 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
 		pipe_wait(pipe);
 	}
 	mutex_unlock(&inode->i_mutex);
-	/* Signal writers asynchronously that there is more room.  */
+
+	/* Signal writers asynchronously that there is more room. */
 	if (do_wakeup) {
 		wake_up_interruptible(&pipe->wait);
 		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
@@ -242,6 +244,7 @@ static ssize_t
 pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
 {
 	struct iovec iov = { .iov_base = buf, .iov_len = count };
+
 	return pipe_readv(filp, &iov, 1, ppos);
 }
 
@@ -276,10 +279,12 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 	/* We try to merge small writes */
 	chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */
 	if (pipe->nrbufs && chars != 0) {
-		int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) & (PIPE_BUFFERS-1);
+		int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) &
+							(PIPE_BUFFERS-1);
 		struct pipe_buffer *buf = pipe->bufs + lastbuf;
 		struct pipe_buf_operations *ops = buf->ops;
 		int offset = buf->offset + buf->len;
+
 		if (ops->can_merge && offset + chars <= PAGE_SIZE) {
 			void *addr;
 			int error;
@@ -306,9 +311,11 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 
 	for (;;) {
 		int bufs;
+
 		if (!pipe->readers) {
 			send_sig(SIGPIPE, current, 0);
-			if (!ret) ret = -EPIPE;
+			if (!ret)
+				ret = -EPIPE;
 			break;
 		}
 		bufs = pipe->nrbufs;
@@ -326,7 +333,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 				}
 				pipe->tmp_page = page;
 			}
-			/* Always wakeup, even if the copy fails. Otherwise
+			/* Always wake up, even if the copy fails. Otherwise
 			 * we lock up (O_NONBLOCK-)readers that sleep due to
 			 * syscall merging.
 			 * FIXME! Is this really true?
@@ -339,7 +346,8 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 			error = pipe_iov_copy_from_user(kmap(page), iov, chars);
 			kunmap(page);
 			if (unlikely(error)) {
-				if (!ret) ret = -EFAULT;
+				if (!ret)
+					ret = -EFAULT;
 				break;
 			}
 			ret += chars;
@@ -359,11 +367,13 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 		if (bufs < PIPE_BUFFERS)
 			continue;
 		if (filp->f_flags & O_NONBLOCK) {
-			if (!ret) ret = -EAGAIN;
+			if (!ret)
+				ret = -EAGAIN;
 			break;
 		}
 		if (signal_pending(current)) {
-			if (!ret) ret = -ERESTARTSYS;
+			if (!ret)
+				ret = -ERESTARTSYS;
 			break;
 		}
 		if (do_wakeup) {
@@ -391,6 +401,7 @@ pipe_write(struct file *filp, const char __user *buf,
 	   size_t count, loff_t *ppos)
 {
 	struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count };
+
 	return pipe_writev(filp, &iov, 1, ppos);
 }
 
@@ -401,7 +412,8 @@ bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
 }
 
 static ssize_t
-bad_pipe_w(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
+bad_pipe_w(struct file *filp, const char __user *buf, size_t count,
+	   loff_t *ppos)
 {
 	return -EBADF;
 }
@@ -475,6 +487,7 @@ pipe_release(struct inode *inode, int decr, int decw)
 	pipe = inode->i_pipe;
 	pipe->readers -= decr;
 	pipe->writers -= decw;
+
 	if (!pipe->readers && !pipe->writers) {
 		free_pipe_info(inode);
 	} else {
@@ -525,14 +538,15 @@ static int
 pipe_rdwr_fasync(int fd, struct file *filp, int on)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
+	struct pipe_inode_info *pipe = inode->i_pipe;
 	int retval;
 
 	mutex_lock(&inode->i_mutex);
 
-	retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers);
+	retval = fasync_helper(fd, filp, on, &pipe->fasync_readers);
 
 	if (retval >= 0)
-		retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers);
+		retval = fasync_helper(fd, filp, on, &pipe->fasync_writers);
 
 	mutex_unlock(&inode->i_mutex);
 
@@ -720,6 +734,7 @@ static int pipefs_delete_dentry(struct dentry *dentry)
 {
 	return 1;
 }
+
 static struct dentry_operations pipefs_dentry_operations = {
 	.d_delete	= pipefs_delete_dentry,
 };
@@ -757,6 +772,7 @@ static struct inode * get_pipe_inode(void)
 
 fail_iput:
 	iput(inode);
+
 fail_inode:
 	return NULL;
 }
@@ -769,7 +785,7 @@ int do_pipe(int *fd)
 	struct inode * inode;
 	struct file *f1, *f2;
 	int error;
-	int i,j;
+	int i, j;
 
 	error = -ENFILE;
 	f1 = get_empty_filp();
@@ -802,6 +818,7 @@ int do_pipe(int *fd)
 	dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this);
 	if (!dentry)
 		goto close_f12_inode_i_j;
+
 	dentry->d_op = &pipefs_dentry_operations;
 	d_add(dentry, inode);
 	f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt));
@@ -825,6 +842,7 @@ int do_pipe(int *fd)
 	fd_install(j, f2);
 	fd[0] = i;
 	fd[1] = j;
+
 	return 0;
 
 close_f12_inode_i_j:
@@ -849,8 +867,9 @@ int do_pipe(int *fd)
  * d_name - pipe: will go nicely and kill the special-casing in procfs.
  */
 
-static struct super_block *pipefs_get_sb(struct file_system_type *fs_type,
-	int flags, const char *dev_name, void *data)
+static struct super_block *
+pipefs_get_sb(struct file_system_type *fs_type, int flags,
+	      const char *dev_name, void *data)
 {
 	return get_sb_pseudo(fs_type, "pipe:", NULL, PIPEFS_MAGIC);
 }
@@ -864,6 +883,7 @@ static struct file_system_type pipe_fs_type = {
 static int __init init_pipe_fs(void)
 {
 	int err = register_filesystem(&pipe_fs_type);
+
 	if (!err) {
 		pipe_mnt = kern_mount(&pipe_fs_type);
 		if (IS_ERR(pipe_mnt)) {

commit 73d62d83ec3627782ba6f55defc76f3ffbef46ee
Author: Ingo Molnar <mingo@elte.hu>
Date:   Tue Apr 11 13:57:21 2006 +0200

    [PATCH] splice: comment styles
    
     - capitalize consistently
     - end sentences in one way or another
     - update comment text to match the implementation
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: Jens Axboe <axboe@suse.de>

diff --git a/fs/splice.c b/fs/splice.c
index 48b4382cc114..e50a460239dd 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -92,7 +92,7 @@ static void *page_cache_pipe_buf_map(struct file *file,
 
 		/*
 		 * Page got truncated/unhashed. This will cause a 0-byte
-		 * splice, if this is the first page
+		 * splice, if this is the first page.
 		 */
 		if (!page->mapping) {
 			err = -ENODATA;
@@ -100,7 +100,7 @@ static void *page_cache_pipe_buf_map(struct file *file,
 		}
 
 		/*
-		 * uh oh, read-error from disk
+		 * Uh oh, read-error from disk.
 		 */
 		if (!PageUptodate(page)) {
 			err = -EIO;
@@ -108,7 +108,7 @@ static void *page_cache_pipe_buf_map(struct file *file,
 		}
 
 		/*
-		 * page is ok afterall, fall through to mapping
+		 * Page is ok afterall, fall through to mapping.
 		 */
 		unlock_page(page);
 	}
@@ -249,7 +249,7 @@ __generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe,
 		nr_pages = PIPE_BUFFERS;
 
 	/*
-	 * initiate read-ahead on this page range. however, don't call into
+	 * Initiate read-ahead on this page range. however, don't call into
 	 * read-ahead if this is a non-zero offset (we are likely doing small
 	 * chunk splice and the page is already there) for a single page.
 	 */
@@ -257,7 +257,7 @@ __generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe,
 		do_page_cache_readahead(mapping, in, index, nr_pages);
 
 	/*
-	 * now fill in the holes
+	 * Now fill in the holes:
 	 */
 	error = 0;
 	for (i = 0; i < nr_pages; i++, index++) {
@@ -396,10 +396,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *info,
 	int more;
 
 	/*
-	 * sub-optimal, but we are limited by the pipe ->map. we don't
+	 * Sub-optimal, but we are limited by the pipe ->map. We don't
 	 * need a kmap'ed buffer here, we just want to make sure we
 	 * have the page pinned if the pipe page originates from the
-	 * page cache
+	 * page cache.
 	 */
 	ptr = buf->ops->map(file, info, buf);
 	if (IS_ERR(ptr))
@@ -460,7 +460,7 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
 	offset = sd->pos & ~PAGE_CACHE_MASK;
 
 	/*
-	 * reuse buf page, if SPLICE_F_MOVE is set
+	 * Reuse buf page, if SPLICE_F_MOVE is set.
 	 */
 	if (sd->flags & SPLICE_F_MOVE) {
 		/*
@@ -501,7 +501,7 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
 
 				if (!PageUptodate(page)) {
 					/*
-					 * page got invalidated, repeat
+					 * Page got invalidated, repeat.
 					 */
 					if (!page->mapping) {
 						unlock_page(page);
@@ -598,6 +598,7 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out,
 			ret += sd.len;
 			buf->offset += sd.len;
 			buf->len -= sd.len;
+
 			if (!buf->len) {
 				buf->ops = NULL;
 				ops->release(pipe, buf);
@@ -681,7 +682,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
 	ret = move_from_pipe(pipe, out, len, flags, pipe_to_file);
 
 	/*
-	 * if file or inode is SYNC and we actually wrote some data, sync it
+	 * If file or inode is SYNC and we actually wrote some data, sync it.
 	 */
 	if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(mapping->host))
 	    && ret > 0) {
@@ -815,7 +816,7 @@ long do_splice_direct(struct file *in, struct file *out, size_t len,
 	}
 
 	/*
-	 * do the splice
+	 * Do the splice.
 	 */
 	ret = 0;
 	bytes = 0;

commit 923f4f23940d2361e8d5c4245982163a8e9d1c91
Author: Ingo Molnar <mingo@elte.hu>
Date:   Tue Apr 11 13:53:33 2006 +0200

    [PATCH] pipe.c/fifo.c code cleanups
    
    more code cleanups after the macro conversion:
    
     - standardize on 'struct pipe_inode_info *pipe' variable names
     - introduce 'pipe' temporaries to reduce mass inode->i_pipe dereferencing
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: Jens Axboe <axboe@suse.de>

diff --git a/fs/fifo.c b/fs/fifo.c
index 2c27f56d7304..49035b174b48 100644
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -33,14 +33,17 @@ static void wake_up_partner(struct inode* inode)
 
 static int fifo_open(struct inode *inode, struct file *filp)
 {
+	struct pipe_inode_info *pipe;
 	int ret;
 
 	mutex_lock(&inode->i_mutex);
-	if (!inode->i_pipe) {
+	pipe = inode->i_pipe;
+	if (!pipe) {
 		ret = -ENOMEM;
-		inode->i_pipe = alloc_pipe_info(inode);
-		if (!inode->i_pipe)
+		pipe = alloc_pipe_info(inode);
+		if (!pipe)
 			goto err_nocleanup;
+		inode->i_pipe = pipe;
 	}
 	filp->f_version = 0;
 
@@ -55,18 +58,18 @@ static int fifo_open(struct inode *inode, struct file *filp)
 	 *  opened, even when there is no process writing the FIFO.
 	 */
 		filp->f_op = &read_fifo_fops;
-		inode->i_pipe->r_counter++;
-		if (inode->i_pipe->readers++ == 0)
+		pipe->r_counter++;
+		if (pipe->readers++ == 0)
 			wake_up_partner(inode);
 
-		if (!inode->i_pipe->writers) {
+		if (!pipe->writers) {
 			if ((filp->f_flags & O_NONBLOCK)) {
 				/* suppress POLLHUP until we have
 				 * seen a writer */
-				filp->f_version = inode->i_pipe->w_counter;
+				filp->f_version = pipe->w_counter;
 			} else 
 			{
-				wait_for_partner(inode, &inode->i_pipe->w_counter);
+				wait_for_partner(inode, &pipe->w_counter);
 				if(signal_pending(current))
 					goto err_rd;
 			}
@@ -80,16 +83,16 @@ static int fifo_open(struct inode *inode, struct file *filp)
 	 *  errno=ENXIO when there is no process reading the FIFO.
 	 */
 		ret = -ENXIO;
-		if ((filp->f_flags & O_NONBLOCK) && !inode->i_pipe->readers)
+		if ((filp->f_flags & O_NONBLOCK) && !pipe->readers)
 			goto err;
 
 		filp->f_op = &write_fifo_fops;
-		inode->i_pipe->w_counter++;
-		if (!inode->i_pipe->writers++)
+		pipe->w_counter++;
+		if (!pipe->writers++)
 			wake_up_partner(inode);
 
-		if (!inode->i_pipe->readers) {
-			wait_for_partner(inode, &inode->i_pipe->r_counter);
+		if (!pipe->readers) {
+			wait_for_partner(inode, &pipe->r_counter);
 			if (signal_pending(current))
 				goto err_wr;
 		}
@@ -104,11 +107,11 @@ static int fifo_open(struct inode *inode, struct file *filp)
 	 */
 		filp->f_op = &rdwr_fifo_fops;
 
-		inode->i_pipe->readers++;
-		inode->i_pipe->writers++;
-		inode->i_pipe->r_counter++;
-		inode->i_pipe->w_counter++;
-		if (inode->i_pipe->readers == 1 || inode->i_pipe->writers == 1)
+		pipe->readers++;
+		pipe->writers++;
+		pipe->r_counter++;
+		pipe->w_counter++;
+		if (pipe->readers == 1 || pipe->writers == 1)
 			wake_up_partner(inode);
 		break;
 
@@ -122,19 +125,19 @@ static int fifo_open(struct inode *inode, struct file *filp)
 	return 0;
 
 err_rd:
-	if (!--inode->i_pipe->readers)
-		wake_up_interruptible(&inode->i_pipe->wait);
+	if (!--pipe->readers)
+		wake_up_interruptible(&pipe->wait);
 	ret = -ERESTARTSYS;
 	goto err;
 
 err_wr:
-	if (!--inode->i_pipe->writers)
-		wake_up_interruptible(&inode->i_pipe->wait);
+	if (!--pipe->writers)
+		wake_up_interruptible(&pipe->wait);
 	ret = -ERESTARTSYS;
 	goto err;
 
 err:
-	if (!inode->i_pipe->readers && !inode->i_pipe->writers)
+	if (!pipe->readers && !pipe->writers)
 		free_pipe_info(inode);
 
 err_nocleanup:
diff --git a/fs/pipe.c b/fs/pipe.c
index 0602fc9f7eba..b941e1951eac 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -93,7 +93,7 @@ pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len)
 	return 0;
 }
 
-static void anon_pipe_buf_release(struct pipe_inode_info *info, struct pipe_buffer *buf)
+static void anon_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
 {
 	struct page *page = buf->page;
 
@@ -104,8 +104,8 @@ static void anon_pipe_buf_release(struct pipe_inode_info *info, struct pipe_buff
 	 * temporary page, let's keep track of it as a one-deep
 	 * allocation cache
 	 */
-	if (page_count(page) == 1 && !info->tmp_page) {
-		info->tmp_page = page;
+	if (page_count(page) == 1 && !pipe->tmp_page) {
+		pipe->tmp_page = page;
 		return;
 	}
 
@@ -115,17 +115,17 @@ static void anon_pipe_buf_release(struct pipe_inode_info *info, struct pipe_buff
 	page_cache_release(page);
 }
 
-static void *anon_pipe_buf_map(struct file *file, struct pipe_inode_info *info, struct pipe_buffer *buf)
+static void *anon_pipe_buf_map(struct file *file, struct pipe_inode_info *pipe, struct pipe_buffer *buf)
 {
 	return kmap(buf->page);
 }
 
-static void anon_pipe_buf_unmap(struct pipe_inode_info *info, struct pipe_buffer *buf)
+static void anon_pipe_buf_unmap(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
 {
 	kunmap(buf->page);
 }
 
-static int anon_pipe_buf_steal(struct pipe_inode_info *info,
+static int anon_pipe_buf_steal(struct pipe_inode_info *pipe,
 			       struct pipe_buffer *buf)
 {
 	buf->flags |= PIPE_BUF_FLAG_STOLEN;
@@ -145,7 +145,7 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
 	   unsigned long nr_segs, loff_t *ppos)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
-	struct pipe_inode_info *info;
+	struct pipe_inode_info *pipe;
 	int do_wakeup;
 	ssize_t ret;
 	struct iovec *iov = (struct iovec *)_iov;
@@ -159,12 +159,12 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
 	do_wakeup = 0;
 	ret = 0;
 	mutex_lock(&inode->i_mutex);
-	info = inode->i_pipe;
+	pipe = inode->i_pipe;
 	for (;;) {
-		int bufs = info->nrbufs;
+		int bufs = pipe->nrbufs;
 		if (bufs) {
-			int curbuf = info->curbuf;
-			struct pipe_buffer *buf = info->bufs + curbuf;
+			int curbuf = pipe->curbuf;
+			struct pipe_buffer *buf = pipe->bufs + curbuf;
 			struct pipe_buf_operations *ops = buf->ops;
 			void *addr;
 			size_t chars = buf->len;
@@ -173,14 +173,14 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
 			if (chars > total_len)
 				chars = total_len;
 
-			addr = ops->map(filp, info, buf);
+			addr = ops->map(filp, pipe, buf);
 			if (IS_ERR(addr)) {
 				if (!ret)
 					ret = PTR_ERR(addr);
 				break;
 			}
 			error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars);
-			ops->unmap(info, buf);
+			ops->unmap(pipe, buf);
 			if (unlikely(error)) {
 				if (!ret) ret = -EFAULT;
 				break;
@@ -190,10 +190,10 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
 			buf->len -= chars;
 			if (!buf->len) {
 				buf->ops = NULL;
-				ops->release(info, buf);
+				ops->release(pipe, buf);
 				curbuf = (curbuf + 1) & (PIPE_BUFFERS-1);
-				info->curbuf = curbuf;
-				info->nrbufs = --bufs;
+				pipe->curbuf = curbuf;
+				pipe->nrbufs = --bufs;
 				do_wakeup = 1;
 			}
 			total_len -= chars;
@@ -202,9 +202,9 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
 		}
 		if (bufs)	/* More to do? */
 			continue;
-		if (!inode->i_pipe->writers)
+		if (!pipe->writers)
 			break;
-		if (!inode->i_pipe->waiting_writers) {
+		if (!pipe->waiting_writers) {
 			/* syscall merging: Usually we must not sleep
 			 * if O_NONBLOCK is set, or if we got some data.
 			 * But if a writer sleeps in kernel space, then
@@ -222,16 +222,16 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
 			break;
 		}
 		if (do_wakeup) {
-			wake_up_interruptible_sync(&inode->i_pipe->wait);
- 			kill_fasync(&inode->i_pipe->fasync_writers, SIGIO, POLL_OUT);
+			wake_up_interruptible_sync(&pipe->wait);
+ 			kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
 		}
-		pipe_wait(inode->i_pipe);
+		pipe_wait(pipe);
 	}
 	mutex_unlock(&inode->i_mutex);
 	/* Signal writers asynchronously that there is more room.  */
 	if (do_wakeup) {
-		wake_up_interruptible(&inode->i_pipe->wait);
-		kill_fasync(&inode->i_pipe->fasync_writers, SIGIO, POLL_OUT);
+		wake_up_interruptible(&pipe->wait);
+		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
 	}
 	if (ret > 0)
 		file_accessed(filp);
@@ -250,7 +250,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 	    unsigned long nr_segs, loff_t *ppos)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
-	struct pipe_inode_info *info;
+	struct pipe_inode_info *pipe;
 	ssize_t ret;
 	int do_wakeup;
 	struct iovec *iov = (struct iovec *)_iov;
@@ -265,9 +265,9 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 	do_wakeup = 0;
 	ret = 0;
 	mutex_lock(&inode->i_mutex);
-	info = inode->i_pipe;
+	pipe = inode->i_pipe;
 
-	if (!inode->i_pipe->readers) {
+	if (!pipe->readers) {
 		send_sig(SIGPIPE, current, 0);
 		ret = -EPIPE;
 		goto out;
@@ -275,23 +275,23 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 
 	/* We try to merge small writes */
 	chars = total_len & (PAGE_SIZE-1); /* size of the last buffer */
-	if (info->nrbufs && chars != 0) {
-		int lastbuf = (info->curbuf + info->nrbufs - 1) & (PIPE_BUFFERS-1);
-		struct pipe_buffer *buf = info->bufs + lastbuf;
+	if (pipe->nrbufs && chars != 0) {
+		int lastbuf = (pipe->curbuf + pipe->nrbufs - 1) & (PIPE_BUFFERS-1);
+		struct pipe_buffer *buf = pipe->bufs + lastbuf;
 		struct pipe_buf_operations *ops = buf->ops;
 		int offset = buf->offset + buf->len;
 		if (ops->can_merge && offset + chars <= PAGE_SIZE) {
 			void *addr;
 			int error;
 
-			addr = ops->map(filp, info, buf);
+			addr = ops->map(filp, pipe, buf);
 			if (IS_ERR(addr)) {
 				error = PTR_ERR(addr);
 				goto out;
 			}
 			error = pipe_iov_copy_from_user(offset + addr, iov,
 							chars);
-			ops->unmap(info, buf);
+			ops->unmap(pipe, buf);
 			ret = error;
 			do_wakeup = 1;
 			if (error)
@@ -306,16 +306,16 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 
 	for (;;) {
 		int bufs;
-		if (!inode->i_pipe->readers) {
+		if (!pipe->readers) {
 			send_sig(SIGPIPE, current, 0);
 			if (!ret) ret = -EPIPE;
 			break;
 		}
-		bufs = info->nrbufs;
+		bufs = pipe->nrbufs;
 		if (bufs < PIPE_BUFFERS) {
-			int newbuf = (info->curbuf + bufs) & (PIPE_BUFFERS-1);
-			struct pipe_buffer *buf = info->bufs + newbuf;
-			struct page *page = info->tmp_page;
+			int newbuf = (pipe->curbuf + bufs) & (PIPE_BUFFERS-1);
+			struct pipe_buffer *buf = pipe->bufs + newbuf;
+			struct page *page = pipe->tmp_page;
 			int error;
 
 			if (!page) {
@@ -324,7 +324,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 					ret = ret ? : -ENOMEM;
 					break;
 				}
-				info->tmp_page = page;
+				pipe->tmp_page = page;
 			}
 			/* Always wakeup, even if the copy fails. Otherwise
 			 * we lock up (O_NONBLOCK-)readers that sleep due to
@@ -349,8 +349,8 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 			buf->ops = &anon_pipe_buf_ops;
 			buf->offset = 0;
 			buf->len = chars;
-			info->nrbufs = ++bufs;
-			info->tmp_page = NULL;
+			pipe->nrbufs = ++bufs;
+			pipe->tmp_page = NULL;
 
 			total_len -= chars;
 			if (!total_len)
@@ -367,19 +367,19 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 			break;
 		}
 		if (do_wakeup) {
-			wake_up_interruptible_sync(&inode->i_pipe->wait);
-			kill_fasync(&inode->i_pipe->fasync_readers, SIGIO, POLL_IN);
+			wake_up_interruptible_sync(&pipe->wait);
+			kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
 			do_wakeup = 0;
 		}
-		inode->i_pipe->waiting_writers++;
-		pipe_wait(inode->i_pipe);
-		inode->i_pipe->waiting_writers--;
+		pipe->waiting_writers++;
+		pipe_wait(pipe);
+		pipe->waiting_writers--;
 	}
 out:
 	mutex_unlock(&inode->i_mutex);
 	if (do_wakeup) {
-		wake_up_interruptible(&inode->i_pipe->wait);
-		kill_fasync(&inode->i_pipe->fasync_readers, SIGIO, POLL_IN);
+		wake_up_interruptible(&pipe->wait);
+		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
 	}
 	if (ret > 0)
 		file_update_time(filp);
@@ -411,21 +411,22 @@ pipe_ioctl(struct inode *pino, struct file *filp,
 	   unsigned int cmd, unsigned long arg)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
-	struct pipe_inode_info *info;
+	struct pipe_inode_info *pipe;
 	int count, buf, nrbufs;
 
 	switch (cmd) {
 		case FIONREAD:
 			mutex_lock(&inode->i_mutex);
-			info =  inode->i_pipe;
+			pipe = inode->i_pipe;
 			count = 0;
-			buf = info->curbuf;
-			nrbufs = info->nrbufs;
+			buf = pipe->curbuf;
+			nrbufs = pipe->nrbufs;
 			while (--nrbufs >= 0) {
-				count += info->bufs[buf].len;
+				count += pipe->bufs[buf].len;
 				buf = (buf+1) & (PIPE_BUFFERS-1);
 			}
 			mutex_unlock(&inode->i_mutex);
+
 			return put_user(count, (int __user *)arg);
 		default:
 			return -EINVAL;
@@ -438,17 +439,17 @@ pipe_poll(struct file *filp, poll_table *wait)
 {
 	unsigned int mask;
 	struct inode *inode = filp->f_dentry->d_inode;
-	struct pipe_inode_info *info = inode->i_pipe;
+	struct pipe_inode_info *pipe = inode->i_pipe;
 	int nrbufs;
 
-	poll_wait(filp, &inode->i_pipe->wait, wait);
+	poll_wait(filp, &pipe->wait, wait);
 
 	/* Reading only -- no need for acquiring the semaphore.  */
-	nrbufs = info->nrbufs;
+	nrbufs = pipe->nrbufs;
 	mask = 0;
 	if (filp->f_mode & FMODE_READ) {
 		mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0;
-		if (!inode->i_pipe->writers && filp->f_version != inode->i_pipe->w_counter)
+		if (!pipe->writers && filp->f_version != pipe->w_counter)
 			mask |= POLLHUP;
 	}
 
@@ -458,7 +459,7 @@ pipe_poll(struct file *filp, poll_table *wait)
 		 * Most Unices do not set POLLERR for FIFOs but on Linux they
 		 * behave exactly like pipes for poll().
 		 */
-		if (!inode->i_pipe->readers)
+		if (!pipe->readers)
 			mask |= POLLERR;
 	}
 
@@ -468,15 +469,18 @@ pipe_poll(struct file *filp, poll_table *wait)
 static int
 pipe_release(struct inode *inode, int decr, int decw)
 {
+	struct pipe_inode_info *pipe;
+
 	mutex_lock(&inode->i_mutex);
-	inode->i_pipe->readers -= decr;
-	inode->i_pipe->writers -= decw;
-	if (!inode->i_pipe->readers && !inode->i_pipe->writers) {
+	pipe = inode->i_pipe;
+	pipe->readers -= decr;
+	pipe->writers -= decw;
+	if (!pipe->readers && !pipe->writers) {
 		free_pipe_info(inode);
 	} else {
-		wake_up_interruptible(&inode->i_pipe->wait);
-		kill_fasync(&inode->i_pipe->fasync_readers, SIGIO, POLL_IN);
-		kill_fasync(&inode->i_pipe->fasync_writers, SIGIO, POLL_OUT);
+		wake_up_interruptible(&pipe->wait);
+		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
+		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
 	}
 	mutex_unlock(&inode->i_mutex);
 
@@ -679,30 +683,30 @@ static struct file_operations rdwr_pipe_fops = {
 
 struct pipe_inode_info * alloc_pipe_info(struct inode *inode)
 {
-	struct pipe_inode_info *info;
+	struct pipe_inode_info *pipe;
 
-	info = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
-	if (info) {
-		init_waitqueue_head(&info->wait);
-		info->r_counter = info->w_counter = 1;
-		info->inode = inode;
+	pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
+	if (pipe) {
+		init_waitqueue_head(&pipe->wait);
+		pipe->r_counter = pipe->w_counter = 1;
+		pipe->inode = inode;
 	}
 
-	return info;
+	return pipe;
 }
 
-void __free_pipe_info(struct pipe_inode_info *info)
+void __free_pipe_info(struct pipe_inode_info *pipe)
 {
 	int i;
 
 	for (i = 0; i < PIPE_BUFFERS; i++) {
-		struct pipe_buffer *buf = info->bufs + i;
+		struct pipe_buffer *buf = pipe->bufs + i;
 		if (buf->ops)
-			buf->ops->release(info, buf);
+			buf->ops->release(pipe, buf);
 	}
-	if (info->tmp_page)
-		__free_page(info->tmp_page);
-	kfree(info);
+	if (pipe->tmp_page)
+		__free_page(pipe->tmp_page);
+	kfree(pipe);
 }
 
 void free_pipe_info(struct inode *inode)
@@ -723,15 +727,17 @@ static struct dentry_operations pipefs_dentry_operations = {
 static struct inode * get_pipe_inode(void)
 {
 	struct inode *inode = new_inode(pipe_mnt->mnt_sb);
+	struct pipe_inode_info *pipe;
 
 	if (!inode)
 		goto fail_inode;
 
-	inode->i_pipe = alloc_pipe_info(inode);
-	if (!inode->i_pipe)
+	pipe = alloc_pipe_info(inode);
+	if (!pipe)
 		goto fail_iput;
+	inode->i_pipe = pipe;
 
-	inode->i_pipe->readers = inode->i_pipe->writers = 1;
+	pipe->readers = pipe->writers = 1;
 	inode->i_fop = &rdwr_pipe_fops;
 
 	/*
@@ -746,6 +752,7 @@ static struct inode * get_pipe_inode(void)
 	inode->i_gid = current->fsgid;
 	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	inode->i_blksize = PAGE_SIZE;
+
 	return inode;
 
 fail_iput:

commit 9aeedfc4712ed58d9f7ae41596185c72b8dc97e8
Author: Ingo Molnar <mingo@elte.hu>
Date:   Tue Apr 11 13:53:10 2006 +0200

    [PATCH] get rid of the PIPE_*() macros
    
    get rid of the PIPE_*() macros. Scripted transformation.
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: Jens Axboe <axboe@suse.de>

diff --git a/fs/fifo.c b/fs/fifo.c
index b16e2f597d61..2c27f56d7304 100644
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -28,14 +28,14 @@ static void wait_for_partner(struct inode* inode, unsigned int *cnt)
 
 static void wake_up_partner(struct inode* inode)
 {
-	wake_up_interruptible(PIPE_WAIT(*inode));
+	wake_up_interruptible(&inode->i_pipe->wait);
 }
 
 static int fifo_open(struct inode *inode, struct file *filp)
 {
 	int ret;
 
-	mutex_lock(PIPE_MUTEX(*inode));
+	mutex_lock(&inode->i_mutex);
 	if (!inode->i_pipe) {
 		ret = -ENOMEM;
 		inode->i_pipe = alloc_pipe_info(inode);
@@ -55,18 +55,18 @@ static int fifo_open(struct inode *inode, struct file *filp)
 	 *  opened, even when there is no process writing the FIFO.
 	 */
 		filp->f_op = &read_fifo_fops;
-		PIPE_RCOUNTER(*inode)++;
-		if (PIPE_READERS(*inode)++ == 0)
+		inode->i_pipe->r_counter++;
+		if (inode->i_pipe->readers++ == 0)
 			wake_up_partner(inode);
 
-		if (!PIPE_WRITERS(*inode)) {
+		if (!inode->i_pipe->writers) {
 			if ((filp->f_flags & O_NONBLOCK)) {
 				/* suppress POLLHUP until we have
 				 * seen a writer */
-				filp->f_version = PIPE_WCOUNTER(*inode);
+				filp->f_version = inode->i_pipe->w_counter;
 			} else 
 			{
-				wait_for_partner(inode, &PIPE_WCOUNTER(*inode));
+				wait_for_partner(inode, &inode->i_pipe->w_counter);
 				if(signal_pending(current))
 					goto err_rd;
 			}
@@ -80,16 +80,16 @@ static int fifo_open(struct inode *inode, struct file *filp)
 	 *  errno=ENXIO when there is no process reading the FIFO.
 	 */
 		ret = -ENXIO;
-		if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode))
+		if ((filp->f_flags & O_NONBLOCK) && !inode->i_pipe->readers)
 			goto err;
 
 		filp->f_op = &write_fifo_fops;
-		PIPE_WCOUNTER(*inode)++;
-		if (!PIPE_WRITERS(*inode)++)
+		inode->i_pipe->w_counter++;
+		if (!inode->i_pipe->writers++)
 			wake_up_partner(inode);
 
-		if (!PIPE_READERS(*inode)) {
-			wait_for_partner(inode, &PIPE_RCOUNTER(*inode));
+		if (!inode->i_pipe->readers) {
+			wait_for_partner(inode, &inode->i_pipe->r_counter);
 			if (signal_pending(current))
 				goto err_wr;
 		}
@@ -104,11 +104,11 @@ static int fifo_open(struct inode *inode, struct file *filp)
 	 */
 		filp->f_op = &rdwr_fifo_fops;
 
-		PIPE_READERS(*inode)++;
-		PIPE_WRITERS(*inode)++;
-		PIPE_RCOUNTER(*inode)++;
-		PIPE_WCOUNTER(*inode)++;
-		if (PIPE_READERS(*inode) == 1 || PIPE_WRITERS(*inode) == 1)
+		inode->i_pipe->readers++;
+		inode->i_pipe->writers++;
+		inode->i_pipe->r_counter++;
+		inode->i_pipe->w_counter++;
+		if (inode->i_pipe->readers == 1 || inode->i_pipe->writers == 1)
 			wake_up_partner(inode);
 		break;
 
@@ -118,27 +118,27 @@ static int fifo_open(struct inode *inode, struct file *filp)
 	}
 
 	/* Ok! */
-	mutex_unlock(PIPE_MUTEX(*inode));
+	mutex_unlock(&inode->i_mutex);
 	return 0;
 
 err_rd:
-	if (!--PIPE_READERS(*inode))
-		wake_up_interruptible(PIPE_WAIT(*inode));
+	if (!--inode->i_pipe->readers)
+		wake_up_interruptible(&inode->i_pipe->wait);
 	ret = -ERESTARTSYS;
 	goto err;
 
 err_wr:
-	if (!--PIPE_WRITERS(*inode))
-		wake_up_interruptible(PIPE_WAIT(*inode));
+	if (!--inode->i_pipe->writers)
+		wake_up_interruptible(&inode->i_pipe->wait);
 	ret = -ERESTARTSYS;
 	goto err;
 
 err:
-	if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode))
+	if (!inode->i_pipe->readers && !inode->i_pipe->writers)
 		free_pipe_info(inode);
 
 err_nocleanup:
-	mutex_unlock(PIPE_MUTEX(*inode));
+	mutex_unlock(&inode->i_mutex);
 	return ret;
 }
 
diff --git a/fs/pipe.c b/fs/pipe.c
index 036536f072c9..0602fc9f7eba 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -158,7 +158,7 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
 
 	do_wakeup = 0;
 	ret = 0;
-	mutex_lock(PIPE_MUTEX(*inode));
+	mutex_lock(&inode->i_mutex);
 	info = inode->i_pipe;
 	for (;;) {
 		int bufs = info->nrbufs;
@@ -202,9 +202,9 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
 		}
 		if (bufs)	/* More to do? */
 			continue;
-		if (!PIPE_WRITERS(*inode))
+		if (!inode->i_pipe->writers)
 			break;
-		if (!PIPE_WAITING_WRITERS(*inode)) {
+		if (!inode->i_pipe->waiting_writers) {
 			/* syscall merging: Usually we must not sleep
 			 * if O_NONBLOCK is set, or if we got some data.
 			 * But if a writer sleeps in kernel space, then
@@ -222,16 +222,16 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
 			break;
 		}
 		if (do_wakeup) {
-			wake_up_interruptible_sync(PIPE_WAIT(*inode));
- 			kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
+			wake_up_interruptible_sync(&inode->i_pipe->wait);
+ 			kill_fasync(&inode->i_pipe->fasync_writers, SIGIO, POLL_OUT);
 		}
 		pipe_wait(inode->i_pipe);
 	}
-	mutex_unlock(PIPE_MUTEX(*inode));
+	mutex_unlock(&inode->i_mutex);
 	/* Signal writers asynchronously that there is more room.  */
 	if (do_wakeup) {
-		wake_up_interruptible(PIPE_WAIT(*inode));
-		kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
+		wake_up_interruptible(&inode->i_pipe->wait);
+		kill_fasync(&inode->i_pipe->fasync_writers, SIGIO, POLL_OUT);
 	}
 	if (ret > 0)
 		file_accessed(filp);
@@ -264,10 +264,10 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 
 	do_wakeup = 0;
 	ret = 0;
-	mutex_lock(PIPE_MUTEX(*inode));
+	mutex_lock(&inode->i_mutex);
 	info = inode->i_pipe;
 
-	if (!PIPE_READERS(*inode)) {
+	if (!inode->i_pipe->readers) {
 		send_sig(SIGPIPE, current, 0);
 		ret = -EPIPE;
 		goto out;
@@ -306,7 +306,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 
 	for (;;) {
 		int bufs;
-		if (!PIPE_READERS(*inode)) {
+		if (!inode->i_pipe->readers) {
 			send_sig(SIGPIPE, current, 0);
 			if (!ret) ret = -EPIPE;
 			break;
@@ -367,19 +367,19 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 			break;
 		}
 		if (do_wakeup) {
-			wake_up_interruptible_sync(PIPE_WAIT(*inode));
-			kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
+			wake_up_interruptible_sync(&inode->i_pipe->wait);
+			kill_fasync(&inode->i_pipe->fasync_readers, SIGIO, POLL_IN);
 			do_wakeup = 0;
 		}
-		PIPE_WAITING_WRITERS(*inode)++;
+		inode->i_pipe->waiting_writers++;
 		pipe_wait(inode->i_pipe);
-		PIPE_WAITING_WRITERS(*inode)--;
+		inode->i_pipe->waiting_writers--;
 	}
 out:
-	mutex_unlock(PIPE_MUTEX(*inode));
+	mutex_unlock(&inode->i_mutex);
 	if (do_wakeup) {
-		wake_up_interruptible(PIPE_WAIT(*inode));
-		kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
+		wake_up_interruptible(&inode->i_pipe->wait);
+		kill_fasync(&inode->i_pipe->fasync_readers, SIGIO, POLL_IN);
 	}
 	if (ret > 0)
 		file_update_time(filp);
@@ -416,7 +416,7 @@ pipe_ioctl(struct inode *pino, struct file *filp,
 
 	switch (cmd) {
 		case FIONREAD:
-			mutex_lock(PIPE_MUTEX(*inode));
+			mutex_lock(&inode->i_mutex);
 			info =  inode->i_pipe;
 			count = 0;
 			buf = info->curbuf;
@@ -425,7 +425,7 @@ pipe_ioctl(struct inode *pino, struct file *filp,
 				count += info->bufs[buf].len;
 				buf = (buf+1) & (PIPE_BUFFERS-1);
 			}
-			mutex_unlock(PIPE_MUTEX(*inode));
+			mutex_unlock(&inode->i_mutex);
 			return put_user(count, (int __user *)arg);
 		default:
 			return -EINVAL;
@@ -441,14 +441,14 @@ pipe_poll(struct file *filp, poll_table *wait)
 	struct pipe_inode_info *info = inode->i_pipe;
 	int nrbufs;
 
-	poll_wait(filp, PIPE_WAIT(*inode), wait);
+	poll_wait(filp, &inode->i_pipe->wait, wait);
 
 	/* Reading only -- no need for acquiring the semaphore.  */
 	nrbufs = info->nrbufs;
 	mask = 0;
 	if (filp->f_mode & FMODE_READ) {
 		mask = (nrbufs > 0) ? POLLIN | POLLRDNORM : 0;
-		if (!PIPE_WRITERS(*inode) && filp->f_version != PIPE_WCOUNTER(*inode))
+		if (!inode->i_pipe->writers && filp->f_version != inode->i_pipe->w_counter)
 			mask |= POLLHUP;
 	}
 
@@ -458,7 +458,7 @@ pipe_poll(struct file *filp, poll_table *wait)
 		 * Most Unices do not set POLLERR for FIFOs but on Linux they
 		 * behave exactly like pipes for poll().
 		 */
-		if (!PIPE_READERS(*inode))
+		if (!inode->i_pipe->readers)
 			mask |= POLLERR;
 	}
 
@@ -468,17 +468,17 @@ pipe_poll(struct file *filp, poll_table *wait)
 static int
 pipe_release(struct inode *inode, int decr, int decw)
 {
-	mutex_lock(PIPE_MUTEX(*inode));
-	PIPE_READERS(*inode) -= decr;
-	PIPE_WRITERS(*inode) -= decw;
-	if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {
+	mutex_lock(&inode->i_mutex);
+	inode->i_pipe->readers -= decr;
+	inode->i_pipe->writers -= decw;
+	if (!inode->i_pipe->readers && !inode->i_pipe->writers) {
 		free_pipe_info(inode);
 	} else {
-		wake_up_interruptible(PIPE_WAIT(*inode));
-		kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
-		kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
+		wake_up_interruptible(&inode->i_pipe->wait);
+		kill_fasync(&inode->i_pipe->fasync_readers, SIGIO, POLL_IN);
+		kill_fasync(&inode->i_pipe->fasync_writers, SIGIO, POLL_OUT);
 	}
-	mutex_unlock(PIPE_MUTEX(*inode));
+	mutex_unlock(&inode->i_mutex);
 
 	return 0;
 }
@@ -489,9 +489,9 @@ pipe_read_fasync(int fd, struct file *filp, int on)
 	struct inode *inode = filp->f_dentry->d_inode;
 	int retval;
 
-	mutex_lock(PIPE_MUTEX(*inode));
-	retval = fasync_helper(fd, filp, on, PIPE_FASYNC_READERS(*inode));
-	mutex_unlock(PIPE_MUTEX(*inode));
+	mutex_lock(&inode->i_mutex);
+	retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers);
+	mutex_unlock(&inode->i_mutex);
 
 	if (retval < 0)
 		return retval;
@@ -506,9 +506,9 @@ pipe_write_fasync(int fd, struct file *filp, int on)
 	struct inode *inode = filp->f_dentry->d_inode;
 	int retval;
 
-	mutex_lock(PIPE_MUTEX(*inode));
-	retval = fasync_helper(fd, filp, on, PIPE_FASYNC_WRITERS(*inode));
-	mutex_unlock(PIPE_MUTEX(*inode));
+	mutex_lock(&inode->i_mutex);
+	retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers);
+	mutex_unlock(&inode->i_mutex);
 
 	if (retval < 0)
 		return retval;
@@ -523,14 +523,14 @@ pipe_rdwr_fasync(int fd, struct file *filp, int on)
 	struct inode *inode = filp->f_dentry->d_inode;
 	int retval;
 
-	mutex_lock(PIPE_MUTEX(*inode));
+	mutex_lock(&inode->i_mutex);
 
-	retval = fasync_helper(fd, filp, on, PIPE_FASYNC_READERS(*inode));
+	retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_readers);
 
 	if (retval >= 0)
-		retval = fasync_helper(fd, filp, on, PIPE_FASYNC_WRITERS(*inode));
+		retval = fasync_helper(fd, filp, on, &inode->i_pipe->fasync_writers);
 
-	mutex_unlock(PIPE_MUTEX(*inode));
+	mutex_unlock(&inode->i_mutex);
 
 	if (retval < 0)
 		return retval;
@@ -569,9 +569,9 @@ pipe_read_open(struct inode *inode, struct file *filp)
 {
 	/* We could have perhaps used atomic_t, but this and friends
 	   below are the only places.  So it doesn't seem worthwhile.  */
-	mutex_lock(PIPE_MUTEX(*inode));
-	PIPE_READERS(*inode)++;
-	mutex_unlock(PIPE_MUTEX(*inode));
+	mutex_lock(&inode->i_mutex);
+	inode->i_pipe->readers++;
+	mutex_unlock(&inode->i_mutex);
 
 	return 0;
 }
@@ -579,9 +579,9 @@ pipe_read_open(struct inode *inode, struct file *filp)
 static int
 pipe_write_open(struct inode *inode, struct file *filp)
 {
-	mutex_lock(PIPE_MUTEX(*inode));
-	PIPE_WRITERS(*inode)++;
-	mutex_unlock(PIPE_MUTEX(*inode));
+	mutex_lock(&inode->i_mutex);
+	inode->i_pipe->writers++;
+	mutex_unlock(&inode->i_mutex);
 
 	return 0;
 }
@@ -589,12 +589,12 @@ pipe_write_open(struct inode *inode, struct file *filp)
 static int
 pipe_rdwr_open(struct inode *inode, struct file *filp)
 {
-	mutex_lock(PIPE_MUTEX(*inode));
+	mutex_lock(&inode->i_mutex);
 	if (filp->f_mode & FMODE_READ)
-		PIPE_READERS(*inode)++;
+		inode->i_pipe->readers++;
 	if (filp->f_mode & FMODE_WRITE)
-		PIPE_WRITERS(*inode)++;
-	mutex_unlock(PIPE_MUTEX(*inode));
+		inode->i_pipe->writers++;
+	mutex_unlock(&inode->i_mutex);
 
 	return 0;
 }
@@ -731,7 +731,7 @@ static struct inode * get_pipe_inode(void)
 	if (!inode->i_pipe)
 		goto fail_iput;
 
-	PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
+	inode->i_pipe->readers = inode->i_pipe->writers = 1;
 	inode->i_fop = &rdwr_pipe_fops;
 
 	/*
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index 660e9d866e5d..123a7c24bc72 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -43,16 +43,6 @@ struct pipe_inode_info {
    memory allocation, whereas PIPE_BUF makes atomicity guarantees.  */
 #define PIPE_SIZE		PAGE_SIZE
 
-#define PIPE_MUTEX(inode)	(&(inode).i_mutex)
-#define PIPE_WAIT(inode)	(&(inode).i_pipe->wait)
-#define PIPE_READERS(inode)	((inode).i_pipe->readers)
-#define PIPE_WRITERS(inode)	((inode).i_pipe->writers)
-#define PIPE_WAITING_WRITERS(inode)	((inode).i_pipe->waiting_writers)
-#define PIPE_RCOUNTER(inode)	((inode).i_pipe->r_counter)
-#define PIPE_WCOUNTER(inode)	((inode).i_pipe->w_counter)
-#define PIPE_FASYNC_READERS(inode)     (&((inode).i_pipe->fasync_readers))
-#define PIPE_FASYNC_WRITERS(inode)     (&((inode).i_pipe->fasync_writers))
-
 /* Drop the inode semaphore and wait for a pipe event, atomically */
 void pipe_wait(struct pipe_inode_info *pipe);
 

commit 529565dcb1581c9a1e3f6df1c1763ca3e0f0d512
Author: Ingo Molnar <mingo@elte.hu>
Date:   Mon Apr 10 15:18:58 2006 +0200

    [PATCH] splice: add optional input and output offsets
    
    add optional input and output offsets to sys_splice(), for seekable file
    descriptors:
    
     asmlinkage long sys_splice(int fd_in, loff_t __user *off_in,
                                int fd_out, loff_t __user *off_out,
                                size_t len, unsigned int flags);
    
    semantics are straightforward: f_pos will be updated with the offset
    provided by user-space, before the splice transfer is about to begin.
    Providing a NULL offset pointer means the existing f_pos will be used
    (and updated in situ).  Providing an offset for a pipe results in
    -ESPIPE. Providing an invalid offset pointer results in -EFAULT.
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: Jens Axboe <axboe@suse.de>

diff --git a/fs/splice.c b/fs/splice.c
index ed91a62402e0..a5326127aad5 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -680,7 +680,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
  * Attempt to initiate a splice from pipe to file.
  */
 static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
-			   size_t len, unsigned int flags)
+			   loff_t __user *off_out, size_t len,
+			   unsigned int flags)
 {
 	loff_t pos;
 	int ret;
@@ -691,7 +692,11 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
 	if (!(out->f_mode & FMODE_WRITE))
 		return -EBADF;
 
+	if (off_out && copy_from_user(&out->f_pos, off_out, sizeof(loff_t)))
+		return -EFAULT;
+
 	pos = out->f_pos;
+
 	ret = rw_verify_area(WRITE, out, &pos, len);
 	if (unlikely(ret < 0))
 		return ret;
@@ -702,8 +707,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
 /*
  * Attempt to initiate a splice from a file to a pipe.
  */
-static long do_splice_to(struct file *in, struct pipe_inode_info *pipe,
-			 size_t len, unsigned int flags)
+static long do_splice_to(struct file *in, loff_t __user *off_in,
+			 struct pipe_inode_info *pipe, size_t len,
+			 unsigned int flags)
 {
 	loff_t pos, isize, left;
 	int ret;
@@ -714,7 +720,11 @@ static long do_splice_to(struct file *in, struct pipe_inode_info *pipe,
 	if (!(in->f_mode & FMODE_READ))
 		return -EBADF;
 
+	if (off_in && copy_from_user(&in->f_pos, off_in, sizeof(loff_t)))
+		return -EFAULT;
+
 	pos = in->f_pos;
+
 	ret = rw_verify_area(READ, in, &pos, len);
 	if (unlikely(ret < 0))
 		return ret;
@@ -733,23 +743,39 @@ static long do_splice_to(struct file *in, struct pipe_inode_info *pipe,
 /*
  * Determine where to splice to/from.
  */
-static long do_splice(struct file *in, struct file *out, size_t len,
-		      unsigned int flags)
+static long do_splice(struct file *in, loff_t __user *off_in,
+		      struct file *out, loff_t __user *off_out,
+		      size_t len, unsigned int flags)
 {
 	struct pipe_inode_info *pipe;
 
+	if (off_out && out->f_op->llseek == no_llseek)
+		return -EINVAL;
+	if (off_in && in->f_op->llseek == no_llseek)
+		return -EINVAL;
+
 	pipe = in->f_dentry->d_inode->i_pipe;
-	if (pipe)
-		return do_splice_from(pipe, out, len, flags);
+	if (pipe) {
+		if (off_in)
+			return -ESPIPE;
+
+		return do_splice_from(pipe, out, off_out, len, flags);
+	}
 
 	pipe = out->f_dentry->d_inode->i_pipe;
-	if (pipe)
-		return do_splice_to(in, pipe, len, flags);
+	if (pipe) {
+		if (off_out)
+			return -ESPIPE;
+
+		return do_splice_to(in, off_in, pipe, len, flags);
+	}
 
 	return -EINVAL;
 }
 
-asmlinkage long sys_splice(int fdin, int fdout, size_t len, unsigned int flags)
+asmlinkage long sys_splice(int fd_in, loff_t __user *off_in,
+			   int fd_out, loff_t __user *off_out,
+			   size_t len, unsigned int flags)
 {
 	long error;
 	struct file *in, *out;
@@ -759,13 +785,15 @@ asmlinkage long sys_splice(int fdin, int fdout, size_t len, unsigned int flags)
 		return 0;
 
 	error = -EBADF;
-	in = fget_light(fdin, &fput_in);
+	in = fget_light(fd_in, &fput_in);
 	if (in) {
 		if (in->f_mode & FMODE_READ) {
-			out = fget_light(fdout, &fput_out);
+			out = fget_light(fd_out, &fput_out);
 			if (out) {
 				if (out->f_mode & FMODE_WRITE)
-					error = do_splice(in, out, len, flags);
+					error = do_splice(in, off_in,
+							  out, off_out,
+							  len, flags);
 				fput_light(out, fput_out);
 			}
 		}
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 5717147596b6..4c292faa70c9 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -569,8 +569,11 @@ asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user * filename,
 asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename,
 				   int flags, int mode);
 asmlinkage long sys_unshare(unsigned long unshare_flags);
-asmlinkage long sys_splice(int fdin, int fdout, size_t len,
-				unsigned int flags);
+
+asmlinkage long sys_splice(int fd_in, loff_t __user *off_in,
+			   int fd_out, loff_t __user *off_out,
+			   size_t len, unsigned int flags);
+
 asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
 					int flags);
 

commit 3a326a2ce88e71d00ac0d133e314a3342a7709f8
Author: Ingo Molnar <mingo@elte.hu>
Date:   Mon Apr 10 15:18:35 2006 +0200

    [PATCH] introduce a "kernel-internal pipe object" abstraction
    
    separate out the 'internal pipe object' abstraction, and make it
    usable to splice. This cleans up and fixes several aspects of the
    internal splice APIs and the pipe code:
    
     - pipes: the allocation and freeing of pipe_inode_info is now more symmetric
       and more streamlined with existing kernel practices.
    
     - splice: small micro-optimization: less pointer dereferencing in splice
       methods
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    
    Update XFS for the ->splice_read/->splice_write changes.
    
    Signed-off-by: Jens Axboe <axboe@suse.de>

diff --git a/fs/fifo.c b/fs/fifo.c
index 889f722ee36d..b16e2f597d61 100644
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -15,12 +15,13 @@
 #include <linux/fs.h>
 #include <linux/pipe_fs_i.h>
 
-static void wait_for_partner(struct inode* inode, unsigned int* cnt)
+static void wait_for_partner(struct inode* inode, unsigned int *cnt)
 {
 	int cur = *cnt;	
-	while(cur == *cnt) {
-		pipe_wait(inode);
-		if(signal_pending(current))
+
+	while (cur == *cnt) {
+		pipe_wait(inode->i_pipe);
+		if (signal_pending(current))
 			break;
 	}
 }
@@ -37,7 +38,8 @@ static int fifo_open(struct inode *inode, struct file *filp)
 	mutex_lock(PIPE_MUTEX(*inode));
 	if (!inode->i_pipe) {
 		ret = -ENOMEM;
-		if(!pipe_new(inode))
+		inode->i_pipe = alloc_pipe_info(inode);
+		if (!inode->i_pipe)
 			goto err_nocleanup;
 	}
 	filp->f_version = 0;
diff --git a/fs/pipe.c b/fs/pipe.c
index 795df987cd38..705b48692627 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -36,7 +36,7 @@
  */
 
 /* Drop the inode semaphore and wait for a pipe event, atomically */
-void pipe_wait(struct inode * inode)
+void pipe_wait(struct pipe_inode_info *pipe)
 {
 	DEFINE_WAIT(wait);
 
@@ -44,11 +44,13 @@ void pipe_wait(struct inode * inode)
 	 * Pipes are system-local resources, so sleeping on them
 	 * is considered a noninteractive wait:
 	 */
-	prepare_to_wait(PIPE_WAIT(*inode), &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
-	mutex_unlock(PIPE_MUTEX(*inode));
+	prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE|TASK_NONINTERACTIVE);
+	if (pipe->inode)
+		mutex_unlock(&pipe->inode->i_mutex);
 	schedule();
-	finish_wait(PIPE_WAIT(*inode), &wait);
-	mutex_lock(PIPE_MUTEX(*inode));
+	finish_wait(&pipe->wait, &wait);
+	if (pipe->inode)
+		mutex_lock(&pipe->inode->i_mutex);
 }
 
 static int
@@ -223,7 +225,7 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
 			wake_up_interruptible_sync(PIPE_WAIT(*inode));
  			kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
 		}
-		pipe_wait(inode);
+		pipe_wait(inode->i_pipe);
 	}
 	mutex_unlock(PIPE_MUTEX(*inode));
 	/* Signal writers asynchronously that there is more room.  */
@@ -370,7 +372,7 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
 			do_wakeup = 0;
 		}
 		PIPE_WAITING_WRITERS(*inode)++;
-		pipe_wait(inode);
+		pipe_wait(inode->i_pipe);
 		PIPE_WAITING_WRITERS(*inode)--;
 	}
 out:
@@ -675,6 +677,20 @@ static struct file_operations rdwr_pipe_fops = {
 	.fasync		= pipe_rdwr_fasync,
 };
 
+struct pipe_inode_info * alloc_pipe_info(struct inode *inode)
+{
+	struct pipe_inode_info *info;
+
+	info = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
+	if (info) {
+		init_waitqueue_head(&info->wait);
+		info->r_counter = info->w_counter = 1;
+		info->inode = inode;
+	}
+
+	return info;
+}
+
 void free_pipe_info(struct inode *inode)
 {
 	int i;
@@ -691,23 +707,6 @@ void free_pipe_info(struct inode *inode)
 	kfree(info);
 }
 
-struct inode* pipe_new(struct inode* inode)
-{
-	struct pipe_inode_info *info;
-
-	info = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
-	if (!info)
-		goto fail_page;
-	inode->i_pipe = info;
-
-	init_waitqueue_head(PIPE_WAIT(*inode));
-	PIPE_RCOUNTER(*inode) = PIPE_WCOUNTER(*inode) = 1;
-
-	return inode;
-fail_page:
-	return NULL;
-}
-
 static struct vfsmount *pipe_mnt __read_mostly;
 static int pipefs_delete_dentry(struct dentry *dentry)
 {
@@ -724,8 +723,10 @@ static struct inode * get_pipe_inode(void)
 	if (!inode)
 		goto fail_inode;
 
-	if(!pipe_new(inode))
+	inode->i_pipe = alloc_pipe_info(inode);
+	if (!inode->i_pipe)
 		goto fail_iput;
+
 	PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
 	inode->i_fop = &rdwr_pipe_fops;
 
diff --git a/fs/splice.c b/fs/splice.c
index 9bfd6af0cf45..ed91a62402e0 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -136,34 +136,33 @@ static struct pipe_buf_operations page_cache_pipe_buf_ops = {
  * Pipe output worker. This sets up our pipe format with the page cache
  * pipe buffer operations. Otherwise very similar to the regular pipe_writev().
  */
-static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
+static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages,
 			    int nr_pages, unsigned long offset,
 			    unsigned long len, unsigned int flags)
 {
-	struct pipe_inode_info *info;
 	int ret, do_wakeup, i;
 
 	ret = 0;
 	do_wakeup = 0;
 	i = 0;
 
-	mutex_lock(PIPE_MUTEX(*inode));
+	if (pipe->inode)
+		mutex_lock(&pipe->inode->i_mutex);
 
-	info = inode->i_pipe;
 	for (;;) {
 		int bufs;
 
-		if (!PIPE_READERS(*inode)) {
+		if (!pipe->readers) {
 			send_sig(SIGPIPE, current, 0);
 			if (!ret)
 				ret = -EPIPE;
 			break;
 		}
 
-		bufs = info->nrbufs;
+		bufs = pipe->nrbufs;
 		if (bufs < PIPE_BUFFERS) {
-			int newbuf = (info->curbuf + bufs) & (PIPE_BUFFERS - 1);
-			struct pipe_buffer *buf = info->bufs + newbuf;
+			int newbuf = (pipe->curbuf + bufs) & (PIPE_BUFFERS - 1);
+			struct pipe_buffer *buf = pipe->bufs + newbuf;
 			struct page *page = pages[i++];
 			unsigned long this_len;
 
@@ -175,7 +174,7 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
 			buf->offset = offset;
 			buf->len = this_len;
 			buf->ops = &page_cache_pipe_buf_ops;
-			info->nrbufs = ++bufs;
+			pipe->nrbufs = ++bufs;
 			do_wakeup = 1;
 
 			ret += this_len;
@@ -205,25 +204,25 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
 
 		if (do_wakeup) {
 			smp_mb();
-			if (waitqueue_active(PIPE_WAIT(*inode)))
-				wake_up_interruptible_sync(PIPE_WAIT(*inode));
-			kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO,
-				    POLL_IN);
+			if (waitqueue_active(&pipe->wait))
+				wake_up_interruptible_sync(&pipe->wait);
+			kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
 			do_wakeup = 0;
 		}
 
-		PIPE_WAITING_WRITERS(*inode)++;
-		pipe_wait(inode);
-		PIPE_WAITING_WRITERS(*inode)--;
+		pipe->waiting_writers++;
+		pipe_wait(pipe);
+		pipe->waiting_writers--;
 	}
 
-	mutex_unlock(PIPE_MUTEX(*inode));
+	if (pipe->inode)
+		mutex_unlock(&pipe->inode->i_mutex);
 
 	if (do_wakeup) {
 		smp_mb();
-		if (waitqueue_active(PIPE_WAIT(*inode)))
-			wake_up_interruptible(PIPE_WAIT(*inode));
-		kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
+		if (waitqueue_active(&pipe->wait))
+			wake_up_interruptible(&pipe->wait);
+		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
 	}
 
 	while (i < nr_pages)
@@ -232,8 +231,9 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
 	return ret;
 }
 
-static int __generic_file_splice_read(struct file *in, struct inode *pipe,
-				      size_t len, unsigned int flags)
+static int
+__generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe,
+			   size_t len, unsigned int flags)
 {
 	struct address_space *mapping = in->f_mapping;
 	unsigned int offset, nr_pages;
@@ -298,7 +298,7 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe,
  * Will read pages from given file and fill them into a pipe.
  *
  */
-ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
+ssize_t generic_file_splice_read(struct file *in, struct pipe_inode_info *pipe,
 				 size_t len, unsigned int flags)
 {
 	ssize_t spliced;
@@ -306,6 +306,7 @@ ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
 
 	ret = 0;
 	spliced = 0;
+
 	while (len) {
 		ret = __generic_file_splice_read(in, pipe, len, flags);
 
@@ -509,11 +510,10 @@ typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
  * key here is the 'actor' worker passed in that actually moves the data
  * to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
  */
-static ssize_t move_from_pipe(struct inode *inode, struct file *out,
+static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out,
 			      size_t len, unsigned int flags,
 			      splice_actor *actor)
 {
-	struct pipe_inode_info *info;
 	int ret, do_wakeup, err;
 	struct splice_desc sd;
 
@@ -525,22 +525,22 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
 	sd.file = out;
 	sd.pos = out->f_pos;
 
-	mutex_lock(PIPE_MUTEX(*inode));
+	if (pipe->inode)
+		mutex_lock(&pipe->inode->i_mutex);
 
-	info = inode->i_pipe;
 	for (;;) {
-		int bufs = info->nrbufs;
+		int bufs = pipe->nrbufs;
 
 		if (bufs) {
-			int curbuf = info->curbuf;
-			struct pipe_buffer *buf = info->bufs + curbuf;
+			int curbuf = pipe->curbuf;
+			struct pipe_buffer *buf = pipe->bufs + curbuf;
 			struct pipe_buf_operations *ops = buf->ops;
 
 			sd.len = buf->len;
 			if (sd.len > sd.total_len)
 				sd.len = sd.total_len;
 
-			err = actor(info, buf, &sd);
+			err = actor(pipe, buf, &sd);
 			if (err) {
 				if (!ret && err != -ENODATA)
 					ret = err;
@@ -553,10 +553,10 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
 			buf->len -= sd.len;
 			if (!buf->len) {
 				buf->ops = NULL;
-				ops->release(info, buf);
+				ops->release(pipe, buf);
 				curbuf = (curbuf + 1) & (PIPE_BUFFERS - 1);
-				info->curbuf = curbuf;
-				info->nrbufs = --bufs;
+				pipe->curbuf = curbuf;
+				pipe->nrbufs = --bufs;
 				do_wakeup = 1;
 			}
 
@@ -568,9 +568,9 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
 
 		if (bufs)
 			continue;
-		if (!PIPE_WRITERS(*inode))
+		if (!pipe->writers)
 			break;
-		if (!PIPE_WAITING_WRITERS(*inode)) {
+		if (!pipe->waiting_writers) {
 			if (ret)
 				break;
 		}
@@ -589,22 +589,23 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
 
 		if (do_wakeup) {
 			smp_mb();
-			if (waitqueue_active(PIPE_WAIT(*inode)))
-				wake_up_interruptible_sync(PIPE_WAIT(*inode));
-			kill_fasync(PIPE_FASYNC_WRITERS(*inode),SIGIO,POLL_OUT);
+			if (waitqueue_active(&pipe->wait))
+				wake_up_interruptible_sync(&pipe->wait);
+			kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
 			do_wakeup = 0;
 		}
 
-		pipe_wait(inode);
+		pipe_wait(pipe);
 	}
 
-	mutex_unlock(PIPE_MUTEX(*inode));
+	if (pipe->inode)
+		mutex_unlock(&pipe->inode->i_mutex);
 
 	if (do_wakeup) {
 		smp_mb();
-		if (waitqueue_active(PIPE_WAIT(*inode)))
-			wake_up_interruptible(PIPE_WAIT(*inode));
-		kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
+		if (waitqueue_active(&pipe->wait))
+			wake_up_interruptible(&pipe->wait);
+		kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
 	}
 
 	mutex_lock(&out->f_mapping->host->i_mutex);
@@ -616,7 +617,7 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
 
 /**
  * generic_file_splice_write - splice data from a pipe to a file
- * @inode:	pipe inode
+ * @pipe:	pipe info
  * @out:	file to write to
  * @len:	number of bytes to splice
  * @flags:	splice modifier flags
@@ -625,11 +626,14 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
  * the given pipe inode to the given file.
  *
  */
-ssize_t generic_file_splice_write(struct inode *inode, struct file *out,
-				  size_t len, unsigned int flags)
+ssize_t
+generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
+			  size_t len, unsigned int flags)
 {
 	struct address_space *mapping = out->f_mapping;
-	ssize_t ret = move_from_pipe(inode, out, len, flags, pipe_to_file);
+	ssize_t ret;
+
+	ret = move_from_pipe(pipe, out, len, flags, pipe_to_file);
 
 	/*
 	 * if file or inode is SYNC and we actually wrote some data, sync it
@@ -664,10 +668,10 @@ EXPORT_SYMBOL(generic_file_splice_write);
  * is involved.
  *
  */
-ssize_t generic_splice_sendpage(struct inode *inode, struct file *out,
+ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out,
 				size_t len, unsigned int flags)
 {
-	return move_from_pipe(inode, out, len, flags, pipe_to_sendpage);
+	return move_from_pipe(pipe, out, len, flags, pipe_to_sendpage);
 }
 
 EXPORT_SYMBOL(generic_splice_sendpage);
@@ -675,8 +679,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
 /*
  * Attempt to initiate a splice from pipe to file.
  */
-static long do_splice_from(struct inode *pipe, struct file *out, size_t len,
-			   unsigned int flags)
+static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+			   size_t len, unsigned int flags)
 {
 	loff_t pos;
 	int ret;
@@ -698,8 +702,8 @@ static long do_splice_from(struct inode *pipe, struct file *out, size_t len,
 /*
  * Attempt to initiate a splice from a file to a pipe.
  */
-static long do_splice_to(struct file *in, struct inode *pipe, size_t len,
-			 unsigned int flags)
+static long do_splice_to(struct file *in, struct pipe_inode_info *pipe,
+			 size_t len, unsigned int flags)
 {
 	loff_t pos, isize, left;
 	int ret;
@@ -732,14 +736,14 @@ static long do_splice_to(struct file *in, struct inode *pipe, size_t len,
 static long do_splice(struct file *in, struct file *out, size_t len,
 		      unsigned int flags)
 {
-	struct inode *pipe;
+	struct pipe_inode_info *pipe;
 
-	pipe = in->f_dentry->d_inode;
-	if (pipe->i_pipe)
+	pipe = in->f_dentry->d_inode->i_pipe;
+	if (pipe)
 		return do_splice_from(pipe, out, len, flags);
 
-	pipe = out->f_dentry->d_inode;
-	if (pipe->i_pipe)
+	pipe = out->f_dentry->d_inode->i_pipe;
+	if (pipe)
 		return do_splice_to(in, pipe, len, flags);
 
 	return -EINVAL;
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index ae4c4754ed31..269721af02f3 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -252,7 +252,7 @@ xfs_file_sendfile_invis(
 STATIC ssize_t
 xfs_file_splice_read(
 	struct file		*infilp,
-	struct inode		*pipe,
+	struct pipe_inode_info	*pipe,
 	size_t			len,
 	unsigned int		flags)
 {
@@ -266,7 +266,7 @@ xfs_file_splice_read(
 STATIC ssize_t
 xfs_file_splice_read_invis(
 	struct file		*infilp,
-	struct inode		*pipe,
+	struct pipe_inode_info	*pipe,
 	size_t			len,
 	unsigned int		flags)
 {
@@ -279,7 +279,7 @@ xfs_file_splice_read_invis(
 
 STATIC ssize_t
 xfs_file_splice_write(
-	struct inode		*pipe,
+	struct pipe_inode_info	*pipe,
 	struct file		*outfilp,
 	size_t			len,
 	unsigned int		flags)
@@ -293,7 +293,7 @@ xfs_file_splice_write(
 
 STATIC ssize_t
 xfs_file_splice_write_invis(
-	struct inode		*pipe,
+	struct pipe_inode_info	*pipe,
 	struct file		*outfilp,
 	size_t			len,
 	unsigned int		flags)
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 90cd314acbaa..74a52937f208 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -338,7 +338,7 @@ ssize_t
 xfs_splice_read(
 	bhv_desc_t		*bdp,
 	struct file		*infilp,
-	struct inode		*pipe,
+	struct pipe_inode_info	*pipe,
 	size_t			count,
 	int			flags,
 	int			ioflags,
@@ -380,7 +380,7 @@ xfs_splice_read(
 ssize_t
 xfs_splice_write(
 	bhv_desc_t		*bdp,
-	struct inode		*pipe,
+	struct pipe_inode_info	*pipe,
 	struct file		*outfilp,
 	size_t			count,
 	int			flags,
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
index eaa5659713fb..55c689a86ad2 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -94,9 +94,9 @@ extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *,
 				loff_t *, int, size_t, read_actor_t,
 				void *, struct cred *);
 extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *,
-				struct inode *, size_t, int, int,
+				struct pipe_inode_info *, size_t, int, int,
 				struct cred *);
-extern ssize_t xfs_splice_write(struct bhv_desc *, struct inode *,
+extern ssize_t xfs_splice_write(struct bhv_desc *, struct pipe_inode_info *,
 				struct file *, size_t, int, int,
 				struct cred *);
 
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 6f1c79a28f8b..88b09f186289 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -174,9 +174,9 @@ typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *,
 				loff_t *, int, size_t, read_actor_t,
 				void *, struct cred *);
 typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *,
-				struct inode *, size_t, int, int,
+				struct pipe_inode_info *, size_t, int, int,
 				struct cred *);
-typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct inode *,
+typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *,
 				struct file *, size_t, int, int,
 				struct cred *);
 typedef int	(*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1e9ebaba07b7..7e6454454fbd 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1039,8 +1039,8 @@ struct file_operations {
 	int (*check_flags)(int);
 	int (*dir_notify)(struct file *filp, unsigned long arg);
 	int (*flock) (struct file *, int, struct file_lock *);
-	ssize_t (*splice_write)(struct inode *, struct file *, size_t, unsigned int);
-	ssize_t (*splice_read)(struct file *, struct inode *, size_t, unsigned int);
+	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned int);
+	ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int);
 };
 
 struct inode_operations {
@@ -1611,8 +1611,8 @@ extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor
 extern void do_generic_mapping_read(struct address_space *mapping,
 				    struct file_ra_state *, struct file *,
 				    loff_t *, read_descriptor_t *, read_actor_t);
-extern ssize_t generic_file_splice_read(struct file *, struct inode *, size_t, unsigned int);
-extern ssize_t generic_file_splice_write(struct inode *, struct file *, size_t, unsigned int);
+extern ssize_t generic_file_splice_read(struct file *, struct pipe_inode_info *, size_t, unsigned int);
+extern ssize_t generic_file_splice_write(struct pipe_inode_info *, struct file *, size_t, unsigned int);
 extern void
 file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
 extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov, 
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index ec384958d509..9cf99cb34c15 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -36,6 +36,7 @@ struct pipe_inode_info {
 	unsigned int w_counter;
 	struct fasync_struct *fasync_readers;
 	struct fasync_struct *fasync_writers;
+	struct inode *inode;
 };
 
 /* Differs from PIPE_BUF in that PIPE_SIZE is the length of the actual
@@ -53,10 +54,10 @@ struct pipe_inode_info {
 #define PIPE_FASYNC_WRITERS(inode)     (&((inode).i_pipe->fasync_writers))
 
 /* Drop the inode semaphore and wait for a pipe event, atomically */
-void pipe_wait(struct inode * inode);
+void pipe_wait(struct pipe_inode_info *pipe);
 
-struct inode* pipe_new(struct inode* inode);
-void free_pipe_info(struct inode* inode);
+struct pipe_inode_info * alloc_pipe_info(struct inode * inode);
+void free_pipe_info(struct inode * inode);
 
 /*
  * splice is tied to pipes as a transport (at least for now), so we'll just

commit 48b192686dd20cb1576ae1d8ccd17a07971ef24a
Author: Ingo Molnar <mingo@elte.hu>
Date:   Fri Mar 31 02:29:41 2006 -0800

    [PATCH] sem2mutex: drivers/mtd/
    
    Semaphore to mutex conversion.
    
    The conversion was generated via scripts, and the result was validated
    automatically via a script as well.
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Acked-by: David Woodhouse <dwmw2@infradead.org>
    Signed-off-by: Andrew Morton <akpm@osdl.org>
    Signed-off-by: Linus Torvalds <torvalds@osdl.org>

diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
index 04f864d238db..d732532635a1 100644
--- a/drivers/mtd/devices/blkmtd.c
+++ b/drivers/mtd/devices/blkmtd.c
@@ -29,7 +29,7 @@
 #include <linux/list.h>
 #include <linux/init.h>
 #include <linux/mtd/mtd.h>
-
+#include <linux/mutex.h>
 
 #define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg)
 #define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg)
@@ -46,7 +46,7 @@ struct blkmtd_dev {
 	struct list_head list;
 	struct block_device *blkdev;
 	struct mtd_info mtd_info;
-	struct semaphore wrbuf_mutex;
+	struct mutex wrbuf_mutex;
 };
 
 
@@ -268,7 +268,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to,
 	if(end_len)
 		pagecnt++;
 
-	down(&dev->wrbuf_mutex);
+	mutex_lock(&dev->wrbuf_mutex);
 
 	DEBUG(3, "blkmtd: write: start_len = %zd len = %zd end_len = %zd pagecnt = %d\n",
 	      start_len, len, end_len, pagecnt);
@@ -376,7 +376,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to,
 		blkmtd_write_out(bio);
 
 	DEBUG(2, "blkmtd: write: end, retlen = %zd, err = %d\n", *retlen, err);
-	up(&dev->wrbuf_mutex);
+	mutex_unlock(&dev->wrbuf_mutex);
 
 	if(retlen)
 		*retlen = thislen;
@@ -659,7 +659,7 @@ static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size
 	memset(dev, 0, sizeof(struct blkmtd_dev));
 	dev->blkdev = bdev;
 	if(!readonly) {
-		init_MUTEX(&dev->wrbuf_mutex);
+		mutex_init(&dev->wrbuf_mutex);
 	}
 
 	dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 7ff403b2a0a0..4160b8334c53 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/mtd/mtd.h>
 #include <linux/buffer_head.h>
+#include <linux/mutex.h>
 
 #define VERSION "$Revision: 1.30 $"
 
@@ -31,7 +32,7 @@ struct block2mtd_dev {
 	struct list_head list;
 	struct block_device *blkdev;
 	struct mtd_info mtd;
-	struct semaphore write_mutex;
+	struct mutex write_mutex;
 };
 
 
@@ -134,9 +135,9 @@ static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
 	int err;
 
 	instr->state = MTD_ERASING;
-	down(&dev->write_mutex);
+	mutex_lock(&dev->write_mutex);
 	err = _block2mtd_erase(dev, from, len);
-	up(&dev->write_mutex);
+	mutex_unlock(&dev->write_mutex);
 	if (err) {
 		ERROR("erase failed err = %d", err);
 		instr->state = MTD_ERASE_FAILED;
@@ -249,9 +250,9 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
 	if (to + len > mtd->size)
 		len = mtd->size - to;
 
-	down(&dev->write_mutex);
+	mutex_lock(&dev->write_mutex);
 	err = _block2mtd_write(dev, buf, to, len, retlen);
-	up(&dev->write_mutex);
+	mutex_unlock(&dev->write_mutex);
 	if (err > 0)
 		err = 0;
 	return err;
@@ -310,7 +311,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
 		goto devinit_err;
 	}
 
-	init_MUTEX(&dev->write_mutex);
+	mutex_init(&dev->write_mutex);
 
 	/* Setup the MTD structure */
 	/* make the name contain the block device in */
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 0f2c956a90d3..23e7a5c7d2c1 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -606,7 +606,7 @@ static void DoC2k_init(struct mtd_info *mtd)
 
 	this->curfloor = -1;
 	this->curchip = -1;
-	init_MUTEX(&this->lock);
+	mutex_init(&this->lock);
 
 	/* Ident all the chips present. */
 	DoC_ScanChips(this, maxchips);
@@ -646,7 +646,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
 	if (from >= this->totlen)
 		return -EINVAL;
 
-	down(&this->lock);
+	mutex_lock(&this->lock);
 
 	*retlen = 0;
 	while (left) {
@@ -775,7 +775,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
 		buf += len;
 	}
 
-	up(&this->lock);
+	mutex_unlock(&this->lock);
 
 	return ret;
 }
@@ -804,7 +804,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
 	if (to >= this->totlen)
 		return -EINVAL;
 
-	down(&this->lock);
+	mutex_lock(&this->lock);
 
 	*retlen = 0;
 	while (left) {
@@ -874,7 +874,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
 				printk(KERN_ERR "Error programming flash\n");
 				/* Error in programming */
 				*retlen = 0;
-				up(&this->lock);
+				mutex_unlock(&this->lock);
 				return -EIO;
 			}
 
@@ -936,7 +936,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
 			printk(KERN_ERR "Error programming flash\n");
 			/* Error in programming */
 			*retlen = 0;
-			up(&this->lock);
+			mutex_unlock(&this->lock);
 			return -EIO;
 		}
 
@@ -957,7 +957,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
 
 			ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
 			if (ret) {
-				up(&this->lock);
+				mutex_unlock(&this->lock);
 				return ret;
 			}
 		}
@@ -967,7 +967,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
 		buf += len;
 	}
 
-	up(&this->lock);
+	mutex_unlock(&this->lock);
 	return 0;
 }
 
@@ -1038,7 +1038,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
 	int len256 = 0, ret;
 	struct Nand *mychip;
 
-	down(&this->lock);
+	mutex_lock(&this->lock);
 
 	mychip = &this->chips[ofs >> this->chipshift];
 
@@ -1084,7 +1084,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
 
 	ret = DoC_WaitReady(this);
 
-	up(&this->lock);
+	mutex_unlock(&this->lock);
 	return ret;
 
 }
@@ -1198,10 +1198,10 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
  	struct DiskOnChip *this = mtd->priv;
  	int ret;
 
- 	down(&this->lock);
+ 	mutex_lock(&this->lock);
  	ret = doc_write_oob_nolock(mtd, ofs, len, retlen, buf);
 
- 	up(&this->lock);
+ 	mutex_unlock(&this->lock);
  	return ret;
 }
 
@@ -1215,10 +1215,10 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
 	struct Nand *mychip;
 	int status;
 
- 	down(&this->lock);
+ 	mutex_lock(&this->lock);
 
 	if (ofs & (mtd->erasesize-1) || len & (mtd->erasesize-1)) {
-		up(&this->lock);
+		mutex_unlock(&this->lock);
 		return -EINVAL;
 	}
 
@@ -1266,7 +1266,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
  callback:
 	mtd_erase_callback(instr);
 
-	up(&this->lock);
+	mutex_unlock(&this->lock);
 	return 0;
 }
 
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 840dd66ce2dc..458d3c8ae1ee 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -19,12 +19,12 @@
 #include <linux/spinlock.h>
 #include <linux/hdreg.h>
 #include <linux/init.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 #include <asm/uaccess.h>
 
 static LIST_HEAD(blktrans_majors);
 
-extern struct semaphore mtd_table_mutex;
+extern struct mutex mtd_table_mutex;
 extern struct mtd_info *mtd_table[];
 
 struct mtd_blkcore_priv {
@@ -122,9 +122,9 @@ static int mtd_blktrans_thread(void *arg)
 
 		spin_unlock_irq(rq->queue_lock);
 
-		down(&dev->sem);
+		mutex_lock(&dev->lock);
 		res = do_blktrans_request(tr, dev, req);
-		up(&dev->sem);
+		mutex_unlock(&dev->lock);
 
 		spin_lock_irq(rq->queue_lock);
 
@@ -235,8 +235,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 	int last_devnum = -1;
 	struct gendisk *gd;
 
-	if (!down_trylock(&mtd_table_mutex)) {
-		up(&mtd_table_mutex);
+	if (!!mutex_trylock(&mtd_table_mutex)) {
+		mutex_unlock(&mtd_table_mutex);
 		BUG();
 	}
 
@@ -267,7 +267,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 		return -EBUSY;
 	}
 
-	init_MUTEX(&new->sem);
+	mutex_init(&new->lock);
 	list_add_tail(&new->list, &tr->devs);
  added:
 	if (!tr->writesect)
@@ -313,8 +313,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 
 int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
 {
-	if (!down_trylock(&mtd_table_mutex)) {
-		up(&mtd_table_mutex);
+	if (!!mutex_trylock(&mtd_table_mutex)) {
+		mutex_unlock(&mtd_table_mutex);
 		BUG();
 	}
 
@@ -378,14 +378,14 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
 
 	memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv));
 
-	down(&mtd_table_mutex);
+	mutex_lock(&mtd_table_mutex);
 
 	ret = register_blkdev(tr->major, tr->name);
 	if (ret) {
 		printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
 		       tr->name, tr->major, ret);
 		kfree(tr->blkcore_priv);
-		up(&mtd_table_mutex);
+		mutex_unlock(&mtd_table_mutex);
 		return ret;
 	}
 	spin_lock_init(&tr->blkcore_priv->queue_lock);
@@ -396,7 +396,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
 	if (!tr->blkcore_priv->rq) {
 		unregister_blkdev(tr->major, tr->name);
 		kfree(tr->blkcore_priv);
-		up(&mtd_table_mutex);
+		mutex_unlock(&mtd_table_mutex);
 		return -ENOMEM;
 	}
 
@@ -407,7 +407,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
 		blk_cleanup_queue(tr->blkcore_priv->rq);
 		unregister_blkdev(tr->major, tr->name);
 		kfree(tr->blkcore_priv);
-		up(&mtd_table_mutex);
+		mutex_unlock(&mtd_table_mutex);
 		return ret;
 	}
 
@@ -419,7 +419,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
 			tr->add_mtd(tr, mtd_table[i]);
 	}
 
-	up(&mtd_table_mutex);
+	mutex_unlock(&mtd_table_mutex);
 
 	return 0;
 }
@@ -428,7 +428,7 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
 {
 	struct list_head *this, *next;
 
-	down(&mtd_table_mutex);
+	mutex_lock(&mtd_table_mutex);
 
 	/* Clean up the kernel thread */
 	tr->blkcore_priv->exiting = 1;
@@ -446,7 +446,7 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
 	blk_cleanup_queue(tr->blkcore_priv->rq);
 	unregister_blkdev(tr->major, tr->name);
 
-	up(&mtd_table_mutex);
+	mutex_unlock(&mtd_table_mutex);
 
 	kfree(tr->blkcore_priv);
 
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index e84756644fd1..2cef280e388c 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -19,11 +19,13 @@
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/blktrans.h>
+#include <linux/mutex.h>
+
 
 static struct mtdblk_dev {
 	struct mtd_info *mtd;
 	int count;
-	struct semaphore cache_sem;
+	struct mutex cache_mutex;
 	unsigned char *cache_data;
 	unsigned long cache_offset;
 	unsigned int cache_size;
@@ -284,7 +286,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
 	mtdblk->count = 1;
 	mtdblk->mtd = mtd;
 
-	init_MUTEX (&mtdblk->cache_sem);
+	mutex_init(&mtdblk->cache_mutex);
 	mtdblk->cache_state = STATE_EMPTY;
 	if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM &&
 	    mtdblk->mtd->erasesize) {
@@ -306,9 +308,9 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
 
    	DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
 
-	down(&mtdblk->cache_sem);
+	mutex_lock(&mtdblk->cache_mutex);
 	write_cached_data(mtdblk);
-	up(&mtdblk->cache_sem);
+	mutex_unlock(&mtdblk->cache_mutex);
 
 	if (!--mtdblk->count) {
 		/* It was the last usage. Free the device */
@@ -327,9 +329,9 @@ static int mtdblock_flush(struct mtd_blktrans_dev *dev)
 {
 	struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
 
-	down(&mtdblk->cache_sem);
+	mutex_lock(&mtdblk->cache_mutex);
 	write_cached_data(mtdblk);
-	up(&mtdblk->cache_sem);
+	mutex_unlock(&mtdblk->cache_mutex);
 
 	if (mtdblk->mtd->sync)
 		mtdblk->mtd->sync(mtdblk->mtd);
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index dade02ab0687..9c3813486a1a 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -27,7 +27,7 @@
 
 /* These are exported solely for the purpose of mtd_blkdevs.c. You
    should not use them for _anything_ else */
-DECLARE_MUTEX(mtd_table_mutex);
+DEFINE_MUTEX(mtd_table_mutex);
 struct mtd_info *mtd_table[MAX_MTD_DEVICES];
 
 EXPORT_SYMBOL_GPL(mtd_table_mutex);
@@ -49,7 +49,7 @@ int add_mtd_device(struct mtd_info *mtd)
 {
 	int i;
 
-	down(&mtd_table_mutex);
+	mutex_lock(&mtd_table_mutex);
 
 	for (i=0; i < MAX_MTD_DEVICES; i++)
 		if (!mtd_table[i]) {
@@ -67,7 +67,7 @@ int add_mtd_device(struct mtd_info *mtd)
 				not->add(mtd);
 			}
 
-			up(&mtd_table_mutex);
+			mutex_unlock(&mtd_table_mutex);
 			/* We _know_ we aren't being removed, because
 			   our caller is still holding us here. So none
 			   of this try_ nonsense, and no bitching about it
@@ -76,7 +76,7 @@ int add_mtd_device(struct mtd_info *mtd)
 			return 0;
 		}
 
-	up(&mtd_table_mutex);
+	mutex_unlock(&mtd_table_mutex);
 	return 1;
 }
 
@@ -94,7 +94,7 @@ int del_mtd_device (struct mtd_info *mtd)
 {
 	int ret;
 
-	down(&mtd_table_mutex);
+	mutex_lock(&mtd_table_mutex);
 
 	if (mtd_table[mtd->index] != mtd) {
 		ret = -ENODEV;
@@ -118,7 +118,7 @@ int del_mtd_device (struct mtd_info *mtd)
 		ret = 0;
 	}
 
-	up(&mtd_table_mutex);
+	mutex_unlock(&mtd_table_mutex);
 	return ret;
 }
 
@@ -135,7 +135,7 @@ void register_mtd_user (struct mtd_notifier *new)
 {
 	int i;
 
-	down(&mtd_table_mutex);
+	mutex_lock(&mtd_table_mutex);
 
 	list_add(&new->list, &mtd_notifiers);
 
@@ -145,7 +145,7 @@ void register_mtd_user (struct mtd_notifier *new)
 		if (mtd_table[i])
 			new->add(mtd_table[i]);
 
-	up(&mtd_table_mutex);
+	mutex_unlock(&mtd_table_mutex);
 }
 
 /**
@@ -162,7 +162,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
 {
 	int i;
 
-	down(&mtd_table_mutex);
+	mutex_lock(&mtd_table_mutex);
 
 	module_put(THIS_MODULE);
 
@@ -171,7 +171,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
 			old->remove(mtd_table[i]);
 
 	list_del(&old->list);
-	up(&mtd_table_mutex);
+	mutex_unlock(&mtd_table_mutex);
 	return 0;
 }
 
@@ -193,7 +193,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
 	struct mtd_info *ret = NULL;
 	int i;
 
-	down(&mtd_table_mutex);
+	mutex_lock(&mtd_table_mutex);
 
 	if (num == -1) {
 		for (i=0; i< MAX_MTD_DEVICES; i++)
@@ -211,7 +211,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
 	if (ret)
 		ret->usecount++;
 
-	up(&mtd_table_mutex);
+	mutex_unlock(&mtd_table_mutex);
 	return ret;
 }
 
@@ -219,9 +219,9 @@ void put_mtd_device(struct mtd_info *mtd)
 {
 	int c;
 
-	down(&mtd_table_mutex);
+	mutex_lock(&mtd_table_mutex);
 	c = --mtd->usecount;
-	up(&mtd_table_mutex);
+	mutex_unlock(&mtd_table_mutex);
 	BUG_ON(c < 0);
 
 	module_put(mtd->owner);
@@ -319,7 +319,7 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count,
 	int len, l, i;
         off_t   begin = 0;
 
-	down(&mtd_table_mutex);
+	mutex_lock(&mtd_table_mutex);
 
 	len = sprintf(page, "dev:    size   erasesize  name\n");
         for (i=0; i< MAX_MTD_DEVICES; i++) {
@@ -337,7 +337,7 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count,
         *eof = 1;
 
 done:
-	up(&mtd_table_mutex);
+	mutex_unlock(&mtd_table_mutex);
         if (off >= len+begin)
                 return 0;
         *start = page + (off-begin);
diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h
index f46afec6fbf8..72fc68c5ee96 100644
--- a/include/linux/mtd/blktrans.h
+++ b/include/linux/mtd/blktrans.h
@@ -10,7 +10,7 @@
 #ifndef __MTD_TRANS_H__
 #define __MTD_TRANS_H__
 
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 struct hd_geometry;
 struct mtd_info;
@@ -22,7 +22,7 @@ struct mtd_blktrans_dev {
 	struct mtd_blktrans_ops *tr;
 	struct list_head list;
 	struct mtd_info *mtd;
-	struct semaphore sem;
+	struct mutex lock;
 	int devnum;
 	int blksize;
 	unsigned long size;
diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h
index 386a52cf8b1b..9addd073bf15 100644
--- a/include/linux/mtd/doc2000.h
+++ b/include/linux/mtd/doc2000.h
@@ -15,7 +15,7 @@
 #define __MTD_DOC2000_H__
 
 #include <linux/mtd/mtd.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 
 #define DoC_Sig1 0
 #define DoC_Sig2 1
@@ -187,7 +187,7 @@ struct DiskOnChip {
 	int numchips;
 	struct Nand *chips;
 	struct mtd_info *nextdoc;
-	struct semaphore lock;
+	struct mutex lock;
 };
 
 int doc_decode_ecc(unsigned char sector[512], unsigned char ecc1[6]);