Whamcloud - gitweb
git://git.whamcloud.com
/
fs
/
lustre-release.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
| inline |
side by side
LU-6142 libcfs: discard PO2_ROUNDUP_TYPED, LOWEST_BIT_SET
[fs/lustre-release.git]
/
lustre
/
osd-zfs
/
osd_io.c
diff --git
a/lustre/osd-zfs/osd_io.c
b/lustre/osd-zfs/osd_io.c
index
f2a72b6
..
dd26c0a
100644
(file)
--- a/
lustre/osd-zfs/osd_io.c
+++ b/
lustre/osd-zfs/osd_io.c
@@
-141,14
+141,14
@@
static ssize_t osd_read(const struct lu_env *env, struct dt_object *dt,
{
struct osd_device *osd = osd_obj2dev(osd_dt_obj(dt));
size_t size = buf->lb_len;
-
ktime_t start
;
+
hrtime_t start = gethrtime()
;
s64 delta_ms;
int rc;
- start = ktime_get();
record_start_io(osd, READ, 0);
rc = __osd_read(env, dt, buf, pos, &size);
- delta_ms = ktime_ms_delta(ktime_get(), start);
+ delta_ms = gethrtime() - start;
+ do_div(delta_ms, NSEC_PER_MSEC);
record_end_io(osd, READ, delta_ms, size, size >> PAGE_SHIFT);
return rc;
@@
-334,7
+334,7
@@
static int osd_bufs_get_read(const struct lu_env *env, struct osd_object *obj,
{
struct osd_device *osd = osd_obj2dev(obj);
int rc, i, numbufs, npages = 0, drop_cache = 0;
-
ktime_t start = ktime_get
();
+
hrtime_t start = gethrtime
();
dmu_buf_t **dbp;
s64 delta_ms;
@@
-422,7
+422,8
@@
static int osd_bufs_get_read(const struct lu_env *env, struct osd_object *obj,
dmu_buf_rele_array(dbp, numbufs, osd_0copy_tag);
}
- delta_ms = ktime_ms_delta(ktime_get(), start);
+ delta_ms = gethrtime() - start;
+ do_div(delta_ms, NSEC_PER_MSEC);
record_end_io(osd, READ, delta_ms, npages * PAGE_SIZE, npages);
RETURN(npages);
@@
-613,11
+614,9
@@
static inline uint64_t osd_roundup2blocksz(uint64_t size,
size += offset % blksz;
if (likely(is_power_of_2(blksz)))
- return PO2_ROUNDUP_TYPED(size, blksz, uint64_t);
-
- size += blksz - 1;
- do_div(size, blksz);
- return size * blksz;
+ return round_up(size, blksz);
+ else
+ return DIV_ROUND_UP_ULL(size, blksz) * blksz;
}
static int osd_declare_write_commit(const struct lu_env *env,
@@
-1024,9
+1023,11
@@
static int osd_read_prep(const struct lu_env *env, struct dt_object *dt,
* dmu_tx_hold_sa() and if off < size, dmu_tx_hold_free()
* called and then assigned to a transaction group.
*/
-static int __osd_object_punch(
objset_t *os, dnode_t *dn, dmu_tx_t *tx
,
-
uint64_t size
, uint64_t off, uint64_t len)
+static int __osd_object_punch(
struct osd_object *obj, objset_t *os
,
+
dmu_tx_t *tx
, uint64_t off, uint64_t len)
{
+ dnode_t *dn = obj->oo_dn;
+ uint64_t size = obj->oo_attr.la_size;
int rc = 0;
/* Assert that the transaction has been assigned to a
@@
-1038,6
+1039,19
@@
static int __osd_object_punch(objset_t *os, dnode_t *dn, dmu_tx_t *tx,
if (len == DMU_OBJECT_END && size == off)
return 0;
+ /* if object holds encrypted content, we need to make sure we truncate
+ * on an encryption unit boundary, or subsequent reads will get
+ * corrupted content
+ */
+ if (len != DMU_OBJECT_END)
+ len -= LUSTRE_ENCRYPTION_UNIT_SIZE -
+ (off & ~LUSTRE_ENCRYPTION_MASK);
+ if (obj->oo_lma_flags & LUSTRE_ENCRYPT_FL &&
+ off & ~LUSTRE_ENCRYPTION_MASK)
+ off = (off & LUSTRE_ENCRYPTION_MASK) +
+ LUSTRE_ENCRYPTION_UNIT_SIZE;
+
+
/* XXX: dnode_free_range() can be used to save on dnode lookup */
if (off < size)
dmu_free_range(os, dn->dn_object, off, len, tx);
@@
-1069,8
+1083,8
@@
static int osd_punch(const struct lu_env *env, struct dt_object *dt,
len = end - start;
write_unlock(&obj->oo_attr_lock);
- rc = __osd_object_punch(o
sd->od_os, obj->oo_dn, oh->ot_tx,
- obj->oo_attr.la_size, start, len);
+ rc = __osd_object_punch(o
bj, osd->od_os, oh->ot_tx, start, len);
+
/* set new size */
if (len == DMU_OBJECT_END) {
write_lock(&obj->oo_attr_lock);
@@
-1100,6
+1114,14
@@
static int osd_declare_punch(const struct lu_env *env, struct dt_object *dt,
len = end - start;
/* declare we'll free some blocks ... */
+ /* if object holds encrypted content, we need to make sure we truncate
+ * on an encryption unit boundary, or subsequent reads will get
+ * corrupted content
+ */
+ if (obj->oo_lma_flags & LUSTRE_ENCRYPT_FL &&
+ start & ~LUSTRE_ENCRYPTION_MASK)
+ start = (start & LUSTRE_ENCRYPTION_MASK) +
+ LUSTRE_ENCRYPTION_UNIT_SIZE;
if (start < obj->oo_attr.la_size) {
read_unlock(&obj->oo_attr_lock);
dmu_tx_mark_netfree(oh->ot_tx);
@@
-1142,7
+1164,8
@@
static int osd_fallocate(const struct lu_env *env, struct dt_object *dt,
}
static int osd_declare_fallocate(const struct lu_env *env,
- struct dt_object *dt, struct thandle *th)
+ struct dt_object *dt, __u64 start, __u64 end,
+ int mode, struct thandle *th)
{
int rc = -EOPNOTSUPP;
ENTRY;
@@
-1154,6
+1177,48
@@
static int osd_declare_fallocate(const struct lu_env *env,
RETURN(rc);
}
+static loff_t osd_lseek(const struct lu_env *env, struct dt_object *dt,
+ loff_t offset, int whence)
+{
+ struct osd_object *obj = osd_dt_obj(dt);
+ uint64_t size = obj->oo_attr.la_size;
+ uint64_t result = offset;
+ int rc;
+ boolean_t hole = whence == SEEK_HOLE;
+
+ ENTRY;
+
+ LASSERT(dt_object_exists(dt));
+ LASSERT(osd_invariant(obj));
+ LASSERT(offset >= 0);
+
+ /* for SEEK_HOLE treat 'offset' beyond the end of file as in real
+ * hole. LOV to decide after all if that real hole or not.
+ */
+ if (offset >= size)
+ RETURN(hole ? offset : -ENXIO);
+
+ rc = osd_dmu_offset_next(osd_obj2dev(obj)->od_os,
+ obj->oo_dn->dn_object, hole, &result);
+ if (rc == ESRCH)
+ RETURN(-ENXIO);
+
+ /* file was dirty, so fall back to using generic logic:
+ * For HOLE return file size, for DATA the result is set
+ * already to the 'offset' parameter value.
+ */
+ if (rc == EBUSY && hole)
+ result = size;
+
+ /* dmu_offset_next() only works on whole blocks so may return SEEK_HOLE
+ * result as end of the last block instead of logical EOF which we need
+ */
+ if (result > size)
+ result = size;
+
+ RETURN(result);
+}
+
struct dt_body_operations osd_body_ops = {
.dbo_read = osd_read,
.dbo_declare_write = osd_declare_write,
@@
-1169,6
+1234,7
@@
struct dt_body_operations osd_body_ops = {
.dbo_ladvise = osd_ladvise,
.dbo_declare_fallocate = osd_declare_fallocate,
.dbo_fallocate = osd_fallocate,
+ .dbo_lseek = osd_lseek,
};
struct dt_body_operations osd_body_scrub_ops = {