aboutsummaryrefslogtreecommitdiffstats
path: root/fs/configfs/dir.c
diff options
context:
space:
mode:
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