Home » Mailing lists » Devel » [PATCH 2/3] SUNRPC: traverse clients tree on PipeFS event
[PATCH 2/3] SUNRPC: traverse clients tree on PipeFS event [message #45966] |
Fri, 20 April 2012 14:19  |
Stanislav Kinsbursky
Messages: 683 Registered: October 2011
|
Senior Member |
|
|
If client is a clone, then it's parent can not be in the list.
But parent's PipeFS dentries have to be created and destroyed as well.
Note: event skip helper for clients introduced
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
---
net/sunrpc/clnt.c | 30 ++++++++++++++++++++++++++----
1 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 8a19849..80b59f1 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -176,8 +176,16 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name)
return 0;
}
-static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event,
- struct super_block *sb)
+static inline int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event)
+{
+ if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) ||
+ ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry))
+ return 1;
+ return 0;
+}
+
+static int __rpc_clnt_handle_event(struct rpc_clnt *clnt, unsigned long event,
+ struct super_block *sb)
{
struct dentry *dentry;
int err = 0;
@@ -206,6 +214,21 @@ static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event,
return err;
}
+static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event,
+ struct super_block *sb)
+{
+ int error;
+
+ if (!rpc_clnt_skip_event(clnt, event)) {
+ error = __rpc_clnt_handle_event(clnt, event, sb);
+ if (error)
+ return error;
+ }
+ if (clnt != clnt->cl_parent)
+ return __rpc_pipefs_event(clnt->cl_parent, event, sb);
+ return 0;
+}
+
static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event)
{
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
@@ -215,8 +238,7 @@ static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event)
list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
if (clnt->cl_program->pipe_dir_name == NULL)
break;
- if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) ||
- ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry))
+ if (rpc_clnt_skip_event(clnt, event))
continue;
if (atomic_inc_not_zero(&clnt->cl_count) == 0)
continue;
|
|
|
Re: [PATCH 2/3] SUNRPC: traverse clients tree on PipeFS event [message #46124 is a reply to message #45966] |
Thu, 26 April 2012 18:11   |
Myklebust, Trond
Messages: 52 Registered: November 2011
|
Member |
|
|
On Fri, 2012-04-20 at 18:19 +0400, Stanislav Kinsbursky wrote:
> +static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event,
> + struct super_block *sb)
> +{
> + int error;
> +
> + if (!rpc_clnt_skip_event(clnt, event)) {
> + error = __rpc_clnt_handle_event(clnt, event, sb);
> + if (error)
> + return error;
> + }
> + if (clnt != clnt->cl_parent)
> + return __rpc_pipefs_event(clnt->cl_parent, event, sb);
> + return 0;
> +}
Hi Stanislav,
Recursion in the kernel is generally frowned upon due to the stack size
limits. Could you please rewrite the above into a simple loop. Something
along the lines of:
for(;;) {
...
if (clnt == clnt->cl_parent)
break;
clnt = clnt->cl_parent;
}
--
Trond Myklebust
Linux NFS client maintainer
NetApp
Trond.Myklebust@netapp.com
www.netapp.com
|
|
|
Re: [PATCH 2/3] SUNRPC: traverse clients tree on PipeFS event [message #46126 is a reply to message #46124] |
Thu, 26 April 2012 18:26   |
Stanislav Kinsbursky
Messages: 683 Registered: October 2011
|
Senior Member |
|
|
26.04.2012 22:11, Myklebust, Trond написал:
> On Fri, 2012-04-20 at 18:19 +0400, Stanislav Kinsbursky wrote:
>
>> +static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event,
>> + struct super_block *sb)
>> +{
>> + int error;
>> +
>> + if (!rpc_clnt_skip_event(clnt, event)) {
>> + error = __rpc_clnt_handle_event(clnt, event, sb);
>> + if (error)
>> + return error;
>> + }
>> + if (clnt != clnt->cl_parent)
>> + return __rpc_pipefs_event(clnt->cl_parent, event, sb);
>> + return 0;
>> +}
> Hi Stanislav,
>
> Recursion in the kernel is generally frowned upon due to the stack size
> limits. Could you please rewrite the above into a simple loop. Something
> along the lines of:
>
> for(;;) {
> ...
>
> if (clnt == clnt->cl_parent)
> break;
> clnt = clnt->cl_parent;
> }
>
Hi, Trond.
Yes, sure, I can do this.
|
|
|
[PATCH v2 2/3] SUNRPC: traverse clients tree on PipeFS event [message #46145 is a reply to message #45966] |
Fri, 27 April 2012 09:00  |
Stanislav Kinsbursky
Messages: 683 Registered: October 2011
|
Senior Member |
|
|
v2: recursion was replaced by loop
If client is a clone, then it's parent can not be in the list.
But parent's Pipefs dentries have to be created and destroyed.
Note: event skip helper for clients introduced
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
---
net/sunrpc/clnt.c | 29 +++++++++++++++++++++++++----
1 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 8a19849..d127bd7 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -176,8 +176,16 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name)
return 0;
}
-static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event,
- struct super_block *sb)
+static inline int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event)
+{
+ if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) ||
+ ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry))
+ return 1;
+ return 0;
+}
+
+static int __rpc_clnt_handle_event(struct rpc_clnt *clnt, unsigned long event,
+ struct super_block *sb)
{
struct dentry *dentry;
int err = 0;
@@ -206,6 +214,20 @@ static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event,
return err;
}
+static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event,
+ struct super_block *sb)
+{
+ int error = 0;
+
+ for (;; clnt = clnt->cl_parent) {
+ if (!rpc_clnt_skip_event(clnt, event))
+ error = __rpc_clnt_handle_event(clnt, event, sb);
+ if (error || clnt == clnt->cl_parent)
+ break;
+ }
+ return error;
+}
+
static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event)
{
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
@@ -215,8 +237,7 @@ static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event)
list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
if (clnt->cl_program->pipe_dir_name == NULL)
break;
- if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) ||
- ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry))
+ if (rpc_clnt_skip_event(clnt, event))
continue;
if (atomic_inc_not_zero(&clnt->cl_count) == 0)
continue;
|
|
|
Goto Forum:
Current Time: Sat Jul 26 04:21:57 GMT 2025
Total time taken to generate the page: 0.25533 seconds
|