From 922843467ee45b2e54df71593149aff3282bf032 Mon Sep 17 00:00:00 2001 From: rread Date: Tue, 8 Oct 2002 06:52:45 +0000 Subject: [PATCH] * Protect d_it with a semaphore, Part I * this patch uses the new semaphore in the all places it will be needed, but does not change where d_it is being set. --- lustre/extN/Makefile.am | 4 ++-- lustre/include/linux/lustre_lite.h | 6 +++++ lustre/llite/dcache.c | 45 +++++++++++++++++++++++++++++++++++--- lustre/llite/namei.c | 8 +++++++ 4 files changed, 58 insertions(+), 5 deletions(-) diff --git a/lustre/extN/Makefile.am b/lustre/extN/Makefile.am index 828f099..05f04e3 100644 --- a/lustre/extN/Makefile.am +++ b/lustre/extN/Makefile.am @@ -13,8 +13,8 @@ EXTRA_PROGRAMS = extN # It will be applied automatically by the extN build process, or you # can apply it to the source kernel tree and fix ext3 also. For chaos22 # (or other RH < 12.5 kernels) use the "chaos22" patch instead. -#EXTN_FIXES = ../patches/patch-2.4.18-chaos22 -EXTN_FIXES = ext3-2.4.18-fixes.diff +EXTN_FIXES = ../patches/patch-2.4.18-chaos22 +#EXTN_FIXES = ext3-2.4.18-fixes.diff EXTNP = htree-ext3-2.4.18.diff linux-2.4.18ea-0.8.26.diff EXTNP+= ext3-2.4.18-ino_sb_macro.diff extN-misc-fixup.diff EXTNC = balloc.c bitmap.c dir.c file.c fsync.c ialloc.c inode.c ioctl.c diff --git a/lustre/include/linux/lustre_lite.h b/lustre/include/linux/lustre_lite.h index 377a2fb..dc8e027 100644 --- a/lustre/include/linux/lustre_lite.h +++ b/lustre/include/linux/lustre_lite.h @@ -32,6 +32,11 @@ struct ll_file_data { __u32 fd_flags; }; +struct ll_dentry_data { + struct semaphore lld_it_sem; +}; + +#define ll_d2d(dentry) ((struct ll_dentry_data*) dentry->d_fsdata) struct ll_read_inode2_cookie { struct mds_body *lic_body; @@ -143,6 +148,7 @@ int ll_unlock(__u32 mode, struct lustre_handle *lockh); /* dcache.c */ void ll_intent_release(struct dentry *de); +int ll_set_dd(struct dentry *de); /* dir.c */ extern struct file_operations ll_dir_operations; diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index af5e1e6..42d2aa2 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -31,6 +31,14 @@ extern struct address_space_operations ll_aops; +void ll_release(struct dentry *de) +{ + ENTRY; + + OBD_FREE(de->d_fsdata, sizeof(struct ll_dentry_data)); + EXIT; +} + void ll_intent_release(struct dentry *de) { struct lustre_handle *handle; @@ -40,6 +48,9 @@ void ll_intent_release(struct dentry *de) EXIT; return; } + + LASSERT(ll_d2d(de) != NULL); + if (de->d_it->it_lock_mode) { handle = (struct lustre_handle *)de->d_it->it_lock_handle; if (de->d_it->it_op == IT_SETATTR) { @@ -51,7 +62,8 @@ void ll_intent_release(struct dentry *de) } else ldlm_lock_decref(handle, de->d_it->it_lock_mode); } - de->d_it = NULL; + // de->d_it = NULL; + up(&ll_d2d(de)->lld_it_sem); EXIT; } @@ -100,10 +112,37 @@ int ll_revalidate2(struct dentry *de, int flags, struct lookup_intent *it) if (atomic_read(&de->d_count) > 0) RETURN(1); + if (ll_d2d(de) == NULL) { + CERROR("allocating fsdata\n"); + ll_set_dd(de); + } + down(&ll_d2d(de)->lld_it_sem); + // de->d_it = it; + + RETURN(0); +} + +int ll_set_dd(struct dentry *de) +{ + ENTRY; + LASSERT(de != NULL); + + lock_kernel(); + + if (de->d_fsdata != NULL) { + CERROR("dentry %p already has d_fsdata set\n", de); + } else { + OBD_ALLOC(de->d_fsdata, sizeof(struct ll_dentry_data)); + sema_init(&ll_d2d(de)->lld_it_sem, 1); + } + + unlock_kernel(); + RETURN(0); } struct dentry_operations ll_d_ops = { - d_revalidate2: ll_revalidate2, - d_intent_release: ll_intent_release + .d_revalidate2 = ll_revalidate2, + .d_intent_release = ll_intent_release, + .d_release = ll_release, }; diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index e050cee..68bbed7 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -283,9 +283,17 @@ static struct dentry *ll_lookup2(struct inode *dir, struct dentry *dentry, negative: dentry->d_op = &ll_d_ops; d_add(dentry, inode); + + if (ll_d2d(dentry) == NULL) { + ll_set_dd(dentry); + } + down(&ll_d2d(dentry)->lld_it_sem); + // dentry->d_it = it; + if (it->it_op == IT_LOOKUP) ll_intent_release(dentry); + return NULL; drop_req: -- 1.8.3.1