DCACHE_LUSTRE_INVALID is lustre private flag in vfs layer.
Replace it with dentry->d_fsdata->lld_invalid so that it won't
conflict with VFS flags.
After dcache scalability patch, dentry->d_fsdata is always set
before dentry is materised/rehashed. So if a dentry's d_fsdata
is not set, then it is not hashed/materised. The patch make use
of the fact and treat such dentry as invalid as well. It is
necessary because d_lustre_invalidate() can be called in
ll_invalidate_negative_children() and finds unmaterised/unhashed
dentries.
Also drop all vfs_races patches as they are no longer needed.
Plus two minor cleanups.
Signed-off-by: Peng Tao <tao.peng@emc.com>
Change-Id: I655154b8807440c99574ad6b865bd550cbc145f1
Reviewed-on: http://review.whamcloud.com/2407
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Fan Yong <yong.fan@whamcloud.com>
Reviewed-by: Lai Siyao <laisiyao@whamcloud.com>
+++ /dev/null
-diff -urp linux-2.6.18.rawops/fs/dcache.c linux-2.6.18.races/fs/dcache.c
---- linux-2.6.18.rawops/fs/dcache.c 2007-02-08 19:00:31.000000000 +0200
-+++ linux-2.6.18.races/fs/dcache.c 2007-02-14 19:23:49.000000000 +0200
-@@ -230,6 +230,13 @@ int d_invalidate(struct dentry * dentry)
- spin_unlock(&dcache_lock);
- return 0;
- }
-+
-+ /* network invalidation by Lustre */
-+ if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
-+ spin_unlock(&dcache_lock);
-+ return 0;
-+ }
-+
- /*
- * Check whether to do a partial shrink_dcache
- * to get rid of unused child entries.
-@@ -1400,13 +1407,21 @@ static void _d_rehash(struct dentry * en
- * Adds a dentry to the hash according to its name.
- */
-
--void d_rehash(struct dentry * entry)
-+void d_rehash_cond(struct dentry * entry, int lock)
- {
-- spin_lock(&dcache_lock);
-+ if (lock)
-+ spin_lock(&dcache_lock);
- spin_lock(&entry->d_lock);
- _d_rehash(entry);
- spin_unlock(&entry->d_lock);
-- spin_unlock(&dcache_lock);
-+ if (lock)
-+ spin_unlock(&dcache_lock);
-+}
-+EXPORT_SYMBOL(d_rehash_cond);
-+
-+void d_rehash(struct dentry * entry)
-+{
-+ d_rehash_cond(entry, 1);
- }
-
- #define do_switch(x,y) do { \
-diff -urp linux-2.6.18.rawops/include/linux/dcache.h linux-2.6.18.races/include/linux/dcache.h
---- linux-2.6.18.rawops/include/linux/dcache.h 2007-02-14 16:52:37.000000000 +0200
-+++ linux-2.6.18.races/include/linux/dcache.h 2007-02-14 19:21:14.000000000 +0200
-@@ -177,6 +177,7 @@ d_iput: no no no yes
-
- #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */
- #define DCACHE_UNHASHED 0x0010
-+#define DCACHE_LUSTRE_INVALID 0x0040 /* Lustre invalidated */
-
- #define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 /* Parent inode is watched */
-
-@@ -254,6 +255,7 @@ extern int have_submounts(struct dentry
- * This adds the entry to the hash queues.
- */
- extern void d_rehash(struct dentry *);
-+extern void d_rehash_cond(struct dentry *, int lock);
-
- /**
- * d_add - add dentry to hash queues
+++ /dev/null
-Index: linux-2.6.22.5/fs/dcache.c
-===================================================================
---- linux-2.6.22.5.orig/fs/dcache.c 2007-08-22 17:23:54.000000000 -0600
-+++ linux-2.6.22.5/fs/dcache.c 2008-02-21 00:56:09.000000000 -0700
-@@ -245,6 +245,13 @@
- spin_unlock(&dcache_lock);
- return 0;
- }
-+
-+ /* network invalidation by Lustre */
-+ if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
-+ spin_unlock(&dcache_lock);
-+ return 0;
-+ }
-+
- /*
- * Check whether to do a partial shrink_dcache
- * to get rid of unused child entries.
-Index: linux-2.6.22.5/include/linux/dcache.h
-===================================================================
---- linux-2.6.22.5.orig/include/linux/dcache.h 2007-08-22 17:23:54.000000000 -0600
-+++ linux-2.6.22.5/include/linux/dcache.h 2008-02-21 00:56:09.000000000 -0700
-@@ -174,6 +174,7 @@
-
- #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */
- #define DCACHE_UNHASHED 0x0010
-+#define DCACHE_LUSTRE_INVALID 0x0040 /* Lustre invalidated */
-
- #define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 /* Parent inode is watched */
-
+++ /dev/null
-Index: linux-2.6.32-71.18.1.el6/fs/dcache.c
-===================================================================
---- linux-2.6.32-71.18.1.el6.orig/fs/dcache.c
-+++ linux-2.6.32-71.18.1.el6/fs/dcache.c
-@@ -280,6 +280,13 @@ int d_invalidate(struct dentry * dentry)
- spin_unlock(&dcache_lock);
- return 0;
- }
-+
-+ /* network invalidation by Lustre */
-+ if (dentry->d_flags & DCACHE_LUSTRE_INVALID) {
-+ spin_unlock(&dcache_lock);
-+ return 0;
-+ }
-+
- /*
- * Check whether to do a partial shrink_dcache
- * to get rid of unused child entries.
-Index: linux-2.6.32-71.18.1.el6/include/linux/dcache.h
-===================================================================
---- linux-2.6.32-71.18.1.el6.orig/include/linux/dcache.h
-+++ linux-2.6.32-71.18.1.el6/include/linux/dcache.h
-@@ -185,6 +185,7 @@ d_iput: no no no yes
- #define DCACHE_MANAGE_TRANSIT 0x40000 /* manage transit from this dirent */
- #define DCACHE_MANAGED_DENTRY \
- (DCACHE_MOUNTED|DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT)
-+#define DCACHE_LUSTRE_INVALID 0x4000000 /* Lustre invalidated */
-
- extern spinlock_t dcache_lock;
- extern seqlock_t rename_lock;
lustre_version.patch
-vfs_races-2.6-rhel5.patch
jbd-jcberr-2.6.18-vanilla.patch
export_symbols-2.6.12.patch
dev_read_only-2.6.18-vanilla.patch
lustre_version.patch
mpt-fusion-max-sge-rhel6.patch
raid5-mmp-unplug-dev-rhel6.patch
-vfs_races-2.6.32-rhel6.patch
dev_read_only-2.6.32-rhel6.patch
blkdev_tunables-2.6-rhel6.patch
export-2.6.32-vanilla.patch
-vfs_races-2.6.22-vanilla.patch
iopen-misc-2.6.22-vanilla.patch
export_symbols-2.6.22-vanilla.patch
dev_read_only-2.6.27-vanilla.patch
#include "llite_internal.h"
+static void free_dentry_data(struct rcu_head *head)
+{
+ struct ll_dentry_data *lld;
+
+ lld = container_of(head, struct ll_dentry_data, lld_rcu_head);
+ OBD_FREE_PTR(lld);
+}
+
/* should NOT be called with the dcache lock, see fs/dcache.c */
static void ll_release(struct dentry *de)
{
ll_intent_release(lld->lld_it);
OBD_FREE(lld->lld_it, sizeof(*lld->lld_it));
}
- LASSERT(lld->lld_cwd_count == 0);
- LASSERT(lld->lld_mnt_count == 0);
- OBD_FREE(de->d_fsdata, sizeof(*lld));
+ LASSERT(lld->lld_cwd_count == 0);
+ LASSERT(lld->lld_mnt_count == 0);
+ de->d_fsdata = NULL;
+ call_rcu(&lld->lld_rcu_head, free_dentry_data);
- EXIT;
+ EXIT;
}
/* Compare if two dentries are the same. Don't match if the existing dentry
- * is marked DCACHE_LUSTRE_INVALID. Returns 1 if different, 0 if the same.
+ * is marked invalid. Returns 1 if different, 0 if the same.
*
* This avoids a race where ll_lookup_it() instantiates a dentry, but we get
* an AST before calling d_revalidate_it(). The dentry still exists (marked
if (it->it_op == IT_LOOKUP && !d_lustre_invalid(de))
RETURN(1);
- if ((it->it_op == IT_OPEN) && de->d_inode) {
- struct inode *inode = de->d_inode;
- struct ll_inode_info *lli = ll_i2info(inode);
- struct obd_client_handle **och_p;
- __u64 *och_usecount;
- __u64 ibits;
+ if (it->it_op == IT_OPEN) {
+ struct inode *inode = de->d_inode;
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct obd_client_handle **och_p;
+ __u64 *och_usecount;
+ __u64 ibits;
/*
* We used to check for MDS_INODELOCK_OPEN here, but in fact
#define LL_DIR_END_OFF 0x7fffffffffffffffULL
#define LL_DIR_END_OFF_32BIT 0x7fffffffUL
-#ifndef DCACHE_LUSTRE_INVALID
-#define DCACHE_LUSTRE_INVALID 0x4000000
-#endif
-
#define LL_IT2STR(it) ((it) ? ldlm_it2str((it)->it_op) : "0")
#define LUSTRE_FPRIVATE(file) ((file)->private_data)
struct ll_dentry_data {
- int lld_cwd_count;
- int lld_mnt_count;
- struct obd_client_handle lld_cwd_och;
- struct obd_client_handle lld_mnt_och;
- struct lookup_intent *lld_it;
- unsigned int lld_sa_generation;
+ int lld_cwd_count;
+ int lld_mnt_count;
+ struct obd_client_handle lld_cwd_och;
+ struct obd_client_handle lld_mnt_och;
+ struct lookup_intent *lld_it;
+ unsigned int lld_sa_generation;
+ unsigned int lld_invalid:1;
+ struct rcu_head lld_rcu_head;
};
#define ll_d2d(de) ((struct ll_dentry_data*)((de)->d_fsdata))
static inline int d_lustre_invalid(const struct dentry *dentry)
{
- return dentry->d_flags & DCACHE_LUSTRE_INVALID;
+ struct ll_dentry_data *lld = ll_d2d(dentry);
+
+ return (lld == NULL) || lld->lld_invalid;
}
static inline void __d_lustre_invalidate(struct dentry *dentry)
{
- dentry->d_flags |= DCACHE_LUSTRE_INVALID;
+ struct ll_dentry_data *lld = ll_d2d(dentry);
+
+ if (lld != NULL)
+ lld->lld_invalid = 1;
}
/*
static inline void d_lustre_revalidate(struct dentry *dentry)
{
spin_lock(&dentry->d_lock);
- dentry->d_flags &= ~DCACHE_LUSTRE_INVALID;
+ LASSERT(ll_d2d(dentry) != NULL);
+ ll_d2d(dentry)->lld_invalid = 0;
spin_unlock(&dentry->d_lock);
}
}
/*
- * Similar to d_splice_alias(), but lustre treats DCACHE_LUSTRE_INVALID alias
+ * Similar to d_splice_alias(), but lustre treats invalid alias
* similar to DCACHE_DISCONNECTED, and tries to use it anyway.
*/
struct dentry *ll_splice_alias(struct inode *inode, struct dentry *de)
return new;
}
}
- __d_lustre_invalidate(de);
ll_dops_init(de, 1, 1);
+ __d_lustre_invalidate(de);
d_add(de, inode);
CDEBUG(D_DENTRY, "Add dentry %p inode %p refc %d flags %#x\n",
de, de->d_inode, d_refcount(de), de->d_flags);