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
nexedi
linux
Commits
e85c40cd
Commit
e85c40cd
authored
Feb 07, 2004
by
Trond Myklebust
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
NFSv4: Preparation for the server reboot recovery code.
parent
2d5e9ebc
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
253 additions
and
4 deletions
+253
-4
fs/nfs/nfs4proc.c
fs/nfs/nfs4proc.c
+51
-4
fs/nfs/nfs4state.c
fs/nfs/nfs4state.c
+89
-0
fs/nfs/nfs4xdr.c
fs/nfs/nfs4xdr.c
+97
-0
include/linux/nfs4.h
include/linux/nfs4.h
+1
-0
include/linux/nfs_fs.h
include/linux/nfs_fs.h
+2
-0
include/linux/nfs_xdr.h
include/linux/nfs_xdr.h
+13
-0
No files found.
fs/nfs/nfs4proc.c
View file @
e85c40cd
...
...
@@ -458,6 +458,54 @@ process_cinfo(struct nfs4_change_info *info, struct nfs_fattr *fattr)
}
}
/*
* OPEN_RECLAIM:
* reclaim state on the server after a reboot.
* Assumes caller is holding the sp->so_sem
*/
int
nfs4_open_reclaim
(
struct
nfs4_state_owner
*
sp
,
struct
nfs4_state
*
state
)
{
struct
inode
*
inode
=
state
->
inode
;
struct
nfs_server
*
server
=
NFS_SERVER
(
inode
);
struct
nfs_fattr
fattr
=
{
.
valid
=
0
,
};
struct
nfs4_change_info
d_cinfo
;
struct
nfs4_getattr
f_getattr
=
{
.
gt_bmval
=
nfs4_fattr_bitmap
,
.
gt_attrs
=
&
fattr
,
};
struct
nfs_open_reclaimargs
o_arg
=
{
.
fh
=
NFS_FH
(
inode
),
.
seqid
=
sp
->
so_seqid
,
.
id
=
sp
->
so_id
,
.
share_access
=
state
->
state
,
.
clientid
=
server
->
nfs4_state
->
cl_clientid
,
.
claim
=
NFS4_OPEN_CLAIM_PREVIOUS
,
.
f_getattr
=
&
f_getattr
,
};
struct
nfs_openres
o_res
=
{
.
cinfo
=
&
d_cinfo
,
.
f_getattr
=
&
f_getattr
,
.
server
=
server
,
/* Grrr */
};
struct
rpc_message
msg
=
{
.
rpc_proc
=
&
nfs4_procedures
[
NFSPROC4_CLNT_OPEN_RECLAIM
],
.
rpc_argp
=
&
o_arg
,
.
rpc_resp
=
&
o_res
,
.
rpc_cred
=
sp
->
so_cred
,
};
int
status
;
status
=
rpc_call_sync
(
server
->
client
,
&
msg
,
0
);
nfs4_increment_seqid
(
status
,
sp
);
/* Update the inode attributes */
nfs_refresh_inode
(
inode
,
&
fattr
);
return
status
;
}
struct
nfs4_state
*
nfs4_do_open
(
struct
inode
*
dir
,
struct
qstr
*
name
,
int
flags
,
struct
iattr
*
sattr
,
struct
rpc_cred
*
cred
)
{
...
...
@@ -523,10 +571,9 @@ nfs4_do_open(struct inode *dir, struct qstr *name, int flags, struct iattr *satt
o_arg
.
id
=
sp
->
so_id
;
status
=
rpc_call_sync
(
server
->
client
,
&
msg
,
0
);
if
(
status
)
{
goto
out_up
;
}
nfs4_increment_seqid
(
status
,
sp
);
if
(
status
)
goto
out_up
;
process_cinfo
(
&
d_cinfo
,
&
d_attr
);
nfs_refresh_inode
(
dir
,
&
d_attr
);
...
...
@@ -555,9 +602,9 @@ nfs4_do_open(struct inode *dir, struct qstr *name, int flags, struct iattr *satt
memcpy
(
&
oc_arg
.
stateid
,
&
o_res
.
stateid
,
sizeof
(
oc_arg
.
stateid
));
status
=
rpc_call_sync
(
server
->
client
,
&
msg
,
0
);
nfs4_increment_seqid
(
status
,
sp
);
if
(
status
)
goto
out_up
;
nfs4_increment_seqid
(
status
,
sp
);
memcpy
(
&
state
->
stateid
,
&
oc_res
.
stateid
,
sizeof
(
state
->
stateid
));
}
else
memcpy
(
&
state
->
stateid
,
&
o_res
.
stateid
,
sizeof
(
state
->
stateid
));
...
...
fs/nfs/nfs4state.c
View file @
e85c40cd
...
...
@@ -382,6 +382,95 @@ nfs4_increment_seqid(int status, struct nfs4_state_owner *sp)
sp
->
so_seqid
++
;
}
static
int
reclaimer
(
void
*
);
struct
reclaimer_args
{
struct
nfs4_client
*
clp
;
struct
completion
complete
;
};
/*
* State recovery routine
*/
void
nfs4_recover_state
(
struct
nfs4_client
*
clp
)
{
struct
reclaimer_args
args
=
{
.
clp
=
clp
,
};
init_completion
(
&
args
.
complete
);
down_read
(
&
clp
->
cl_sem
);
if
(
kernel_thread
(
reclaimer
,
&
args
,
CLONE_KERNEL
)
<
0
)
goto
out_failed
;
wait_for_completion
(
&
args
.
complete
);
return
;
out_failed:
up_read
(
&
clp
->
cl_sem
);
}
static
void
nfs4_reclaim_open_state
(
struct
nfs4_state_owner
*
sp
)
{
struct
nfs4_state
*
state
;
int
status
;
list_for_each_entry
(
state
,
&
sp
->
so_states
,
open_states
)
{
status
=
nfs4_open_reclaim
(
sp
,
state
);
if
(
status
)
{
/*
* Open state on this file cannot be recovered
* All we can do is revert to using the zero stateid.
*/
memset
(
state
->
stateid
.
data
,
0
,
sizeof
(
state
->
stateid
.
data
));
/* Mark the file as being 'closed' */
state
->
state
=
0
;
}
}
}
static
int
reclaimer
(
void
*
ptr
)
{
struct
reclaimer_args
*
args
=
(
struct
reclaimer_args
*
)
ptr
;
struct
nfs4_client
*
clp
=
args
->
clp
;
struct
nfs4_state_owner
*
sp
;
int
status
;
daemonize
(
"%u.%u.%u.%u-reclaim"
,
NIPQUAD
(
clp
->
cl_addr
));
allow_signal
(
SIGKILL
);
complete
(
&
args
->
complete
);
/* Are there any NFS mounts out there? */
if
(
list_empty
(
&
clp
->
cl_superblocks
))
goto
out
;
status
=
nfs4_proc_setclientid
(
clp
,
0
,
0
);
if
(
status
)
goto
out_error
;
status
=
nfs4_proc_setclientid_confirm
(
clp
);
if
(
status
)
goto
out_error
;
spin_lock
(
&
clp
->
cl_lock
);
list_for_each_entry
(
sp
,
&
clp
->
cl_state_owners
,
so_list
)
{
atomic_inc
(
&
sp
->
so_count
);
spin_unlock
(
&
clp
->
cl_lock
);
down
(
&
sp
->
so_sema
);
nfs4_reclaim_open_state
(
sp
);
up
(
&
sp
->
so_sema
);
nfs4_put_state_owner
(
sp
);
spin_lock
(
&
clp
->
cl_lock
);
}
spin_unlock
(
&
clp
->
cl_lock
);
out:
up_read
(
&
clp
->
cl_sem
);
return
0
;
out_error:
printk
(
KERN_WARNING
"Error: state recovery failed on NFSv4 server %u.%u.%u.%u
\n
"
,
NIPQUAD
(
clp
->
cl_addr
.
s_addr
));
goto
out
;
}
/*
* Local variables:
* c-basic-offset: 8
...
...
fs/nfs/nfs4xdr.c
View file @
e85c40cd
...
...
@@ -166,6 +166,16 @@ static int nfs_stat_to_errno(int);
#define NFS4_dec_open_confirm_sz compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
op_decode_hdr_maxsz + 4
#define NFS4_enc_open_reclaim_sz compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
op_encode_hdr_maxsz + \
11 + \
encode_getattr_maxsz
#define NFS4_dec_open_reclaim_sz compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
op_decode_hdr_maxsz + \
4 + 5 + 2 + 3 + \
decode_getattr_maxsz
#define NFS4_enc_close_sz compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
op_encode_hdr_maxsz + 5
...
...
@@ -666,6 +676,41 @@ encode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmargs *arg)
}
static
int
encode_open_reclaim
(
struct
xdr_stream
*
xdr
,
struct
nfs_open_reclaimargs
*
arg
)
{
uint32_t
*
p
;
/*
* opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4,
* owner 4, opentype 4, claim 4, delegation_type 4 = 44
*/
RESERVE_SPACE
(
44
);
WRITE32
(
OP_OPEN
);
WRITE32
(
arg
->
seqid
);
switch
(
arg
->
share_access
)
{
case
FMODE_READ
:
WRITE32
(
NFS4_SHARE_ACCESS_READ
);
break
;
case
FMODE_WRITE
:
WRITE32
(
NFS4_SHARE_ACCESS_WRITE
);
break
;
case
FMODE_READ
|
FMODE_WRITE
:
WRITE32
(
NFS4_SHARE_ACCESS_BOTH
);
break
;
default:
BUG
();
}
WRITE32
(
0
);
/* for linux, share_deny = 0 always */
WRITE64
(
arg
->
clientid
);
WRITE32
(
4
);
WRITE32
(
arg
->
id
);
WRITE32
(
NFS4_OPEN_NOCREATE
);
WRITE32
(
NFS4_OPEN_CLAIM_PREVIOUS
);
WRITE32
(
NFS4_OPEN_DELEGATE_NONE
);
return
0
;
}
static
int
encode_putfh
(
struct
xdr_stream
*
xdr
,
struct
nfs_fh
*
fh
)
{
...
...
@@ -1058,6 +1103,32 @@ nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, uint32_t *p, struct nfs_open_con
return
status
;
}
/*
* Encode an OPEN request
*/
static
int
nfs4_xdr_enc_open_reclaim
(
struct
rpc_rqst
*
req
,
uint32_t
*
p
,
struct
nfs_open_reclaimargs
*
args
)
{
struct
xdr_stream
xdr
;
struct
compound_hdr
hdr
=
{
.
nops
=
3
,
};
int
status
;
xdr_init_encode
(
&
xdr
,
&
req
->
rq_snd_buf
,
p
);
encode_compound_hdr
(
&
xdr
,
&
hdr
);
status
=
encode_putfh
(
&
xdr
,
args
->
fh
);
if
(
status
)
goto
out
;
status
=
encode_open_reclaim
(
&
xdr
,
args
);
if
(
status
)
goto
out
;
status
=
encode_getattr
(
&
xdr
,
args
->
f_getattr
);
out:
return
status
;
}
/*
* Encode a READ request
...
...
@@ -2417,6 +2488,31 @@ nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_open_c
return
status
;
}
/*
* Decode OPEN_RECLAIM response
*/
static
int
nfs4_xdr_dec_open_reclaim
(
struct
rpc_rqst
*
rqstp
,
uint32_t
*
p
,
struct
nfs_openres
*
res
)
{
struct
xdr_stream
xdr
;
struct
compound_hdr
hdr
;
int
status
;
xdr_init_decode
(
&
xdr
,
&
rqstp
->
rq_rcv_buf
,
p
);
status
=
decode_compound_hdr
(
&
xdr
,
&
hdr
);
if
(
status
)
goto
out
;
status
=
decode_putfh
(
&
xdr
);
if
(
status
)
goto
out
;
status
=
decode_open
(
&
xdr
,
res
);
if
(
status
)
goto
out
;
status
=
decode_getattr
(
&
xdr
,
res
->
f_getattr
,
res
->
server
);
out:
return
status
;
}
/*
* Decode SETATTR response
*/
...
...
@@ -2730,6 +2826,7 @@ struct rpc_procinfo nfs4_procedures[] = {
PROC
(
COMMIT
,
enc_commit
,
dec_commit
),
PROC
(
OPEN
,
enc_open
,
dec_open
),
PROC
(
OPEN_CONFIRM
,
enc_open_confirm
,
dec_open_confirm
),
PROC
(
OPEN_RECLAIM
,
enc_open_reclaim
,
dec_open_reclaim
),
PROC
(
CLOSE
,
enc_close
,
dec_close
),
PROC
(
SETATTR
,
enc_setattr
,
dec_setattr
),
PROC
(
FSINFO
,
enc_fsinfo
,
dec_fsinfo
),
...
...
include/linux/nfs4.h
View file @
e85c40cd
...
...
@@ -289,6 +289,7 @@ enum {
NFSPROC4_CLNT_COMMIT
,
NFSPROC4_CLNT_OPEN
,
NFSPROC4_CLNT_OPEN_CONFIRM
,
NFSPROC4_CLNT_OPEN_RECLAIM
,
NFSPROC4_CLNT_CLOSE
,
NFSPROC4_CLNT_SETATTR
,
NFSPROC4_CLNT_FSINFO
,
...
...
include/linux/nfs_fs.h
View file @
e85c40cd
...
...
@@ -554,6 +554,7 @@ struct nfs4_state {
/* nfs4proc.c */
extern
int
nfs4_proc_setclientid
(
struct
nfs4_client
*
,
u32
,
unsigned
short
);
extern
int
nfs4_proc_setclientid_confirm
(
struct
nfs4_client
*
);
extern
int
nfs4_open_reclaim
(
struct
nfs4_state_owner
*
,
struct
nfs4_state
*
);
extern
int
nfs4_proc_async_renew
(
struct
nfs4_client
*
);
extern
int
nfs4_do_close
(
struct
inode
*
,
struct
nfs4_state
*
);
...
...
@@ -572,6 +573,7 @@ extern void nfs4_put_state_owner(struct nfs4_state_owner *);
extern
struct
nfs4_state
*
nfs4_get_open_state
(
struct
inode
*
,
struct
nfs4_state_owner
*
);
extern
void
nfs4_put_open_state
(
struct
nfs4_state
*
);
extern
void
nfs4_increment_seqid
(
int
status
,
struct
nfs4_state_owner
*
sp
);
extern
void
nfs4_recover_state
(
struct
nfs4_client
*
);
struct
nfs4_mount_data
;
#else
...
...
include/linux/nfs_xdr.h
View file @
e85c40cd
...
...
@@ -133,6 +133,19 @@ struct nfs_open_confirmres {
nfs4_stateid
stateid
;
};
/*
* Arguments to the open_reclaim call.
*/
struct
nfs_open_reclaimargs
{
struct
nfs_fh
*
fh
;
__u64
clientid
;
__u32
seqid
;
__u32
id
;
__u32
share_access
;
__u32
claim
;
struct
nfs4_getattr
*
f_getattr
;
};
/*
* Arguments to the close call.
*/
...
...
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