From: Dave Chinner <david@fromorbit.com>
To: xfs@oss.sgi.com
Subject: [PATCH 5/7] xfs: split buffered IO write path from xfs_file_aio_write
Date: Wed, 15 Dec 2010 12:23:26 +1100 [thread overview]
Message-ID: <1292376208-16282-6-git-send-email-david@fromorbit.com> (raw)
In-Reply-To: <1292376208-16282-1-git-send-email-david@fromorbit.com>
From: Dave Chinner <dchinner@redhat.com>
Complete the split of the different write IO paths by splitting the
buffered IO write path out of xfs_file_aio_write(). This makes the
different mechanisms of the write patchs easier to follow.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
fs/xfs/linux-2.6/xfs_file.c | 160 ++++++++++++++++++++-----------------------
1 files changed, 75 insertions(+), 85 deletions(-)
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index d70a249..e10e703 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -698,132 +698,123 @@ xfs_file_dio_aio_write(
}
STATIC ssize_t
-xfs_file_aio_write(
+xfs_file_buffered_aio_write(
struct kiocb *iocb,
const struct iovec *iovp,
unsigned long nr_segs,
- loff_t pos)
+ loff_t pos,
+ size_t ocount,
+ int *need_i_mutex,
+ int *iolock)
{
struct file *file = iocb->ki_filp;
struct address_space *mapping = file->f_mapping;
struct inode *inode = mapping->host;
struct xfs_inode *ip = XFS_I(inode);
- struct xfs_mount *mp = ip->i_mount;
ssize_t ret = 0, error = 0;
- int ioflags = 0;
+ int enospc = 0;
xfs_fsize_t new_size;
- int iolock;
- size_t ocount = 0, count;
- int need_i_mutex;
-
- XFS_STATS_INC(xs_write_calls);
-
- BUG_ON(iocb->ki_pos != pos);
-
- if (unlikely(file->f_flags & O_DIRECT))
- ioflags |= IO_ISDIRECT;
- if (file->f_mode & FMODE_NOCMTIME)
- ioflags |= IO_INVIS;
-
- error = generic_segment_checks(iovp, &nr_segs, &ocount, VERIFY_READ);
- if (error)
- return error;
-
- count = ocount;
- if (count == 0)
- return 0;
-
- xfs_wait_for_freeze(mp, SB_FREEZE_WRITE);
-
- if (XFS_FORCED_SHUTDOWN(mp))
- return -EIO;
-
- if (ioflags & IO_ISDIRECT) {
- ret = xfs_file_dio_aio_write(iocb, iovp, nr_segs, pos,
- ocount, &need_i_mutex, &iolock);
- goto done_io;
- }
+ size_t count = ocount;
- iolock = XFS_IOLOCK_EXCL;
- need_i_mutex = 1;
+ *iolock = XFS_IOLOCK_EXCL;
+ *need_i_mutex = 1;
mutex_lock(&inode->i_mutex);
- xfs_ilock(ip, XFS_ILOCK_EXCL|iolock);
+ xfs_ilock(ip, XFS_ILOCK_EXCL|*iolock);
- error = -generic_write_checks(file, &pos, &count,
+ error = generic_write_checks(file, &pos, &count,
S_ISBLK(inode->i_mode));
if (error) {
- xfs_iunlock(ip, XFS_ILOCK_EXCL|iolock);
- goto out_unlock_mutex;
+ xfs_iunlock(ip, XFS_ILOCK_EXCL|*iolock);
+ *iolock = 0;
+ return error;
}
new_size = pos + count;
if (new_size > ip->i_size)
ip->i_new_size = new_size;
- if (likely(!(ioflags & IO_INVIS)))
+ if (likely(!(file->f_mode & FMODE_NOCMTIME)))
file_update_time(file);
- /*
- * If the offset is beyond the size of the file, we have a couple
- * of things to do. First, if there is already space allocated
- * we need to either create holes or zero the disk or ...
- *
- * If there is a page where the previous size lands, we need
- * to zero it out up to the new size.
- */
-
if (pos > ip->i_size) {
- error = xfs_zero_eof(ip, pos, ip->i_size);
+ error = -xfs_zero_eof(ip, pos, ip->i_size);
if (error) {
xfs_iunlock(ip, XFS_ILOCK_EXCL);
- goto out_unlock_internal;
+ return error;
}
}
xfs_iunlock(ip, XFS_ILOCK_EXCL);
- /*
- * If we're writing the file then make sure to clear the
- * setuid and setgid bits if the process is not being run
- * by root. This keeps people from modifying setuid and
- * setgid binaries.
- */
- error = -file_remove_suid(file);
+ error = file_remove_suid(file);
if (unlikely(error))
- goto out_unlock_internal;
+ return error;
/* We can write back this queue in page reclaim */
current->backing_dev_info = mapping->backing_dev_info;
- if (!(ioflags & IO_ISDIRECT)) {
- int enospc = 0;
- ssize_t ret2 = 0;
-
write_retry:
- trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, ioflags);
- ret2 = generic_file_buffered_write(iocb, iovp, nr_segs,
- pos, &iocb->ki_pos, count, ret);
- /*
- * if we just got an ENOSPC, flush the inode now we
- * aren't holding any page locks and retry *once*
- */
- if (ret2 == -ENOSPC && !enospc) {
- error = xfs_flush_pages(ip, 0, -1, 0, FI_NONE);
- if (error)
- goto out_unlock_internal;
- enospc = 1;
- goto write_retry;
- }
- ret = ret2;
+ trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, 0);
+ error = generic_file_buffered_write(iocb, iovp, nr_segs,
+ pos, &iocb->ki_pos, count, ret);
+ /*
+ * if we just got an ENOSPC, flush the inode now we aren't holding any
+ * page locks and retry *once*
+ */
+ if (error == -ENOSPC && !enospc) {
+ error = -xfs_flush_pages(ip, 0, -1, 0, FI_NONE);
+ if (error)
+ return error;
+ enospc = 1;
+ goto write_retry;
}
-
current->backing_dev_info = NULL;
+ return error;
+}
+
+STATIC ssize_t
+xfs_file_aio_write(
+ struct kiocb *iocb,
+ const struct iovec *iovp,
+ unsigned long nr_segs,
+ loff_t pos)
+{
+ struct file *file = iocb->ki_filp;
+ struct address_space *mapping = file->f_mapping;
+ struct inode *inode = mapping->host;
+ struct xfs_inode *ip = XFS_I(inode);
+ ssize_t ret = 0, error = 0;
+ int iolock;
+ size_t ocount = 0;
+ int need_i_mutex;
+
+ XFS_STATS_INC(xs_write_calls);
+
+ BUG_ON(iocb->ki_pos != pos);
+
+ error = generic_segment_checks(iovp, &nr_segs, &ocount, VERIFY_READ);
+ if (error)
+ return error;
+
+ if (ocount == 0)
+ return 0;
+
+ xfs_wait_for_freeze(ip->i_mount, SB_FREEZE_WRITE);
+
+ if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+ return -EIO;
+
+ if (unlikely(file->f_flags & O_DIRECT))
+ ret = xfs_file_dio_aio_write(iocb, iovp, nr_segs, pos,
+ ocount, &need_i_mutex, &iolock);
+ else
+ ret = xfs_file_buffered_aio_write(iocb, iovp, nr_segs, pos,
+ ocount, &need_i_mutex, &iolock);
-done_io:
xfs_aio_write_isize_update(inode, &iocb->ki_pos, ret);
error = -ret;
if (ret <= 0)
- goto out_unlock_internal;
+ goto out_unlock;
XFS_STATS_ADD(xs_write_bytes, ret);
@@ -849,10 +840,9 @@ done_io:
error = error2;
}
- out_unlock_internal:
+ out_unlock:
xfs_aio_write_newsize_update(ip);
xfs_iunlock(ip, iolock);
- out_unlock_mutex:
if (need_i_mutex)
mutex_unlock(&inode->i_mutex);
return -error;
--
1.7.2.3
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2010-12-15 1:23 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-15 1:23 [PATCH 0/7] xfs: serialise unaligned direct IOs Dave Chinner
2010-12-15 1:23 ` [PATCH 1/7] xfs: ensure sync write errors are returned Dave Chinner
2010-12-16 11:57 ` Christoph Hellwig
2010-12-16 21:57 ` Dave Chinner
2010-12-16 20:50 ` Alex Elder
2010-12-17 6:43 ` Dave Chinner
2010-12-15 1:23 ` [PATCH 2/7] xfs: factor common post-write isize handling code Dave Chinner
2010-12-15 1:23 ` [PATCH 4/7] xfs: split direct IO write path from xfs_file_aio_write Dave Chinner
2010-12-16 12:06 ` Christoph Hellwig
2010-12-17 7:31 ` Dave Chinner
2010-12-20 11:29 ` Christoph Hellwig
2010-12-21 0:51 ` Dave Chinner
2010-12-15 1:23 ` Dave Chinner [this message]
2010-12-15 1:23 ` [PATCH 6/7] xfs: factor common write setup code Dave Chinner
2010-12-15 1:23 ` [PATCH 7/7] xfs: serialise unaligned direct IOs Dave Chinner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1292376208-16282-6-git-send-email-david@fromorbit.com \
--to=david@fromorbit.com \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.