Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
4800a811
Commit
4800a811
authored
Mar 10, 2005
by
Trond Myklebust
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
NFS: Cleanups for the network partition reclaim code
Signed-off-by:
Trond Myklebust
<
Trond.Myklebust@netapp.com
>
parent
16ba67b1
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
72 additions
and
45 deletions
+72
-45
fs/nfs/nfs4proc.c
fs/nfs/nfs4proc.c
+55
-42
fs/nfs/nfs4state.c
fs/nfs/nfs4state.c
+17
-3
No files found.
fs/nfs/nfs4proc.c
View file @
4800a811
...
@@ -190,6 +190,23 @@ static void update_changeattr(struct inode *inode, struct nfs4_change_info *cinf
...
@@ -190,6 +190,23 @@ static void update_changeattr(struct inode *inode, struct nfs4_change_info *cinf
nfsi
->
change_attr
=
cinfo
->
after
;
nfsi
->
change_attr
=
cinfo
->
after
;
}
}
static
void
update_open_stateid
(
struct
nfs4_state
*
state
,
nfs4_stateid
*
stateid
,
int
open_flags
)
{
struct
inode
*
inode
=
state
->
inode
;
open_flags
&=
(
FMODE_READ
|
FMODE_WRITE
);
/* Protect against nfs4_find_state() */
spin_lock
(
&
inode
->
i_lock
);
state
->
state
|=
open_flags
;
/* NB! List reordering - see the reclaim code for why. */
if
((
open_flags
&
FMODE_WRITE
)
&&
0
==
state
->
nwriters
++
)
list_move
(
&
state
->
open_states
,
&
state
->
owner
->
so_states
);
if
(
open_flags
&
FMODE_READ
)
state
->
nreaders
++
;
memcpy
(
&
state
->
stateid
,
stateid
,
sizeof
(
state
->
stateid
));
spin_unlock
(
&
inode
->
i_lock
);
}
/*
/*
* OPEN_RECLAIM:
* OPEN_RECLAIM:
* reclaim state on the server after a reboot.
* reclaim state on the server after a reboot.
...
@@ -334,7 +351,7 @@ int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state)
...
@@ -334,7 +351,7 @@ int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state)
return
err
;
return
err
;
}
}
static
int
_nfs4_proc_open_confirm
(
struct
rpc_clnt
*
clnt
,
const
struct
nfs_fh
*
fh
,
struct
nfs4_state_owner
*
sp
,
nfs4_stateid
*
stateid
)
static
in
line
in
t
_nfs4_proc_open_confirm
(
struct
rpc_clnt
*
clnt
,
const
struct
nfs_fh
*
fh
,
struct
nfs4_state_owner
*
sp
,
nfs4_stateid
*
stateid
)
{
{
struct
nfs_open_confirmargs
arg
=
{
struct
nfs_open_confirmargs
arg
=
{
.
fh
=
fh
,
.
fh
=
fh
,
...
@@ -357,6 +374,39 @@ static int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *f
...
@@ -357,6 +374,39 @@ static int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *f
return
status
;
return
status
;
}
}
static
int
_nfs4_proc_open
(
struct
inode
*
dir
,
struct
nfs4_state_owner
*
sp
,
struct
nfs_openargs
*
o_arg
,
struct
nfs_openres
*
o_res
)
{
struct
nfs_server
*
server
=
NFS_SERVER
(
dir
);
struct
rpc_message
msg
=
{
.
rpc_proc
=
&
nfs4_procedures
[
NFSPROC4_CLNT_OPEN
],
.
rpc_argp
=
o_arg
,
.
rpc_resp
=
o_res
,
.
rpc_cred
=
sp
->
so_cred
,
};
int
status
;
/* Update sequence id. The caller must serialize! */
o_arg
->
seqid
=
sp
->
so_seqid
;
o_arg
->
id
=
sp
->
so_id
;
o_arg
->
clientid
=
sp
->
so_client
->
cl_clientid
;
status
=
rpc_call_sync
(
server
->
client
,
&
msg
,
RPC_TASK_NOINTR
);
nfs4_increment_seqid
(
status
,
sp
);
if
(
status
!=
0
)
goto
out
;
update_changeattr
(
dir
,
&
o_res
->
cinfo
);
if
(
o_res
->
rflags
&
NFS4_OPEN_RESULT_CONFIRM
)
{
status
=
_nfs4_proc_open_confirm
(
server
->
client
,
&
o_res
->
fh
,
sp
,
&
o_res
->
stateid
);
if
(
status
!=
0
)
goto
out
;
}
if
(
!
(
o_res
->
f_attr
->
valid
&
NFS_ATTR_FATTR
))
status
=
server
->
rpc_ops
->
getattr
(
server
,
&
o_res
->
fh
,
o_res
->
f_attr
);
out:
return
status
;
}
static
int
_nfs4_do_access
(
struct
inode
*
inode
,
struct
rpc_cred
*
cred
,
int
openflags
)
static
int
_nfs4_do_access
(
struct
inode
*
inode
,
struct
rpc_cred
*
cred
,
int
openflags
)
{
{
struct
nfs_access_entry
cache
;
struct
nfs_access_entry
cache
;
...
@@ -434,16 +484,8 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred
...
@@ -434,16 +484,8 @@ static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred
unlock_kernel
();
unlock_kernel
();
if
(
err
!=
0
)
if
(
err
!=
0
)
goto
out_err
;
goto
out_err
;
spin_lock
(
&
inode
->
i_lock
);
memcpy
(
state
->
stateid
.
data
,
delegation
->
stateid
.
data
,
sizeof
(
state
->
stateid
.
data
));
state
->
state
|=
open_flags
;
if
(
open_flags
&
FMODE_READ
)
state
->
nreaders
++
;
if
(
open_flags
&
FMODE_WRITE
)
state
->
nwriters
++
;
set_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
);
set_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
);
spin_unlock
(
&
inode
->
i_lock
);
update_open_stateid
(
state
,
&
delegation
->
stateid
,
open_flags
);
out_ok:
out_ok:
up
(
&
sp
->
so_sema
);
up
(
&
sp
->
so_sema
);
nfs4_put_state_owner
(
sp
);
nfs4_put_state_owner
(
sp
);
...
@@ -506,12 +548,6 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
...
@@ -506,12 +548,6 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
.
f_attr
=
&
f_attr
,
.
f_attr
=
&
f_attr
,
.
server
=
server
,
.
server
=
server
,
};
};
struct
rpc_message
msg
=
{
.
rpc_proc
=
&
nfs4_procedures
[
NFSPROC4_CLNT_OPEN
],
.
rpc_argp
=
&
o_arg
,
.
rpc_resp
=
&
o_res
,
.
rpc_cred
=
cred
,
};
/* Protect against reboot recovery conflicts */
/* Protect against reboot recovery conflicts */
down_read
(
&
clp
->
cl_sem
);
down_read
(
&
clp
->
cl_sem
);
...
@@ -528,26 +564,10 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
...
@@ -528,26 +564,10 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
o_arg
.
u
.
attrs
=
sattr
;
o_arg
.
u
.
attrs
=
sattr
;
/* Serialization for the sequence id */
/* Serialization for the sequence id */
down
(
&
sp
->
so_sema
);
down
(
&
sp
->
so_sema
);
o_arg
.
seqid
=
sp
->
so_seqid
;
o_arg
.
id
=
sp
->
so_id
;
o_arg
.
clientid
=
clp
->
cl_clientid
,
status
=
rpc_call_sync
(
server
->
client
,
&
msg
,
RPC_TASK_NOINTR
);
status
=
_nfs4_proc_open
(
dir
,
sp
,
&
o_arg
,
&
o_res
);
nfs4_increment_seqid
(
status
,
sp
);
if
(
status
)
goto
out_err
;
update_changeattr
(
dir
,
&
o_res
.
cinfo
);
if
(
o_res
.
rflags
&
NFS4_OPEN_RESULT_CONFIRM
)
{
status
=
_nfs4_proc_open_confirm
(
server
->
client
,
&
o_res
.
fh
,
sp
,
&
o_res
.
stateid
);
if
(
status
!=
0
)
if
(
status
!=
0
)
goto
out_err
;
goto
out_err
;
}
if
(
!
(
f_attr
.
valid
&
NFS_ATTR_FATTR
))
{
status
=
server
->
rpc_ops
->
getattr
(
server
,
&
o_res
.
fh
,
&
f_attr
);
if
(
status
<
0
)
goto
out_err
;
}
status
=
-
ENOMEM
;
status
=
-
ENOMEM
;
inode
=
nfs_fhget
(
dir
->
i_sb
,
&
o_res
.
fh
,
&
f_attr
);
inode
=
nfs_fhget
(
dir
->
i_sb
,
&
o_res
.
fh
,
&
f_attr
);
...
@@ -556,14 +576,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
...
@@ -556,14 +576,7 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, st
state
=
nfs4_get_open_state
(
inode
,
sp
);
state
=
nfs4_get_open_state
(
inode
,
sp
);
if
(
!
state
)
if
(
!
state
)
goto
out_err
;
goto
out_err
;
memcpy
(
&
state
->
stateid
,
&
o_res
.
stateid
,
sizeof
(
state
->
stateid
));
update_open_stateid
(
state
,
&
o_res
.
stateid
,
flags
);
spin_lock
(
&
inode
->
i_lock
);
if
(
flags
&
FMODE_READ
)
state
->
nreaders
++
;
if
(
flags
&
FMODE_WRITE
)
state
->
nwriters
++
;
state
->
state
|=
flags
&
(
FMODE_READ
|
FMODE_WRITE
);
spin_unlock
(
&
inode
->
i_lock
);
if
(
o_res
.
delegation_type
!=
0
)
if
(
o_res
.
delegation_type
!=
0
)
nfs_inode_set_delegation
(
inode
,
cred
,
&
o_res
);
nfs_inode_set_delegation
(
inode
,
cred
,
&
o_res
);
up
(
&
sp
->
so_sema
);
up
(
&
sp
->
so_sema
);
...
...
fs/nfs/nfs4state.c
View file @
4800a811
...
@@ -447,7 +447,9 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner)
...
@@ -447,7 +447,9 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner)
if
(
state
==
NULL
&&
new
!=
NULL
)
{
if
(
state
==
NULL
&&
new
!=
NULL
)
{
state
=
new
;
state
=
new
;
/* Caller *must* be holding owner->so_sem */
/* Caller *must* be holding owner->so_sem */
list_add
(
&
state
->
open_states
,
&
owner
->
so_states
);
/* Note: The reclaim code dictates that we add stateless
* and read-only stateids to the end of the list */
list_add_tail
(
&
state
->
open_states
,
&
owner
->
so_states
);
state
->
owner
=
owner
;
state
->
owner
=
owner
;
atomic_inc
(
&
owner
->
so_count
);
atomic_inc
(
&
owner
->
so_count
);
list_add
(
&
state
->
inode_states
,
&
nfsi
->
open_states
);
list_add
(
&
state
->
inode_states
,
&
nfsi
->
open_states
);
...
@@ -503,8 +505,12 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode)
...
@@ -503,8 +505,12 @@ void nfs4_close_state(struct nfs4_state *state, mode_t mode)
state
->
nreaders
--
;
state
->
nreaders
--
;
if
(
mode
&
FMODE_WRITE
)
if
(
mode
&
FMODE_WRITE
)
state
->
nwriters
--
;
state
->
nwriters
--
;
if
(
state
->
nwriters
==
0
&&
state
->
nreaders
==
0
)
if
(
state
->
nwriters
==
0
)
{
if
(
state
->
nreaders
==
0
)
list_del_init
(
&
state
->
inode_states
);
list_del_init
(
&
state
->
inode_states
);
/* See reclaim code */
list_move_tail
(
&
state
->
open_states
,
&
owner
->
so_states
);
}
spin_unlock
(
&
inode
->
i_lock
);
spin_unlock
(
&
inode
->
i_lock
);
newstate
=
0
;
newstate
=
0
;
if
(
state
->
state
!=
0
)
{
if
(
state
->
state
!=
0
)
{
...
@@ -798,6 +804,14 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp)
...
@@ -798,6 +804,14 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp)
struct
nfs4_lock_state
*
lock
;
struct
nfs4_lock_state
*
lock
;
int
status
=
0
;
int
status
=
0
;
/* Note: we rely on the sp->so_states list being ordered
* so that we always reclaim open(O_RDWR) and/or open(O_WRITE)
* states first.
* This is needed to ensure that the server won't give us any
* read delegations that we have to return if, say, we are
* recovering after a network partition or a reboot from a
* server that doesn't support a grace period.
*/
list_for_each_entry
(
state
,
&
sp
->
so_states
,
open_states
)
{
list_for_each_entry
(
state
,
&
sp
->
so_states
,
open_states
)
{
if
(
state
->
state
==
0
)
if
(
state
->
state
==
0
)
continue
;
continue
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment