ceph: add F_SYNC file flag to force sync (non-O_DIRECT) io
authorSage Weil <sage@newdream.net>
Tue, 26 Jul 2011 18:26:07 +0000 (11:26 -0700)
committerSage Weil <sage@newdream.net>
Tue, 26 Jul 2011 18:26:07 +0000 (11:26 -0700)
This allows us to force IO through the sync path which you normally only
get when multiple clients are reading/writing to the same file or by
mounting with -o sync.  Among other things, this lets test programs verify
correctness with a single mount.

Reviewed-by: Yehuda Sadeh <yehuda@hq.newdream.net>
Signed-off-by: Sage Weil <sage@newdream.net>
fs/ceph/file.c
fs/ceph/ioctl.c
fs/ceph/ioctl.h
fs/ceph/super.h

index 4698a5c553dc010fa0aedabe3f3f4e0fb68b65c8..44e4fe9fba026e9a6c0a49d68b3505a9b1122a32 100644 (file)
@@ -643,7 +643,8 @@ again:
 
        if ((got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0 ||
            (iocb->ki_filp->f_flags & O_DIRECT) ||
-           (inode->i_sb->s_flags & MS_SYNCHRONOUS))
+           (inode->i_sb->s_flags & MS_SYNCHRONOUS) ||
+           (fi->flags & CEPH_F_SYNC))
                /* hmm, this isn't really async... */
                ret = ceph_sync_read(filp, base, len, ppos, &checkeof);
        else
@@ -720,7 +721,8 @@ retry_snap:
 
        if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 ||
            (iocb->ki_filp->f_flags & O_DIRECT) ||
-           (inode->i_sb->s_flags & MS_SYNCHRONOUS)) {
+           (inode->i_sb->s_flags & MS_SYNCHRONOUS) ||
+           (fi->flags & CEPH_F_SYNC)) {
                ret = ceph_sync_write(file, iov->iov_base, iov->iov_len,
                        &iocb->ki_pos);
        } else {
index ef0b5f48e13ac77a75233a40634d000068c9a21c..a757a5680578df3d08a6e0f974f110a502cb6f98 100644 (file)
@@ -231,6 +231,14 @@ static long ceph_ioctl_lazyio(struct file *file)
        return 0;
 }
 
+static long ceph_ioctl_syncio(struct file *file)
+{
+       struct ceph_file_info *fi = file->private_data;
+
+       fi->flags |= CEPH_F_SYNC;
+       return 0;
+}
+
 long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        dout("ioctl file %p cmd %u arg %lu\n", file, cmd, arg);
@@ -249,6 +257,9 @@ long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
        case CEPH_IOC_LAZYIO:
                return ceph_ioctl_lazyio(file);
+
+       case CEPH_IOC_SYNCIO:
+               return ceph_ioctl_syncio(file);
        }
 
        return -ENOTTY;
index 52e8fd74d450b9e2895eb7c29d80e38b77eb0807..0c5167e43180c9a0f41b24f39a35b0a4e5de1246 100644 (file)
@@ -40,5 +40,6 @@ struct ceph_ioctl_dataloc {
                                   struct ceph_ioctl_dataloc)
 
 #define CEPH_IOC_LAZYIO _IO(CEPH_IOCTL_MAGIC, 4)
+#define CEPH_IOC_SYNCIO _IO(CEPH_IOCTL_MAGIC, 5)
 
 #endif
index 8febe6fce2b1f715f094da8c8db7c764a0880ea5..cdb17d36755c4a67ade569afb16a724031cc2530 100644 (file)
@@ -543,6 +543,8 @@ extern void ceph_reservation_status(struct ceph_fs_client *client,
 /*
  * we keep buffered readdir results attached to file->private_data
  */
+#define CEPH_F_SYNC     1
+
 struct ceph_file_info {
        short fmode;     /* initialized on open */
        short flags;     /* CEPH_F_* */