static void
 filelayout_set_layoutcommit(struct nfs_pgio_header *hdr)
 {
+       loff_t end_offs = 0;
 
        if (FILELAYOUT_LSEG(hdr->lseg)->commit_through_mds ||
-           hdr->res.verf->committed != NFS_DATA_SYNC)
+           hdr->res.verf->committed == NFS_FILE_SYNC)
                return;
+       if (hdr->res.verf->committed == NFS_DATA_SYNC)
+               end_offs = hdr->mds_offset + (loff_t)hdr->res.count;
 
-       pnfs_set_layoutcommit(hdr->inode, hdr->lseg,
-                       hdr->mds_offset + hdr->res.count);
+       /* Note: if the write is unstable, don't set end_offs until commit */
+       pnfs_set_layoutcommit(hdr->inode, hdr->lseg, end_offs);
        dprintk("%s inode %lu pls_end_pos %lu\n", __func__, hdr->inode->i_ino,
                (unsigned long) NFS_I(hdr->inode)->layout->plh_lwb);
 }
 
 static int ff_layout_write_done_cb(struct rpc_task *task,
                                struct nfs_pgio_header *hdr)
 {
+       loff_t end_offs = 0;
        int err;
 
        trace_nfs4_pnfs_write(hdr, task->tk_status);
 
        if (hdr->res.verf->committed == NFS_FILE_SYNC ||
            hdr->res.verf->committed == NFS_DATA_SYNC)
-               ff_layout_set_layoutcommit(hdr->inode, hdr->lseg,
-                               hdr->mds_offset + (loff_t)hdr->res.count);
+               end_offs = hdr->mds_offset + (loff_t)hdr->res.count;
+
+       /* Note: if the write is unstable, don't set end_offs until commit */
+       ff_layout_set_layoutcommit(hdr->inode, hdr->lseg, end_offs);
 
        /* zero out fattr since we don't care DS attr at all */
        hdr->fattr.valid = 0;
 
        p = xdr_encode_hyper(p, args->lastbytewritten + 1);     /* length */
        *p = cpu_to_be32(0); /* reclaim */
        encode_nfs4_stateid(xdr, &args->stateid);
-       p = reserve_space(xdr, 20);
-       *p++ = cpu_to_be32(1); /* newoffset = TRUE */
-       p = xdr_encode_hyper(p, args->lastbytewritten);
+       if (args->lastbytewritten != U64_MAX) {
+               p = reserve_space(xdr, 20);
+               *p++ = cpu_to_be32(1); /* newoffset = TRUE */
+               p = xdr_encode_hyper(p, args->lastbytewritten);
+       } else {
+               p = reserve_space(xdr, 12);
+               *p++ = cpu_to_be32(0); /* newoffset = FALSE */
+       }
        *p++ = cpu_to_be32(0); /* Never send time_modify_changed */
        *p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */
 
 
        nfs_fattr_init(&data->fattr);
        data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;
        data->res.fattr = &data->fattr;
-       data->args.lastbytewritten = end_pos - 1;
+       if (end_pos != 0)
+               data->args.lastbytewritten = end_pos - 1;
+       else
+               data->args.lastbytewritten = U64_MAX;
        data->res.server = NFS_SERVER(inode);
 
        if (ld->prepare_layoutcommit) {
 
 int
 pnfs_nfs_generic_sync(struct inode *inode, bool datasync)
 {
+       int ret;
+
+       if (!pnfs_layoutcommit_outstanding(inode))
+               return 0;
+       ret = nfs_commit_inode(inode, FLUSH_SYNC);
+       if (ret < 0)
+               return ret;
        if (datasync)
                return 0;
        return pnfs_layoutcommit_inode(inode, true);