aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-17 13:55:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-17 13:55:51 -0400
commit5b664cb235e97afbf34db9c4d77f08ebd725335e (patch)
tree518540649c38342209790de8e0b575ac1a6fa722 /fs
parentf39548a6ad1dbdfaab552419386ec5bb1d76fa0d (diff)
parentc0420ad2ca514551ca086510b0e7d17a05c70492 (diff)
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2: [PATCH] ocfs2: fix oops in mmap_truncate testing configfs: call drop_link() to cleanup after create_link() failure configfs: Allow ->make_item() and ->make_group() to return detailed errors. configfs: Fix failing mkdir() making racing rmdir() fail configfs: Fix deadlock with racing rmdir() and rename() configfs: Make configfs_new_dirent() return error code instead of NULL configfs: Protect configfs_dirent s_links list mutations configfs: Introduce configfs_dirent_lock ocfs2: Don't snprintf() without a format. ocfs2: Fix CONFIG_OCFS2_DEBUG_FS #ifdefs ocfs2/net: Silence build warnings on sparc64 ocfs2: Handle error during journal load ocfs2: Silence an error message in ocfs2_file_aio_read() ocfs2: use simple_read_from_buffer() ocfs2: fix printk format warnings with OCFS2_FS_STATS=n [PATCH 2/2] ocfs2: Instrument fs cluster locks [PATCH 1/2] ocfs2: Add CONFIG_OCFS2_FS_STATS config option
Diffstat (limited to 'fs')
-rw-r--r--fs/Kconfig8
-rw-r--r--fs/configfs/configfs_internal.h4
-rw-r--r--fs/configfs/dir.c147
-rw-r--r--fs/configfs/inode.c2
-rw-r--r--fs/configfs/symlink.c16
-rw-r--r--fs/dlm/config.c45
-rw-r--r--fs/ocfs2/aops.c13
-rw-r--r--fs/ocfs2/cluster/heartbeat.c17
-rw-r--r--fs/ocfs2/cluster/netdebug.c8
-rw-r--r--fs/ocfs2/cluster/nodemanager.c45
-rw-r--r--fs/ocfs2/dlmglue.c122
-rw-r--r--fs/ocfs2/file.c2
-rw-r--r--fs/ocfs2/journal.c2
-rw-r--r--fs/ocfs2/localalloc.c2
-rw-r--r--fs/ocfs2/ocfs2.h12
-rw-r--r--fs/ocfs2/ocfs2_fs.h2
-rw-r--r--fs/ocfs2/stack_user.c19
-rw-r--r--fs/ocfs2/super.c6
18 files changed, 361 insertions, 111 deletions
diff --git a/fs/Kconfig b/fs/Kconfig
index 17216ba99c85..37db79a2ff95 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -470,6 +470,14 @@ config OCFS2_FS_USERSPACE_CLUSTER
470 It is safe to say Y, as the clustering method is run-time 470 It is safe to say Y, as the clustering method is run-time
471 selectable. 471 selectable.
472 472
473config OCFS2_FS_STATS
474 bool "OCFS2 statistics"
475 depends on OCFS2_FS
476 default y
477 help
478 This option allows some fs statistics to be captured. Enabling
479 this option may increase the memory consumption.
480
473config OCFS2_DEBUG_MASKLOG 481config OCFS2_DEBUG_MASKLOG
474 bool "OCFS2 logging support" 482 bool "OCFS2 logging support"
475 depends on OCFS2_FS 483 depends on OCFS2_FS
diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h
index cca98609aa7f..da015c12e3ea 100644
--- a/fs/configfs/configfs_internal.h
+++ b/fs/configfs/configfs_internal.h
@@ -26,6 +26,7 @@
26 26
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/spinlock.h>
29 30
30struct configfs_dirent { 31struct configfs_dirent {
31 atomic_t s_count; 32 atomic_t s_count;
@@ -47,8 +48,11 @@ struct configfs_dirent {
47#define CONFIGFS_USET_DIR 0x0040 48#define CONFIGFS_USET_DIR 0x0040
48#define CONFIGFS_USET_DEFAULT 0x0080 49#define CONFIGFS_USET_DEFAULT 0x0080
49#define CONFIGFS_USET_DROPPING 0x0100 50#define CONFIGFS_USET_DROPPING 0x0100
51#define CONFIGFS_USET_IN_MKDIR 0x0200
50#define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) 52#define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR)
51 53
54extern spinlock_t configfs_dirent_lock;
55
52extern struct vfsmount * configfs_mount; 56extern struct vfsmount * configfs_mount;
53extern struct kmem_cache *configfs_dir_cachep; 57extern struct kmem_cache *configfs_dir_cachep;
54 58
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index a48dc7dd8765..0e64312a084c 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -30,11 +30,25 @@
30#include <linux/mount.h> 30#include <linux/mount.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/err.h>
33 34
34#include <linux/configfs.h> 35#include <linux/configfs.h>
35#include "configfs_internal.h" 36#include "configfs_internal.h"
36 37
37DECLARE_RWSEM(configfs_rename_sem); 38DECLARE_RWSEM(configfs_rename_sem);
39/*
40 * Protects mutations of configfs_dirent linkage together with proper i_mutex
41 * Also protects mutations of symlinks linkage to target configfs_dirent
42 * Mutators of configfs_dirent linkage must *both* have the proper inode locked
43 * and configfs_dirent_lock locked, in that order.
44 * This allows one to safely traverse configfs_dirent trees and symlinks without
45 * having to lock inodes.
46 *
47 * Protects setting of CONFIGFS_USET_DROPPING: checking the flag
48 * unlocked is not reliable unless in detach_groups() called from
49 * rmdir()/unregister() and from configfs_attach_group()
50 */
51DEFINE_SPINLOCK(configfs_dirent_lock);
38 52
39static void configfs_d_iput(struct dentry * dentry, 53static void configfs_d_iput(struct dentry * dentry,
40 struct inode * inode) 54 struct inode * inode)
@@ -74,13 +88,20 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare
74 88
75 sd = kmem_cache_zalloc(configfs_dir_cachep, GFP_KERNEL); 89 sd = kmem_cache_zalloc(configfs_dir_cachep, GFP_KERNEL);
76 if (!sd) 90 if (!sd)
77 return NULL; 91 return ERR_PTR(-ENOMEM);
78 92
79 atomic_set(&sd->s_count, 1); 93 atomic_set(&sd->s_count, 1);
80 INIT_LIST_HEAD(&sd->s_links); 94 INIT_LIST_HEAD(&sd->s_links);
81 INIT_LIST_HEAD(&sd->s_children); 95 INIT_LIST_HEAD(&sd->s_children);
82 list_add(&sd->s_sibling, &parent_sd->s_children);
83 sd->s_element = element; 96 sd->s_element = element;
97 spin_lock(&configfs_dirent_lock);
98 if (parent_sd->s_type & CONFIGFS_USET_DROPPING) {
99 spin_unlock(&configfs_dirent_lock);
100 kmem_cache_free(configfs_dir_cachep, sd);
101 return ERR_PTR(-ENOENT);
102 }
103 list_add(&sd->s_sibling, &parent_sd->s_children);
104 spin_unlock(&configfs_dirent_lock);
84 105
85 return sd; 106 return sd;
86} 107}
@@ -118,8 +139,8 @@ int configfs_make_dirent(struct configfs_dirent * parent_sd,
118 struct configfs_dirent * sd; 139 struct configfs_dirent * sd;
119 140
120 sd = configfs_new_dirent(parent_sd, element); 141 sd = configfs_new_dirent(parent_sd, element);
121 if (!sd) 142 if (IS_ERR(sd))
122 return -ENOMEM; 143 return PTR_ERR(sd);
123 144
124 sd->s_mode = mode; 145 sd->s_mode = mode;
125 sd->s_type = type; 146 sd->s_type = type;
@@ -173,7 +194,9 @@ static int create_dir(struct config_item * k, struct dentry * p,
173 } else { 194 } else {
174 struct configfs_dirent *sd = d->d_fsdata; 195 struct configfs_dirent *sd = d->d_fsdata;
175 if (sd) { 196 if (sd) {
197 spin_lock(&configfs_dirent_lock);
176 list_del_init(&sd->s_sibling); 198 list_del_init(&sd->s_sibling);
199 spin_unlock(&configfs_dirent_lock);
177 configfs_put(sd); 200 configfs_put(sd);
178 } 201 }
179 } 202 }
@@ -224,7 +247,9 @@ int configfs_create_link(struct configfs_symlink *sl,
224 else { 247 else {
225 struct configfs_dirent *sd = dentry->d_fsdata; 248 struct configfs_dirent *sd = dentry->d_fsdata;
226 if (sd) { 249 if (sd) {
250 spin_lock(&configfs_dirent_lock);
227 list_del_init(&sd->s_sibling); 251 list_del_init(&sd->s_sibling);
252 spin_unlock(&configfs_dirent_lock);
228 configfs_put(sd); 253 configfs_put(sd);
229 } 254 }
230 } 255 }
@@ -238,7 +263,9 @@ static void remove_dir(struct dentry * d)
238 struct configfs_dirent * sd; 263 struct configfs_dirent * sd;
239 264
240 sd = d->d_fsdata; 265 sd = d->d_fsdata;
266 spin_lock(&configfs_dirent_lock);
241 list_del_init(&sd->s_sibling); 267 list_del_init(&sd->s_sibling);
268 spin_unlock(&configfs_dirent_lock);
242 configfs_put(sd); 269 configfs_put(sd);
243 if (d->d_inode) 270 if (d->d_inode)
244 simple_rmdir(parent->d_inode,d); 271 simple_rmdir(parent->d_inode,d);
@@ -331,13 +358,13 @@ static struct dentry * configfs_lookup(struct inode *dir,
331 358
332/* 359/*
333 * Only subdirectories count here. Files (CONFIGFS_NOT_PINNED) are 360 * Only subdirectories count here. Files (CONFIGFS_NOT_PINNED) are
334 * attributes and are removed by rmdir(). We recurse, taking i_mutex 361 * attributes and are removed by rmdir(). We recurse, setting
335 * on all children that are candidates for default detach. If the 362 * CONFIGFS_USET_DROPPING on all children that are candidates for
336 * result is clean, then configfs_detach_group() will handle dropping 363 * default detach.
337 * i_mutex. If there is an error, the caller will clean up the i_mutex 364 * If there is an error, the caller will reset the flags via
338 * holders via configfs_detach_rollback(). 365 * configfs_detach_rollback().
339 */ 366 */
340static int configfs_detach_prep(struct dentry *dentry) 367static int configfs_detach_prep(struct dentry *dentry, struct mutex **wait_mutex)
341{ 368{
342 struct configfs_dirent *parent_sd = dentry->d_fsdata; 369 struct configfs_dirent *parent_sd = dentry->d_fsdata;
343 struct configfs_dirent *sd; 370 struct configfs_dirent *sd;
@@ -352,15 +379,20 @@ static int configfs_detach_prep(struct dentry *dentry)
352 if (sd->s_type & CONFIGFS_NOT_PINNED) 379 if (sd->s_type & CONFIGFS_NOT_PINNED)
353 continue; 380 continue;
354 if (sd->s_type & CONFIGFS_USET_DEFAULT) { 381 if (sd->s_type & CONFIGFS_USET_DEFAULT) {
355 mutex_lock(&sd->s_dentry->d_inode->i_mutex); 382 /* Abort if racing with mkdir() */
356 /* Mark that we've taken i_mutex */ 383 if (sd->s_type & CONFIGFS_USET_IN_MKDIR) {
384 if (wait_mutex)
385 *wait_mutex = &sd->s_dentry->d_inode->i_mutex;
386 return -EAGAIN;
387 }
388 /* Mark that we're trying to drop the group */
357 sd->s_type |= CONFIGFS_USET_DROPPING; 389 sd->s_type |= CONFIGFS_USET_DROPPING;
358 390
359 /* 391 /*
360 * Yup, recursive. If there's a problem, blame 392 * Yup, recursive. If there's a problem, blame
361 * deep nesting of default_groups 393 * deep nesting of default_groups
362 */ 394 */
363 ret = configfs_detach_prep(sd->s_dentry); 395 ret = configfs_detach_prep(sd->s_dentry, wait_mutex);
364 if (!ret) 396 if (!ret)
365 continue; 397 continue;
366 } else 398 } else
@@ -374,7 +406,7 @@ out:
374} 406}
375 407
376/* 408/*
377 * Walk the tree, dropping i_mutex wherever CONFIGFS_USET_DROPPING is 409 * Walk the tree, resetting CONFIGFS_USET_DROPPING wherever it was
378 * set. 410 * set.
379 */ 411 */
380static void configfs_detach_rollback(struct dentry *dentry) 412static void configfs_detach_rollback(struct dentry *dentry)
@@ -385,11 +417,7 @@ static void configfs_detach_rollback(struct dentry *dentry)
385 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { 417 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
386 if (sd->s_type & CONFIGFS_USET_DEFAULT) { 418 if (sd->s_type & CONFIGFS_USET_DEFAULT) {
387 configfs_detach_rollback(sd->s_dentry); 419 configfs_detach_rollback(sd->s_dentry);
388 420 sd->s_type &= ~CONFIGFS_USET_DROPPING;
389 if (sd->s_type & CONFIGFS_USET_DROPPING) {
390 sd->s_type &= ~CONFIGFS_USET_DROPPING;
391 mutex_unlock(&sd->s_dentry->d_inode->i_mutex);
392 }
393 } 421 }
394 } 422 }
395} 423}
@@ -410,7 +438,9 @@ static void detach_attrs(struct config_item * item)
410 list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { 438 list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
411 if (!sd->s_element || !(sd->s_type & CONFIGFS_NOT_PINNED)) 439 if (!sd->s_element || !(sd->s_type & CONFIGFS_NOT_PINNED))
412 continue; 440 continue;
441 spin_lock(&configfs_dirent_lock);
413 list_del_init(&sd->s_sibling); 442 list_del_init(&sd->s_sibling);
443 spin_unlock(&configfs_dirent_lock);
414 configfs_drop_dentry(sd, dentry); 444 configfs_drop_dentry(sd, dentry);
415 configfs_put(sd); 445 configfs_put(sd);
416 } 446 }
@@ -466,16 +496,12 @@ static void detach_groups(struct config_group *group)
466 496
467 child = sd->s_dentry; 497 child = sd->s_dentry;
468 498
499 mutex_lock(&child->d_inode->i_mutex);
500
469 configfs_detach_group(sd->s_element); 501 configfs_detach_group(sd->s_element);
470 child->d_inode->i_flags |= S_DEAD; 502 child->d_inode->i_flags |= S_DEAD;
471 503
472 /* 504 mutex_unlock(&child->d_inode->i_mutex);
473 * From rmdir/unregister, a configfs_detach_prep() pass
474 * has taken our i_mutex for us. Drop it.
475 * From mkdir/register cleanup, there is no sem held.
476 */
477 if (sd->s_type & CONFIGFS_USET_DROPPING)
478 mutex_unlock(&child->d_inode->i_mutex);
479 505
480 d_delete(child); 506 d_delete(child);
481 dput(child); 507 dput(child);
@@ -1047,25 +1073,24 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1047 group = NULL; 1073 group = NULL;
1048 item = NULL; 1074 item = NULL;
1049 if (type->ct_group_ops->make_group) { 1075 if (type->ct_group_ops->make_group) {
1050 group = type->ct_group_ops->make_group(to_config_group(parent_item), name); 1076 ret = type->ct_group_ops->make_group(to_config_group(parent_item), name, &group);
1051 if (group) { 1077 if (!ret) {
1052 link_group(to_config_group(parent_item), group); 1078 link_group(to_config_group(parent_item), group);
1053 item = &group->cg_item; 1079 item = &group->cg_item;
1054 } 1080 }
1055 } else { 1081 } else {
1056 item = type->ct_group_ops->make_item(to_config_group(parent_item), name); 1082 ret = type->ct_group_ops->make_item(to_config_group(parent_item), name, &item);
1057 if (item) 1083 if (!ret)
1058 link_obj(parent_item, item); 1084 link_obj(parent_item, item);
1059 } 1085 }
1060 mutex_unlock(&subsys->su_mutex); 1086 mutex_unlock(&subsys->su_mutex);
1061 1087
1062 kfree(name); 1088 kfree(name);
1063 if (!item) { 1089 if (ret) {
1064 /* 1090 /*
1065 * If item == NULL, then link_obj() was never called. 1091 * If ret != 0, then link_obj() was never called.
1066 * There are no extra references to clean up. 1092 * There are no extra references to clean up.
1067 */ 1093 */
1068 ret = -ENOMEM;
1069 goto out_put; 1094 goto out_put;
1070 } 1095 }
1071 1096
@@ -1093,11 +1118,26 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1093 */ 1118 */
1094 module_got = 1; 1119 module_got = 1;
1095 1120
1121 /*
1122 * Make racing rmdir() fail if it did not tag parent with
1123 * CONFIGFS_USET_DROPPING
1124 * Note: if CONFIGFS_USET_DROPPING is already set, attach_group() will
1125 * fail and let rmdir() terminate correctly
1126 */
1127 spin_lock(&configfs_dirent_lock);
1128 /* This will make configfs_detach_prep() fail */
1129 sd->s_type |= CONFIGFS_USET_IN_MKDIR;
1130 spin_unlock(&configfs_dirent_lock);
1131
1096 if (group) 1132 if (group)
1097 ret = configfs_attach_group(parent_item, item, dentry); 1133 ret = configfs_attach_group(parent_item, item, dentry);
1098 else 1134 else
1099 ret = configfs_attach_item(parent_item, item, dentry); 1135 ret = configfs_attach_item(parent_item, item, dentry);
1100 1136
1137 spin_lock(&configfs_dirent_lock);
1138 sd->s_type &= ~CONFIGFS_USET_IN_MKDIR;
1139 spin_unlock(&configfs_dirent_lock);
1140
1101out_unlink: 1141out_unlink:
1102 if (ret) { 1142 if (ret) {
1103 /* Tear down everything we built up */ 1143 /* Tear down everything we built up */
@@ -1161,12 +1201,27 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
1161 return -EINVAL; 1201 return -EINVAL;
1162 } 1202 }
1163 1203
1164 ret = configfs_detach_prep(dentry); 1204 spin_lock(&configfs_dirent_lock);
1165 if (ret) { 1205 do {
1166 configfs_detach_rollback(dentry); 1206 struct mutex *wait_mutex;
1167 config_item_put(parent_item); 1207
1168 return ret; 1208 ret = configfs_detach_prep(dentry, &wait_mutex);
1169 } 1209 if (ret) {
1210 configfs_detach_rollback(dentry);
1211 spin_unlock(&configfs_dirent_lock);
1212 if (ret != -EAGAIN) {
1213 config_item_put(parent_item);
1214 return ret;
1215 }
1216
1217 /* Wait until the racing operation terminates */
1218 mutex_lock(wait_mutex);
1219 mutex_unlock(wait_mutex);
1220
1221 spin_lock(&configfs_dirent_lock);
1222 }
1223 } while (ret == -EAGAIN);
1224 spin_unlock(&configfs_dirent_lock);
1170 1225
1171 /* Get a working ref for the duration of this function */ 1226 /* Get a working ref for the duration of this function */
1172 item = configfs_get_config_item(dentry); 1227 item = configfs_get_config_item(dentry);
@@ -1258,7 +1313,7 @@ static int configfs_dir_open(struct inode *inode, struct file *file)
1258 file->private_data = configfs_new_dirent(parent_sd, NULL); 1313 file->private_data = configfs_new_dirent(parent_sd, NULL);
1259 mutex_unlock(&dentry->d_inode->i_mutex); 1314 mutex_unlock(&dentry->d_inode->i_mutex);
1260 1315
1261 return file->private_data ? 0 : -ENOMEM; 1316 return IS_ERR(file->private_data) ? PTR_ERR(file->private_data) : 0;
1262 1317
1263} 1318}
1264 1319
@@ -1268,7 +1323,9 @@ static int configfs_dir_close(struct inode *inode, struct file *file)
1268 struct configfs_dirent * cursor = file->private_data; 1323 struct configfs_dirent * cursor = file->private_data;
1269 1324
1270 mutex_lock(&dentry->d_inode->i_mutex); 1325 mutex_lock(&dentry->d_inode->i_mutex);
1326 spin_lock(&configfs_dirent_lock);
1271 list_del_init(&cursor->s_sibling); 1327 list_del_init(&cursor->s_sibling);
1328 spin_unlock(&configfs_dirent_lock);
1272 mutex_unlock(&dentry->d_inode->i_mutex); 1329 mutex_unlock(&dentry->d_inode->i_mutex);
1273 1330
1274 release_configfs_dirent(cursor); 1331 release_configfs_dirent(cursor);
@@ -1308,7 +1365,9 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir
1308 /* fallthrough */ 1365 /* fallthrough */
1309 default: 1366 default:
1310 if (filp->f_pos == 2) { 1367 if (filp->f_pos == 2) {
1368 spin_lock(&configfs_dirent_lock);
1311 list_move(q, &parent_sd->s_children); 1369 list_move(q, &parent_sd->s_children);
1370 spin_unlock(&configfs_dirent_lock);
1312 } 1371 }
1313 for (p=q->next; p!= &parent_sd->s_children; p=p->next) { 1372 for (p=q->next; p!= &parent_sd->s_children; p=p->next) {
1314 struct configfs_dirent *next; 1373 struct configfs_dirent *next;
@@ -1331,7 +1390,9 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir
1331 dt_type(next)) < 0) 1390 dt_type(next)) < 0)
1332 return 0; 1391 return 0;
1333 1392
1393 spin_lock(&configfs_dirent_lock);
1334 list_move(q, p); 1394 list_move(q, p);
1395 spin_unlock(&configfs_dirent_lock);
1335 p = q; 1396 p = q;
1336 filp->f_pos++; 1397 filp->f_pos++;
1337 } 1398 }
@@ -1362,6 +1423,7 @@ static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin)
1362 struct list_head *p; 1423 struct list_head *p;
1363 loff_t n = file->f_pos - 2; 1424 loff_t n = file->f_pos - 2;
1364 1425
1426 spin_lock(&configfs_dirent_lock);
1365 list_del(&cursor->s_sibling); 1427 list_del(&cursor->s_sibling);
1366 p = sd->s_children.next; 1428 p = sd->s_children.next;
1367 while (n && p != &sd->s_children) { 1429 while (n && p != &sd->s_children) {
@@ -1373,6 +1435,7 @@ static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin)
1373 p = p->next; 1435 p = p->next;
1374 } 1436 }
1375 list_add_tail(&cursor->s_sibling, p); 1437 list_add_tail(&cursor->s_sibling, p);
1438 spin_unlock(&configfs_dirent_lock);
1376 } 1439 }
1377 } 1440 }
1378 mutex_unlock(&dentry->d_inode->i_mutex); 1441 mutex_unlock(&dentry->d_inode->i_mutex);
@@ -1448,9 +1511,11 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
1448 mutex_lock_nested(&configfs_sb->s_root->d_inode->i_mutex, 1511 mutex_lock_nested(&configfs_sb->s_root->d_inode->i_mutex,
1449 I_MUTEX_PARENT); 1512 I_MUTEX_PARENT);
1450 mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); 1513 mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD);
1451 if (configfs_detach_prep(dentry)) { 1514 spin_lock(&configfs_dirent_lock);
1515 if (configfs_detach_prep(dentry, NULL)) {
1452 printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n"); 1516 printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n");
1453 } 1517 }
1518 spin_unlock(&configfs_dirent_lock);
1454 configfs_detach_group(&group->cg_item); 1519 configfs_detach_group(&group->cg_item);
1455 dentry->d_inode->i_flags |= S_DEAD; 1520 dentry->d_inode->i_flags |= S_DEAD;
1456 mutex_unlock(&dentry->d_inode->i_mutex); 1521 mutex_unlock(&dentry->d_inode->i_mutex);
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c
index b9a1d810346d..4803ccc94480 100644
--- a/fs/configfs/inode.c
+++ b/fs/configfs/inode.c
@@ -247,7 +247,9 @@ void configfs_hash_and_remove(struct dentry * dir, const char * name)
247 if (!sd->s_element) 247 if (!sd->s_element)
248 continue; 248 continue;
249 if (!strcmp(configfs_get_name(sd), name)) { 249 if (!strcmp(configfs_get_name(sd), name)) {
250 spin_lock(&configfs_dirent_lock);
250 list_del_init(&sd->s_sibling); 251 list_del_init(&sd->s_sibling);
252 spin_unlock(&configfs_dirent_lock);
251 configfs_drop_dentry(sd, dir); 253 configfs_drop_dentry(sd, dir);
252 configfs_put(sd); 254 configfs_put(sd);
253 break; 255 break;
diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c
index 2a731ef5f305..0004d18c40ac 100644
--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -77,12 +77,15 @@ static int create_link(struct config_item *parent_item,
77 sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL); 77 sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL);
78 if (sl) { 78 if (sl) {
79 sl->sl_target = config_item_get(item); 79 sl->sl_target = config_item_get(item);
80 /* FIXME: needs a lock, I'd bet */ 80 spin_lock(&configfs_dirent_lock);
81 list_add(&sl->sl_list, &target_sd->s_links); 81 list_add(&sl->sl_list, &target_sd->s_links);
82 spin_unlock(&configfs_dirent_lock);
82 ret = configfs_create_link(sl, parent_item->ci_dentry, 83 ret = configfs_create_link(sl, parent_item->ci_dentry,
83 dentry); 84 dentry);
84 if (ret) { 85 if (ret) {
86 spin_lock(&configfs_dirent_lock);
85 list_del_init(&sl->sl_list); 87 list_del_init(&sl->sl_list);
88 spin_unlock(&configfs_dirent_lock);
86 config_item_put(item); 89 config_item_put(item);
87 kfree(sl); 90 kfree(sl);
88 } 91 }
@@ -137,8 +140,12 @@ int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symna
137 goto out_put; 140 goto out_put;
138 141
139 ret = type->ct_item_ops->allow_link(parent_item, target_item); 142 ret = type->ct_item_ops->allow_link(parent_item, target_item);
140 if (!ret) 143 if (!ret) {
141 ret = create_link(parent_item, target_item, dentry); 144 ret = create_link(parent_item, target_item, dentry);
145 if (ret && type->ct_item_ops->drop_link)
146 type->ct_item_ops->drop_link(parent_item,
147 target_item);
148 }
142 149
143 config_item_put(target_item); 150 config_item_put(target_item);
144 path_put(&nd.path); 151 path_put(&nd.path);
@@ -169,7 +176,9 @@ int configfs_unlink(struct inode *dir, struct dentry *dentry)
169 parent_item = configfs_get_config_item(dentry->d_parent); 176 parent_item = configfs_get_config_item(dentry->d_parent);
170 type = parent_item->ci_type; 177 type = parent_item->ci_type;
171 178
179 spin_lock(&configfs_dirent_lock);
172 list_del_init(&sd->s_sibling); 180 list_del_init(&sd->s_sibling);
181 spin_unlock(&configfs_dirent_lock);
173 configfs_drop_dentry(sd, dentry->d_parent); 182 configfs_drop_dentry(sd, dentry->d_parent);
174 dput(dentry); 183 dput(dentry);
175 configfs_put(sd); 184 configfs_put(sd);
@@ -184,8 +193,9 @@ int configfs_unlink(struct inode *dir, struct dentry *dentry)
184 type->ct_item_ops->drop_link(parent_item, 193 type->ct_item_ops->drop_link(parent_item,
185 sl->sl_target); 194 sl->sl_target);
186 195
187 /* FIXME: Needs lock */ 196 spin_lock(&configfs_dirent_lock);
188 list_del_init(&sl->sl_list); 197 list_del_init(&sl->sl_list);
198 spin_unlock(&configfs_dirent_lock);
189 199
190 /* Put reference from create_link() */ 200 /* Put reference from create_link() */
191 config_item_put(sl->sl_target); 201 config_item_put(sl->sl_target);
diff --git a/fs/dlm/config.c b/fs/dlm/config.c
index eac23bd288b2..492d8caaaf25 100644
--- a/fs/dlm/config.c
+++ b/fs/dlm/config.c
@@ -41,16 +41,20 @@ struct comm;
41struct nodes; 41struct nodes;
42struct node; 42struct node;
43 43
44static struct config_group *make_cluster(struct config_group *, const char *); 44static int make_cluster(struct config_group *, const char *,
45 struct config_group **);
45static void drop_cluster(struct config_group *, struct config_item *); 46static void drop_cluster(struct config_group *, struct config_item *);
46static void release_cluster(struct config_item *); 47static void release_cluster(struct config_item *);
47static struct config_group *make_space(struct config_group *, const char *); 48static int make_space(struct config_group *, const char *,
49 struct config_group **);
48static void drop_space(struct config_group *, struct config_item *); 50static void drop_space(struct config_group *, struct config_item *);
49static void release_space(struct config_item *); 51static void release_space(struct config_item *);
50static struct config_item *make_comm(struct config_group *, const char *); 52static int make_comm(struct config_group *, const char *,
53 struct config_item **);
51static void drop_comm(struct config_group *, struct config_item *); 54static void drop_comm(struct config_group *, struct config_item *);
52static void release_comm(struct config_item *); 55static void release_comm(struct config_item *);
53static struct config_item *make_node(struct config_group *, const char *); 56static int make_node(struct config_group *, const char *,
57 struct config_item **);
54static void drop_node(struct config_group *, struct config_item *); 58static void drop_node(struct config_group *, struct config_item *);
55static void release_node(struct config_item *); 59static void release_node(struct config_item *);
56 60
@@ -392,8 +396,8 @@ static struct node *to_node(struct config_item *i)
392 return i ? container_of(i, struct node, item) : NULL; 396 return i ? container_of(i, struct node, item) : NULL;
393} 397}
394 398
395static struct config_group *make_cluster(struct config_group *g, 399static int make_cluster(struct config_group *g, const char *name,
396 const char *name) 400 struct config_group **new_g)
397{ 401{
398 struct cluster *cl = NULL; 402 struct cluster *cl = NULL;
399 struct spaces *sps = NULL; 403 struct spaces *sps = NULL;
@@ -431,14 +435,15 @@ static struct config_group *make_cluster(struct config_group *g,
431 435
432 space_list = &sps->ss_group; 436 space_list = &sps->ss_group;
433 comm_list = &cms->cs_group; 437 comm_list = &cms->cs_group;
434 return &cl->group; 438 *new_g = &cl->group;
439 return 0;
435 440
436 fail: 441 fail:
437 kfree(cl); 442 kfree(cl);
438 kfree(gps); 443 kfree(gps);
439 kfree(sps); 444 kfree(sps);
440 kfree(cms); 445 kfree(cms);
441 return NULL; 446 return -ENOMEM;
442} 447}
443 448
444static void drop_cluster(struct config_group *g, struct config_item *i) 449static void drop_cluster(struct config_group *g, struct config_item *i)
@@ -466,7 +471,8 @@ static void release_cluster(struct config_item *i)
466 kfree(cl); 471 kfree(cl);
467} 472}
468 473
469static struct config_group *make_space(struct config_group *g, const char *name) 474static int make_space(struct config_group *g, const char *name,
475 struct config_group **new_g)
470{ 476{
471 struct space *sp = NULL; 477 struct space *sp = NULL;
472 struct nodes *nds = NULL; 478 struct nodes *nds = NULL;
@@ -489,13 +495,14 @@ static struct config_group *make_space(struct config_group *g, const char *name)
489 INIT_LIST_HEAD(&sp->members); 495 INIT_LIST_HEAD(&sp->members);
490 mutex_init(&sp->members_lock); 496 mutex_init(&sp->members_lock);
491 sp->members_count = 0; 497 sp->members_count = 0;
492 return &sp->group; 498 *new_g = &sp->group;
499 return 0;
493 500
494 fail: 501 fail:
495 kfree(sp); 502 kfree(sp);
496 kfree(gps); 503 kfree(gps);
497 kfree(nds); 504 kfree(nds);
498 return NULL; 505 return -ENOMEM;
499} 506}
500 507
501static void drop_space(struct config_group *g, struct config_item *i) 508static void drop_space(struct config_group *g, struct config_item *i)
@@ -522,19 +529,21 @@ static void release_space(struct config_item *i)
522 kfree(sp); 529 kfree(sp);
523} 530}
524 531
525static struct config_item *make_comm(struct config_group *g, const char *name) 532static int make_comm(struct config_group *g, const char *name,
533 struct config_item **new_i)
526{ 534{
527 struct comm *cm; 535 struct comm *cm;
528 536
529 cm = kzalloc(sizeof(struct comm), GFP_KERNEL); 537 cm = kzalloc(sizeof(struct comm), GFP_KERNEL);
530 if (!cm) 538 if (!cm)
531 return NULL; 539 return -ENOMEM;
532 540
533 config_item_init_type_name(&cm->item, name, &comm_type); 541 config_item_init_type_name(&cm->item, name, &comm_type);
534 cm->nodeid = -1; 542 cm->nodeid = -1;
535 cm->local = 0; 543 cm->local = 0;
536 cm->addr_count = 0; 544 cm->addr_count = 0;
537 return &cm->item; 545 *new_i = &cm->item;
546 return 0;
538} 547}
539 548
540static void drop_comm(struct config_group *g, struct config_item *i) 549static void drop_comm(struct config_group *g, struct config_item *i)
@@ -554,14 +563,15 @@ static void release_comm(struct config_item *i)
554 kfree(cm); 563 kfree(cm);
555} 564}
556 565
557static struct config_item *make_node(struct config_group *g, const char *name) 566static int make_node(struct config_group *g, const char *name,
567 struct config_item **new_i)
558{ 568{
559 struct space *sp = to_space(g->cg_item.ci_parent); 569 struct space *sp = to_space(g->cg_item.ci_parent);
560 struct node *nd; 570 struct node *nd;
561 571
562 nd = kzalloc(sizeof(struct node), GFP_KERNEL); 572 nd = kzalloc(sizeof(struct node), GFP_KERNEL);
563 if (!nd) 573 if (!nd)
564 return NULL; 574 return -ENOMEM;
565 575
566 config_item_init_type_name(&nd->item, name, &node_type); 576 config_item_init_type_name(&nd->item, name, &node_type);
567 nd->nodeid = -1; 577 nd->nodeid = -1;
@@ -573,7 +583,8 @@ static struct config_item *make_node(struct config_group *g, const char *name)
573 sp->members_count++; 583 sp->members_count++;
574 mutex_unlock(&sp->members_lock); 584 mutex_unlock(&sp->members_lock);
575 585
576 return &nd->item; 586 *new_i = &nd->item;
587 return 0;
577} 588}
578 589
579static void drop_node(struct config_group *g, struct config_item *i) 590static void drop_node(struct config_group *g, struct config_item *i)
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 17964c0505a9..1db080135c6d 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -174,10 +174,17 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
174 * need to use BH_New is when we're extending i_size on a file 174 * need to use BH_New is when we're extending i_size on a file
175 * system which doesn't support holes, in which case BH_New 175 * system which doesn't support holes, in which case BH_New
176 * allows block_prepare_write() to zero. 176 * allows block_prepare_write() to zero.
177 *
178 * If we see this on a sparse file system, then a truncate has
179 * raced us and removed the cluster. In this case, we clear
180 * the buffers dirty and uptodate bits and let the buffer code
181 * ignore it as a hole.
177 */ 182 */
178 mlog_bug_on_msg(create && p_blkno == 0 && ocfs2_sparse_alloc(osb), 183 if (create && p_blkno == 0 && ocfs2_sparse_alloc(osb)) {
179 "ino %lu, iblock %llu\n", inode->i_ino, 184 clear_buffer_dirty(bh_result);
180 (unsigned long long)iblock); 185 clear_buffer_uptodate(bh_result);
186 goto bail;
187 }
181 188
182 /* Treat the unwritten extent as a hole for zeroing purposes. */ 189 /* Treat the unwritten extent as a hole for zeroing purposes. */
183 if (p_blkno && !(ext_flags & OCFS2_EXT_UNWRITTEN)) 190 if (p_blkno && !(ext_flags & OCFS2_EXT_UNWRITTEN))
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index f02ccb34604d..443d108211ab 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -1489,25 +1489,28 @@ static struct o2hb_heartbeat_group *to_o2hb_heartbeat_group(struct config_group
1489 : NULL; 1489 : NULL;
1490} 1490}
1491 1491
1492static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *group, 1492static int o2hb_heartbeat_group_make_item(struct config_group *group,
1493 const char *name) 1493 const char *name,
1494 struct config_item **new_item)
1494{ 1495{
1495 struct o2hb_region *reg = NULL; 1496 struct o2hb_region *reg = NULL;
1496 struct config_item *ret = NULL; 1497 int ret = 0;
1497 1498
1498 reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL); 1499 reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL);
1499 if (reg == NULL) 1500 if (reg == NULL) {
1500 goto out; /* ENOMEM */ 1501 ret = -ENOMEM;
1502 goto out;
1503 }
1501 1504
1502 config_item_init_type_name(&reg->hr_item, name, &o2hb_region_type); 1505 config_item_init_type_name(&reg->hr_item, name, &o2hb_region_type);
1503 1506
1504 ret = &reg->hr_item; 1507 *new_item = &reg->hr_item;
1505 1508
1506 spin_lock(&o2hb_live_lock); 1509 spin_lock(&o2hb_live_lock);
1507 list_add_tail(&reg->hr_all_item, &o2hb_all_regions); 1510 list_add_tail(&reg->hr_all_item, &o2hb_all_regions);
1508 spin_unlock(&o2hb_live_lock); 1511 spin_unlock(&o2hb_live_lock);
1509out: 1512out:
1510 if (ret == NULL) 1513 if (ret)
1511 kfree(reg); 1514 kfree(reg);
1512 1515
1513 return ret; 1516 return ret;
diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c
index 7bf3c0ea7bd9..d8bfa0eb41b2 100644
--- a/fs/ocfs2/cluster/netdebug.c
+++ b/fs/ocfs2/cluster/netdebug.c
@@ -146,8 +146,10 @@ static int nst_seq_show(struct seq_file *seq, void *v)
146 nst->st_task->comm, nst->st_node, 146 nst->st_task->comm, nst->st_node,
147 nst->st_sc, nst->st_id, nst->st_msg_type, 147 nst->st_sc, nst->st_id, nst->st_msg_type,
148 nst->st_msg_key, 148 nst->st_msg_key,
149 nst->st_sock_time.tv_sec, nst->st_sock_time.tv_usec, 149 nst->st_sock_time.tv_sec,
150 nst->st_send_time.tv_sec, nst->st_send_time.tv_usec, 150 (unsigned long)nst->st_sock_time.tv_usec,
151 nst->st_send_time.tv_sec,
152 (unsigned long)nst->st_send_time.tv_usec,
151 nst->st_status_time.tv_sec, 153 nst->st_status_time.tv_sec,
152 nst->st_status_time.tv_usec); 154 nst->st_status_time.tv_usec);
153 } 155 }
@@ -274,7 +276,7 @@ static void *sc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
274 return sc; /* unused, just needs to be null when done */ 276 return sc; /* unused, just needs to be null when done */
275} 277}
276 278
277#define TV_SEC_USEC(TV) TV.tv_sec, TV.tv_usec 279#define TV_SEC_USEC(TV) TV.tv_sec, (unsigned long)TV.tv_usec
278 280
279static int sc_seq_show(struct seq_file *seq, void *v) 281static int sc_seq_show(struct seq_file *seq, void *v)
280{ 282{
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c
index cfdb08b484ed..b364b7052e46 100644
--- a/fs/ocfs2/cluster/nodemanager.c
+++ b/fs/ocfs2/cluster/nodemanager.c
@@ -644,27 +644,32 @@ out:
644 return ret; 644 return ret;
645} 645}
646 646
647static struct config_item *o2nm_node_group_make_item(struct config_group *group, 647static int o2nm_node_group_make_item(struct config_group *group,
648 const char *name) 648 const char *name,
649 struct config_item **new_item)
649{ 650{
650 struct o2nm_node *node = NULL; 651 struct o2nm_node *node = NULL;
651 struct config_item *ret = NULL; 652 int ret = 0;
652 653
653 if (strlen(name) > O2NM_MAX_NAME_LEN) 654 if (strlen(name) > O2NM_MAX_NAME_LEN) {
654 goto out; /* ENAMETOOLONG */ 655 ret = -ENAMETOOLONG;
656 goto out;
657 }
655 658
656 node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL); 659 node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL);
657 if (node == NULL) 660 if (node == NULL) {
658 goto out; /* ENOMEM */ 661 ret = -ENOMEM;
662 goto out;
663 }
659 664
660 strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */ 665 strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */
661 config_item_init_type_name(&node->nd_item, name, &o2nm_node_type); 666 config_item_init_type_name(&node->nd_item, name, &o2nm_node_type);
662 spin_lock_init(&node->nd_lock); 667 spin_lock_init(&node->nd_lock);
663 668
664 ret = &node->nd_item; 669 *new_item = &node->nd_item;
665 670
666out: 671out:
667 if (ret == NULL) 672 if (ret)
668 kfree(node); 673 kfree(node);
669 674
670 return ret; 675 return ret;
@@ -751,25 +756,31 @@ static struct o2nm_cluster_group *to_o2nm_cluster_group(struct config_group *gro
751} 756}
752#endif 757#endif
753 758
754static struct config_group *o2nm_cluster_group_make_group(struct config_group *group, 759static int o2nm_cluster_group_make_group(struct config_group *group,
755 const char *name) 760 const char *name,
761 struct config_group **new_group)
756{ 762{
757 struct o2nm_cluster *cluster = NULL; 763 struct o2nm_cluster *cluster = NULL;
758 struct o2nm_node_group *ns = NULL; 764 struct o2nm_node_group *ns = NULL;
759 struct config_group *o2hb_group = NULL, *ret = NULL; 765 struct config_group *o2hb_group = NULL;
760 void *defs = NULL; 766 void *defs = NULL;
767 int ret = 0;
761 768
762 /* this runs under the parent dir's i_mutex; there can be only 769 /* this runs under the parent dir's i_mutex; there can be only
763 * one caller in here at a time */ 770 * one caller in here at a time */
764 if (o2nm_single_cluster) 771 if (o2nm_single_cluster) {
765 goto out; /* ENOSPC */ 772 ret = -ENOSPC;
773 goto out;
774 }
766 775
767 cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL); 776 cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL);
768 ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL); 777 ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL);
769 defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL); 778 defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL);
770 o2hb_group = o2hb_alloc_hb_set(); 779 o2hb_group = o2hb_alloc_hb_set();
771 if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL) 780 if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL) {
781 ret = -ENOMEM;
772 goto out; 782 goto out;
783 }
773 784
774 config_group_init_type_name(&cluster->cl_group, name, 785 config_group_init_type_name(&cluster->cl_group, name,
775 &o2nm_cluster_type); 786 &o2nm_cluster_type);
@@ -786,11 +797,11 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g
786 cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT; 797 cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT;
787 cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT; 798 cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT;
788 799
789 ret = &cluster->cl_group; 800 *new_group = &cluster->cl_group;
790 o2nm_single_cluster = cluster; 801 o2nm_single_cluster = cluster;
791 802
792out: 803out:
793 if (ret == NULL) { 804 if (ret) {
794 kfree(cluster); 805 kfree(cluster);
795 kfree(ns); 806 kfree(ns);
796 o2hb_free_hb_set(o2hb_group); 807 o2hb_free_hb_set(o2hb_group);
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 80e20d9f2780..eae3d643a5e4 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -31,6 +31,7 @@
31#include <linux/pagemap.h> 31#include <linux/pagemap.h>
32#include <linux/debugfs.h> 32#include <linux/debugfs.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34#include <linux/time.h>
34 35
35#define MLOG_MASK_PREFIX ML_DLM_GLUE 36#define MLOG_MASK_PREFIX ML_DLM_GLUE
36#include <cluster/masklog.h> 37#include <cluster/masklog.h>
@@ -59,6 +60,9 @@ struct ocfs2_mask_waiter {
59 struct completion mw_complete; 60 struct completion mw_complete;
60 unsigned long mw_mask; 61 unsigned long mw_mask;
61 unsigned long mw_goal; 62 unsigned long mw_goal;
63#ifdef CONFIG_OCFS2_FS_STATS
64 unsigned long long mw_lock_start;
65#endif
62}; 66};
63 67
64static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres); 68static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres);
@@ -366,6 +370,75 @@ static void ocfs2_remove_lockres_tracking(struct ocfs2_lock_res *res)
366 spin_unlock(&ocfs2_dlm_tracking_lock); 370 spin_unlock(&ocfs2_dlm_tracking_lock);
367} 371}
368 372
373#ifdef CONFIG_OCFS2_FS_STATS
374static void ocfs2_init_lock_stats(struct ocfs2_lock_res *res)
375{
376 res->l_lock_num_prmode = 0;
377 res->l_lock_num_prmode_failed = 0;
378 res->l_lock_total_prmode = 0;
379 res->l_lock_max_prmode = 0;
380 res->l_lock_num_exmode = 0;
381 res->l_lock_num_exmode_failed = 0;
382 res->l_lock_total_exmode = 0;
383 res->l_lock_max_exmode = 0;
384 res->l_lock_refresh = 0;
385}
386
387static void ocfs2_update_lock_stats(struct ocfs2_lock_res *res, int level,
388 struct ocfs2_mask_waiter *mw, int ret)
389{
390 unsigned long long *num, *sum;
391 unsigned int *max, *failed;
392 struct timespec ts = current_kernel_time();
393 unsigned long long time = timespec_to_ns(&ts) - mw->mw_lock_start;
394
395 if (level == LKM_PRMODE) {
396 num = &res->l_lock_num_prmode;
397 sum = &res->l_lock_total_prmode;
398 max = &res->l_lock_max_prmode;
399 failed = &res->l_lock_num_prmode_failed;
400 } else if (level == LKM_EXMODE) {
401 num = &res->l_lock_num_exmode;
402 sum = &res->l_lock_total_exmode;
403 max = &res->l_lock_max_exmode;
404 failed = &res->l_lock_num_exmode_failed;
405 } else
406 return;
407
408 (*num)++;
409 (*sum) += time;
410 if (time > *max)
411 *max = time;
412 if (ret)
413 (*failed)++;
414}
415
416static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
417{
418 lockres->l_lock_refresh++;
419}
420
421static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw)
422{
423 struct timespec ts = current_kernel_time();
424 mw->mw_lock_start = timespec_to_ns(&ts);
425}
426#else
427static inline void ocfs2_init_lock_stats(struct ocfs2_lock_res *res)
428{
429}
430static inline void ocfs2_update_lock_stats(struct ocfs2_lock_res *res,
431 int level, struct ocfs2_mask_waiter *mw, int ret)
432{
433}
434static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
435{
436}
437static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw)
438{
439}
440#endif
441
369static void ocfs2_lock_res_init_common(struct ocfs2_super *osb, 442static void ocfs2_lock_res_init_common(struct ocfs2_super *osb,
370 struct ocfs2_lock_res *res, 443 struct ocfs2_lock_res *res,
371 enum ocfs2_lock_type type, 444 enum ocfs2_lock_type type,
@@ -385,6 +458,8 @@ static void ocfs2_lock_res_init_common(struct ocfs2_super *osb,
385 res->l_flags = OCFS2_LOCK_INITIALIZED; 458 res->l_flags = OCFS2_LOCK_INITIALIZED;
386 459
387 ocfs2_add_lockres_tracking(res, osb->osb_dlm_debug); 460 ocfs2_add_lockres_tracking(res, osb->osb_dlm_debug);
461
462 ocfs2_init_lock_stats(res);
388} 463}
389 464
390void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res) 465void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res)
@@ -1048,6 +1123,7 @@ static void ocfs2_init_mask_waiter(struct ocfs2_mask_waiter *mw)
1048{ 1123{
1049 INIT_LIST_HEAD(&mw->mw_item); 1124 INIT_LIST_HEAD(&mw->mw_item);
1050 init_completion(&mw->mw_complete); 1125 init_completion(&mw->mw_complete);
1126 ocfs2_init_start_time(mw);
1051} 1127}
1052 1128
1053static int ocfs2_wait_for_mask(struct ocfs2_mask_waiter *mw) 1129static int ocfs2_wait_for_mask(struct ocfs2_mask_waiter *mw)
@@ -1254,6 +1330,7 @@ out:
1254 goto again; 1330 goto again;
1255 mlog_errno(ret); 1331 mlog_errno(ret);
1256 } 1332 }
1333 ocfs2_update_lock_stats(lockres, level, &mw, ret);
1257 1334
1258 mlog_exit(ret); 1335 mlog_exit(ret);
1259 return ret; 1336 return ret;
@@ -1983,6 +2060,7 @@ static int ocfs2_inode_lock_update(struct inode *inode,
1983 le32_to_cpu(fe->i_flags)); 2060 le32_to_cpu(fe->i_flags));
1984 2061
1985 ocfs2_refresh_inode(inode, fe); 2062 ocfs2_refresh_inode(inode, fe);
2063 ocfs2_track_lock_refresh(lockres);
1986 } 2064 }
1987 2065
1988 status = 0; 2066 status = 0;
@@ -2267,6 +2345,7 @@ int ocfs2_super_lock(struct ocfs2_super *osb,
2267 2345
2268 if (status < 0) 2346 if (status < 0)
2269 mlog_errno(status); 2347 mlog_errno(status);
2348 ocfs2_track_lock_refresh(lockres);
2270 } 2349 }
2271bail: 2350bail:
2272 mlog_exit(status); 2351 mlog_exit(status);
@@ -2461,7 +2540,7 @@ static void *ocfs2_dlm_seq_next(struct seq_file *m, void *v, loff_t *pos)
2461} 2540}
2462 2541
2463/* So that debugfs.ocfs2 can determine which format is being used */ 2542/* So that debugfs.ocfs2 can determine which format is being used */
2464#define OCFS2_DLM_DEBUG_STR_VERSION 1 2543#define OCFS2_DLM_DEBUG_STR_VERSION 2
2465static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) 2544static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
2466{ 2545{
2467 int i; 2546 int i;
@@ -2502,6 +2581,47 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
2502 for(i = 0; i < DLM_LVB_LEN; i++) 2581 for(i = 0; i < DLM_LVB_LEN; i++)
2503 seq_printf(m, "0x%x\t", lvb[i]); 2582 seq_printf(m, "0x%x\t", lvb[i]);
2504 2583
2584#ifdef CONFIG_OCFS2_FS_STATS
2585# define lock_num_prmode(_l) (_l)->l_lock_num_prmode
2586# define lock_num_exmode(_l) (_l)->l_lock_num_exmode
2587# define lock_num_prmode_failed(_l) (_l)->l_lock_num_prmode_failed
2588# define lock_num_exmode_failed(_l) (_l)->l_lock_num_exmode_failed
2589# define lock_total_prmode(_l) (_l)->l_lock_total_prmode
2590# define lock_total_exmode(_l) (_l)->l_lock_total_exmode
2591# define lock_max_prmode(_l) (_l)->l_lock_max_prmode
2592# define lock_max_exmode(_l) (_l)->l_lock_max_exmode
2593# define lock_refresh(_l) (_l)->l_lock_refresh
2594#else
2595# define lock_num_prmode(_l) (0ULL)
2596# define lock_num_exmode(_l) (0ULL)
2597# define lock_num_prmode_failed(_l) (0)
2598# define lock_num_exmode_failed(_l) (0)
2599# define lock_total_prmode(_l) (0ULL)
2600# define lock_total_exmode(_l) (0ULL)
2601# define lock_max_prmode(_l) (0)
2602# define lock_max_exmode(_l) (0)
2603# define lock_refresh(_l) (0)
2604#endif
2605 /* The following seq_print was added in version 2 of this output */
2606 seq_printf(m, "%llu\t"
2607 "%llu\t"
2608 "%u\t"
2609 "%u\t"
2610 "%llu\t"
2611 "%llu\t"
2612 "%u\t"
2613 "%u\t"
2614 "%u\t",
2615 lock_num_prmode(lockres),
2616 lock_num_exmode(lockres),
2617 lock_num_prmode_failed(lockres),
2618 lock_num_exmode_failed(lockres),
2619 lock_total_prmode(lockres),
2620 lock_total_exmode(lockres),
2621 lock_max_prmode(lockres),
2622 lock_max_exmode(lockres),
2623 lock_refresh(lockres));
2624
2505 /* End the line */ 2625 /* End the line */
2506 seq_printf(m, "\n"); 2626 seq_printf(m, "\n");
2507 return 0; 2627 return 0;
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 57e0d30cde98..e8514e8b6ce8 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2202,7 +2202,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
2202 2202
2203 ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos); 2203 ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos);
2204 if (ret == -EINVAL) 2204 if (ret == -EINVAL)
2205 mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n"); 2205 mlog(0, "generic_file_aio_read returned -EINVAL\n");
2206 2206
2207 /* buffered aio wouldn't have proper lock coverage today */ 2207 /* buffered aio wouldn't have proper lock coverage today */
2208 BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT)); 2208 BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT));
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 9698338adc39..a8c19cb3cfdd 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -329,7 +329,7 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks)
329 329
330 mlog(0, "Trying to extend transaction by %d blocks\n", nblocks); 330 mlog(0, "Trying to extend transaction by %d blocks\n", nblocks);
331 331
332#ifdef OCFS2_DEBUG_FS 332#ifdef CONFIG_OCFS2_DEBUG_FS
333 status = 1; 333 status = 1;
334#else 334#else
335 status = journal_extend(handle, nblocks); 335 status = journal_extend(handle, nblocks);
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index be774bdc8b36..28e492e4ec88 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -498,7 +498,7 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
498 498
499 alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data; 499 alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data;
500 500
501#ifdef OCFS2_DEBUG_FS 501#ifdef CONFIG_OCFS2_DEBUG_FS
502 if (le32_to_cpu(alloc->id1.bitmap1.i_used) != 502 if (le32_to_cpu(alloc->id1.bitmap1.i_used) !=
503 ocfs2_local_alloc_count_bits(alloc)) { 503 ocfs2_local_alloc_count_bits(alloc)) {
504 ocfs2_error(osb->sb, "local alloc inode %llu says it has " 504 ocfs2_error(osb->sb, "local alloc inode %llu says it has "
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 31692379c170..1cb814be8ef1 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -132,6 +132,18 @@ struct ocfs2_lock_res {
132 wait_queue_head_t l_event; 132 wait_queue_head_t l_event;
133 133
134 struct list_head l_debug_list; 134 struct list_head l_debug_list;
135
136#ifdef CONFIG_OCFS2_FS_STATS
137 unsigned long long l_lock_num_prmode; /* PR acquires */
138 unsigned long long l_lock_num_exmode; /* EX acquires */
139 unsigned int l_lock_num_prmode_failed; /* Failed PR gets */
140 unsigned int l_lock_num_exmode_failed; /* Failed EX gets */
141 unsigned long long l_lock_total_prmode; /* Tot wait for PR */
142 unsigned long long l_lock_total_exmode; /* Tot wait for EX */
143 unsigned int l_lock_max_prmode; /* Max wait for PR */
144 unsigned int l_lock_max_exmode; /* Max wait for EX */
145 unsigned int l_lock_refresh; /* Disk refreshes */
146#endif
135}; 147};
136 148
137struct ocfs2_dlm_debug { 149struct ocfs2_dlm_debug {
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index 52c426665154..3f1945177629 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -901,7 +901,7 @@ static inline int ocfs2_sprintf_system_inode_name(char *buf, int len,
901 * list has a copy per slot. 901 * list has a copy per slot.
902 */ 902 */
903 if (type <= OCFS2_LAST_GLOBAL_SYSTEM_INODE) 903 if (type <= OCFS2_LAST_GLOBAL_SYSTEM_INODE)
904 chars = snprintf(buf, len, 904 chars = snprintf(buf, len, "%s",
905 ocfs2_system_inodes[type].si_name); 905 ocfs2_system_inodes[type].si_name);
906 else 906 else
907 chars = snprintf(buf, len, 907 chars = snprintf(buf, len,
diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c
index bd7e0f3acfc7..353fc35c6748 100644
--- a/fs/ocfs2/stack_user.c
+++ b/fs/ocfs2/stack_user.c
@@ -550,26 +550,17 @@ static ssize_t ocfs2_control_read(struct file *file,
550 size_t count, 550 size_t count,
551 loff_t *ppos) 551 loff_t *ppos)
552{ 552{
553 char *proto_string = OCFS2_CONTROL_PROTO; 553 ssize_t ret;
554 size_t to_write = 0;
555
556 if (*ppos >= OCFS2_CONTROL_PROTO_LEN)
557 return 0;
558
559 to_write = OCFS2_CONTROL_PROTO_LEN - *ppos;
560 if (to_write > count)
561 to_write = count;
562 if (copy_to_user(buf, proto_string + *ppos, to_write))
563 return -EFAULT;
564 554
565 *ppos += to_write; 555 ret = simple_read_from_buffer(buf, count, ppos,
556 OCFS2_CONTROL_PROTO, OCFS2_CONTROL_PROTO_LEN);
566 557
567 /* Have we read the whole protocol list? */ 558 /* Have we read the whole protocol list? */
568 if (*ppos >= OCFS2_CONTROL_PROTO_LEN) 559 if (ret > 0 && *ppos >= OCFS2_CONTROL_PROTO_LEN)
569 ocfs2_control_set_handshake_state(file, 560 ocfs2_control_set_handshake_state(file,
570 OCFS2_CONTROL_HANDSHAKE_READ); 561 OCFS2_CONTROL_HANDSHAKE_READ);
571 562
572 return to_write; 563 return ret;
573} 564}
574 565
575static int ocfs2_control_release(struct inode *inode, struct file *file) 566static int ocfs2_control_release(struct inode *inode, struct file *file)
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index df63ba20ae90..ccecfe5094fa 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1703,7 +1703,11 @@ static int ocfs2_check_volume(struct ocfs2_super *osb)
1703 local = ocfs2_mount_local(osb); 1703 local = ocfs2_mount_local(osb);
1704 1704
1705 /* will play back anything left in the journal. */ 1705 /* will play back anything left in the journal. */
1706 ocfs2_journal_load(osb->journal, local); 1706 status = ocfs2_journal_load(osb->journal, local);
1707 if (status < 0) {
1708 mlog(ML_ERROR, "ocfs2 journal load failed! %d\n", status);
1709 goto finally;
1710 }
1707 1711
1708 if (dirty) { 1712 if (dirty) {
1709 /* recover my local alloc if we didn't unmount cleanly. */ 1713 /* recover my local alloc if we didn't unmount cleanly. */