kernel 3.6 changes i_dentry/d_alias from list to hlist.
Signed-off-by: Peng Tao <tao.peng@emc.com>
Signed-off-by: yang sheng <ys@whamcloud.com>
Change-Id: If05f01fe6fe34225ec24b90bf85eb9e9e80f44f3
Reviewed-on: http://review.whamcloud.com/4385
Tested-by: Hudson
Reviewed-by: Lai Siyao <laisiyao@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Yang Sheng <yang.sheng@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
])
#
+# 3.6 switch i_dentry/d_alias from list to hlist
+#
+AC_DEFUN([LC_HAVE_DENTRY_D_ALIAS_HLIST],
+[AC_MSG_CHECKING([if i_dentry/d_alias uses hlist])
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ #include <linux/list.h>
+],[
+ struct inode inode;
+ struct dentry dentry;
+ struct hlist_head head;
+ struct hlist_node node;
+ inode.i_dentry = head;
+ dentry.d_alias = node;
+],[
+ AC_DEFINE(HAVE_DENTRY_D_ALIAS_HLIST, 1,
+ [have i_dentry/d_alias uses hlist])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+])
+
+#
# LC_PROG_LINUX
#
# Lustre linux kernel checks
LC_HAVE_CLEAR_INODE
LC_HAVE_ENCODE_FH_PARENT
+ # 3.6
+ LC_HAVE_DENTRY_D_ALIAS_HLIST
+
#
if test x$enable_server = xyes ; then
AC_DEFINE(HAVE_SERVER_SUPPORT, 1, [support server])
#define clear_inode(i) end_writeback(i)
#endif
+#ifdef HAVE_DENTRY_D_ALIAS_HLIST
+#define ll_d_hlist_node hlist_node
+#define ll_d_hlist_empty(list) hlist_empty(list)
+#define ll_d_hlist_entry(ptr, type, name) hlist_entry(ptr.first, type, name)
+#define ll_d_hlist_for_each(tmp, i_dentry) hlist_for_each(tmp, i_dentry)
+#define ll_d_hlist_for_each_entry(dentry, p, i_dentry, alias) \
+ hlist_for_each_entry(dentry, p, i_dentry, alias)
+#else
+#define ll_d_hlist_node list_head
+#define ll_d_hlist_empty(list) list_empty(list)
+#define ll_d_hlist_entry(ptr, type, name) list_entry(ptr.next, type, name)
+#define ll_d_hlist_for_each(tmp, i_dentry) list_for_each(tmp, i_dentry)
+#define ll_d_hlist_for_each_entry(dentry, p, i_dentry, alias) \
+ p = NULL; list_for_each_entry(dentry, i_dentry, alias)
+#endif
+
#ifndef HAVE_BI_HW_SEGMENTS
#define bio_hw_segments(q, bio) 0
void ll_invalidate_aliases(struct inode *inode)
{
struct dentry *dentry;
+ struct ll_d_hlist_node *p;
ENTRY;
LASSERT(inode != NULL);
inode->i_ino, inode->i_generation, inode);
ll_lock_dcache(inode);
- cfs_list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
- CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p "
- "inode %p flags %d\n", dentry->d_name.len,
- dentry->d_name.name, dentry, dentry->d_parent,
- dentry->d_inode, dentry->d_flags);
+ ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) {
+ CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p "
+ "inode %p flags %d\n", dentry->d_name.len,
+ dentry->d_name.name, dentry, dentry->d_parent,
+ dentry->d_inode, dentry->d_flags);
if (dentry->d_name.len == 1 && dentry->d_name.name[0] == '/') {
CERROR("called on root (?) dentry=%p, inode=%p "
void ll_dump_inode(struct inode *inode)
{
- struct list_head *tmp;
- int dentry_count = 0;
+ struct ll_d_hlist_node *tmp;
+ int dentry_count = 0;
- LASSERT(inode != NULL);
+ LASSERT(inode != NULL);
- list_for_each(tmp, &inode->i_dentry)
- dentry_count++;
+ ll_d_hlist_for_each(tmp, &inode->i_dentry)
+ dentry_count++;
- CERROR("inode %p dump: dev=%s ino=%lu mode=%o count=%u, %d dentries\n",
- inode, ll_i2mdexp(inode)->exp_obd->obd_name, inode->i_ino,
- inode->i_mode, atomic_read(&inode->i_count), dentry_count);
+ CERROR("inode %p dump: dev=%s ino=%lu mode=%o count=%u, %d dentries\n",
+ inode, ll_i2mdexp(inode)->exp_obd->obd_name, inode->i_ino,
+ inode->i_mode, atomic_read(&inode->i_count), dentry_count);
}
void lustre_dump_dentry(struct dentry *dentry, int recur)
static void ll_invalidate_negative_children(struct inode *dir)
{
struct dentry *dentry, *tmp_subdir;
+ struct ll_d_hlist_node *p;
ll_lock_dcache(dir);
- list_for_each_entry(dentry, &dir->i_dentry, d_alias) {
+ ll_d_hlist_for_each_entry(dentry, p, &dir->i_dentry, d_alias) {
spin_lock(&dentry->d_lock);
if (!list_empty(&dentry->d_subdirs)) {
struct dentry *child;
static struct dentry *ll_find_alias(struct inode *inode, struct dentry *dentry)
{
struct dentry *alias, *discon_alias, *invalid_alias;
+ struct ll_d_hlist_node *p;
- if (list_empty(&inode->i_dentry))
+ if (ll_d_hlist_empty(&inode->i_dentry))
return NULL;
discon_alias = invalid_alias = NULL;
ll_lock_dcache(inode);
- list_for_each_entry(alias, &inode->i_dentry, d_alias) {
+ ll_d_hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) {
LASSERT(alias != dentry);
spin_lock(&alias->d_lock);
if (rc)
GOTO(out, inode = ERR_PTR(rc));
- LASSERT(list_empty(&inode->i_dentry));
+ LASSERT(ll_d_hlist_empty(&inode->i_dentry));
/* We asked for a lock on the directory, but were granted a
* lock on the inode. Since we finally have an inode pointer,
static void ll_get_child_fid(struct inode * dir, struct qstr *name,
struct lu_fid *fid)
{
- struct dentry *parent, *child;
+ struct dentry *parent, *child;
- parent = list_entry(dir->i_dentry.next, struct dentry, d_alias);
- child = d_lookup(parent, name);
+ parent = ll_d_hlist_entry(dir->i_dentry, struct dentry, d_alias);
+ child = d_lookup(parent, name);
if (child) {
if (child->d_inode)
*fid = *ll_inode2fid(child->d_inode);