.RS 1.2i
.TP
\fBwillread\fR to prefetch data into server cache
+.TP
+\fBdontneed\fR to cleanup data cache on server
.RE
.TP
\fB\-b\fR, \fB\-\-background
.B $ lfs ladvise -a willread -s 0 -e 1048576000 /mnt/lustre/file1
This gives the OST(s) holding the first 1GB of \fB/mnt/lustre/file1\fR a hint
that the first 1GB of the file will be read soon.
+.TP
+.B $ lfs ladvise -a dontneed -s 0 -e 1048576000 /mnt/lustre/file1
+This gives the OST(s) holding the first 1GB of \fB/mnt/lustre/file1\fR a hint
+that the first 1GB of file will not be read in the near future, thus the OST(s)
+could clear the cache of the file in the memory.
.SH AVAILABILITY
The lfs ladvise command is part of the Lustre filesystem.
.SH SEE ALSO
enum lu_ladvise_type {
LU_LADVISE_INVALID = 0,
LU_LADVISE_WILLREAD = 1,
+ LU_LADVISE_DONTNEED = 2,
};
#define LU_LADVISE_NAMES { \
[LU_LADVISE_WILLREAD] = "willread", \
+ [LU_LADVISE_DONTNEED] = "dontneed", \
}
/* This is the userspace argument for ladvise. It is currently the same as
struct lustre_handle lockh = { 0 };
__u64 flags = 0;
int i;
+ struct dt_object *dob;
ENTRY;
CFS_FAIL_TIMEOUT(OBD_FAIL_OST_LADVISE_PAUSE, cfs_fail_val);
RETURN(rc);
}
LASSERT(fo != NULL);
+ dob = ofd_object_child(fo);
for (i = 0; i < num_advise; i++, ladvise++) {
if (ladvise->lla_end <= ladvise->lla_start) {
ladvise->lla_end);
tgt_extent_unlock(&lockh, LCK_PR);
break;
+ case LU_LADVISE_DONTNEED:
+ rc = dt_ladvise(env, dob, ladvise->lla_start,
+ ladvise->lla_end, LU_LADVISE_DONTNEED);
+ break;
}
if (rc != 0)
break;
static int osd_ladvise(const struct lu_env *env, struct dt_object *dt,
__u64 start, __u64 end, enum lu_ladvise_type advice)
{
- int rc;
+ int rc = 0;
+ struct inode *inode = osd_dt_obj(dt)->oo_inode;
ENTRY;
switch (advice) {
+ case LU_LADVISE_DONTNEED:
+ if (end == 0)
+ break;
+ invalidate_mapping_pages(inode->i_mapping,
+ start >> PAGE_CACHE_SHIFT,
+ (end - 1) >> PAGE_CACHE_SHIFT);
+ break;
default:
rc = -ENOTSUPP;
break;
(long long)(int)sizeof(((struct lu_ladvise *)0)->lla_value4));
LASSERTF(LU_LADVISE_WILLREAD == 1, "found %lld\n",
(long long)LU_LADVISE_WILLREAD);
+ LASSERTF(LU_LADVISE_DONTNEED == 2, "found %lld\n",
+ (long long)LU_LADVISE_DONTNEED);
/* Checks for struct ladvise_hdr */
LASSERTF(LADVISE_MAGIC == 0x1ADF1CE0, "found 0x%.8x\n",
}
run_test 255a "check 'lfs ladvise -a willread'"
+facet_meminfo() {
+ local facet=$1
+ local info=$2
+
+ do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
+}
+
+test_255b() {
+ lfs setstripe -c -1 -i 0 $DIR/$tfile
+
+ ladvise_no_type dontneed $DIR/$tfile &&
+ skip "dontneed ladvise is not supported" && return
+
+ ladvise_no_ioctl $DIR/$tfile &&
+ skip "ladvise ioctl is not supported" && return
+
+ [ $(lustre_version_code ost1) -lt $(version_code 2.8.54) ] &&
+ skip "lustre < 2.8.54 does not support ladvise" && return
+
+ [ "$(facet_fstype ost1)" = "zfs" ] &&
+ skip "zfs-osd does not support dontneed advice" && return
+
+ local size_mb=100
+ local size=$((size_mb * 1048576))
+ # In order to prevent disturbance of other processes, only check 3/4
+ # of the memory usage
+ local kibibytes=$((size_mb * 1024 * 3 / 4))
+
+ dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
+ error "dd to $DIR/$tfile failed"
+
+ local total=$(facet_meminfo ost1 MemTotal)
+ echo "Total memory: $total KiB"
+
+ do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
+ local before_read=$(facet_meminfo ost1 Cached)
+ echo "Cache used before read: $before_read KiB"
+
+ lfs ladvise -a willread $DIR/$tfile ||
+ error "Ladvise willread failed"
+ local after_read=$(facet_meminfo ost1 Cached)
+ echo "Cache used after read: $after_read KiB"
+
+ lfs ladvise -a dontneed $DIR/$tfile ||
+ error "Ladvise dontneed again failed"
+ local no_read=$(facet_meminfo ost1 Cached)
+ echo "Cache used after dontneed ladvise: $no_read KiB"
+
+ if [ $total -lt $((before_read + kibibytes)) ]; then
+ echo "Memory is too small, abort checking"
+ return 0
+ fi
+
+ if [ $((before_read + kibibytes)) -gt $after_read ]; then
+ error "Ladvise willread should use more memory" \
+ "than $kibibytes KiB"
+ fi
+
+ if [ $((no_read + kibibytes)) -gt $after_read ]; then
+ error "Ladvise dontneed should release more memory" \
+ "than $kibibytes KiB"
+ fi
+}
+run_test 255b "check 'lfs ladvise -a dontneed'"
+
test_256() {
local cl_user
local cat_sl
CHECK_MEMBER(lu_ladvise, lla_value3);
CHECK_MEMBER(lu_ladvise, lla_value4);
CHECK_VALUE(LU_LADVISE_WILLREAD);
+ CHECK_VALUE(LU_LADVISE_DONTNEED);
CHECK_VALUE(LF_ASYNC);
CHECK_VALUE(LADVISE_MAGIC);
(long long)(int)sizeof(((struct lu_ladvise *)0)->lla_value4));
LASSERTF(LU_LADVISE_WILLREAD == 1, "found %lld\n",
(long long)LU_LADVISE_WILLREAD);
+ LASSERTF(LU_LADVISE_DONTNEED == 2, "found %lld\n",
+ (long long)LU_LADVISE_DONTNEED);
/* Checks for struct ladvise_hdr */
LASSERTF(LADVISE_MAGIC == 0x1ADF1CE0, "found 0x%.8x\n",