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
be6c1a46
Commit
be6c1a46
authored
Apr 08, 2003
by
Trond Myklebust
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make NFSv4 'setattr()' method use the cached stateid if the file is
already open.
parent
45f3fae6
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
134 additions
and
59 deletions
+134
-59
fs/nfs/nfs4proc.c
fs/nfs/nfs4proc.c
+58
-46
fs/nfs/nfs4xdr.c
fs/nfs/nfs4xdr.c
+64
-13
include/linux/nfs4.h
include/linux/nfs4.h
+1
-0
include/linux/nfs_xdr.h
include/linux/nfs_xdr.h
+11
-0
No files found.
fs/nfs/nfs4proc.c
View file @
be6c1a46
...
@@ -461,18 +461,6 @@ nfs4_setup_savefh(struct nfs4_compound *cp)
...
@@ -461,18 +461,6 @@ nfs4_setup_savefh(struct nfs4_compound *cp)
cp
->
req_nops
++
;
cp
->
req_nops
++
;
}
}
static
void
nfs4_setup_setattr
(
struct
nfs4_compound
*
cp
,
char
*
stateid
,
struct
iattr
*
iap
)
{
struct
nfs4_setattr
*
setattr
=
GET_OP
(
cp
,
setattr
);
setattr
->
st_stateid
=
stateid
;
setattr
->
st_iap
=
iap
;
OPNUM
(
cp
)
=
OP_SETATTR
;
cp
->
req_nops
++
;
}
static
void
static
void
nfs4_setup_setclientid
(
struct
nfs4_compound
*
cp
,
u32
program
,
unsigned
short
port
)
nfs4_setup_setclientid
(
struct
nfs4_compound
*
cp
,
u32
program
,
unsigned
short
port
)
{
{
...
@@ -681,20 +669,39 @@ nfs4_do_open(struct inode *dir, struct qstr *name, int flags,
...
@@ -681,20 +669,39 @@ nfs4_do_open(struct inode *dir, struct qstr *name, int flags,
return
status
;
return
status
;
}
}
static
int
int
do_setattr
(
struct
nfs_server
*
server
,
struct
nfs_fattr
*
fattr
,
nfs4_do_setattr
(
struct
nfs_server
*
server
,
struct
nfs_fattr
*
fattr
,
struct
nfs_fh
*
fhandle
,
struct
iattr
*
sattr
,
char
*
stateid
)
struct
nfs_fh
*
fhandle
,
struct
iattr
*
sattr
,
{
struct
nfs4_shareowner
*
sp
)
struct
nfs4_compound
compound
;
{
struct
nfs4_op
ops
[
3
];
u32
g_bmres
[
2
];
u32
bmres
[
2
];
struct
nfs4_getattr
getattr
=
{
.
gt_bmval
=
nfs4_fattr_bitmap
,
fattr
->
valid
=
0
;
.
gt_attrs
=
fattr
,
nfs4_setup_compound
(
&
compound
,
ops
,
server
,
"setattr"
);
.
gt_bmres
=
g_bmres
,
nfs4_setup_putfh
(
&
compound
,
fhandle
);
};
nfs4_setup_setattr
(
&
compound
,
stateid
,
sattr
);
struct
nfs_setattrargs
arg
=
{
nfs4_setup_getattr
(
&
compound
,
fattr
,
bmres
);
.
fh
=
fhandle
,
return
nfs4_call_compound
(
&
compound
,
NULL
,
0
);
.
iap
=
sattr
,
.
attr
=
&
getattr
,
};
struct
nfs_setattrres
res
=
{
.
attr
=
&
getattr
,
};
struct
rpc_message
msg
=
{
.
rpc_proc
=
&
nfs4_procedures
[
NFSPROC4_CLNT_SETATTR
],
.
rpc_argp
=
&
arg
,
.
rpc_resp
=
&
res
,
};
fattr
->
valid
=
0
;
if
(
sp
)
memcpy
(
arg
.
stateid
,
sp
->
so_stateid
,
sizeof
(
nfs4_stateid
));
else
memcpy
(
arg
.
stateid
,
zero_stateid
,
sizeof
(
nfs4_stateid
));
return
(
rpc_call_sync
(
server
->
client
,
&
msg
,
0
));
}
}
/*
/*
...
@@ -839,7 +846,18 @@ nfs4_proc_getattr(struct inode *inode, struct nfs_fattr *fattr)
...
@@ -839,7 +846,18 @@ nfs4_proc_getattr(struct inode *inode, struct nfs_fattr *fattr)
* The file is not closed if it is opened due to the a request to change
* The file is not closed if it is opened due to the a request to change
* the size of the file. The open call will not be needed once the
* the size of the file. The open call will not be needed once the
* VFS layer lookup-intents are implemented.
* VFS layer lookup-intents are implemented.
*
* Close is called when the inode is destroyed.
* Close is called when the inode is destroyed.
* If we haven't opened the file for O_WRONLY, we
* need to in the size_change case to obtain a stateid.
*
* Got race?
* Because OPEN is always done by name in nfsv4, it is
* possible that we opened a different file by the same
* name. We can recognize this race condition, but we
* can't do anything about it besides returning an error.
*
* This will be fixed with VFS changes (lookup-intent).
*/
*/
static
int
static
int
nfs4_proc_setattr
(
struct
dentry
*
dentry
,
struct
nfs_fattr
*
fattr
,
nfs4_proc_setattr
(
struct
dentry
*
dentry
,
struct
nfs_fattr
*
fattr
,
...
@@ -847,37 +865,31 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
...
@@ -847,37 +865,31 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
{
{
struct
inode
*
inode
=
dentry
->
d_inode
;
struct
inode
*
inode
=
dentry
->
d_inode
;
int
size_change
=
sattr
->
ia_valid
&
ATTR_SIZE
;
int
size_change
=
sattr
->
ia_valid
&
ATTR_SIZE
;
struct
nfs_fh
throwaway_fh
;
struct
nfs4_shareowner
*
sp
=
NULL
;
struct
nfs4_shareowner
*
sp
=
NULL
;
int
status
,
fake
=
1
;
int
status
;
fattr
->
valid
=
0
;
fattr
->
valid
=
0
;
if
(
size_change
)
{
if
(
size_change
)
{
if
(
NFS_I
(
inode
)
->
wo_owner
)
{
/* file is already open for O_WRONLY */
sp
=
NFS_I
(
inode
)
->
wo_owner
;
goto
no_open
;
}
status
=
nfs4_do_open
(
dentry
->
d_parent
->
d_inode
,
status
=
nfs4_do_open
(
dentry
->
d_parent
->
d_inode
,
&
dentry
->
d_name
,
&
dentry
->
d_name
,
O_WRONLY
,
NULL
,
fattr
,
O_WRONLY
,
NULL
,
fattr
,
NULL
,
&
sp
);
&
throwaway_fh
,
&
sp
);
if
(
status
)
if
(
status
)
return
status
;
return
status
;
fake
=
0
;
/*
* Because OPEN is always done by name in nfsv4, it is
* possible that we opened a different file by the same
* name. We can recognize this race condition, but we
* can't do anything about it besides returning an error.
*
* XXX: Should we compare filehandles too, as in
* nfs_find_actor()?
*/
if
(
fattr
->
fileid
!=
NFS_FILEID
(
inode
))
{
if
(
fattr
->
fileid
!=
NFS_FILEID
(
inode
))
{
printk
(
KERN_WARNING
"nfs: raced in setattr, returning -EIO
\n
"
);
printk
(
KERN_WARNING
"nfs: raced in setattr, returning -EIO
\n
"
);
return
-
EIO
;
return
-
EIO
;
}
}
}
}
no_open:
status
=
do_setattr
(
NFS_SERVER
(
inode
),
fattr
,
NFS_FH
(
inode
),
sattr
,
status
=
nfs4_do_setattr
(
NFS_SERVER
(
inode
),
fattr
,
fake
==
1
?
zero_stateid
:
sp
->
so_stateid
);
NFS_FH
(
inode
),
sattr
,
sp
);
return
status
;
return
status
;
}
}
...
@@ -1097,8 +1109,8 @@ nfs4_proc_create(struct inode *dir, struct qstr *name, struct iattr *sattr,
...
@@ -1097,8 +1109,8 @@ nfs4_proc_create(struct inode *dir, struct qstr *name, struct iattr *sattr,
status
=
nfs4_do_open
(
dir
,
name
,
oflags
,
sattr
,
fattr
,
fhandle
,
&
sp
);
status
=
nfs4_do_open
(
dir
,
name
,
oflags
,
sattr
,
fattr
,
fhandle
,
&
sp
);
if
(
!
status
)
{
if
(
!
status
)
{
if
(
flags
&
O_EXCL
)
{
if
(
flags
&
O_EXCL
)
{
status
=
do_setattr
(
NFS_SERVER
(
dir
),
fattr
,
status
=
nfs4_
do_setattr
(
NFS_SERVER
(
dir
),
fattr
,
fhandle
,
sattr
,
sp
->
so_stateid
);
fhandle
,
sattr
,
sp
);
/* XXX should i bother closing the file? */
/* XXX should i bother closing the file? */
}
}
}
}
...
...
fs/nfs/nfs4xdr.c
View file @
be6c1a46
...
@@ -150,8 +150,14 @@ extern int nfs_stat_to_errno(int);
...
@@ -150,8 +150,14 @@ extern int nfs_stat_to_errno(int);
#define NFS4_dec_close_sz compound_decode_hdr_maxsz + \
#define NFS4_dec_close_sz compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
decode_putfh_maxsz + \
op_decode_hdr_maxsz + 4
op_decode_hdr_maxsz + 4
#define NFS4_enc_setattr_sz compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
op_encode_hdr_maxsz + 4 + \
nfs4_fattr_bitmap_maxsz + \
encode_getattr_maxsz
#define NFS4_dec_setattr_sz compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
op_decode_hdr_maxsz + 3
static
struct
{
static
struct
{
...
@@ -771,16 +777,16 @@ encode_savefh(struct xdr_stream *xdr)
...
@@ -771,16 +777,16 @@ encode_savefh(struct xdr_stream *xdr)
}
}
static
int
static
int
encode_setattr
(
struct
xdr_stream
*
xdr
,
struct
nfs
4_setattr
*
setattr
)
encode_setattr
(
struct
xdr_stream
*
xdr
,
struct
nfs
_setattrargs
*
arg
)
{
{
int
status
;
int
status
;
uint32_t
*
p
;
uint32_t
*
p
;
RESERVE_SPACE
(
4
+
sizeof
(
nfs4_stateid
));
RESERVE_SPACE
(
4
+
sizeof
(
nfs4_stateid
));
WRITE32
(
OP_SETATTR
);
WRITE32
(
OP_SETATTR
);
WRITEMEM
(
setattr
->
st_
stateid
,
sizeof
(
nfs4_stateid
));
WRITEMEM
(
arg
->
stateid
,
sizeof
(
nfs4_stateid
));
if
((
status
=
encode_attrs
(
xdr
,
setattr
->
st_
iap
)))
if
((
status
=
encode_attrs
(
xdr
,
arg
->
iap
)))
return
status
;
return
status
;
return
0
;
return
0
;
...
@@ -907,9 +913,6 @@ encode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs
...
@@ -907,9 +913,6 @@ encode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs
case
OP_SAVEFH
:
case
OP_SAVEFH
:
status
=
encode_savefh
(
xdr
);
status
=
encode_savefh
(
xdr
);
break
;
break
;
case
OP_SETATTR
:
status
=
encode_setattr
(
xdr
,
&
cp
->
ops
[
i
].
u
.
setattr
);
break
;
case
OP_SETCLIENTID
:
case
OP_SETCLIENTID
:
status
=
encode_setclientid
(
xdr
,
&
cp
->
ops
[
i
].
u
.
setclientid
);
status
=
encode_setclientid
(
xdr
,
&
cp
->
ops
[
i
].
u
.
setclientid
);
break
;
break
;
...
@@ -1061,6 +1064,31 @@ nfs4_xdr_enc_read(struct rpc_rqst *req, uint32_t *p, struct nfs_readargs *args)
...
@@ -1061,6 +1064,31 @@ nfs4_xdr_enc_read(struct rpc_rqst *req, uint32_t *p, struct nfs_readargs *args)
return
status
;
return
status
;
}
}
/*
* Encode an SETATTR request
*/
static
int
nfs4_xdr_enc_setattr
(
struct
rpc_rqst
*
req
,
uint32_t
*
p
,
struct
nfs_setattrargs
*
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_setattr
(
&
xdr
,
args
);
if
(
status
)
goto
out
;
status
=
encode_getattr
(
&
xdr
,
args
->
attr
);
out:
return
status
;
}
/*
/*
* Encode a WRITE request
* Encode a WRITE request
*/
*/
...
@@ -1991,7 +2019,7 @@ decode_savefh(struct xdr_stream *xdr)
...
@@ -1991,7 +2019,7 @@ decode_savefh(struct xdr_stream *xdr)
}
}
static
int
static
int
decode_setattr
(
struct
xdr_stream
*
xdr
)
decode_setattr
(
struct
xdr_stream
*
xdr
,
struct
nfs_setattrres
*
res
)
{
{
uint32_t
*
p
;
uint32_t
*
p
;
uint32_t
bmlen
;
uint32_t
bmlen
;
...
@@ -2144,9 +2172,6 @@ decode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs
...
@@ -2144,9 +2172,6 @@ decode_compound(struct xdr_stream *xdr, struct nfs4_compound *cp, struct rpc_rqs
case
OP_SAVEFH
:
case
OP_SAVEFH
:
status
=
decode_savefh
(
xdr
);
status
=
decode_savefh
(
xdr
);
break
;
break
;
case
OP_SETATTR
:
status
=
decode_setattr
(
xdr
);
break
;
case
OP_SETCLIENTID
:
case
OP_SETCLIENTID
:
status
=
decode_setclientid
(
xdr
,
&
op
->
u
.
setclientid
);
status
=
decode_setclientid
(
xdr
,
&
op
->
u
.
setclientid
);
break
;
break
;
...
@@ -2274,6 +2299,31 @@ nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_open_c
...
@@ -2274,6 +2299,31 @@ nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_open_c
return
status
;
return
status
;
}
}
/*
* Decode SETATTR response
*/
static
int
nfs4_xdr_dec_setattr
(
struct
rpc_rqst
*
rqstp
,
uint32_t
*
p
,
struct
nfs_setattrres
*
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_setattr
(
&
xdr
,
res
);
if
(
status
)
goto
out
;
status
=
decode_getattr
(
&
xdr
,
res
->
attr
);
out:
return
status
;
}
/*
/*
* Decode Read response
* Decode Read response
...
@@ -2418,7 +2468,8 @@ struct rpc_procinfo nfs4_procedures[] = {
...
@@ -2418,7 +2468,8 @@ struct rpc_procinfo nfs4_procedures[] = {
PROC
(
COMMIT
,
enc_commit
,
dec_commit
),
PROC
(
COMMIT
,
enc_commit
,
dec_commit
),
PROC
(
OPEN
,
enc_open
,
dec_open
),
PROC
(
OPEN
,
enc_open
,
dec_open
),
PROC
(
OPEN_CONFIRM
,
enc_open_confirm
,
dec_open_confirm
),
PROC
(
OPEN_CONFIRM
,
enc_open_confirm
,
dec_open_confirm
),
PROC
(
CLOSE
,
enc_close
,
dec_close
),
PROC
(
CLOSE
,
enc_close
,
dec_close
),
PROC
(
SETATTR
,
enc_setattr
,
dec_setattr
),
};
};
struct
rpc_version
nfs_version4
=
{
struct
rpc_version
nfs_version4
=
{
...
...
include/linux/nfs4.h
View file @
be6c1a46
...
@@ -209,6 +209,7 @@ enum {
...
@@ -209,6 +209,7 @@ enum {
NFSPROC4_CLNT_OPEN
,
NFSPROC4_CLNT_OPEN
,
NFSPROC4_CLNT_OPEN_CONFIRM
,
NFSPROC4_CLNT_OPEN_CONFIRM
,
NFSPROC4_CLNT_CLOSE
,
NFSPROC4_CLNT_CLOSE
,
NFSPROC4_CLNT_SETATTR
,
};
};
#endif
#endif
...
...
include/linux/nfs_xdr.h
View file @
be6c1a46
...
@@ -241,6 +241,17 @@ struct nfs_renameargs {
...
@@ -241,6 +241,17 @@ struct nfs_renameargs {
unsigned
int
tolen
;
unsigned
int
tolen
;
};
};
struct
nfs_setattrargs
{
struct
nfs_fh
*
fh
;
nfs4_stateid
stateid
;
struct
iattr
*
iap
;
struct
nfs4_getattr
*
attr
;
};
struct
nfs_setattrres
{
struct
nfs4_getattr
*
attr
;
};
struct
nfs_linkargs
{
struct
nfs_linkargs
{
struct
nfs_fh
*
fromfh
;
struct
nfs_fh
*
fromfh
;
struct
nfs_fh
*
tofh
;
struct
nfs_fh
*
tofh
;
...
...
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