Skip to content

Commit 6c92501

Browse files
committed
Updating based on PR Feedback(6)
1. Updated typo in man page zfs.4. 2. Fix fat fingered typing errors in zpl_aio_write(). 3. Fixed spelling O_DIRECT typo in zpl_direct_IO_impl() 4. Updated dmu_write_uio_dnode() to issue a write_size based multiple dn->dn_datablksz chunks at once. 5. Removed empty lines in zfs_write(). 6. Returned code back to same indentation in zfs_get_data(). 7. Removed duplicate ASSERT statements in dmu_buf_will_clone_or_dio(). 8. Fixed spelling typo of cause in comment in dmu_buf_will_clone_or_dio(). 9. Return 0 in FreeBSD zfs_uio_get_pages() when count != nr_pages. 10. Updated FreeBSD zfs_uio_get_dio_pages_alloc() to unhold pages in the event of an error. 11. Linux changed zfs_uio_iov_step() to use SET_ERROR() so it matches the FreeBSD implementation. 12. Upated zfs_read() to add back dio_remaining_resid to n in the event of an error. 13. Added an ASSERT in zio_ddt_write() making sure no Direct I/O writes are issued with deduplication. Also, added a comment with ASSERT to state why Direct I/O writes can not use deduplication. 14. Removed _KERNEL include guard around zfs_dio_page_aligned(). The proper uio_impl.h or uio.h is included through zfs_context.h. 15. Updated the zfsprop man page to state that Direct I/O is not currenntly available for zvols. Also that Direct I/O writes are incompatiable with dedup, so dedup will not take place with Direct I/O writes. 16. Fixed typo in comment in manipulate_user_buffer.c. Signed-off-by: Brian Atkinson <[email protected]>
1 parent b439a5d commit 6c92501

File tree

13 files changed

+37
-31
lines changed

13 files changed

+37
-31
lines changed

include/sys/uio_impl.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,12 @@ extern void zfs_uio_free_dio_pages(zfs_uio_t *, zfs_uio_rw_t);
4949
extern int zfs_uio_get_dio_pages_alloc(zfs_uio_t *, zfs_uio_rw_t);
5050
extern boolean_t zfs_uio_page_aligned(zfs_uio_t *);
5151

52-
#ifdef _KERNEL
5352
static inline boolean_t
5453
zfs_dio_page_aligned(void *buf)
5554
{
5655
return ((((uintptr_t)(buf) & (PAGESIZE - 1)) == 0) ?
5756
B_TRUE : B_FALSE);
5857
}
59-
#endif
6058

6159
static inline boolean_t
6260
zfs_dio_offset_aligned(uint64_t offset, uint64_t blksz)

man/man4/zfs.4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ May be increased up to
424424
.Sy ASHIFT_MAX Po 16 Pc ,
425425
but this may negatively impact pool space efficiency.
426426
.
427-
.It Sy zfs_vdev_direct_write_verify Ns = Ns Sy Linux 1 | FreeBSED 0 Pq uint
427+
.It Sy zfs_vdev_direct_write_verify Ns = Ns Sy Linux 1 | FreeBSD 0 Pq uint
428428
If non-zero, then a Direct I/O write's checksum will be verified every
429429
time the write is issued and before it is commited to the block pointer.
430430
In the event the checksum is not valid then the I/O operation will return EIO.

man/man7/zfsprops.7

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,10 @@ Furthermore, if an application uses
10761076
.Xr mmap 2
10771077
based file access then in order to maintain coherency all direct requests
10781078
are converted to buffered requests while the file is mapped.
1079+
Currently Direct I/O is not supported with zvols.
1080+
If dedup is enabled on a dataset, Direct I/O writes will not check for
1081+
deduplication.
1082+
Deduplication and Direct I/O writes are currently incompatible.
10791083
.It Xo
10801084
.Sy dnodesize Ns = Ns Sy legacy Ns | Ns Sy auto Ns | Ns Sy 1k Ns | Ns
10811085
.Sy 2k Ns | Ns Sy 4k Ns | Ns Sy 8k Ns | Ns Sy 16k

