aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorNick Piggin <npiggin@kernel.dk>2011-01-07 01:49:34 -0500
committerNick Piggin <npiggin@kernel.dk>2011-01-07 01:50:21 -0500
commit2fd6b7f50797f2e993eea59e0a0b8c6399c811dc (patch)
treece33b94b34844c09103836cf4cfa4364b742f217 /fs/ceph
parentda5029563a0a026c64821b09e8e7b4fd81d3fe1b (diff)
fs: dcache scale subdirs
Protect d_subdirs and d_child with d_lock, except in filesystems that aren't using dcache_lock for these anyway (eg. using i_mutex). Note: if we change the locking rule in future so that ->d_child protection is provided only with ->d_parent->d_lock, it may allow us to reduce some locking. But it would be an exception to an otherwise regular locking scheme, so we'd have to see some good results. Probably not worthwhile. Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/dir.c6
-rw-r--r--fs/ceph/inode.c8
2 files changed, 11 insertions, 3 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 571f270dca0f..2c924e8d85fe 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -113,6 +113,7 @@ static int __dcache_readdir(struct file *filp,
113 last); 113 last);
114 114
115 spin_lock(&dcache_lock); 115 spin_lock(&dcache_lock);
116 spin_lock(&parent->d_lock);
116 117
117 /* start at beginning? */ 118 /* start at beginning? */
118 if (filp->f_pos == 2 || last == NULL || 119 if (filp->f_pos == 2 || last == NULL ||
@@ -136,7 +137,7 @@ more:
136 fi->at_end = 1; 137 fi->at_end = 1;
137 goto out_unlock; 138 goto out_unlock;
138 } 139 }
139 spin_lock(&dentry->d_lock); 140 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
140 if (!d_unhashed(dentry) && dentry->d_inode && 141 if (!d_unhashed(dentry) && dentry->d_inode &&
141 ceph_snap(dentry->d_inode) != CEPH_SNAPDIR && 142 ceph_snap(dentry->d_inode) != CEPH_SNAPDIR &&
142 ceph_ino(dentry->d_inode) != CEPH_INO_CEPH && 143 ceph_ino(dentry->d_inode) != CEPH_INO_CEPH &&
@@ -154,6 +155,7 @@ more:
154 155
155 dget_dlock(dentry); 156 dget_dlock(dentry);
156 spin_unlock(&dentry->d_lock); 157 spin_unlock(&dentry->d_lock);
158 spin_unlock(&parent->d_lock);
157 spin_unlock(&dcache_lock); 159 spin_unlock(&dcache_lock);
158 160
159 dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, filp->f_pos, 161 dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, filp->f_pos,
@@ -188,10 +190,12 @@ more:
188 } 190 }
189 191
190 spin_lock(&dcache_lock); 192 spin_lock(&dcache_lock);
193 spin_lock(&parent->d_lock);
191 p = p->prev; /* advance to next dentry */ 194 p = p->prev; /* advance to next dentry */
192 goto more; 195 goto more;
193 196
194out_unlock: 197out_unlock:
198 spin_unlock(&parent->d_lock);
195 spin_unlock(&dcache_lock); 199 spin_unlock(&dcache_lock);
196out: 200out:
197 if (last) 201 if (last)
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index bb68c799074d..2c6944473366 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -842,11 +842,13 @@ static void ceph_set_dentry_offset(struct dentry *dn)
842 spin_unlock(&inode->i_lock); 842 spin_unlock(&inode->i_lock);
843 843
844 spin_lock(&dcache_lock); 844 spin_lock(&dcache_lock);
845 spin_lock(&dn->d_lock); 845 spin_lock(&dir->d_lock);
846 spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
846 list_move(&dn->d_u.d_child, &dir->d_subdirs); 847 list_move(&dn->d_u.d_child, &dir->d_subdirs);
847 dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset, 848 dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset,
848 dn->d_u.d_child.prev, dn->d_u.d_child.next); 849 dn->d_u.d_child.prev, dn->d_u.d_child.next);
849 spin_unlock(&dn->d_lock); 850 spin_unlock(&dn->d_lock);
851 spin_unlock(&dir->d_lock);
850 spin_unlock(&dcache_lock); 852 spin_unlock(&dcache_lock);
851} 853}
852 854
@@ -1232,9 +1234,11 @@ retry_lookup:
1232 } else { 1234 } else {
1233 /* reorder parent's d_subdirs */ 1235 /* reorder parent's d_subdirs */
1234 spin_lock(&dcache_lock); 1236 spin_lock(&dcache_lock);
1235 spin_lock(&dn->d_lock); 1237 spin_lock(&parent->d_lock);
1238 spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
1236 list_move(&dn->d_u.d_child, &parent->d_subdirs); 1239 list_move(&dn->d_u.d_child, &parent->d_subdirs);
1237 spin_unlock(&dn->d_lock); 1240 spin_unlock(&dn->d_lock);
1241 spin_unlock(&parent->d_lock);
1238 spin_unlock(&dcache_lock); 1242 spin_unlock(&dcache_lock);
1239 } 1243 }
1240 1244