Whamcloud - gitweb
* Protect d_it with a semaphore, Part I
authorrread <rread>
Tue, 8 Oct 2002 06:52:45 +0000 (06:52 +0000)
committerrread <rread>
Tue, 8 Oct 2002 06:52:45 +0000 (06:52 +0000)
* 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
lustre/include/linux/lustre_lite.h
lustre/llite/dcache.c
lustre/llite/namei.c

index 828f099..05f04e3 100644 (file)
@@ -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
index 377a2fb..dc8e027 100644 (file)
@@ -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;
index af5e1e6..42d2aa2 100644 (file)
 
 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,
 };
index e050cee..68bbed7 100644 (file)
@@ -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: