aboutsummaryrefslogtreecommitdiffstats
path: root/fs/configfs/dir.c
diff options
context:
space:
mode:
authorLouis Rilling <louis.rilling@kerlabs.com>2009-01-28 13:18:33 -0500
committerJoel Becker <joel.becker@oracle.com>2009-04-30 13:48:26 -0400
commit420118caa32c8ccdf9fce5a623b9de3f951573c5 (patch)
treee497cfb33e8491ddba3105c4545d11e95aa3d18c /fs/configfs/dir.c
parente74cc06df3b05e2b2c1611a043f6e6dcadaab1eb (diff)
configfs: Rework configfs_depend_item() locking and make lockdep happy
configfs_depend_item() recursively locks all inodes mutex from configfs root to the target item, which makes lockdep unhappy. The purpose of this recursive locking is to ensure that the item tree can be safely parsed and that the target item, if found, is not about to leave. This patch reworks configfs_depend_item() locking using configfs_dirent_lock. Since configfs_dirent_lock protects all changes to the configfs_dirent tree, and protects tagging of items to be removed, this lock can be used instead of the inodes mutex lock chain. This needs that the check for dependents be done atomically with CONFIGFS_USET_DROPPING tagging. Now lockdep looks happy with configfs. [ Lifted the setting of s_type into configfs_new_dirent() to satisfy the atomic setting of CONFIGFS_USET_CREATING -- Joel ] Signed-off-by: Louis Rilling <louis.rilling@kerlabs.com> Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/configfs/dir.c')
-rw-r--r--fs/configfs/dir.c106
1 files changed, 47 insertions, 59 deletions
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index d4d871fba21e..8e48b52205aa 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -167,8 +167,8 @@ configfs_adjust_dir_dirent_depth_after_populate(struct configfs_dirent *sd)
167/* 167/*
168 * Allocates a new configfs_dirent and links it to the parent configfs_dirent 168 * Allocates a new configfs_dirent and links it to the parent configfs_dirent
169 */ 169 */
170static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * parent_sd, 170static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent *parent_sd,
171 void * element) 171 void *element, int type)
172{ 172{
173 struct configfs_dirent * sd; 173 struct configfs_dirent * sd;
174 174
@@ -180,6 +180,7 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare
180 INIT_LIST_HEAD(&sd->s_links); 180 INIT_LIST_HEAD(&sd->s_links);
181 INIT_LIST_HEAD(&sd->s_children); 181 INIT_LIST_HEAD(&sd->s_children);
182 sd->s_element = element; 182 sd->s_element = element;
183 sd->s_type = type;
183 configfs_init_dirent_depth(sd); 184 configfs_init_dirent_depth(sd);
184 spin_lock(&configfs_dirent_lock); 185 spin_lock(&configfs_dirent_lock);
185 if (parent_sd->s_type & CONFIGFS_USET_DROPPING) { 186 if (parent_sd->s_type & CONFIGFS_USET_DROPPING) {
@@ -225,12 +226,11 @@ int configfs_make_dirent(struct configfs_dirent * parent_sd,
225{ 226{
226 struct configfs_dirent * sd; 227 struct configfs_dirent * sd;
227 228
228 sd = configfs_new_dirent(parent_sd, element); 229 sd = configfs_new_dirent(parent_sd, element, type);
229 if (IS_ERR(sd)) 230 if (IS_ERR(sd))
230 return PTR_ERR(sd); 231 return PTR_ERR(sd);
231 232
232 sd->s_mode = mode; 233 sd->s_mode = mode;
233 sd->s_type = type;
234 sd->s_dentry = dentry; 234 sd->s_dentry = dentry;
235 if (dentry) { 235 if (dentry) {
236 dentry->d_fsdata = configfs_get(sd); 236 dentry->d_fsdata = configfs_get(sd);
@@ -1006,11 +1006,11 @@ static int configfs_dump(struct configfs_dirent *sd, int level)
1006 * Note, btw, that this can be called at *any* time, even when a configfs 1006 * Note, btw, that this can be called at *any* time, even when a configfs
1007 * subsystem isn't registered, or when configfs is loading or unloading. 1007 * subsystem isn't registered, or when configfs is loading or unloading.
1008 * Just like configfs_register_subsystem(). So we take the same 1008 * Just like configfs_register_subsystem(). So we take the same
1009 * precautions. We pin the filesystem. We lock each i_mutex _in_order_ 1009 * precautions. We pin the filesystem. We lock configfs_dirent_lock.
1010 * on our way down the tree. If we can find the target item in the 1010 * If we can find the target item in the
1011 * configfs tree, it must be part of the subsystem tree as well, so we 1011 * configfs tree, it must be part of the subsystem tree as well, so we
1012 * do not need the subsystem semaphore. Holding the i_mutex chain locks 1012 * do not need the subsystem semaphore. Holding configfs_dirent_lock helps
1013 * out mkdir() and rmdir(), who might be racing us. 1013 * locking out mkdir() and rmdir(), who might be racing us.
1014 */ 1014 */
1015 1015
1016/* 1016/*
@@ -1023,17 +1023,21 @@ static int configfs_dump(struct configfs_dirent *sd, int level)
1023 * do that so we can unlock it if we find nothing. 1023 * do that so we can unlock it if we find nothing.
1024 * 1024 *
1025 * Here we do a depth-first search of the dentry hierarchy looking for 1025 * Here we do a depth-first search of the dentry hierarchy looking for
1026 * our object. We take i_mutex on each step of the way down. IT IS 1026 * our object.
1027 * ESSENTIAL THAT i_mutex LOCKING IS ORDERED. If we come back up a branch, 1027 * We deliberately ignore items tagged as dropping since they are virtually
1028 * we'll drop the i_mutex. 1028 * dead, as well as items in the middle of attachment since they virtually
1029 * do not exist yet. This completes the locking out of racing mkdir() and
1030 * rmdir().
1031 * Note: subdirectories in the middle of attachment start with s_type =
1032 * CONFIGFS_DIR|CONFIGFS_USET_CREATING set by create_dir(). When
1033 * CONFIGFS_USET_CREATING is set, we ignore the item. The actual set of
1034 * s_type is in configfs_new_dirent(), which has configfs_dirent_lock.
1029 * 1035 *
1030 * If the target is not found, -ENOENT is bubbled up and we have released 1036 * If the target is not found, -ENOENT is bubbled up.
1031 * all locks. If the target was found, the locks will be cleared by
1032 * configfs_depend_rollback().
1033 * 1037 *
1034 * This adds a requirement that all config_items be unique! 1038 * This adds a requirement that all config_items be unique!
1035 * 1039 *
1036 * This is recursive because the locking traversal is tricky. There isn't 1040 * This is recursive. There isn't
1037 * much on the stack, though, so folks that need this function - be careful 1041 * much on the stack, though, so folks that need this function - be careful
1038 * about your stack! Patches will be accepted to make it iterative. 1042 * about your stack! Patches will be accepted to make it iterative.
1039 */ 1043 */
@@ -1045,13 +1049,13 @@ static int configfs_depend_prep(struct dentry *origin,
1045 1049
1046 BUG_ON(!origin || !sd); 1050 BUG_ON(!origin || !sd);
1047 1051
1048 /* Lock this guy on the way down */
1049 mutex_lock(&sd->s_dentry->d_inode->i_mutex);
1050 if (sd->s_element == target) /* Boo-yah */ 1052 if (sd->s_element == target) /* Boo-yah */
1051 goto out; 1053 goto out;
1052 1054
1053 list_for_each_entry(child_sd, &sd->s_children, s_sibling) { 1055 list_for_each_entry(child_sd, &sd->s_children, s_sibling) {
1054 if (child_sd->s_type & CONFIGFS_DIR) { 1056 if ((child_sd->s_type & CONFIGFS_DIR) &&
1057 !(child_sd->s_type & CONFIGFS_USET_DROPPING) &&
1058 !(child_sd->s_type & CONFIGFS_USET_CREATING)) {
1055 ret = configfs_depend_prep(child_sd->s_dentry, 1059 ret = configfs_depend_prep(child_sd->s_dentry,
1056 target); 1060 target);
1057 if (!ret) 1061 if (!ret)
@@ -1060,33 +1064,12 @@ static int configfs_depend_prep(struct dentry *origin,
1060 } 1064 }
1061 1065
1062 /* We looped all our children and didn't find target */ 1066 /* We looped all our children and didn't find target */
1063 mutex_unlock(&sd->s_dentry->d_inode->i_mutex);
1064 ret = -ENOENT; 1067 ret = -ENOENT;
1065 1068
1066out: 1069out:
1067 return ret; 1070 return ret;
1068} 1071}
1069 1072
1070/*
1071 * This is ONLY called if configfs_depend_prep() did its job. So we can
1072 * trust the entire path from item back up to origin.
1073 *
1074 * We walk backwards from item, unlocking each i_mutex. We finish by
1075 * unlocking origin.
1076 */
1077static void configfs_depend_rollback(struct dentry *origin,
1078 struct config_item *item)
1079{
1080 struct dentry *dentry = item->ci_dentry;
1081
1082 while (dentry != origin) {
1083 mutex_unlock(&dentry->d_inode->i_mutex);
1084 dentry = dentry->d_parent;
1085 }
1086
1087 mutex_unlock(&origin->d_inode->i_mutex);
1088}
1089
1090int configfs_depend_item(struct configfs_subsystem *subsys, 1073int configfs_depend_item(struct configfs_subsystem *subsys,
1091 struct config_item *target) 1074 struct config_item *target)
1092{ 1075{
@@ -1127,17 +1110,21 @@ int configfs_depend_item(struct configfs_subsystem *subsys,
1127 1110
1128 /* Ok, now we can trust subsys/s_item */ 1111 /* Ok, now we can trust subsys/s_item */
1129 1112
1130 /* Scan the tree, locking i_mutex recursively, return 0 if found */ 1113 spin_lock(&configfs_dirent_lock);
1114 /* Scan the tree, return 0 if found */
1131 ret = configfs_depend_prep(subsys_sd->s_dentry, target); 1115 ret = configfs_depend_prep(subsys_sd->s_dentry, target);
1132 if (ret) 1116 if (ret)
1133 goto out_unlock_fs; 1117 goto out_unlock_dirent_lock;
1134 1118
1135 /* We hold all i_mutexes from the subsystem down to the target */ 1119 /*
1120 * We are sure that the item is not about to be removed by rmdir(), and
1121 * not in the middle of attachment by mkdir().
1122 */
1136 p = target->ci_dentry->d_fsdata; 1123 p = target->ci_dentry->d_fsdata;
1137 p->s_dependent_count += 1; 1124 p->s_dependent_count += 1;
1138 1125
1139 configfs_depend_rollback(subsys_sd->s_dentry, target); 1126out_unlock_dirent_lock:
1140 1127 spin_unlock(&configfs_dirent_lock);
1141out_unlock_fs: 1128out_unlock_fs:
1142 mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); 1129 mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex);
1143 1130
@@ -1162,10 +1149,10 @@ void configfs_undepend_item(struct configfs_subsystem *subsys,
1162 struct configfs_dirent *sd; 1149 struct configfs_dirent *sd;
1163 1150
1164 /* 1151 /*
1165 * Since we can trust everything is pinned, we just need i_mutex 1152 * Since we can trust everything is pinned, we just need
1166 * on the item. 1153 * configfs_dirent_lock.
1167 */ 1154 */
1168 mutex_lock(&target->ci_dentry->d_inode->i_mutex); 1155 spin_lock(&configfs_dirent_lock);
1169 1156
1170 sd = target->ci_dentry->d_fsdata; 1157 sd = target->ci_dentry->d_fsdata;
1171 BUG_ON(sd->s_dependent_count < 1); 1158 BUG_ON(sd->s_dependent_count < 1);
@@ -1176,7 +1163,7 @@ void configfs_undepend_item(struct configfs_subsystem *subsys,
1176 * After this unlock, we cannot trust the item to stay alive! 1163 * After this unlock, we cannot trust the item to stay alive!
1177 * DO NOT REFERENCE item after this unlock. 1164 * DO NOT REFERENCE item after this unlock.
1178 */ 1165 */
1179 mutex_unlock(&target->ci_dentry->d_inode->i_mutex); 1166 spin_unlock(&configfs_dirent_lock);
1180} 1167}
1181EXPORT_SYMBOL(configfs_undepend_item); 1168EXPORT_SYMBOL(configfs_undepend_item);
1182 1169
@@ -1376,13 +1363,6 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
1376 if (sd->s_type & CONFIGFS_USET_DEFAULT) 1363 if (sd->s_type & CONFIGFS_USET_DEFAULT)
1377 return -EPERM; 1364 return -EPERM;
1378 1365
1379 /*
1380 * Here's where we check for dependents. We're protected by
1381 * i_mutex.
1382 */
1383 if (sd->s_dependent_count)
1384 return -EBUSY;
1385
1386 /* Get a working ref until we have the child */ 1366 /* Get a working ref until we have the child */
1387 parent_item = configfs_get_config_item(dentry->d_parent); 1367 parent_item = configfs_get_config_item(dentry->d_parent);
1388 subsys = to_config_group(parent_item)->cg_subsys; 1368 subsys = to_config_group(parent_item)->cg_subsys;
@@ -1406,9 +1386,17 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
1406 1386
1407 mutex_lock(&configfs_symlink_mutex); 1387 mutex_lock(&configfs_symlink_mutex);
1408 spin_lock(&configfs_dirent_lock); 1388 spin_lock(&configfs_dirent_lock);
1409 ret = configfs_detach_prep(dentry, &wait_mutex); 1389 /*
1410 if (ret) 1390 * Here's where we check for dependents. We're protected by
1411 configfs_detach_rollback(dentry); 1391 * configfs_dirent_lock.
1392 * If no dependent, atomically tag the item as dropping.
1393 */
1394 ret = sd->s_dependent_count ? -EBUSY : 0;
1395 if (!ret) {
1396 ret = configfs_detach_prep(dentry, &wait_mutex);
1397 if (ret)
1398 configfs_detach_rollback(dentry);
1399 }
1412 spin_unlock(&configfs_dirent_lock); 1400 spin_unlock(&configfs_dirent_lock);
1413 mutex_unlock(&configfs_symlink_mutex); 1401 mutex_unlock(&configfs_symlink_mutex);
1414 1402
@@ -1519,7 +1507,7 @@ static int configfs_dir_open(struct inode *inode, struct file *file)
1519 */ 1507 */
1520 err = -ENOENT; 1508 err = -ENOENT;
1521 if (configfs_dirent_is_ready(parent_sd)) { 1509 if (configfs_dirent_is_ready(parent_sd)) {
1522 file->private_data = configfs_new_dirent(parent_sd, NULL); 1510 file->private_data = configfs_new_dirent(parent_sd, NULL, 0);
1523 if (IS_ERR(file->private_data)) 1511 if (IS_ERR(file->private_data))
1524 err = PTR_ERR(file->private_data); 1512 err = PTR_ERR(file->private_data);
1525 else 1513 else