LL_SBI_FILE_HEAT, /* file heat support */
LL_SBI_PARALLEL_DIO, /* parallel (async) O_DIRECT RPCs */
LL_SBI_ENCRYPT_NAME, /* name encryption */
+ LL_SBI_UNALIGNED_DIO, /* unaligned DIO */
LL_SBI_NUM_FLAGS
};
return test_bit(LL_SBI_PARALLEL_DIO, sbi->ll_flags);
}
+static inline bool ll_sbi_has_unaligned_dio(struct ll_sb_info *sbi)
+{
+ return test_bit(LL_SBI_UNALIGNED_DIO, sbi->ll_flags);
+}
+
void ll_ras_enter(struct file *f, loff_t pos, size_t bytes);
/* llite/lcommon_misc.c */
set_bit(LL_SBI_FAST_READ, sbi->ll_flags);
set_bit(LL_SBI_TINY_WRITE, sbi->ll_flags);
set_bit(LL_SBI_PARALLEL_DIO, sbi->ll_flags);
+ set_bit(LL_SBI_UNALIGNED_DIO, sbi->ll_flags);
ll_sbi_set_encrypt(sbi, true);
ll_sbi_set_name_encrypt(sbi, true);
{LL_SBI_FILE_HEAT, "file_heat"},
{LL_SBI_PARALLEL_DIO, "parallel_dio"},
{LL_SBI_ENCRYPT_NAME, "name_encrypt"},
+ {LL_SBI_UNALIGNED_DIO, "unaligned_dio"},
};
int ll_sbi_flags_seq_show(struct seq_file *m, void *v)
}
LUSTRE_RW_ATTR(tiny_write);
+static ssize_t unaligned_dio_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf)
+{
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kset.kobj);
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n",
+ test_bit(LL_SBI_UNALIGNED_DIO, sbi->ll_flags));
+}
+
+static ssize_t unaligned_dio_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer,
+ size_t count)
+{
+ struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
+ ll_kset.kobj);
+ bool val;
+ int rc;
+
+ rc = kstrtobool(buffer, &val);
+ if (rc)
+ return rc;
+
+ spin_lock(&sbi->ll_lock);
+ if (val)
+ set_bit(LL_SBI_UNALIGNED_DIO, sbi->ll_flags);
+ else
+ clear_bit(LL_SBI_UNALIGNED_DIO, sbi->ll_flags);
+ spin_unlock(&sbi->ll_lock);
+
+ return count;
+}
+LUSTRE_RW_ATTR(unaligned_dio);
+
static ssize_t parallel_dio_show(struct kobject *kobj,
struct attribute *attr,
char *buf)
&lustre_attr_fast_read.attr,
&lustre_attr_tiny_write.attr,
&lustre_attr_parallel_dio.attr,
+ &lustre_attr_unaligned_dio.attr,
&lustre_attr_file_heat.attr,
&lustre_attr_heat_decay_percentage.attr,
&lustre_attr_heat_period_second.attr,
ENTRY;
- /* Check EOF by ourselves */
- if (rw == READ && file_offset >= i_size_read(inode))
- RETURN(0);
-
if (file_offset & ~PAGE_MASK)
unaligned = true;
(count >> PAGE_SHIFT) + !!(count & ~PAGE_MASK),
MAX_DIO_SIZE >> PAGE_SHIFT, unaligned ? ", unaligned" : "");
+ /* Check EOF by ourselves */
+ if (rw == READ && file_offset >= i_size_read(inode))
+ RETURN(0);
+
+ /* unaligned DIO support can be turned off, so is it on? */
+ if (unaligned && !ll_sbi_has_unaligned_dio(ll_i2sbi(inode)))
+ RETURN(-EINVAL);
+
/* the requirement to not return EIOCBQUEUED for pipes (see bottom of
* this function) plays havoc with the unaligned I/O lifecycle, so
* don't allow unaligned I/O on pipes
iflag=direct oflag=direct ||
error "trivial unaligned dio failed"
+ # Test of disabling unaligned DIO support
+ $LCTL set_param llite.*.unaligned_dio=0
+ stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
+ echo "testing disabling unaligned DIO - 'invalid argument' expected:"
+ dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
+ iflag=direct oflag=direct &&
+ error "unaligned dio succeeded when disabled"
+ $LCTL set_param llite.*.unaligned_dio=1
+
# Clean up before next part of test
rm -f $DIR/$tfile.2