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
dc0b027d
Commit
dc0b027d
authored
Dec 23, 2008
by
Trond Myklebust
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
NFSv4: Convert the open and close ops to use fmode
Signed-off-by:
Trond Myklebust
<
Trond.Myklebust@netapp.com
>
parent
7a50c60e
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
94 additions
and
83 deletions
+94
-83
fs/nfs/inode.c
fs/nfs/inode.c
+1
-1
fs/nfs/nfs4_fs.h
fs/nfs/nfs4_fs.h
+4
-4
fs/nfs/nfs4proc.c
fs/nfs/nfs4proc.c
+68
-58
fs/nfs/nfs4state.c
fs/nfs/nfs4state.c
+12
-12
fs/nfs/nfs4xdr.c
fs/nfs/nfs4xdr.c
+5
-5
include/linux/nfs_fs.h
include/linux/nfs_fs.h
+2
-2
include/linux/nfs_xdr.h
include/linux/nfs_xdr.h
+2
-1
No files found.
fs/nfs/inode.c
View file @
dc0b027d
...
@@ -592,7 +592,7 @@ static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context
...
@@ -592,7 +592,7 @@ static void nfs_file_set_open_context(struct file *filp, struct nfs_open_context
/*
/*
* Given an inode, search for an open context with the desired characteristics
* Given an inode, search for an open context with the desired characteristics
*/
*/
struct
nfs_open_context
*
nfs_find_open_context
(
struct
inode
*
inode
,
struct
rpc_cred
*
cred
,
in
t
mode
)
struct
nfs_open_context
*
nfs_find_open_context
(
struct
inode
*
inode
,
struct
rpc_cred
*
cred
,
fmode_
t
mode
)
{
{
struct
nfs_inode
*
nfsi
=
NFS_I
(
inode
);
struct
nfs_inode
*
nfsi
=
NFS_I
(
inode
);
struct
nfs_open_context
*
pos
,
*
ctx
=
NULL
;
struct
nfs_open_context
*
pos
,
*
ctx
=
NULL
;
...
...
fs/nfs/nfs4_fs.h
View file @
dc0b027d
...
@@ -161,7 +161,7 @@ struct nfs4_state {
...
@@ -161,7 +161,7 @@ struct nfs4_state {
unsigned
int
n_rdonly
;
/* Number of read-only references */
unsigned
int
n_rdonly
;
/* Number of read-only references */
unsigned
int
n_wronly
;
/* Number of write-only references */
unsigned
int
n_wronly
;
/* Number of write-only references */
unsigned
int
n_rdwr
;
/* Number of read/write references */
unsigned
int
n_rdwr
;
/* Number of read/write references */
in
t
state
;
/* State on the server (R,W, or RW) */
fmode_
t
state
;
/* State on the server (R,W, or RW) */
atomic_t
count
;
atomic_t
count
;
};
};
...
@@ -223,9 +223,9 @@ extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struc
...
@@ -223,9 +223,9 @@ extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struc
extern
void
nfs4_put_state_owner
(
struct
nfs4_state_owner
*
);
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
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_put_open_state
(
struct
nfs4_state
*
);
extern
void
nfs4_close_state
(
struct
path
*
,
struct
nfs4_state
*
,
mode_t
);
extern
void
nfs4_close_state
(
struct
path
*
,
struct
nfs4_state
*
,
f
mode_t
);
extern
void
nfs4_close_sync
(
struct
path
*
,
struct
nfs4_state
*
,
mode_t
);
extern
void
nfs4_close_sync
(
struct
path
*
,
struct
nfs4_state
*
,
f
mode_t
);
extern
void
nfs4_state_set_mode_locked
(
struct
nfs4_state
*
,
mode_t
);
extern
void
nfs4_state_set_mode_locked
(
struct
nfs4_state
*
,
f
mode_t
);
extern
void
nfs4_schedule_state_recovery
(
struct
nfs_client
*
);
extern
void
nfs4_schedule_state_recovery
(
struct
nfs_client
*
);
extern
void
nfs4_schedule_state_manager
(
struct
nfs_client
*
);
extern
void
nfs4_schedule_state_manager
(
struct
nfs_client
*
);
extern
int
nfs4_state_mark_reclaim_nograce
(
struct
nfs_client
*
clp
,
struct
nfs4_state
*
state
);
extern
int
nfs4_state_mark_reclaim_nograce
(
struct
nfs_client
*
clp
,
struct
nfs4_state
*
state
);
...
...
fs/nfs/nfs4proc.c
View file @
dc0b027d
...
@@ -323,7 +323,7 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
...
@@ -323,7 +323,7 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
}
}
static
struct
nfs4_opendata
*
nfs4_opendata_alloc
(
struct
path
*
path
,
static
struct
nfs4_opendata
*
nfs4_opendata_alloc
(
struct
path
*
path
,
struct
nfs4_state_owner
*
sp
,
int
flags
,
struct
nfs4_state_owner
*
sp
,
fmode_t
fmode
,
int
flags
,
const
struct
iattr
*
attrs
)
const
struct
iattr
*
attrs
)
{
{
struct
dentry
*
parent
=
dget_parent
(
path
->
dentry
);
struct
dentry
*
parent
=
dget_parent
(
path
->
dentry
);
...
@@ -343,7 +343,8 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
...
@@ -343,7 +343,8 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
p
->
owner
=
sp
;
p
->
owner
=
sp
;
atomic_inc
(
&
sp
->
so_count
);
atomic_inc
(
&
sp
->
so_count
);
p
->
o_arg
.
fh
=
NFS_FH
(
dir
);
p
->
o_arg
.
fh
=
NFS_FH
(
dir
);
p
->
o_arg
.
open_flags
=
flags
,
p
->
o_arg
.
open_flags
=
flags
;
p
->
o_arg
.
fmode
=
fmode
&
(
FMODE_READ
|
FMODE_WRITE
);
p
->
o_arg
.
clientid
=
server
->
nfs_client
->
cl_clientid
;
p
->
o_arg
.
clientid
=
server
->
nfs_client
->
cl_clientid
;
p
->
o_arg
.
id
=
sp
->
so_owner_id
.
id
;
p
->
o_arg
.
id
=
sp
->
so_owner_id
.
id
;
p
->
o_arg
.
name
=
&
p
->
path
.
dentry
->
d_name
;
p
->
o_arg
.
name
=
&
p
->
path
.
dentry
->
d_name
;
...
@@ -399,10 +400,13 @@ static int nfs4_wait_for_completion_rpc_task(struct rpc_task *task)
...
@@ -399,10 +400,13 @@ static int nfs4_wait_for_completion_rpc_task(struct rpc_task *task)
return
ret
;
return
ret
;
}
}
static
int
can_open_cached
(
struct
nfs4_state
*
state
,
int
mode
)
static
int
can_open_cached
(
struct
nfs4_state
*
state
,
fmode_t
mode
,
int
open_
mode
)
{
{
int
ret
=
0
;
int
ret
=
0
;
switch
(
mode
&
(
FMODE_READ
|
FMODE_WRITE
|
O_EXCL
))
{
if
(
open_mode
&
O_EXCL
)
goto
out
;
switch
(
mode
&
(
FMODE_READ
|
FMODE_WRITE
))
{
case
FMODE_READ
:
case
FMODE_READ
:
ret
|=
test_bit
(
NFS_O_RDONLY_STATE
,
&
state
->
flags
)
!=
0
;
ret
|=
test_bit
(
NFS_O_RDONLY_STATE
,
&
state
->
flags
)
!=
0
;
break
;
break
;
...
@@ -412,12 +416,13 @@ static int can_open_cached(struct nfs4_state *state, int mode)
...
@@ -412,12 +416,13 @@ static int can_open_cached(struct nfs4_state *state, int mode)
case
FMODE_READ
|
FMODE_WRITE
:
case
FMODE_READ
|
FMODE_WRITE
:
ret
|=
test_bit
(
NFS_O_RDWR_STATE
,
&
state
->
flags
)
!=
0
;
ret
|=
test_bit
(
NFS_O_RDWR_STATE
,
&
state
->
flags
)
!=
0
;
}
}
out:
return
ret
;
return
ret
;
}
}
static
int
can_open_delegated
(
struct
nfs_delegation
*
delegation
,
mode_t
open_flags
)
static
int
can_open_delegated
(
struct
nfs_delegation
*
delegation
,
fmode_t
fmode
)
{
{
if
((
delegation
->
type
&
open_flags
)
!=
open_flags
)
if
((
delegation
->
type
&
fmode
)
!=
fmode
)
return
0
;
return
0
;
if
(
test_bit
(
NFS_DELEGATION_NEED_RECLAIM
,
&
delegation
->
flags
))
if
(
test_bit
(
NFS_DELEGATION_NEED_RECLAIM
,
&
delegation
->
flags
))
return
0
;
return
0
;
...
@@ -425,9 +430,9 @@ static int can_open_delegated(struct nfs_delegation *delegation, mode_t open_fla
...
@@ -425,9 +430,9 @@ static int can_open_delegated(struct nfs_delegation *delegation, mode_t open_fla
return
1
;
return
1
;
}
}
static
void
update_open_stateflags
(
struct
nfs4_state
*
state
,
mode_t
open_flags
)
static
void
update_open_stateflags
(
struct
nfs4_state
*
state
,
fmode_t
fmode
)
{
{
switch
(
open_flags
)
{
switch
(
fmode
)
{
case
FMODE_WRITE
:
case
FMODE_WRITE
:
state
->
n_wronly
++
;
state
->
n_wronly
++
;
break
;
break
;
...
@@ -437,15 +442,15 @@ static void update_open_stateflags(struct nfs4_state *state, mode_t open_flags)
...
@@ -437,15 +442,15 @@ static void update_open_stateflags(struct nfs4_state *state, mode_t open_flags)
case
FMODE_READ
|
FMODE_WRITE
:
case
FMODE_READ
|
FMODE_WRITE
:
state
->
n_rdwr
++
;
state
->
n_rdwr
++
;
}
}
nfs4_state_set_mode_locked
(
state
,
state
->
state
|
open_flags
);
nfs4_state_set_mode_locked
(
state
,
state
->
state
|
fmode
);
}
}
static
void
nfs_set_open_stateid_locked
(
struct
nfs4_state
*
state
,
nfs4_stateid
*
stateid
,
int
open_flags
)
static
void
nfs_set_open_stateid_locked
(
struct
nfs4_state
*
state
,
nfs4_stateid
*
stateid
,
fmode_t
fmode
)
{
{
if
(
test_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
)
==
0
)
if
(
test_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
)
==
0
)
memcpy
(
state
->
stateid
.
data
,
stateid
->
data
,
sizeof
(
state
->
stateid
.
data
));
memcpy
(
state
->
stateid
.
data
,
stateid
->
data
,
sizeof
(
state
->
stateid
.
data
));
memcpy
(
state
->
open_stateid
.
data
,
stateid
->
data
,
sizeof
(
state
->
open_stateid
.
data
));
memcpy
(
state
->
open_stateid
.
data
,
stateid
->
data
,
sizeof
(
state
->
open_stateid
.
data
));
switch
(
open_flags
)
{
switch
(
fmode
)
{
case
FMODE_READ
:
case
FMODE_READ
:
set_bit
(
NFS_O_RDONLY_STATE
,
&
state
->
flags
);
set_bit
(
NFS_O_RDONLY_STATE
,
&
state
->
flags
);
break
;
break
;
...
@@ -457,14 +462,14 @@ static void nfs_set_open_stateid_locked(struct nfs4_state *state, nfs4_stateid *
...
@@ -457,14 +462,14 @@ static void nfs_set_open_stateid_locked(struct nfs4_state *state, nfs4_stateid *
}
}
}
}
static
void
nfs_set_open_stateid
(
struct
nfs4_state
*
state
,
nfs4_stateid
*
stateid
,
int
open_flags
)
static
void
nfs_set_open_stateid
(
struct
nfs4_state
*
state
,
nfs4_stateid
*
stateid
,
fmode_t
fmode
)
{
{
write_seqlock
(
&
state
->
seqlock
);
write_seqlock
(
&
state
->
seqlock
);
nfs_set_open_stateid_locked
(
state
,
stateid
,
open_flags
);
nfs_set_open_stateid_locked
(
state
,
stateid
,
fmode
);
write_sequnlock
(
&
state
->
seqlock
);
write_sequnlock
(
&
state
->
seqlock
);
}
}
static
void
__update_open_stateid
(
struct
nfs4_state
*
state
,
nfs4_stateid
*
open_stateid
,
const
nfs4_stateid
*
deleg_stateid
,
int
open_flags
)
static
void
__update_open_stateid
(
struct
nfs4_state
*
state
,
nfs4_stateid
*
open_stateid
,
const
nfs4_stateid
*
deleg_stateid
,
fmode_t
fmode
)
{
{
/*
/*
* Protect the call to nfs4_state_set_mode_locked and
* Protect the call to nfs4_state_set_mode_locked and
...
@@ -476,20 +481,20 @@ static void __update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_s
...
@@ -476,20 +481,20 @@ static void __update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_s
set_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
);
set_bit
(
NFS_DELEGATED_STATE
,
&
state
->
flags
);
}
}
if
(
open_stateid
!=
NULL
)
if
(
open_stateid
!=
NULL
)
nfs_set_open_stateid_locked
(
state
,
open_stateid
,
open_flags
);
nfs_set_open_stateid_locked
(
state
,
open_stateid
,
fmode
);
write_sequnlock
(
&
state
->
seqlock
);
write_sequnlock
(
&
state
->
seqlock
);
spin_lock
(
&
state
->
owner
->
so_lock
);
spin_lock
(
&
state
->
owner
->
so_lock
);
update_open_stateflags
(
state
,
open_flags
);
update_open_stateflags
(
state
,
fmode
);
spin_unlock
(
&
state
->
owner
->
so_lock
);
spin_unlock
(
&
state
->
owner
->
so_lock
);
}
}
static
int
update_open_stateid
(
struct
nfs4_state
*
state
,
nfs4_stateid
*
open_stateid
,
nfs4_stateid
*
delegation
,
int
open_flags
)
static
int
update_open_stateid
(
struct
nfs4_state
*
state
,
nfs4_stateid
*
open_stateid
,
nfs4_stateid
*
delegation
,
fmode_t
fmode
)
{
{
struct
nfs_inode
*
nfsi
=
NFS_I
(
state
->
inode
);
struct
nfs_inode
*
nfsi
=
NFS_I
(
state
->
inode
);
struct
nfs_delegation
*
deleg_cur
;
struct
nfs_delegation
*
deleg_cur
;
int
ret
=
0
;
int
ret
=
0
;
open_flags
&=
(
FMODE_READ
|
FMODE_WRITE
);
fmode
&=
(
FMODE_READ
|
FMODE_WRITE
);
rcu_read_lock
();
rcu_read_lock
();
deleg_cur
=
rcu_dereference
(
nfsi
->
delegation
);
deleg_cur
=
rcu_dereference
(
nfsi
->
delegation
);
...
@@ -498,7 +503,7 @@ static int update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stat
...
@@ -498,7 +503,7 @@ static int update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stat
spin_lock
(
&
deleg_cur
->
lock
);
spin_lock
(
&
deleg_cur
->
lock
);
if
(
nfsi
->
delegation
!=
deleg_cur
||
if
(
nfsi
->
delegation
!=
deleg_cur
||
(
deleg_cur
->
type
&
open_flags
)
!=
open_flags
)
(
deleg_cur
->
type
&
fmode
)
!=
fmode
)
goto
no_delegation_unlock
;
goto
no_delegation_unlock
;
if
(
delegation
==
NULL
)
if
(
delegation
==
NULL
)
...
@@ -507,7 +512,7 @@ static int update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stat
...
@@ -507,7 +512,7 @@ static int update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stat
goto
no_delegation_unlock
;
goto
no_delegation_unlock
;
nfs_mark_delegation_referenced
(
deleg_cur
);
nfs_mark_delegation_referenced
(
deleg_cur
);
__update_open_stateid
(
state
,
open_stateid
,
&
deleg_cur
->
stateid
,
open_flags
);
__update_open_stateid
(
state
,
open_stateid
,
&
deleg_cur
->
stateid
,
fmode
);
ret
=
1
;
ret
=
1
;
no_delegation_unlock:
no_delegation_unlock:
spin_unlock
(
&
deleg_cur
->
lock
);
spin_unlock
(
&
deleg_cur
->
lock
);
...
@@ -515,7 +520,7 @@ static int update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stat
...
@@ -515,7 +520,7 @@ static int update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stat
rcu_read_unlock
();
rcu_read_unlock
();
if
(
!
ret
&&
open_stateid
!=
NULL
)
{
if
(
!
ret
&&
open_stateid
!=
NULL
)
{
__update_open_stateid
(
state
,
open_stateid
,
NULL
,
open_flags
);
__update_open_stateid
(
state
,
open_stateid
,
NULL
,
fmode
);
ret
=
1
;
ret
=
1
;
}
}
...
@@ -523,13 +528,13 @@ static int update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stat
...
@@ -523,13 +528,13 @@ static int update_open_stateid(struct nfs4_state *state, nfs4_stateid *open_stat
}
}
static
void
nfs4_return_incompatible_delegation
(
struct
inode
*
inode
,
mode_t
open_flags
)
static
void
nfs4_return_incompatible_delegation
(
struct
inode
*
inode
,
fmode_t
fmode
)
{
{
struct
nfs_delegation
*
delegation
;
struct
nfs_delegation
*
delegation
;
rcu_read_lock
();
rcu_read_lock
();
delegation
=
rcu_dereference
(
NFS_I
(
inode
)
->
delegation
);
delegation
=
rcu_dereference
(
NFS_I
(
inode
)
->
delegation
);
if
(
delegation
==
NULL
||
(
delegation
->
type
&
open_flags
)
==
open_flags
)
{
if
(
delegation
==
NULL
||
(
delegation
->
type
&
fmode
)
==
fmode
)
{
rcu_read_unlock
();
rcu_read_unlock
();
return
;
return
;
}
}
...
@@ -542,15 +547,16 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
...
@@ -542,15 +547,16 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
struct
nfs4_state
*
state
=
opendata
->
state
;
struct
nfs4_state
*
state
=
opendata
->
state
;
struct
nfs_inode
*
nfsi
=
NFS_I
(
state
->
inode
);
struct
nfs_inode
*
nfsi
=
NFS_I
(
state
->
inode
);
struct
nfs_delegation
*
delegation
;
struct
nfs_delegation
*
delegation
;
int
open_mode
=
opendata
->
o_arg
.
open_flags
&
(
FMODE_READ
|
FMODE_WRITE
|
O_EXCL
);
int
open_mode
=
opendata
->
o_arg
.
open_flags
&
O_EXCL
;
fmode_t
fmode
=
opendata
->
o_arg
.
fmode
;
nfs4_stateid
stateid
;
nfs4_stateid
stateid
;
int
ret
=
-
EAGAIN
;
int
ret
=
-
EAGAIN
;
for
(;;)
{
for
(;;)
{
if
(
can_open_cached
(
state
,
open_mode
))
{
if
(
can_open_cached
(
state
,
fmode
,
open_mode
))
{
spin_lock
(
&
state
->
owner
->
so_lock
);
spin_lock
(
&
state
->
owner
->
so_lock
);
if
(
can_open_cached
(
state
,
open_mode
))
{
if
(
can_open_cached
(
state
,
fmode
,
open_mode
))
{
update_open_stateflags
(
state
,
open_
mode
);
update_open_stateflags
(
state
,
f
mode
);
spin_unlock
(
&
state
->
owner
->
so_lock
);
spin_unlock
(
&
state
->
owner
->
so_lock
);
goto
out_return_state
;
goto
out_return_state
;
}
}
...
@@ -559,7 +565,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
...
@@ -559,7 +565,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
rcu_read_lock
();
rcu_read_lock
();
delegation
=
rcu_dereference
(
nfsi
->
delegation
);
delegation
=
rcu_dereference
(
nfsi
->
delegation
);
if
(
delegation
==
NULL
||
if
(
delegation
==
NULL
||
!
can_open_delegated
(
delegation
,
open_
mode
))
{
!
can_open_delegated
(
delegation
,
f
mode
))
{
rcu_read_unlock
();
rcu_read_unlock
();
break
;
break
;
}
}
...
@@ -572,7 +578,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
...
@@ -572,7 +578,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
ret
=
-
EAGAIN
;
ret
=
-
EAGAIN
;
/* Try to update the stateid using the delegation */
/* Try to update the stateid using the delegation */
if
(
update_open_stateid
(
state
,
NULL
,
&
stateid
,
open_
mode
))
if
(
update_open_stateid
(
state
,
NULL
,
&
stateid
,
f
mode
))
goto
out_return_state
;
goto
out_return_state
;
}
}
out:
out:
...
@@ -624,7 +630,7 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data
...
@@ -624,7 +630,7 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data
}
}
update_open_stateid
(
state
,
&
data
->
o_res
.
stateid
,
NULL
,
update_open_stateid
(
state
,
&
data
->
o_res
.
stateid
,
NULL
,
data
->
o_arg
.
open_flags
);
data
->
o_arg
.
fmode
);
iput
(
inode
);
iput
(
inode
);
out:
out:
return
state
;
return
state
;
...
@@ -655,7 +661,7 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
...
@@ -655,7 +661,7 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
{
{
struct
nfs4_opendata
*
opendata
;
struct
nfs4_opendata
*
opendata
;
opendata
=
nfs4_opendata_alloc
(
&
ctx
->
path
,
state
->
owner
,
0
,
NULL
);
opendata
=
nfs4_opendata_alloc
(
&
ctx
->
path
,
state
->
owner
,
0
,
0
,
NULL
);
if
(
opendata
==
NULL
)
if
(
opendata
==
NULL
)
return
ERR_PTR
(
-
ENOMEM
);
return
ERR_PTR
(
-
ENOMEM
);
opendata
->
state
=
state
;
opendata
->
state
=
state
;
...
@@ -663,12 +669,13 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
...
@@ -663,12 +669,13 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
return
opendata
;
return
opendata
;
}
}
static
int
nfs4_open_recover_helper
(
struct
nfs4_opendata
*
opendata
,
mode_t
openflags
,
struct
nfs4_state
**
res
)
static
int
nfs4_open_recover_helper
(
struct
nfs4_opendata
*
opendata
,
fmode_t
fmode
,
struct
nfs4_state
**
res
)
{
{
struct
nfs4_state
*
newstate
;
struct
nfs4_state
*
newstate
;
int
ret
;
int
ret
;
opendata
->
o_arg
.
open_flags
=
openflags
;
opendata
->
o_arg
.
open_flags
=
0
;
opendata
->
o_arg
.
fmode
=
fmode
;
memset
(
&
opendata
->
o_res
,
0
,
sizeof
(
opendata
->
o_res
));
memset
(
&
opendata
->
o_res
,
0
,
sizeof
(
opendata
->
o_res
));
memset
(
&
opendata
->
c_res
,
0
,
sizeof
(
opendata
->
c_res
));
memset
(
&
opendata
->
c_res
,
0
,
sizeof
(
opendata
->
c_res
));
nfs4_init_opendata_res
(
opendata
);
nfs4_init_opendata_res
(
opendata
);
...
@@ -678,7 +685,7 @@ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openf
...
@@ -678,7 +685,7 @@ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openf
newstate
=
nfs4_opendata_to_nfs4_state
(
opendata
);
newstate
=
nfs4_opendata_to_nfs4_state
(
opendata
);
if
(
IS_ERR
(
newstate
))
if
(
IS_ERR
(
newstate
))
return
PTR_ERR
(
newstate
);
return
PTR_ERR
(
newstate
);
nfs4_close_state
(
&
opendata
->
path
,
newstate
,
openflags
);
nfs4_close_state
(
&
opendata
->
path
,
newstate
,
fmode
);
*
res
=
newstate
;
*
res
=
newstate
;
return
0
;
return
0
;
}
}
...
@@ -734,7 +741,7 @@ static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
...
@@ -734,7 +741,7 @@ static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state
{
{
struct
nfs_delegation
*
delegation
;
struct
nfs_delegation
*
delegation
;
struct
nfs4_opendata
*
opendata
;
struct
nfs4_opendata
*
opendata
;
in
t
delegation_type
=
0
;
fmode_
t
delegation_type
=
0
;
int
status
;
int
status
;
opendata
=
nfs4_open_recoverdata_alloc
(
ctx
,
state
);
opendata
=
nfs4_open_recoverdata_alloc
(
ctx
,
state
);
...
@@ -847,7 +854,7 @@ static void nfs4_open_confirm_release(void *calldata)
...
@@ -847,7 +854,7 @@ static void nfs4_open_confirm_release(void *calldata)
goto
out_free
;
goto
out_free
;
state
=
nfs4_opendata_to_nfs4_state
(
data
);
state
=
nfs4_opendata_to_nfs4_state
(
data
);
if
(
!
IS_ERR
(
state
))
if
(
!
IS_ERR
(
state
))
nfs4_close_state
(
&
data
->
path
,
state
,
data
->
o_arg
.
open_flags
);
nfs4_close_state
(
&
data
->
path
,
state
,
data
->
o_arg
.
fmode
);
out_free:
out_free:
nfs4_opendata_put
(
data
);
nfs4_opendata_put
(
data
);
}
}
...
@@ -911,7 +918,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
...
@@ -911,7 +918,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
if
(
data
->
state
!=
NULL
)
{
if
(
data
->
state
!=
NULL
)
{
struct
nfs_delegation
*
delegation
;
struct
nfs_delegation
*
delegation
;
if
(
can_open_cached
(
data
->
state
,
data
->
o_arg
.
open_flags
&
(
FMODE_READ
|
FMODE_WRITE
|
O_EXCL
)
))
if
(
can_open_cached
(
data
->
state
,
data
->
o_arg
.
fmode
,
data
->
o_arg
.
open_flags
))
goto
out_no_action
;
goto
out_no_action
;
rcu_read_lock
();
rcu_read_lock
();
delegation
=
rcu_dereference
(
NFS_I
(
data
->
state
->
inode
)
->
delegation
);
delegation
=
rcu_dereference
(
NFS_I
(
data
->
state
->
inode
)
->
delegation
);
...
@@ -980,7 +987,7 @@ static void nfs4_open_release(void *calldata)
...
@@ -980,7 +987,7 @@ static void nfs4_open_release(void *calldata)
goto
out_free
;
goto
out_free
;
state
=
nfs4_opendata_to_nfs4_state
(
data
);
state
=
nfs4_opendata_to_nfs4_state
(
data
);
if
(
!
IS_ERR
(
state
))
if
(
!
IS_ERR
(
state
))
nfs4_close_state
(
&
data
->
path
,
state
,
data
->
o_arg
.
open_flags
);
nfs4_close_state
(
&
data
->
path
,
state
,
data
->
o_arg
.
fmode
);
out_free:
out_free:
nfs4_opendata_put
(
data
);
nfs4_opendata_put
(
data
);
}
}
...
@@ -1135,7 +1142,7 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct
...
@@ -1135,7 +1142,7 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata, struct
/*
/*
* Returns a referenced nfs4_state
* Returns a referenced nfs4_state
*/
*/
static
int
_nfs4_do_open
(
struct
inode
*
dir
,
struct
path
*
path
,
int
flags
,
struct
iattr
*
sattr
,
struct
rpc_cred
*
cred
,
struct
nfs4_state
**
res
)
static
int
_nfs4_do_open
(
struct
inode
*
dir
,
struct
path
*
path
,
fmode_t
fmode
,
int
flags
,
struct
iattr
*
sattr
,
struct
rpc_cred
*
cred
,
struct
nfs4_state
**
res
)
{
{
struct
nfs4_state_owner
*
sp
;
struct
nfs4_state_owner
*
sp
;
struct
nfs4_state
*
state
=
NULL
;
struct
nfs4_state
*
state
=
NULL
;
...
@@ -1153,9 +1160,9 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct
...
@@ -1153,9 +1160,9 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct
if
(
status
!=
0
)
if
(
status
!=
0
)
goto
err_put_state_owner
;
goto
err_put_state_owner
;
if
(
path
->
dentry
->
d_inode
!=
NULL
)
if
(
path
->
dentry
->
d_inode
!=
NULL
)
nfs4_return_incompatible_delegation
(
path
->
dentry
->
d_inode
,
f
lags
&
(
FMODE_READ
|
FMODE_WRITE
)
);
nfs4_return_incompatible_delegation
(
path
->
dentry
->
d_inode
,
f
mode
);
status
=
-
ENOMEM
;
status
=
-
ENOMEM
;
opendata
=
nfs4_opendata_alloc
(
path
,
sp
,
flags
,
sattr
);
opendata
=
nfs4_opendata_alloc
(
path
,
sp
,
f
mode
,
f
lags
,
sattr
);
if
(
opendata
==
NULL
)
if
(
opendata
==
NULL
)
goto
err_put_state_owner
;
goto
err_put_state_owner
;
...
@@ -1187,14 +1194,14 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct
...
@@ -1187,14 +1194,14 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, int flags, struct
}
}
static
struct
nfs4_state
*
nfs4_do_open
(
struct
inode
*
dir
,
struct
path
*
path
,
int
flags
,
struct
iattr
*
sattr
,
struct
rpc_cred
*
cred
)
static
struct
nfs4_state
*
nfs4_do_open
(
struct
inode
*
dir
,
struct
path
*
path
,
fmode_t
fmode
,
int
flags
,
struct
iattr
*
sattr
,
struct
rpc_cred
*
cred
)
{
{
struct
nfs4_exception
exception
=
{
};
struct
nfs4_exception
exception
=
{
};
struct
nfs4_state
*
res
;
struct
nfs4_state
*
res
;
int
status
;
int
status
;
do
{
do
{
status
=
_nfs4_do_open
(
dir
,
path
,
flags
,
sattr
,
cred
,
&
res
);
status
=
_nfs4_do_open
(
dir
,
path
,
f
mode
,
f
lags
,
sattr
,
cred
,
&
res
);
if
(
status
==
0
)
if
(
status
==
0
)
break
;
break
;
/* NOTE: BAD_SEQID means the server and client disagree about the
/* NOTE: BAD_SEQID means the server and client disagree about the
...
@@ -1332,7 +1339,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
...
@@ -1332,7 +1339,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
case
-
NFS4ERR_OLD_STATEID
:
case
-
NFS4ERR_OLD_STATEID
:
case
-
NFS4ERR_BAD_STATEID
:
case
-
NFS4ERR_BAD_STATEID
:
case
-
NFS4ERR_EXPIRED
:
case
-
NFS4ERR_EXPIRED
:
if
(
calldata
->
arg
.
open_flags
==
0
)
if
(
calldata
->
arg
.
fmode
==
0
)
break
;
break
;
default:
default:
if
(
nfs4_async_handle_error
(
task
,
server
,
state
)
==
-
EAGAIN
)
{
if
(
nfs4_async_handle_error
(
task
,
server
,
state
)
==
-
EAGAIN
)
{
...
@@ -1374,10 +1381,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
...
@@ -1374,10 +1381,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
nfs_fattr_init
(
calldata
->
res
.
fattr
);
nfs_fattr_init
(
calldata
->
res
.
fattr
);
if
(
test_bit
(
NFS_O_RDONLY_STATE
,
&
state
->
flags
)
!=
0
)
{
if
(
test_bit
(
NFS_O_RDONLY_STATE
,
&
state
->
flags
)
!=
0
)
{
task
->
tk_msg
.
rpc_proc
=
&
nfs4_procedures
[
NFSPROC4_CLNT_OPEN_DOWNGRADE
];
task
->
tk_msg
.
rpc_proc
=
&
nfs4_procedures
[
NFSPROC4_CLNT_OPEN_DOWNGRADE
];
calldata
->
arg
.
open_flags
=
FMODE_READ
;
calldata
->
arg
.
fmode
=
FMODE_READ
;
}
else
if
(
test_bit
(
NFS_O_WRONLY_STATE
,
&
state
->
flags
)
!=
0
)
{
}
else
if
(
test_bit
(
NFS_O_WRONLY_STATE
,
&
state
->
flags
)
!=
0
)
{
task
->
tk_msg
.
rpc_proc
=
&
nfs4_procedures
[
NFSPROC4_CLNT_OPEN_DOWNGRADE
];
task
->
tk_msg
.
rpc_proc
=
&
nfs4_procedures
[
NFSPROC4_CLNT_OPEN_DOWNGRADE
];
calldata
->
arg
.
open_flags
=
FMODE_WRITE
;
calldata
->
arg
.
fmode
=
FMODE_WRITE
;
}
}
calldata
->
timestamp
=
jiffies
;
calldata
->
timestamp
=
jiffies
;
rpc_call_start
(
task
);
rpc_call_start
(
task
);
...
@@ -1430,7 +1437,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
...
@@ -1430,7 +1437,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
calldata
->
arg
.
seqid
=
nfs_alloc_seqid
(
&
state
->
owner
->
so_seqid
);
calldata
->
arg
.
seqid
=
nfs_alloc_seqid
(
&
state
->
owner
->
so_seqid
);
if
(
calldata
->
arg
.
seqid
==
NULL
)
if
(
calldata
->
arg
.
seqid
==
NULL
)
goto
out_free_calldata
;
goto
out_free_calldata
;
calldata
->
arg
.
open_flags
=
0
;
calldata
->
arg
.
fmode
=
0
;
calldata
->
arg
.
bitmask
=
server
->
attr_bitmask
;
calldata
->
arg
.
bitmask
=
server
->
attr_bitmask
;
calldata
->
res
.
fattr
=
&
calldata
->
fattr
;
calldata
->
res
.
fattr
=
&
calldata
->
fattr
;
calldata
->
res
.
seqid
=
calldata
->
arg
.
seqid
;
calldata
->
res
.
seqid
=
calldata
->
arg
.
seqid
;
...
@@ -1457,13 +1464,13 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
...
@@ -1457,13 +1464,13 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
return
status
;
return
status
;
}
}
static
int
nfs4_intent_set_file
(
struct
nameidata
*
nd
,
struct
path
*
path
,
struct
nfs4_state
*
state
)
static
int
nfs4_intent_set_file
(
struct
nameidata
*
nd
,
struct
path
*
path
,
struct
nfs4_state
*
state
,
fmode_t
fmode
)
{
{
struct
file
*
filp
;
struct
file
*
filp
;
int
ret
;
int
ret
;
/* If the open_intent is for execute, we have an extra check to make */
/* If the open_intent is for execute, we have an extra check to make */
if
(
nd
->
intent
.
open
.
flags
&
FMODE_EXEC
)
{
if
(
fmode
&
FMODE_EXEC
)
{
ret
=
nfs_may_open
(
state
->
inode
,
ret
=
nfs_may_open
(
state
->
inode
,
state
->
owner
->
so_cred
,
state
->
owner
->
so_cred
,
nd
->
intent
.
open
.
flags
);
nd
->
intent
.
open
.
flags
);
...
@@ -1479,7 +1486,7 @@ static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct
...
@@ -1479,7 +1486,7 @@ static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct
}
}
ret
=
PTR_ERR
(
filp
);
ret
=
PTR_ERR
(
filp
);
out_close:
out_close:
nfs4_close_sync
(
path
,
state
,
nd
->
intent
.
open
.
flags
);
nfs4_close_sync
(
path
,
state
,
fmode
&
(
FMODE_READ
|
FMODE_WRITE
)
);
return
ret
;
return
ret
;
}
}
...
@@ -1495,6 +1502,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
...
@@ -1495,6 +1502,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
struct
rpc_cred
*
cred
;
struct
rpc_cred
*
cred
;
struct
nfs4_state
*
state
;
struct
nfs4_state
*
state
;
struct
dentry
*
res
;
struct
dentry
*
res
;
fmode_t
fmode
=
nd
->
intent
.
open
.
flags
&
(
FMODE_READ
|
FMODE_WRITE
|
FMODE_EXEC
);
if
(
nd
->
flags
&
LOOKUP_CREATE
)
{
if
(
nd
->
flags
&
LOOKUP_CREATE
)
{
attr
.
ia_mode
=
nd
->
intent
.
open
.
create_mode
;
attr
.
ia_mode
=
nd
->
intent
.
open
.
create_mode
;
...
@@ -1512,7 +1520,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
...
@@ -1512,7 +1520,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
parent
=
dentry
->
d_parent
;
parent
=
dentry
->
d_parent
;
/* Protect against concurrent sillydeletes */
/* Protect against concurrent sillydeletes */
nfs_block_sillyrename
(
parent
);
nfs_block_sillyrename
(
parent
);
state
=
nfs4_do_open
(
dir
,
&
path
,
nd
->
intent
.
open
.
flags
,
&
attr
,
cred
);
state
=
nfs4_do_open
(
dir
,
&
path
,
fmode
,
nd
->
intent
.
open
.
flags
,
&
attr
,
cred
);
put_rpccred
(
cred
);
put_rpccred
(
cred
);
if
(
IS_ERR
(
state
))
{
if
(
IS_ERR
(
state
))
{
if
(
PTR_ERR
(
state
)
==
-
ENOENT
)
{
if
(
PTR_ERR
(
state
)
==
-
ENOENT
)
{
...
@@ -1527,7 +1535,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
...
@@ -1527,7 +1535,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
path
.
dentry
=
res
;
path
.
dentry
=
res
;
nfs_set_verifier
(
path
.
dentry
,
nfs_save_change_attribute
(
dir
));
nfs_set_verifier
(
path
.
dentry
,
nfs_save_change_attribute
(
dir
));
nfs_unblock_sillyrename
(
parent
);
nfs_unblock_sillyrename
(
parent
);
nfs4_intent_set_file
(
nd
,
&
path
,
state
);
nfs4_intent_set_file
(
nd
,
&
path
,
state
,
fmode
);
return
res
;
return
res
;
}
}
...
@@ -1540,11 +1548,12 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
...
@@ -1540,11 +1548,12 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
};
};
struct
rpc_cred
*
cred
;
struct
rpc_cred
*
cred
;
struct
nfs4_state
*
state
;
struct
nfs4_state
*
state
;
fmode_t
fmode
=
openflags
&
(
FMODE_READ
|
FMODE_WRITE
);
cred
=
rpc_lookup_cred
();
cred
=
rpc_lookup_cred
();
if
(
IS_ERR
(
cred
))
if
(
IS_ERR
(
cred
))
return
PTR_ERR
(
cred
);
return
PTR_ERR
(
cred
);
state
=
nfs4_do_open
(
dir
,
&
path
,
openflags
,
NULL
,
cred
);
state
=
nfs4_do_open
(
dir
,
&
path
,
fmode
,
openflags
,
NULL
,
cred
);
put_rpccred
(
cred
);
put_rpccred
(
cred
);
if
(
IS_ERR
(
state
))
{
if
(
IS_ERR
(
state
))
{
switch
(
PTR_ERR
(
state
))
{
switch
(
PTR_ERR
(
state
))
{
...
@@ -1561,10 +1570,10 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
...
@@ -1561,10 +1570,10 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
}
}
if
(
state
->
inode
==
dentry
->
d_inode
)
{
if
(
state
->
inode
==
dentry
->
d_inode
)
{
nfs_set_verifier
(
dentry
,
nfs_save_change_attribute
(
dir
));
nfs_set_verifier
(
dentry
,
nfs_save_change_attribute
(
dir
));
nfs4_intent_set_file
(
nd
,
&
path
,
state
);
nfs4_intent_set_file
(
nd
,
&
path
,
state
,
fmode
);
return
1
;
return
1
;
}
}
nfs4_close_sync
(
&
path
,
state
,
openflags
);
nfs4_close_sync
(
&
path
,
state
,
fmode
);
out_drop:
out_drop:
d_drop
(
dentry
);
d_drop
(
dentry
);
return
0
;
return
0
;
...
@@ -1990,6 +1999,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
...
@@ -1990,6 +1999,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
};
};
struct
nfs4_state
*
state
;
struct
nfs4_state
*
state
;
struct
rpc_cred
*
cred
;
struct
rpc_cred
*
cred
;
fmode_t
fmode
=
flags
&
(
FMODE_READ
|
FMODE_WRITE
);
int
status
=
0
;
int
status
=
0
;
cred
=
rpc_lookup_cred
();
cred
=
rpc_lookup_cred
();
...
@@ -1997,7 +2007,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
...
@@ -1997,7 +2007,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
status
=
PTR_ERR
(
cred
);
status
=
PTR_ERR
(
cred
);
goto
out
;
goto
out
;
}
}
state
=
nfs4_do_open
(
dir
,
&
path
,
flags
,
sattr
,
cred
);
state
=
nfs4_do_open
(
dir
,
&
path
,
f
mode
,
f
lags
,
sattr
,
cred
);
d_drop
(
dentry
);
d_drop
(
dentry
);
if
(
IS_ERR
(
state
))
{
if
(
IS_ERR
(
state
))
{
status
=
PTR_ERR
(
state
);
status
=
PTR_ERR
(
state
);
...
@@ -2013,9 +2023,9 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
...
@@ -2013,9 +2023,9 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
nfs_post_op_update_inode
(
state
->
inode
,
&
fattr
);
nfs_post_op_update_inode
(
state
->
inode
,
&
fattr
);
}
}
if
(
status
==
0
&&
(
nd
->
flags
&
LOOKUP_OPEN
)
!=
0
)
if
(
status
==
0
&&
(
nd
->
flags
&
LOOKUP_OPEN
)
!=
0
)
status
=
nfs4_intent_set_file
(
nd
,
&
path
,
state
);
status
=
nfs4_intent_set_file
(
nd
,
&
path
,
state
,
fmode
);
else
else
nfs4_close_sync
(
&
path
,
state
,
f
lags
);
nfs4_close_sync
(
&
path
,
state
,
f
mode
);
out_putcred:
out_putcred:
put_rpccred
(
cred
);
put_rpccred
(
cred
);
out:
out:
...
...
fs/nfs/nfs4state.c
View file @
dc0b027d
...
@@ -363,18 +363,18 @@ nfs4_alloc_open_state(void)
...
@@ -363,18 +363,18 @@ nfs4_alloc_open_state(void)
}
}
void
void
nfs4_state_set_mode_locked
(
struct
nfs4_state
*
state
,
mode_t
mode
)
nfs4_state_set_mode_locked
(
struct
nfs4_state
*
state
,
fmode_t
f
mode
)
{
{
if
(
state
->
state
==
mode
)
if
(
state
->
state
==
f
mode
)
return
;
return
;
/* NB! List reordering - see the reclaim code for why. */
/* NB! List reordering - see the reclaim code for why. */
if
((
mode
&
FMODE_WRITE
)
!=
(
state
->
state
&
FMODE_WRITE
))
{
if
((
f
mode
&
FMODE_WRITE
)
!=
(
state
->
state
&
FMODE_WRITE
))
{
if
(
mode
&
FMODE_WRITE
)
if
(
f
mode
&
FMODE_WRITE
)
list_move
(
&
state
->
open_states
,
&
state
->
owner
->
so_states
);
list_move
(
&
state
->
open_states
,
&
state
->
owner
->
so_states
);
else
else
list_move_tail
(
&
state
->
open_states
,
&
state
->
owner
->
so_states
);
list_move_tail
(
&
state
->
open_states
,
&
state
->
owner
->
so_states
);
}
}
state
->
state
=
mode
;
state
->
state
=
f
mode
;
}
}
static
struct
nfs4_state
*
static
struct
nfs4_state
*
...
@@ -454,16 +454,16 @@ void nfs4_put_open_state(struct nfs4_state *state)
...
@@ -454,16 +454,16 @@ void nfs4_put_open_state(struct nfs4_state *state)
/*
/*
* Close the current file.
* Close the current file.
*/
*/
static
void
__nfs4_close
(
struct
path
*
path
,
struct
nfs4_state
*
state
,
mode_t
mode
,
int
wait
)
static
void
__nfs4_close
(
struct
path
*
path
,
struct
nfs4_state
*
state
,
fmode_t
f
mode
,
int
wait
)
{
{
struct
nfs4_state_owner
*
owner
=
state
->
owner
;
struct
nfs4_state_owner
*
owner
=
state
->
owner
;
int
call_close
=
0
;
int
call_close
=
0
;
in
t
newstate
;
fmode_
t
newstate
;
atomic_inc
(
&
owner
->
so_count
);
atomic_inc
(
&
owner
->
so_count
);
/* Protect against nfs4_find_state() */
/* Protect against nfs4_find_state() */
spin_lock
(
&
owner
->
so_lock
);
spin_lock
(
&
owner
->
so_lock
);
switch
(
mode
&
(
FMODE_READ
|
FMODE_WRITE
))
{
switch
(
f
mode
&
(
FMODE_READ
|
FMODE_WRITE
))
{
case
FMODE_READ
:
case
FMODE_READ
:
state
->
n_rdonly
--
;
state
->
n_rdonly
--
;
break
;
break
;
...
@@ -498,14 +498,14 @@ static void __nfs4_close(struct path *path, struct nfs4_state *state, mode_t mod
...
@@ -498,14 +498,14 @@ static void __nfs4_close(struct path *path, struct nfs4_state *state, mode_t mod
nfs4_do_close
(
path
,
state
,
wait
);
nfs4_do_close
(
path
,
state
,
wait
);
}
}
void
nfs4_close_state
(
struct
path
*
path
,
struct
nfs4_state
*
state
,
mode_t
mode
)
void
nfs4_close_state
(
struct
path
*
path
,
struct
nfs4_state
*
state
,
fmode_t
f
mode
)
{
{
__nfs4_close
(
path
,
state
,
mode
,
0
);
__nfs4_close
(
path
,
state
,
f
mode
,
0
);
}
}
void
nfs4_close_sync
(
struct
path
*
path
,
struct
nfs4_state
*
state
,
mode_t
mode
)
void
nfs4_close_sync
(
struct
path
*
path
,
struct
nfs4_state
*
state
,
fmode_t
f
mode
)
{
{
__nfs4_close
(
path
,
state
,
mode
,
1
);
__nfs4_close
(
path
,
state
,
f
mode
,
1
);
}
}
/*
/*
...
...
fs/nfs/nfs4xdr.c
View file @
dc0b027d
...
@@ -953,12 +953,12 @@ static int encode_lookup(struct xdr_stream *xdr, const struct qstr *name)
...
@@ -953,12 +953,12 @@ static int encode_lookup(struct xdr_stream *xdr, const struct qstr *name)
return
0
;
return
0
;
}
}
static
void
encode_share_access
(
struct
xdr_stream
*
xdr
,
int
open_flags
)
static
void
encode_share_access
(
struct
xdr_stream
*
xdr
,
fmode_t
fmode
)
{
{
__be32
*
p
;
__be32
*
p
;
RESERVE_SPACE
(
8
);
RESERVE_SPACE
(
8
);
switch
(
open_flags
&
(
FMODE_READ
|
FMODE_WRITE
))
{
switch
(
fmode
&
(
FMODE_READ
|
FMODE_WRITE
))
{
case
FMODE_READ
:
case
FMODE_READ
:
WRITE32
(
NFS4_SHARE_ACCESS_READ
);
WRITE32
(
NFS4_SHARE_ACCESS_READ
);
break
;
break
;
...
@@ -969,7 +969,7 @@ static void encode_share_access(struct xdr_stream *xdr, int open_flags)
...
@@ -969,7 +969,7 @@ static void encode_share_access(struct xdr_stream *xdr, int open_flags)
WRITE32
(
NFS4_SHARE_ACCESS_BOTH
);
WRITE32
(
NFS4_SHARE_ACCESS_BOTH
);
break
;
break
;
default:
default:
BUG
(
);
WRITE32
(
0
);
}
}
WRITE32
(
0
);
/* for linux, share_deny = 0 always */
WRITE32
(
0
);
/* for linux, share_deny = 0 always */
}
}
...
@@ -984,7 +984,7 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
...
@@ -984,7 +984,7 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
RESERVE_SPACE
(
8
);
RESERVE_SPACE
(
8
);
WRITE32
(
OP_OPEN
);
WRITE32
(
OP_OPEN
);
WRITE32
(
arg
->
seqid
->
sequence
->
counter
);
WRITE32
(
arg
->
seqid
->
sequence
->
counter
);
encode_share_access
(
xdr
,
arg
->
open_flags
);
encode_share_access
(
xdr
,
arg
->
fmode
);
RESERVE_SPACE
(
28
);
RESERVE_SPACE
(
28
);
WRITE64
(
arg
->
clientid
);
WRITE64
(
arg
->
clientid
);
WRITE32
(
16
);
WRITE32
(
16
);
...
@@ -1112,7 +1112,7 @@ static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closea
...
@@ -1112,7 +1112,7 @@ static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closea
WRITE32
(
OP_OPEN_DOWNGRADE
);
WRITE32
(
OP_OPEN_DOWNGRADE
);
WRITEMEM
(
arg
->
stateid
->
data
,
NFS4_STATEID_SIZE
);
WRITEMEM
(
arg
->
stateid
->
data
,
NFS4_STATEID_SIZE
);
WRITE32
(
arg
->
seqid
->
sequence
->
counter
);
WRITE32
(
arg
->
seqid
->
sequence
->
counter
);
encode_share_access
(
xdr
,
arg
->
open_flags
);
encode_share_access
(
xdr
,
arg
->
fmode
);
return
0
;
return
0
;
}
}
...
...
include/linux/nfs_fs.h
View file @
dc0b027d
...
@@ -83,7 +83,7 @@ struct nfs_open_context {
...
@@ -83,7 +83,7 @@ struct nfs_open_context {
struct
rpc_cred
*
cred
;
struct
rpc_cred
*
cred
;
struct
nfs4_state
*
state
;
struct
nfs4_state
*
state
;
fl_owner_t
lockowner
;
fl_owner_t
lockowner
;
in
t
mode
;
fmode_
t
mode
;
unsigned
long
flags
;
unsigned
long
flags
;
#define NFS_CONTEXT_ERROR_WRITE (0)
#define NFS_CONTEXT_ERROR_WRITE (0)
...
@@ -342,7 +342,7 @@ extern int nfs_setattr(struct dentry *, struct iattr *);
...
@@ -342,7 +342,7 @@ extern int nfs_setattr(struct dentry *, struct iattr *);
extern
void
nfs_setattr_update_inode
(
struct
inode
*
inode
,
struct
iattr
*
attr
);
extern
void
nfs_setattr_update_inode
(
struct
inode
*
inode
,
struct
iattr
*
attr
);
extern
struct
nfs_open_context
*
get_nfs_open_context
(
struct
nfs_open_context
*
ctx
);
extern
struct
nfs_open_context
*
get_nfs_open_context
(
struct
nfs_open_context
*
ctx
);
extern
void
put_nfs_open_context
(
struct
nfs_open_context
*
ctx
);
extern
void
put_nfs_open_context
(
struct
nfs_open_context
*
ctx
);
extern
struct
nfs_open_context
*
nfs_find_open_context
(
struct
inode
*
inode
,
struct
rpc_cred
*
cred
,
in
t
mode
);
extern
struct
nfs_open_context
*
nfs_find_open_context
(
struct
inode
*
inode
,
struct
rpc_cred
*
cred
,
fmode_
t
mode
);
extern
u64
nfs_compat_user_ino64
(
u64
fileid
);
extern
u64
nfs_compat_user_ino64
(
u64
fileid
);
extern
void
nfs_fattr_init
(
struct
nfs_fattr
*
fattr
);
extern
void
nfs_fattr_init
(
struct
nfs_fattr
*
fattr
);
...
...
include/linux/nfs_xdr.h
View file @
dc0b027d
...
@@ -120,6 +120,7 @@ struct nfs_openargs {
...
@@ -120,6 +120,7 @@ struct nfs_openargs {
const
struct
nfs_fh
*
fh
;
const
struct
nfs_fh
*
fh
;
struct
nfs_seqid
*
seqid
;
struct
nfs_seqid
*
seqid
;
int
open_flags
;
int
open_flags
;
fmode_t
fmode
;
__u64
clientid
;
__u64
clientid
;
__u64
id
;
__u64
id
;
union
{
union
{
...
@@ -171,7 +172,7 @@ struct nfs_closeargs {
...
@@ -171,7 +172,7 @@ struct nfs_closeargs {
struct
nfs_fh
*
fh
;
struct
nfs_fh
*
fh
;
nfs4_stateid
*
stateid
;
nfs4_stateid
*
stateid
;
struct
nfs_seqid
*
seqid
;
struct
nfs_seqid
*
seqid
;
int
open_flags
;
fmode_t
fmode
;
const
u32
*
bitmask
;
const
u32
*
bitmask
;
};
};
...
...
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