* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2015, Intel Corporation.
+ * Copyright (c) 2011, 2016, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
* super-class definitions.
*/
#include <libcfs/libcfs.h>
+#include <libcfs/libcfs_ptask.h>
#include <lu_object.h>
#include <linux/atomic.h>
#include <linux/mutex.h>
struct cl_req_attr;
+extern struct cfs_ptask_engine *cl_io_engine;
+
/**
* Device in the client stack.
*
*/
loff_t cat_kms;
/** Modification time. Measured in seconds since epoch. */
- time_t cat_mtime;
+ time64_t cat_mtime;
/** Access time. Measured in seconds since epoch. */
- time_t cat_atime;
+ time64_t cat_atime;
/** Change time. Measured in seconds since epoch. */
- time_t cat_ctime;
+ time64_t cat_ctime;
/**
* Blocks allocated to this cl_object on the server file system.
*
/* nlink of the directory */
__u64 cat_nlink;
+
+ /* Project identifier for quota purpose. */
+ __u32 cat_projid;
};
/**
* Fields in cl_attr that are being set.
*/
enum cl_attr_valid {
- CAT_SIZE = 1 << 0,
- CAT_KMS = 1 << 1,
- CAT_MTIME = 1 << 3,
- CAT_ATIME = 1 << 4,
- CAT_CTIME = 1 << 5,
- CAT_BLOCKS = 1 << 6,
- CAT_UID = 1 << 7,
- CAT_GID = 1 << 8
+ CAT_SIZE = 1 << 0,
+ CAT_KMS = 1 << 1,
+ CAT_MTIME = 1 << 3,
+ CAT_ATIME = 1 << 4,
+ CAT_CTIME = 1 << 5,
+ CAT_BLOCKS = 1 << 6,
+ CAT_UID = 1 << 7,
+ CAT_GID = 1 << 8,
+ CAT_PROJID = 1 << 9
};
/**
size_t cl_size;
/** Layout generation. */
u32 cl_layout_gen;
+ /** whether layout is a composite one */
+ bool cl_is_composite;
};
/**
* Object getstripe method.
*/
int (*coo_getstripe)(const struct lu_env *env, struct cl_object *obj,
- struct lov_user_md __user *lum);
+ struct lov_user_md __user *lum, size_t size);
/**
* Get FIEMAP mapping from the object.
*/
/** IO types */
enum cl_io_type {
/** read system call */
- CIT_READ,
+ CIT_READ = 1,
/** write system call */
CIT_WRITE,
/** truncate, utime system calls */
* -EWOULDBLOCK is returned immediately.
*/
CEF_NONBLOCK = 0x00000001,
- /**
- * take lock asynchronously (out of order), as it cannot
- * deadlock. This is for LDLM_FL_HAS_INTENT locks used for glimpsing.
- */
- CEF_ASYNC = 0x00000002,
+ /**
+ * Tell lower layers this is a glimpse request, translated to
+ * LDLM_FL_HAS_INTENT at LDLM layer.
+ *
+ * Also, because glimpse locks never block other locks, we count this
+ * as automatically compatible with other osc locks.
+ * (see osc_lock_compatible)
+ */
+ CEF_GLIMPSE = 0x00000002,
/**
* tell the server to instruct (though a flag in the blocking ast) an
* owner of the conflicting lock, that it can drop dirty pages
* protected by this lock, without sending them to the server.
*/
CEF_DISCARD_DATA = 0x00000004,
- /**
- * tell the sub layers that it must be a `real' lock. This is used for
- * mmapped-buffer locks and glimpse locks that must be never converted
- * into lockless mode.
- *
- * \see vvp_mmap_locks(), cl_glimpse_lock().
- */
- CEF_MUST = 0x00000008,
+ /**
+ * tell the sub layers that it must be a `real' lock. This is used for
+ * mmapped-buffer locks, glimpse locks, manually requested locks
+ * (LU_LADVISE_LOCKAHEAD) that must never be converted into lockless
+ * mode.
+ *
+ * \see vvp_mmap_locks(), cl_glimpse_lock, cl_request_lock().
+ */
+ CEF_MUST = 0x00000008,
/**
* tell the sub layers that never request a `real' lock. This flag is
* not used currently.
*/
CEF_NEVER = 0x00000010,
/**
- * for async glimpse lock.
+ * tell the dlm layer this is a speculative lock request
+ * speculative lock requests are locks which are not requested as part
+ * of an I/O operation. Instead, they are requested because we expect
+ * to use them in the future. They are requested asynchronously at the
+ * ptlrpc layer.
+ *
+ * Currently used for asynchronous glimpse locks and manually requested
+ * locks (LU_LADVISE_LOCKAHEAD).
*/
- CEF_AGL = 0x00000020,
+ CEF_SPECULATIVE = 0x00000020,
/**
* enqueue a lock to test DLM lock existence.
*/
*/
CEF_LOCK_MATCH = 0x00000080,
/**
+ * tell the DLM layer to lock only the requested range
+ */
+ CEF_LOCK_NO_EXPAND = 0x00000100,
+ /**
* mask of enq_flags.
*/
- CEF_MASK = 0x000000ff,
+ CEF_MASK = 0x000001ff,
};
/**
CL_FSYNC_ALL = 3
};
-struct cl_io_rw_common {
- loff_t crw_pos;
- size_t crw_count;
- int crw_nonblock;
+struct cl_io_range {
+ loff_t cir_pos;
+ size_t cir_count;
+};
+
+struct cl_io_pt {
+ struct cl_io_pt *cip_next;
+ struct cfs_ptask cip_task;
+ struct kiocb cip_iocb;
+ struct iov_iter cip_iter;
+ struct file *cip_file;
+ enum cl_io_type cip_iot;
+ loff_t cip_pos;
+ size_t cip_count;
+ ssize_t cip_result;
};
/**
/** lock requirements, this is just a help info for sublayers. */
enum cl_io_lock_dmd ci_lockreq;
union {
- struct cl_rd_io {
- struct cl_io_rw_common rd;
- } ci_rd;
- struct cl_wr_io {
- struct cl_io_rw_common wr;
- int wr_append;
- int wr_sync;
- } ci_wr;
- struct cl_io_rw_common ci_rw;
+ struct cl_rw_io {
+ struct iov_iter rw_iter;
+ struct kiocb rw_iocb;
+ struct cl_io_range rw_range;
+ struct file *rw_file;
+ unsigned int rw_nonblock:1,
+ rw_append:1,
+ rw_sync:1;
+ int (*rw_ptask)(struct cfs_ptask *ptask);
+ } ci_rw;
struct cl_setattr_io {
struct ost_lvb sa_attr;
unsigned int sa_attr_flags;
unsigned int sa_valid;
int sa_stripe_index;
+ struct ost_layout sa_layout;
const struct lu_fid *sa_parent_fid;
} ci_setattr;
struct cl_data_version_io {
*/
ci_ignore_layout:1,
/**
+ * Need MDS intervention to complete a write. This usually means the
+ * corresponding component is not initialized for the writing extent.
+ */
+ ci_need_write_intent:1,
+ /**
* Check if layout changed after the IO finishes. Mainly for HSM
* requirement. If IO occurs to openning files, it doesn't need to
* verify layout because HSM won't release openning files.
/**
* O_NOATIME
*/
- ci_noatime:1;
+ ci_noatime:1,
+ /** Set to 1 if parallel execution is allowed for current I/O? */
+ ci_pio:1,
+ /* Tell sublayers not to expand LDLM locks requested for this IO */
+ ci_lock_no_expand:1;
/**
* Number of pages owned by this IO. For invariant checking.
*/
int cl_object_prune (const struct lu_env *env, struct cl_object *obj);
void cl_object_kill (const struct lu_env *env, struct cl_object *obj);
int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
- struct lov_user_md __user *lum);
+ struct lov_user_md __user *lum, size_t size);
int cl_object_fiemap(const struct lu_env *env, struct cl_object *obj,
struct ll_fiemap_info_key *fmkey, struct fiemap *fiemap,
size_t *buflen);
size_t nob);
int cl_io_cancel (const struct lu_env *env, struct cl_io *io,
struct cl_page_list *queue);
-int cl_io_is_going (const struct lu_env *env);
/**
* True, iff \a io is an O_APPEND write(2).
*/
static inline int cl_io_is_append(const struct cl_io *io)
{
- return io->ci_type == CIT_WRITE && io->u.ci_wr.wr_append;
+ return io->ci_type == CIT_WRITE && io->u.ci_rw.rw_append;
}
static inline int cl_io_is_sync_write(const struct cl_io *io)
{
- return io->ci_type == CIT_WRITE && io->u.ci_wr.wr_sync;
+ return io->ci_type == CIT_WRITE && io->u.ci_rw.rw_sync;
}
static inline int cl_io_is_mkwrite(const struct cl_io *io)