* GPL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright (c) 2011 Whamcloud, Inc.
+ *
*/
/*
* This file is part of Lustre, http://www.lustre.org/
*/
enum cl_lock_transition {
/** operation cannot be completed immediately. Wait for state change. */
- CLO_WAIT = 1,
+ CLO_WAIT = 1,
/** operation had to release lock mutex, restart. */
- CLO_REPEAT = 2
+ CLO_REPEAT = 2,
+ /** lower layer re-enqueued. */
+ CLO_REENQUEUED = 3,
};
/**
CIT_READ,
/** write system call */
CIT_WRITE,
- /** truncate system call */
- CIT_TRUNC,
+ /** truncate, utime system calls */
+ CIT_SETATTR,
/**
* page fault handling
*/
*/
CEF_NEVER = 0x00000010,
/**
+ * for async glimpse lock.
+ */
+ CEF_AGL = 0x00000020,
+ /**
+ * do not trigger re-enqueue.
+ */
+ CEF_NO_REENQUEUE = 0x00000040,
+ /**
* mask of enq_flags.
*/
- CEF_MASK = 0x0000001f
+ CEF_MASK = 0x0000007f,
};
/**
/** Layers are free to decide between local and global locking. */
CILR_MAYBE,
/** Never lock: there is no cache (e.g., liblustre). */
- CILR_NEVER
+ CILR_NEVER,
+ /** Peek lock: use existing locks, don't queue new ones */
+ CILR_PEEK
};
struct cl_io_rw_common {
int wr_append;
} ci_wr;
struct cl_io_rw_common ci_rw;
- struct cl_truncate_io {
- /** new size to which file is truncated */
- size_t tr_size;
- struct obd_capa *tr_capa;
- } ci_truncate;
+ struct cl_setattr_io {
+ struct ost_lvb sa_attr;
+ unsigned int sa_valid;
+ struct obd_capa *sa_capa;
+ } ci_setattr;
struct cl_fault_io {
/** page index within file. */
pgoff_t ft_index;
/** bytes valid byte on a faulted page. */
int ft_nob;
- /** writable page? */
+ /** writable page? for nopage() only */
int ft_writable;
/** page of an executable? */
int ft_executable;
+ /** page_mkwrite() */
+ int ft_mkwrite;
/** resulting page */
struct cl_page *ft_page;
} ci_fault;
/** \defgroup cl_page cl_page
* @{ */
-struct cl_page *cl_page_lookup(struct cl_object_header *hdr,
+enum {
+ CLP_GANG_OKAY = 0,
+ CLP_GANG_RESCHED,
+ CLP_GANG_AGAIN,
+ CLP_GANG_ABORT
+};
+
+/* callback of cl_page_gang_lookup() */
+typedef int (*cl_page_gang_cb_t) (const struct lu_env *, struct cl_io *,
+ struct cl_page *, void *);
+int cl_page_gang_lookup (const struct lu_env *env,
+ struct cl_object *obj,
+ struct cl_io *io,
+ pgoff_t start, pgoff_t end,
+ cl_page_gang_cb_t cb, void *cbdata);
+struct cl_page *cl_page_lookup (struct cl_object_header *hdr,
pgoff_t index);
-void cl_page_gang_lookup(const struct lu_env *env,
- struct cl_object *obj,
- struct cl_io *io,
- pgoff_t start, pgoff_t end,
- struct cl_page_list *plist,
- int nonblock);
struct cl_page *cl_page_find (const struct lu_env *env,
struct cl_object *obj,
pgoff_t idx, struct page *vmpage,
struct cl_page *page);
struct cl_page *cl_vmpage_page (cfs_page_t *vmpage, struct cl_object *obj);
struct cl_page *cl_page_top (struct cl_page *page);
-int cl_is_page (const void *addr);
const struct cl_page_slice *cl_page_at(const struct cl_page *page,
const struct lu_device_type *dtype);
enum cl_lock_state cl_lock_intransit(const struct lu_env *env,
struct cl_lock *lock);
-
void cl_lock_extransit(const struct lu_env *env, struct cl_lock *lock,
enum cl_lock_state state);
-
int cl_lock_is_intransit(struct cl_lock *lock);
+int cl_lock_enqueue_wait(const struct lu_env *env, struct cl_lock *lock,
+ int keep_mutex);
+
/** \name statemachine statemachine
* Interface to lock state machine consists of 3 parts:
*
int cl_unuse_try (const struct lu_env *env, struct cl_lock *lock);
int cl_wait_try (const struct lu_env *env, struct cl_lock *lock);
int cl_use_try (const struct lu_env *env, struct cl_lock *lock, int atomic);
+
/** @} statemachine */
void cl_lock_signal (const struct lu_env *env, struct cl_lock *lock);
void cl_lock_delete(const struct lu_env *env, struct cl_lock *lock);
void cl_lock_error (const struct lu_env *env, struct cl_lock *lock, int error);
void cl_locks_prune(const struct lu_env *env, struct cl_object *obj, int wait);
-int cl_is_lock (const void *addr);
unsigned long cl_lock_weigh(const struct lu_env *env, struct cl_lock *lock);
return io->ci_type == CIT_WRITE && io->u.ci_wr.wr_append;
}
+/**
+ * True, iff \a io is a truncate(2).
+ */
+static inline int cl_io_is_trunc(const struct cl_io *io)
+{
+ return io->ci_type == CIT_SETATTR &&
+ (io->u.ci_setattr.sa_valid & ATTR_SIZE);
+}
+
struct cl_io *cl_io_top(struct cl_io *io);
void cl_io_print(const struct lu_env *env, void *cookie,
* @{ */
/**
+ * Last page in the page list.
+ */
+static inline struct cl_page *cl_page_list_last(struct cl_page_list *plist)
+{
+ LASSERT(plist->pl_nr > 0);
+ return cfs_list_entry(plist->pl_pages.prev, struct cl_page, cp_batch);
+}
+
+/**
* Iterate over pages in a page list.
*/
#define cl_page_list_for_each(page, list) \
void cl_env_unplant (struct lu_env *env, int *refcheck);
unsigned cl_env_cache_purge(unsigned nr);
+void cl_set_ctx_tags(__u32 tags);
+void cl_set_ses_tags(__u32 tags);
/** @} cl_env */
/*