module/os/freebsd/spl/spl_uio.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ zfs_uio_get_user_pages(unsigned long start, int nr_pages,
217217
if (count != nr_pages) {
218218
if (count > 0)
219219
vm_page_unhold_pages(pages, count);
220-
return (count);
220+
return (0);
221221
}
222222

223223
ASSERT3S(count, ==, nr_pages);
@@ -295,6 +295,8 @@ zfs_uio_get_dio_pages_alloc(zfs_uio_t *uio, zfs_uio_rw_t rw)
295295
error = zfs_uio_get_dio_pages_impl(uio);
296296

297297
if (error) {
298+
vm_page_unhold_pages(&uio->uio_dio.pages[0],
299+
uio->uio_dio.npages);
298300
kmem_free(uio->uio_dio.pages, size);
299301
return (error);
300302
}

module/os/linux/zfs/zfs_uio.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -599,9 +599,9 @@ zfs_uio_iov_step(struct iovec v, zfs_uio_rw_t rw, zfs_uio_t *uio,
599599
P2ALIGN_TYPED(addr, PAGE_SIZE, unsigned long), n, rw == UIO_READ,
600600
&uio->uio_dio.pages[uio->uio_dio.npages]);
601601
if (res < 0) {
602-
return (-res);
602+
return (SET_ERROR(-res));
603603
} else if (len != (res * PAGE_SIZE)) {
604-
return (EFAULT);
604+
return (SET_ERROR(EFAULT));
605605
}
606606

607607
ASSERT3S(len, ==, res * PAGE_SIZE);
@@ -632,7 +632,7 @@ zfs_uio_get_dio_pages_iov(zfs_uio_t *uio, zfs_uio_rw_t rw)
632632
int error = zfs_uio_iov_step(iov, rw, uio, &numpages);
633633

634634
if (error)
635-
return (SET_ERROR(error));
635+
return (error);
636636

637637
uio->uio_dio.npages += numpages;
638638
len -= iov.iov_len;

module/os/linux/zfs/zpl_file.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ zpl_aio_write(struct kiocb *kiocb, const struct iovec *iov,
454454
if (ret)
455455
return (ret);
456456

457-
ret = geeric_write_checks(filep, &pos, &count, S_ISBLK(ip->i_mode));
457+
ret = generic_write_checks(filp, &pos, &count, S_ISBLK(ip->i_mode));
458458
if (ret)
459459
return (ret);
460460

@@ -488,7 +488,7 @@ static ssize_t
488488
zpl_direct_IO_impl(void)
489489
{
490490
/*
491-
* All O_DIRCT requests should be handled by
491+
* All O_DIRECT requests should be handled by
492492
* zpl_{iter/aio}_{write/read}(). There is no way kernel generic code
493493
* should call the direct_IO address_space_operations function. We set
494494
* this code path to be fatal if it is executed.

module/zfs/dbuf.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2794,14 +2794,11 @@ dmu_buf_untransform_direct(dmu_buf_impl_t *db, spa_t *spa)
27942794
void
27952795
dmu_buf_will_clone_or_dio(dmu_buf_t *db_fake, dmu_tx_t *tx)
27962796
{
2797-
dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
2798-
ASSERT0(db->db_level);
2799-
ASSERT(db->db_blkid != DMU_BONUS_BLKID);
2800-
ASSERT(db->db.db_object != DMU_META_DNODE_OBJECT);
2801-
28022797
/*
28032798
* Block clones and Direct I/O writes always happen in open-context.
28042799
*/
2800+
dmu_buf_impl_t *db = (dmu_buf_impl_t *)db_fake;
2801+
ASSERT0(db->db_level);
28052802
ASSERT(!dmu_tx_is_syncing(tx));
28062803
ASSERT0(db->db_level);
28072804
ASSERT(db->db_blkid != DMU_BONUS_BLKID);
@@ -2820,7 +2817,7 @@ dmu_buf_will_clone_or_dio(dmu_buf_t *db_fake, dmu_tx_t *tx)
28202817
* to go ahead free up the space accounting through dbuf_undirty() ->
28212818
* dbuf_unoverride() -> zio_free(). Space accountiung for determining
28222819
* if a write can occur in zfs_write() happens through dmu_tx_assign().
2823-
* This can cuase an issue with Direct I/O writes in the case of
2820+
* This can cause an issue with Direct I/O writes in the case of
28242821
* overwriting the same block, because all DVA allocations are being
28252822
* done in open-context. Constantly allowing Direct I/O overwrites to
28262823
* the same block can exhaust the pools available space leading to

module/zfs/dmu.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,10 +1512,11 @@ dmu_write_uio_dnode(dnode_t *dn, zfs_uio_t *uio, uint64_t size, dmu_tx_t *tx)
15121512
} else if (write_size > dn->dn_datablksz &&
15131513
zfs_dio_offset_aligned(zfs_uio_offset(uio),
15141514
dn->dn_datablksz)) {
1515-
err = dmu_write_uio_direct(dn, uio, dn->dn_datablksz,
1516-
tx);
1515+
write_size =
1516+
dn->dn_datablksz * (write_size / dn->dn_datablksz);
1517+
err = dmu_write_uio_direct(dn, uio, write_size, tx);
15171518
if (err == 0) {
1518-
size -= dn->dn_datablksz;
1519+
size -= write_size;
15191520
goto top;
15201521
} else {
15211522
return (err);

module/zfs/zfs_ioctl.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@
160160
#include <sys/types.h>
161161
#include <sys/param.h>
162162
#include <sys/errno.h>
163-
#include <sys/uio_impl.h>
164163
#include <sys/file.h>
165164
#include <sys/kmem.h>
166165
#include <sys/cmn_err.h>

module/zfs/zfs_vnops.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#include <sys/time.h>
3636
#include <sys/sysmacros.h>
3737
#include <sys/vfs.h>
38-
#include <sys/uio_impl.h>
3938
#include <sys/file.h>
4039
#include <sys/stat.h>
4140
#include <sys/kmem.h>
@@ -445,7 +444,6 @@ zfs_read(struct znode *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
445444
n -= nbytes;
446445
}
447446

448-
int64_t nread = start_resid;
449447
if (error == 0 && (uio->uio_extflg & UIO_DIRECT) &&
450448
dio_remaining_resid != 0) {
451449
/*
@@ -464,9 +462,11 @@ zfs_read(struct znode *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
464462
uio->uio_extflg |= UIO_DIRECT;
465463

466464
if (error != 0)
467-
n -= dio_remaining_resid;
465+
n += dio_remaining_resid;
466+
} else if (error && (uio->uio_extflg & UIO_DIRECT)) {
467+
n += dio_remaining_resid;
468468
}
469-
nread -= n;
469+
int64_t nread = start_resid - n;
470470

471471
dataset_kstats_update_read_kstats(&zfsvfs->z_kstat, nread);
472472
out:
@@ -634,7 +634,6 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
634634
return (SET_ERROR(EFAULT));
635635
}
636636

637-
638637
/*
639638
* If in append mode, set the io offset pointer to eof.
640639
*/
@@ -670,7 +669,6 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr)
670669
lr = zfs_rangelock_enter(&zp->z_rangelock, woff, n, RL_WRITER);
671670
}
672671

673-
674672
if (zn_rlimit_fsize_uio(zp, uio)) {
675673
zfs_rangelock_exit(lr);
676674
zfs_exit(zfsvfs, FTAG);
@@ -1139,11 +1137,10 @@ zfs_get_data(void *arg, uint64_t gen, lr_write_t *lr, char *buf,
11391137
for (;;) {
11401138
uint64_t blkoff;
11411139
size = zp->z_blksz;
1142-
blkoff = ISP2(size) ? P2PHASE(offset, size) :
1143-
offset;
1140+
blkoff = ISP2(size) ? P2PHASE(offset, size) : offset;
11441141
offset -= blkoff;
1145-
zgd->zgd_lr = zfs_rangelock_enter(
1146-
&zp->z_rangelock, offset, size, RL_READER);
1142+
zgd->zgd_lr = zfs_rangelock_enter(&zp->z_rangelock,
1143+
offset, size, RL_READER);
11471144
if (zp->z_blksz == size)
11481145
break;
11491146
offset += blkoff;

module/zfs/zio.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3591,6 +3591,13 @@ zio_ddt_write(zio_t *zio)
35913591
ASSERT(BP_GET_CHECKSUM(bp) == zp->zp_checksum);
35923592
ASSERT(BP_IS_HOLE(bp) || zio->io_bp_override);
35933593
ASSERT(!(zio->io_bp_override && (zio->io_flags & ZIO_FLAG_RAW)));
3594+
/*
3595+
* Deduplication will not take place for Direct I/O writes. The
3596+
* ddt_tree will be emptied in syncing context. Direct I/O writes take
3597+
* place in the open-context. Direct I/O write can not attempt to
3598+
* modify the ddt_tree while issuing out a write.
3599+
*/
3600+
ASSERT3B(zio->io_prop.zp_direct_write, ==, B_FALSE);
35943601

35953602
ddt_enter(ddt);
35963603
dde = ddt_lookup(ddt, bp);

tests/zfs-tests/cmd/manipulate_user_buffer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ main(int argc, char *argv[])
243243
}
244244

245245
/*
246-
* Writing using O_DIRECT while manipulating the buffer conntents until
246+
* Writing using O_DIRECT while manipulating the buffer contents until
247247
* the entire file is written.
248248
*/
249249
if ((rc = pthread_create(&manipul_thr, NULL, manipulate_buf_thread,

tests/zfs-tests/tests/functional/direct/dio_dedup.ksh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131

3232
#
3333
# DESCRIPTION:
34-
# Verify deduplication works using Direct I/O.
34+
# Verify deduplication works. Deduplication is disabled when issuing
35+
# Direct I/O writes.
3536
#
3637
# STRATEGY:
3738
# 1. Enable dedup

0 commit comments

Comments
 (0)