Index: lum/fs/exec.c
===================================================================
--- lum.orig/fs/exec.c 2003-08-07 05:11:15.000000000 -0600
-+++ lum/fs/exec.c 2003-08-07 05:14:57.000000000 -0600
++++ lum/fs/exec.c 2003-08-30 07:20:56.000000000 -0600
@@ -107,8 +107,10 @@ asmlinkage long sys_uselib(const char *
struct file * file;
struct nameidata nd;
Index: lum/fs/dcache.c
===================================================================
--- lum.orig/fs/dcache.c 2003-08-07 05:11:15.000000000 -0600
-+++ lum/fs/dcache.c 2003-08-07 05:11:20.000000000 -0600
++++ lum/fs/dcache.c 2003-08-30 07:20:56.000000000 -0600
@@ -181,6 +181,13 @@ int d_invalidate(struct dentry * dentry)
spin_unlock(&dcache_lock);
return 0;
Index: lum/fs/namespace.c
===================================================================
--- lum.orig/fs/namespace.c 2003-08-07 05:11:15.000000000 -0600
-+++ lum/fs/namespace.c 2003-08-07 05:11:20.000000000 -0600
++++ lum/fs/namespace.c 2003-08-30 07:20:56.000000000 -0600
@@ -99,6 +99,7 @@ static void detach_mnt(struct vfsmount *
{
old_nd->dentry = mnt->mnt_mountpoint;
Index: lum/fs/namei.c
===================================================================
--- lum.orig/fs/namei.c 2003-08-07 05:11:15.000000000 -0600
-+++ lum/fs/namei.c 2003-08-07 05:11:20.000000000 -0600
++++ lum/fs/namei.c 2003-08-30 07:21:03.000000000 -0600
@@ -94,6 +94,13 @@
* XEmacs seems to be relying on it...
*/
if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
dput(dentry);
-@@ -281,11 +297,14 @@ static struct dentry * cached_lookup(str
+@@ -281,11 +297,15 @@ static struct dentry * cached_lookup(str
* make sure that nobody added the entry to the dcache in the meantime..
* SMP-safe
*/
{
struct dentry * result;
struct inode *dir = parent->d_inode;
++ int counter = 0;
+again:
-+
++ counter++;
down(&dir->i_sem);
/*
* First re-do the cached lookup just in case it was created
-@@ -300,6 +319,9 @@ static struct dentry * real_lookup(struc
+@@ -300,6 +320,9 @@ static struct dentry * real_lookup(struc
result = ERR_PTR(-ENOMEM);
if (dentry) {
lock_kernel();
result = dir->i_op->lookup(dir, dentry);
unlock_kernel();
if (result)
-@@ -321,6 +343,12 @@ static struct dentry * real_lookup(struc
+@@ -321,6 +344,15 @@ static struct dentry * real_lookup(struc
dput(result);
result = ERR_PTR(-ENOENT);
}
+ if (!result->d_op->d_revalidate_it(result, flags, it) &&
+ !d_invalidate(result)) {
+ dput(result);
-+ goto again;
++ if (counter > 10)
++ result = ERR_PTR(-ESTALE);
++ if (!IS_ERR(result))
++ goto again;
+ }
}
return result;
}
-@@ -332,7 +360,8 @@ static struct dentry * real_lookup(struc
+@@ -332,7 +364,8 @@ static struct dentry * real_lookup(struc
* Without that kind of total limit, nasty chains of consecutive
* symlinks can cause almost arbitrarily long lookups.
*/
{
int err;
if (current->link_count >= 5)
-@@ -346,10 +375,12 @@ static inline int do_follow_link(struct
+@@ -346,10 +379,12 @@ static inline int do_follow_link(struct
current->link_count++;
current->total_link_count++;
UPDATE_ATIME(dentry->d_inode);
path_release(nd);
return -ELOOP;
}
-@@ -447,7 +478,8 @@ static inline void follow_dotdot(struct
+@@ -447,7 +482,8 @@ static inline void follow_dotdot(struct
*
* We expect 'base' to be positive and a directory.
*/
{
struct dentry *dentry;
struct inode *inode;
-@@ -520,9 +552,9 @@ int link_path_walk(const char * name, st
+@@ -520,9 +556,9 @@ int link_path_walk(const char * name, st
break;
}
/* This does the actual lookups.. */
err = PTR_ERR(dentry);
if (IS_ERR(dentry))
break;
-@@ -540,7 +572,7 @@ int link_path_walk(const char * name, st
+@@ -540,7 +576,7 @@ int link_path_walk(const char * name, st
goto out_dput;
if (inode->i_op->follow_link) {
dput(dentry);
if (err)
goto return_err;
-@@ -556,7 +588,7 @@ int link_path_walk(const char * name, st
+@@ -556,7 +592,7 @@ int link_path_walk(const char * name, st
nd->dentry = dentry;
}
err = -ENOTDIR;
break;
continue;
/* here ends the main loop */
-@@ -583,9 +615,9 @@ last_component:
+@@ -583,9 +619,9 @@ last_component:
if (err < 0)
break;
}
err = PTR_ERR(dentry);
if (IS_ERR(dentry))
break;
-@@ -595,7 +627,7 @@ last_component:
+@@ -595,7 +631,7 @@ last_component:
inode = dentry->d_inode;
if ((lookup_flags & LOOKUP_FOLLOW)
&& inode && inode->i_op && inode->i_op->follow_link) {
dput(dentry);
if (err)
goto return_err;
-@@ -609,7 +641,8 @@ last_component:
+@@ -609,7 +645,8 @@ last_component:
goto no_inode;
if (lookup_flags & LOOKUP_DIRECTORY) {
err = -ENOTDIR;
break;
}
goto return_base;
-@@ -633,6 +666,23 @@ return_reval:
+@@ -633,6 +670,21 @@ return_reval:
* Check the cached dentry for staleness.
*/
dentry = nd->dentry;
-+ revalidate_again:
+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) {
+ err = -ESTALE;
+ if (!dentry->d_op->d_revalidate_it(dentry, 0, it)) {
+ d_invalidate(dentry);
+ dput(dentry);
+ dentry = new;
-+ goto revalidate_again;
+ }
+ } else
if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
err = -ESTALE;
if (!dentry->d_op->d_revalidate(dentry, 0)) {
-@@ -646,15 +696,28 @@ out_dput:
+@@ -646,15 +698,28 @@ out_dput:
dput(dentry);
break;
}
}
/* SMP-safe */
-@@ -739,6 +802,17 @@ walk_init_root(const char *name, struct
+@@ -739,6 +804,17 @@ walk_init_root(const char *name, struct
}
/* SMP-safe */
int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
{
int error = 0;
-@@ -753,6 +827,7 @@ int path_init(const char *name, unsigned
+@@ -753,6 +829,7 @@ int path_init(const char *name, unsigned
{
nd->last_type = LAST_ROOT; /* if there are only slashes... */
nd->flags = flags;
if (*name=='/')
return walk_init_root(name,nd);
read_lock(¤t->fs->lock);
-@@ -767,7 +842,8 @@ int path_init(const char *name, unsigned
+@@ -767,7 +844,8 @@ int path_init(const char *name, unsigned
* needs parent already locked. Doesn't follow mounts.
* SMP-safe.
*/
{
struct dentry * dentry;
struct inode *inode;
-@@ -790,13 +866,16 @@ struct dentry * lookup_hash(struct qstr
+@@ -790,13 +868,16 @@ struct dentry * lookup_hash(struct qstr
goto out;
}
dentry = inode->i_op->lookup(inode, new);
unlock_kernel();
if (!dentry)
-@@ -808,6 +887,12 @@ out:
+@@ -808,6 +889,12 @@ out:
return dentry;
}
/* SMP-safe */
struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
{
-@@ -829,7 +914,7 @@ struct dentry * lookup_one_len(const cha
+@@ -829,7 +916,7 @@ struct dentry * lookup_one_len(const cha
}
this.hash = end_name_hash(hash);
access:
return ERR_PTR(-EACCES);
}
-@@ -860,6 +945,23 @@ int __user_walk(const char *name, unsign
+@@ -860,6 +947,23 @@ int __user_walk(const char *name, unsign
return err;
}
/*
* It's inline, so penalty for filesystems that don't use sticky bit is
* minimal.
-@@ -955,7 +1057,8 @@ static inline int lookup_flags(unsigned
+@@ -955,7 +1059,8 @@ static inline int lookup_flags(unsigned
return retval;
}
{
int error;
-@@ -968,12 +1071,15 @@ int vfs_create(struct inode *dir, struct
+@@ -968,12 +1073,15 @@ int vfs_create(struct inode *dir, struct
goto exit_lock;
error = -EACCES; /* shouldn't it be ENOSYS? */
unlock_kernel();
exit_lock:
up(&dir->i_zombie);
-@@ -982,6 +1088,11 @@ exit_lock:
+@@ -982,6 +1090,11 @@ exit_lock:
return error;
}
/*
* open_namei()
*
-@@ -996,7 +1107,8 @@ exit_lock:
+@@ -996,7 +1109,8 @@ exit_lock:
* for symlinks (where the permissions are checked later).
* SMP-safe
*/
{
int acc_mode, error = 0;
struct inode *inode;
-@@ -1006,11 +1118,14 @@ int open_namei(const char * pathname, in
+@@ -1006,11 +1120,14 @@ int open_namei(const char * pathname, in
acc_mode = ACC_MODE(flag);
if (error)
return error;
dentry = nd->dentry;
-@@ -1020,6 +1135,10 @@ int open_namei(const char * pathname, in
+@@ -1020,6 +1137,10 @@ int open_namei(const char * pathname, in
/*
* Create - we need to know the parent.
*/
error = path_lookup(pathname, LOOKUP_PARENT, nd);
if (error)
return error;
-@@ -1035,7 +1154,7 @@ int open_namei(const char * pathname, in
+@@ -1035,7 +1156,7 @@ int open_namei(const char * pathname, in
dir = nd->dentry;
down(&dir->d_inode->i_sem);
do_last:
error = PTR_ERR(dentry);
-@@ -1044,10 +1163,11 @@ do_last:
+@@ -1044,10 +1165,11 @@ do_last:
goto exit;
}
up(&dir->d_inode->i_sem);
dput(nd->dentry);
nd->dentry = dentry;
-@@ -1151,7 +1271,7 @@ ok:
+@@ -1151,7 +1273,7 @@ ok:
if (!error) {
DQUOT_INIT(inode);
}
put_write_access(inode);
if (error)
-@@ -1163,8 +1283,10 @@ ok:
+@@ -1163,8 +1285,10 @@ ok:
return 0;
exit_dput:
path_release(nd);
return error;
-@@ -1183,7 +1305,10 @@ do_link:
+@@ -1183,7 +1307,10 @@ do_link:
* are done. Procfs-like symlinks just set LAST_BIND.
*/
UPDATE_ATIME(dentry->d_inode);
dput(dentry);
if (error)
return error;
-@@ -1205,13 +1330,20 @@ do_link:
+@@ -1205,13 +1332,20 @@ do_link:
}
dir = nd->dentry;
down(&dir->d_inode->i_sem);
{
struct dentry *dentry;
-@@ -1219,7 +1351,7 @@ static struct dentry *lookup_create(stru
+@@ -1219,7 +1353,7 @@ static struct dentry *lookup_create(stru
dentry = ERR_PTR(-EEXIST);
if (nd->last_type != LAST_NORM)
goto fail;
if (IS_ERR(dentry))
goto fail;
if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-@@ -1275,7 +1407,16 @@ asmlinkage long sys_mknod(const char * f
+@@ -1275,7 +1409,16 @@ asmlinkage long sys_mknod(const char * f
error = path_lookup(tmp, LOOKUP_PARENT, &nd);
if (error)
goto out;
error = PTR_ERR(dentry);
mode &= ~current->fs->umask;
-@@ -1296,6 +1437,7 @@ asmlinkage long sys_mknod(const char * f
+@@ -1296,6 +1439,7 @@ asmlinkage long sys_mknod(const char * f
dput(dentry);
}
up(&nd.dentry->d_inode->i_sem);
path_release(&nd);
out:
putname(tmp);
-@@ -1343,7 +1485,14 @@ asmlinkage long sys_mkdir(const char * p
+@@ -1343,7 +1487,14 @@ asmlinkage long sys_mkdir(const char * p
error = path_lookup(tmp, LOOKUP_PARENT, &nd);
if (error)
goto out;
error = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
error = vfs_mkdir(nd.dentry->d_inode, dentry,
-@@ -1351,6 +1500,7 @@ asmlinkage long sys_mkdir(const char * p
+@@ -1351,6 +1502,7 @@ asmlinkage long sys_mkdir(const char * p
dput(dentry);
}
up(&nd.dentry->d_inode->i_sem);
path_release(&nd);
out:
putname(tmp);
-@@ -1451,8 +1601,16 @@ asmlinkage long sys_rmdir(const char * p
+@@ -1451,8 +1603,16 @@ asmlinkage long sys_rmdir(const char * p
error = -EBUSY;
goto exit1;
}
error = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
error = vfs_rmdir(nd.dentry->d_inode, dentry);
-@@ -1510,8 +1668,15 @@ asmlinkage long sys_unlink(const char *
+@@ -1510,8 +1670,15 @@ asmlinkage long sys_unlink(const char *
error = -EISDIR;
if (nd.last_type != LAST_NORM)
goto exit1;
error = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
/* Why not before? Because we want correct error value */
-@@ -1578,15 +1743,23 @@ asmlinkage long sys_symlink(const char *
+@@ -1578,15 +1745,23 @@ asmlinkage long sys_symlink(const char *
error = path_lookup(to, LOOKUP_PARENT, &nd);
if (error)
goto out;
putname(to);
}
putname(from);
-@@ -1662,7 +1835,14 @@ asmlinkage long sys_link(const char * ol
+@@ -1662,7 +1837,14 @@ asmlinkage long sys_link(const char * ol
error = -EXDEV;
if (old_nd.mnt != nd.mnt)
goto out_release;
error = PTR_ERR(new_dentry);
if (!IS_ERR(new_dentry)) {
error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-@@ -1706,7 +1886,7 @@ exit:
+@@ -1706,7 +1888,7 @@ exit:
* locking].
*/
int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
{
int error;
struct inode *target;
-@@ -1785,7 +1965,7 @@ out_unlock:
+@@ -1785,7 +1967,7 @@ out_unlock:
}
int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
{
int error;
-@@ -1873,9 +2053,18 @@ static inline int do_rename(const char *
+@@ -1873,9 +2055,18 @@ static inline int do_rename(const char *
if (newnd.last_type != LAST_NORM)
goto exit2;
error = PTR_ERR(old_dentry);
if (IS_ERR(old_dentry))
goto exit3;
-@@ -1891,16 +2080,16 @@ static inline int do_rename(const char *
+@@ -1891,16 +2082,16 @@ static inline int do_rename(const char *
if (newnd.last.name[newnd.last.len])
goto exit4;
}
dput(new_dentry);
exit4:
dput(old_dentry);
-@@ -1951,20 +2140,26 @@ out:
+@@ -1951,20 +2142,26 @@ out:
}
static inline int
out:
if (current->link_count || res || nd->last_type!=LAST_NORM)
return res;
-@@ -1986,7 +2181,13 @@ fail:
+@@ -1986,7 +2183,13 @@ fail:
int vfs_follow_link(struct nameidata *nd, const char *link)
{
}
/* get the link contents into pagecache */
-@@ -2028,7 +2229,7 @@ int page_follow_link(struct dentry *dent
+@@ -2028,7 +2231,7 @@ int page_follow_link(struct dentry *dent
{
struct page *page = NULL;
char *s = page_getlink(dentry, &page);
Index: lum/fs/open.c
===================================================================
--- lum.orig/fs/open.c 2003-08-07 05:11:15.000000000 -0600
-+++ lum/fs/open.c 2003-08-08 05:30:13.000000000 -0600
++++ lum/fs/open.c 2003-08-30 07:20:56.000000000 -0600
@@ -19,6 +19,8 @@
#include <asm/uaccess.h>
Index: lum/fs/stat.c
===================================================================
--- lum.orig/fs/stat.c 2003-08-07 05:11:15.000000000 -0600
-+++ lum/fs/stat.c 2003-08-07 05:11:20.000000000 -0600
++++ lum/fs/stat.c 2003-08-30 07:20:56.000000000 -0600
@@ -17,10 +17,12 @@
* Revalidate the inode. This is required for proper NFS attribute caching.
*/
Index: lum/include/linux/dcache.h
===================================================================
--- lum.orig/include/linux/dcache.h 2003-08-07 05:11:15.000000000 -0600
-+++ lum/include/linux/dcache.h 2003-08-07 05:16:55.000000000 -0600
++++ lum/include/linux/dcache.h 2003-08-30 07:20:56.000000000 -0600
@@ -7,6 +7,50 @@
#include <linux/mount.h>
#include <linux/kernel.h>
Index: lum/include/linux/fs.h
===================================================================
---- lum.orig/include/linux/fs.h 2003-08-07 05:11:20.000000000 -0600
-+++ lum/include/linux/fs.h 2003-08-07 05:13:52.000000000 -0600
+--- lum.orig/include/linux/fs.h 2003-08-30 07:20:55.000000000 -0600
++++ lum/include/linux/fs.h 2003-08-30 07:20:56.000000000 -0600
@@ -73,6 +73,7 @@ extern int leases_enable, dir_notify_ena
#define FMODE_READ 1
Index: lum/include/linux/fs_struct.h
===================================================================
--- lum.orig/include/linux/fs_struct.h 2003-08-07 05:11:15.000000000 -0600
-+++ lum/include/linux/fs_struct.h 2003-08-07 05:11:20.000000000 -0600
++++ lum/include/linux/fs_struct.h 2003-08-30 07:20:56.000000000 -0600
@@ -34,10 +34,12 @@ static inline void set_fs_root(struct fs
write_lock(&fs->lock);
old_root = fs->root;
}
Index: lum/kernel/ksyms.c
===================================================================
---- lum.orig/kernel/ksyms.c 2003-08-07 05:11:20.000000000 -0600
-+++ lum/kernel/ksyms.c 2003-08-07 05:11:20.000000000 -0600
+--- lum.orig/kernel/ksyms.c 2003-08-30 07:20:55.000000000 -0600
++++ lum/kernel/ksyms.c 2003-08-30 07:20:56.000000000 -0600
@@ -269,6 +269,7 @@ EXPORT_SYMBOL(read_cache_page);
EXPORT_SYMBOL(set_page_dirty);
EXPORT_SYMBOL(vfs_readlink);
Index: lum/kernel/fork.c
===================================================================
--- lum.orig/kernel/fork.c 2003-08-07 05:11:15.000000000 -0600
-+++ lum/kernel/fork.c 2003-08-07 05:11:20.000000000 -0600
++++ lum/kernel/fork.c 2003-08-30 07:20:56.000000000 -0600
@@ -384,10 +384,13 @@ static inline struct fs_struct *__copy_f
fs->umask = old->umask;
read_lock(&old->lock);
Index: lum/kernel/exit.c
===================================================================
--- lum.orig/kernel/exit.c 2003-08-07 05:11:15.000000000 -0600
-+++ lum/kernel/exit.c 2003-08-07 05:11:20.000000000 -0600
++++ lum/kernel/exit.c 2003-08-30 07:20:56.000000000 -0600
@@ -238,11 +238,14 @@ static inline void __put_fs_struct(struc
{
/* No need to hold fs->lock if we are killing it */
cli->cl_conn_count++;
if (cli->cl_conn_count > 1)
GOTO(out_sem, rc);
+ exp = class_conn2export(dlm_handle);
if (obd->obd_namespace != NULL)
CERROR("already have namespace!\n");
LASSERT (imp->imp_state == LUSTRE_IMP_FULL);
- exp = class_conn2export(dlm_handle);
exp->exp_connection = ptlrpc_connection_addref(imp->imp_connection);
- class_export_put(exp);
if (imp->imp_replayable) {
CDEBUG(D_HA, "connected to replayable target: %s\n",
obd->obd_namespace = NULL;
out_disco:
cli->cl_conn_count--;
- class_disconnect(dlm_handle, 0);
+ class_disconnect(exp, 0);
+ } else {
+ class_export_put(exp);
}
out_sem:
up(&cli->cl_sem);
return rc;
}
-int client_disconnect_import(struct lustre_handle *dlm_handle, int failover)
+int client_disconnect_export(struct obd_export *exp, int failover)
{
- struct obd_device *obd = class_conn2obd(dlm_handle);
+ struct obd_device *obd = class_exp2obd(exp);
struct client_obd *cli = &obd->u.cli;
struct obd_import *imp = cli->cl_import;
int rc = 0, err;
ENTRY;
if (!obd) {
- CERROR("invalid connection for disconnect: cookie "LPX64"\n",
- dlm_handle ? dlm_handle->cookie : -1UL);
+ CERROR("invalid export for disconnect: "
+ "exp %p cookie "LPX64"\n", exp,
+ exp ? exp->exp_handle.h_cookie : -1UL);
RETURN(-EINVAL);
}
}
/* Yeah, obd_no_recov also (mainly) means "forced shutdown". */
- if (obd->obd_no_recov) {
+ if (obd->obd_no_recov)
ptlrpc_set_import_active(imp, 0);
- } else {
+ else
rc = ptlrpc_disconnect_import(imp);
- }
-
- imp->imp_state = LUSTRE_IMP_NEW;
+ imp->imp_state = LUSTRE_IMP_NEW;
EXIT;
-
out_no_disconnect:
- err = class_disconnect(dlm_handle, 0);
+ err = class_disconnect(exp, 0);
if (!rc && err)
rc = err;
out_sem:
int target_handle_disconnect(struct ptlrpc_request *req)
{
- struct lustre_handle *conn = &req->rq_reqmsg->handle;
+ struct obd_export *export;
struct obd_import *dlmimp;
int rc;
ENTRY;
if (rc)
RETURN(rc);
- req->rq_status = obd_disconnect(conn, 0);
+ /* Create an export reference to disconnect, so the rq_export
+ * ref is not destroyed. See class_disconnect() for more info. */
+ export = class_export_get(req->rq_export);
+ req->rq_status = obd_disconnect(export, 0);
dlmimp = req->rq_export->exp_ldlm_data.led_import;
class_destroy_import(dlmimp);
obd->obd_recovering = obd->obd_abort_recovery = 0;
obd->obd_recoverable_clients = 0;
+
wake_up(&obd->obd_next_transno_waitq);
target_cancel_recovery_timer(obd);
spin_unlock_bh(&obd->obd_processing_task_lock);
+
+ /* XXX can't call this with spin_lock_bh, but it probably
+ should be protected, somehow. */
+ if (OBT(obd) && OBP(obd, postsetup))
+ OBP(obd, postsetup)(obd);
+
class_disconnect_exports(obd, 0);
abort_delayed_replies(obd);
abort_recovery_queue(obd);
struct ptlrpc_request *req;
int wake_up;
+ /* XXX shouldn't we take obd->obd_processing_task_lock to check these
+ flags and the recovery_queue? */
+ if (obd->obd_abort_recovery || !obd->obd_recovering)
+ return 1;
+
req = list_entry(obd->obd_recovery_queue.next,
struct ptlrpc_request, rq_list);
LASSERT(req->rq_reqmsg->transno >= obd->obd_next_recovery_transno);
- wake_up = req->rq_reqmsg->transno == obd->obd_next_recovery_transno ||
- (obd->obd_recovering) == 0;
+ wake_up = req->rq_reqmsg->transno == obd->obd_next_recovery_transno;
CDEBUG(D_HA, "check_for_next_transno: "LPD64" vs "LPD64", %d == %d\n",
req->rq_reqmsg->transno, obd->obd_next_recovery_transno,
obd->obd_recovering, wake_up);
CERROR("%s: all clients recovered, sending delayed replies\n",
obd->obd_name);
obd->obd_recovering = 0;
+
+ if (OBT(obd) && OBP(obd, postsetup))
+ OBP(obd, postsetup)(obd);
+
list_for_each_safe(tmp, n, &obd->obd_delayed_reply_queue) {
req = list_entry(tmp, struct ptlrpc_request, rq_list);
DEBUG_REQ(D_ERROR, req, "delayed:");
{
return lustre_pack_reply (req, 0, NULL, NULL);
}
+
+