Whamcloud - gitweb
LU-1363 llite: Not held lock when calling security_d_instantiate
authorBobi Jam <bobijam@whamcloud.com>
Thu, 3 May 2012 15:28:26 +0000 (23:28 +0800)
committerOleg Drokin <green@whamcloud.com>
Wed, 30 May 2012 11:47:22 +0000 (07:47 -0400)
security_d_instantiate() could allocate momory and/or yield cpu, don't
held spin lock.

Signed-off-by: Bobi Jam <bobijam@whamcloud.com>
Change-Id: I0a32e067e21ec5f3d8427db020ae5fda6ce96ba1
Reviewed-on: http://review.whamcloud.com/2641
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Fan Yong <yong.fan@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/namei.c

index d5c9fbe..4d94aa7 100644 (file)
@@ -343,9 +343,6 @@ static void ll_d_add(struct dentry *de, struct inode *inode)
         if (inode)
                 list_add(&de->d_alias, &inode->i_dentry);
         de->d_inode = inode;
-        /* d_instantiate() replacement code should initialize security
-         * context. */
-        security_d_instantiate(de, inode);
 
         /* d_rehash */
         if (!d_unhashed(de)) {
@@ -354,7 +351,6 @@ static void ll_d_add(struct dentry *de, struct inode *inode)
                        de->d_name.len, de->d_name.name, de, de->d_hash.next);
                 LBUG();
         }
-        d_rehash_cond(de, 0);
 }
 
 /* Search "inode"'s alias list for a dentry that has the same name and parent
@@ -427,14 +423,16 @@ struct dentry *ll_find_alias(struct inode *inode, struct dentry *de)
                 iput(inode);
                 return last_discon;
         }
-        lock_dentry(de);
-        de->d_flags |= DCACHE_LUSTRE_INVALID;
-        unlock_dentry(de);
-        ll_d_add(de, inode);
-
+       lock_dentry(de);
+       de->d_flags |= DCACHE_LUSTRE_INVALID;
+       unlock_dentry(de);
+       ll_d_add(de, inode);
         spin_unlock(&dcache_lock);
         cfs_spin_unlock(&ll_lookup_lock);
 
+       security_d_instantiate(de, inode);
+       d_rehash(de);
+
         return de;
 }
 
@@ -480,17 +478,24 @@ int ll_lookup_it_finish(struct ptlrpc_request *request,
                 /* we have lookup look - unhide dentry */
                 ll_dentry_reset_flags(*de, bits);
         } else {
-                __u64 ibits;
+               struct lookup_intent parent_it = {
+                                       .it_op = IT_GETATTR,
+                                       .d.lustre.it_lock_handle = 0 };
 
                 ll_dops_init(*de, 1, 1);
-                /* Check that parent has UPDATE lock. If there is none, we
-                   cannot afford to hash this dentry (done by ll_d_add) as it
-                   might get picked up later when UPDATE lock will appear */
-                ibits = MDS_INODELOCK_UPDATE;
-                if (ll_have_md_lock(parent, &ibits, LCK_MINMODE)) {
-                        spin_lock(&dcache_lock);
-                        ll_d_add(*de, NULL);
-                        spin_unlock(&dcache_lock);
+               /* Check that parent has UPDATE lock. If there is none, we
+                  cannot afford to hash this dentry (done by ll_d_add) as it
+                  might get picked up later when UPDATE lock will appear;
+                  otherwise, add ref to the parent UPDATE lock, to make sure
+                  ll_d_add() undergoes with parent's UPDATE lock held */
+               if (md_revalidate_lock(ll_i2mdexp(parent), &parent_it,
+                                      &ll_i2info(parent)->lli_fid, NULL)) {
+                       spin_lock(&dcache_lock);
+                       ll_d_add(*de, NULL);
+                       spin_unlock(&dcache_lock);
+                       security_d_instantiate(*de, inode);
+                       d_rehash(*de);
+                       ll_intent_release(&parent_it);
                 } else {
                         /* negative lookup - and don't have update lock to
                          * parent */