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
b1355604
Commit
b1355604
authored
Apr 10, 2004
by
Trond Myklebust
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
NFSv2/v3/v4: Add support for asynchronous writes even if wsize<PAGE_CACHE_SIZE.
parent
7e19d190
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
297 additions
and
212 deletions
+297
-212
fs/nfs/direct.c
fs/nfs/direct.c
+1
-0
fs/nfs/nfs3proc.c
fs/nfs/nfs3proc.c
+4
-30
fs/nfs/nfs4proc.c
fs/nfs/nfs4proc.c
+10
-59
fs/nfs/nfs4xdr.c
fs/nfs/nfs4xdr.c
+5
-2
fs/nfs/proc.c
fs/nfs/proc.c
+3
-18
fs/nfs/write.c
fs/nfs/write.c
+270
-97
include/linux/nfs_fs.h
include/linux/nfs_fs.h
+0
-2
include/linux/nfs_xdr.h
include/linux/nfs_xdr.h
+4
-4
No files found.
fs/nfs/direct.c
View file @
b1355604
...
@@ -259,6 +259,7 @@ nfs_direct_write_seg(struct inode *inode, struct file *file,
...
@@ -259,6 +259,7 @@ nfs_direct_write_seg(struct inode *inode, struct file *file,
.
inode
=
inode
,
.
inode
=
inode
,
.
args
=
{
.
args
=
{
.
fh
=
NFS_FH
(
inode
),
.
fh
=
NFS_FH
(
inode
),
.
lockowner
=
current
->
files
,
},
},
.
res
=
{
.
res
=
{
.
fattr
=
&
wdata
.
fattr
,
.
fattr
=
&
wdata
.
fattr
,
...
...
fs/nfs/nfs3proc.c
View file @
b1355604
...
@@ -763,11 +763,10 @@ nfs3_write_done(struct rpc_task *task)
...
@@ -763,11 +763,10 @@ nfs3_write_done(struct rpc_task *task)
}
}
static
void
static
void
nfs3_proc_write_setup
(
struct
nfs_write_data
*
data
,
unsigned
int
count
,
int
how
)
nfs3_proc_write_setup
(
struct
nfs_write_data
*
data
,
int
how
)
{
{
struct
rpc_task
*
task
=
&
data
->
task
;
struct
rpc_task
*
task
=
&
data
->
task
;
struct
inode
*
inode
=
data
->
inode
;
struct
inode
*
inode
=
data
->
inode
;
struct
nfs_page
*
req
;
int
stable
;
int
stable
;
int
flags
;
int
flags
;
struct
rpc_message
msg
=
{
struct
rpc_message
msg
=
{
...
@@ -784,28 +783,14 @@ nfs3_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
...
@@ -784,28 +783,14 @@ nfs3_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
stable
=
NFS_DATA_SYNC
;
stable
=
NFS_DATA_SYNC
;
}
else
}
else
stable
=
NFS_UNSTABLE
;
stable
=
NFS_UNSTABLE
;
req
=
nfs_list_entry
(
data
->
pages
.
next
);
data
->
args
.
fh
=
NFS_FH
(
inode
);
data
->
args
.
offset
=
req_offset
(
req
);
data
->
args
.
pgbase
=
req
->
wb_pgbase
;
data
->
args
.
count
=
count
;
data
->
args
.
stable
=
stable
;
data
->
args
.
stable
=
stable
;
data
->
args
.
pages
=
data
->
pagevec
;
data
->
res
.
fattr
=
&
data
->
fattr
;
data
->
res
.
count
=
count
;
data
->
res
.
verf
=
&
data
->
verf
;
/* Set the initial flags for the task. */
/* Set the initial flags for the task. */
flags
=
(
how
&
FLUSH_SYNC
)
?
0
:
RPC_TASK_ASYNC
;
flags
=
(
how
&
FLUSH_SYNC
)
?
0
:
RPC_TASK_ASYNC
;
/* Finalize the task. */
/* Finalize the task. */
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs3_write_done
,
flags
);
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs3_write_done
,
flags
);
task
->
tk_calldata
=
data
;
rpc_call_setup
(
task
,
&
msg
,
0
);
/* Release requests */
task
->
tk_release
=
nfs_writedata_release
;
rpc_call_setup
(
&
data
->
task
,
&
msg
,
0
);
}
}
static
void
static
void
...
@@ -822,7 +807,7 @@ nfs3_commit_done(struct rpc_task *task)
...
@@ -822,7 +807,7 @@ nfs3_commit_done(struct rpc_task *task)
}
}
static
void
static
void
nfs3_proc_commit_setup
(
struct
nfs_write_data
*
data
,
u64
start
,
u32
len
,
int
how
)
nfs3_proc_commit_setup
(
struct
nfs_write_data
*
data
,
int
how
)
{
{
struct
rpc_task
*
task
=
&
data
->
task
;
struct
rpc_task
*
task
=
&
data
->
task
;
struct
inode
*
inode
=
data
->
inode
;
struct
inode
*
inode
=
data
->
inode
;
...
@@ -834,23 +819,12 @@ nfs3_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how)
...
@@ -834,23 +819,12 @@ nfs3_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how)
.
rpc_cred
=
data
->
cred
,
.
rpc_cred
=
data
->
cred
,
};
};
data
->
args
.
fh
=
NFS_FH
(
data
->
inode
);
data
->
args
.
offset
=
start
;
data
->
args
.
count
=
len
;
data
->
res
.
count
=
len
;
data
->
res
.
fattr
=
&
data
->
fattr
;
data
->
res
.
verf
=
&
data
->
verf
;
/* Set the initial flags for the task. */
/* Set the initial flags for the task. */
flags
=
(
how
&
FLUSH_SYNC
)
?
0
:
RPC_TASK_ASYNC
;
flags
=
(
how
&
FLUSH_SYNC
)
?
0
:
RPC_TASK_ASYNC
;
/* Finalize the task. */
/* Finalize the task. */
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs3_commit_done
,
flags
);
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs3_commit_done
,
flags
);
task
->
tk_calldata
=
data
;
rpc_call_setup
(
task
,
&
msg
,
0
);
/* Release requests */
task
->
tk_release
=
nfs_commit_release
;
rpc_call_setup
(
&
data
->
task
,
&
msg
,
0
);
}
}
/*
/*
...
...
fs/nfs/nfs4proc.c
View file @
b1355604
...
@@ -1134,10 +1134,10 @@ nfs4_proc_write(struct nfs_write_data *wdata, struct file *filp)
...
@@ -1134,10 +1134,10 @@ nfs4_proc_write(struct nfs_write_data *wdata, struct file *filp)
if
(
filp
)
{
if
(
filp
)
{
struct
nfs4_state
*
state
;
struct
nfs4_state
*
state
;
state
=
(
struct
nfs4_state
*
)
filp
->
private_data
;
state
=
(
struct
nfs4_state
*
)
filp
->
private_data
;
nfs4_copy_stateid
(
&
wdata
->
args
.
stateid
,
state
,
wdata
->
lockowner
)
;
wdata
->
args
.
state
=
state
;
msg
.
rpc_cred
=
state
->
owner
->
so_cred
;
msg
.
rpc_cred
=
state
->
owner
->
so_cred
;
}
else
{
}
else
{
memcpy
(
&
wdata
->
args
.
stateid
,
&
zero_stateid
,
sizeof
(
wdata
->
args
.
stateid
))
;
wdata
->
args
.
state
=
NULL
;
msg
.
rpc_cred
=
NFS_I
(
inode
)
->
mm_cred
;
msg
.
rpc_cred
=
NFS_I
(
inode
)
->
mm_cred
;
}
}
...
@@ -1166,15 +1166,10 @@ nfs4_proc_commit(struct nfs_write_data *cdata, struct file *filp)
...
@@ -1166,15 +1166,10 @@ nfs4_proc_commit(struct nfs_write_data *cdata, struct file *filp)
/*
/*
* Try first to use O_WRONLY, then O_RDWR stateid.
* Try first to use O_WRONLY, then O_RDWR stateid.
*/
*/
if
(
filp
)
{
if
(
filp
)
struct
nfs4_state
*
state
;
msg
.
rpc_cred
=
((
struct
nfs4_state
*
)
filp
->
private_data
)
->
owner
->
so_cred
;
state
=
(
struct
nfs4_state
*
)
filp
->
private_data
;
else
nfs4_copy_stateid
(
&
cdata
->
args
.
stateid
,
state
,
cdata
->
lockowner
);
msg
.
rpc_cred
=
state
->
owner
->
so_cred
;
}
else
{
memcpy
(
&
cdata
->
args
.
stateid
,
&
zero_stateid
,
sizeof
(
cdata
->
args
.
stateid
));
msg
.
rpc_cred
=
NFS_I
(
inode
)
->
mm_cred
;
msg
.
rpc_cred
=
NFS_I
(
inode
)
->
mm_cred
;
}
fattr
->
valid
=
0
;
fattr
->
valid
=
0
;
status
=
rpc_call_sync
(
server
->
client
,
&
msg
,
0
);
status
=
rpc_call_sync
(
server
->
client
,
&
msg
,
0
);
...
@@ -1548,20 +1543,6 @@ nfs4_proc_read_setup(struct nfs_read_data *data)
...
@@ -1548,20 +1543,6 @@ nfs4_proc_read_setup(struct nfs_read_data *data)
rpc_call_setup
(
task
,
&
msg
,
0
);
rpc_call_setup
(
task
,
&
msg
,
0
);
}
}
static
void
nfs4_restart_write
(
struct
rpc_task
*
task
)
{
struct
nfs_write_data
*
data
=
(
struct
nfs_write_data
*
)
task
->
tk_calldata
;
struct
nfs_page
*
req
;
rpc_restart_call
(
task
);
req
=
nfs_list_entry
(
data
->
pages
.
next
);
if
(
req
->
wb_state
)
nfs4_copy_stateid
(
&
data
->
args
.
stateid
,
req
->
wb_state
,
req
->
wb_lockowner
);
else
memcpy
(
&
data
->
args
.
stateid
,
&
zero_stateid
,
sizeof
(
data
->
args
.
stateid
));
}
static
void
static
void
nfs4_write_done
(
struct
rpc_task
*
task
)
nfs4_write_done
(
struct
rpc_task
*
task
)
{
{
...
@@ -1569,7 +1550,7 @@ nfs4_write_done(struct rpc_task *task)
...
@@ -1569,7 +1550,7 @@ nfs4_write_done(struct rpc_task *task)
struct
inode
*
inode
=
data
->
inode
;
struct
inode
*
inode
=
data
->
inode
;
if
(
nfs4_async_handle_error
(
task
,
NFS_SERVER
(
inode
))
==
-
EAGAIN
)
{
if
(
nfs4_async_handle_error
(
task
,
NFS_SERVER
(
inode
))
==
-
EAGAIN
)
{
task
->
tk_action
=
nfs4_restart_write
;
rpc_restart_call
(
task
)
;
return
;
return
;
}
}
if
(
task
->
tk_status
>=
0
)
if
(
task
->
tk_status
>=
0
)
...
@@ -1579,7 +1560,7 @@ nfs4_write_done(struct rpc_task *task)
...
@@ -1579,7 +1560,7 @@ nfs4_write_done(struct rpc_task *task)
}
}
static
void
static
void
nfs4_proc_write_setup
(
struct
nfs_write_data
*
data
,
unsigned
int
count
,
int
how
)
nfs4_proc_write_setup
(
struct
nfs_write_data
*
data
,
int
how
)
{
{
struct
rpc_task
*
task
=
&
data
->
task
;
struct
rpc_task
*
task
=
&
data
->
task
;
struct
rpc_message
msg
=
{
struct
rpc_message
msg
=
{
...
@@ -1589,7 +1570,6 @@ nfs4_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
...
@@ -1589,7 +1570,6 @@ nfs4_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
.
rpc_cred
=
data
->
cred
,
.
rpc_cred
=
data
->
cred
,
};
};
struct
inode
*
inode
=
data
->
inode
;
struct
inode
*
inode
=
data
->
inode
;
struct
nfs_page
*
req
=
nfs_list_entry
(
data
->
pages
.
next
);
int
stable
;
int
stable
;
int
flags
;
int
flags
;
...
@@ -1600,33 +1580,15 @@ nfs4_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
...
@@ -1600,33 +1580,15 @@ nfs4_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
stable
=
NFS_DATA_SYNC
;
stable
=
NFS_DATA_SYNC
;
}
else
}
else
stable
=
NFS_UNSTABLE
;
stable
=
NFS_UNSTABLE
;
data
->
args
.
fh
=
NFS_FH
(
inode
);
data
->
args
.
offset
=
req_offset
(
req
);
data
->
args
.
pgbase
=
req
->
wb_pgbase
;
data
->
args
.
count
=
count
;
data
->
args
.
stable
=
stable
;
data
->
args
.
stable
=
stable
;
data
->
args
.
pages
=
data
->
pagevec
;
data
->
res
.
fattr
=
&
data
->
fattr
;
data
->
res
.
count
=
count
;
data
->
res
.
verf
=
&
data
->
verf
;
data
->
timestamp
=
jiffies
;
data
->
lockowner
=
req
->
wb_lockowner
;
data
->
timestamp
=
jiffies
;
if
(
req
->
wb_state
)
nfs4_copy_stateid
(
&
data
->
args
.
stateid
,
req
->
wb_state
,
req
->
wb_lockowner
);
else
memcpy
(
&
data
->
args
.
stateid
,
&
zero_stateid
,
sizeof
(
data
->
args
.
stateid
));
/* Set the initial flags for the task. */
/* Set the initial flags for the task. */
flags
=
(
how
&
FLUSH_SYNC
)
?
0
:
RPC_TASK_ASYNC
;
flags
=
(
how
&
FLUSH_SYNC
)
?
0
:
RPC_TASK_ASYNC
;
/* Finalize the task. */
/* Finalize the task. */
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs4_write_done
,
flags
);
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs4_write_done
,
flags
);
task
->
tk_calldata
=
data
;
/* Release requests */
task
->
tk_release
=
nfs_writedata_release
;
rpc_call_setup
(
task
,
&
msg
,
0
);
rpc_call_setup
(
task
,
&
msg
,
0
);
}
}
...
@@ -1637,7 +1599,7 @@ nfs4_commit_done(struct rpc_task *task)
...
@@ -1637,7 +1599,7 @@ nfs4_commit_done(struct rpc_task *task)
struct
inode
*
inode
=
data
->
inode
;
struct
inode
*
inode
=
data
->
inode
;
if
(
nfs4_async_handle_error
(
task
,
NFS_SERVER
(
inode
))
==
-
EAGAIN
)
{
if
(
nfs4_async_handle_error
(
task
,
NFS_SERVER
(
inode
))
==
-
EAGAIN
)
{
task
->
tk_action
=
nfs4_restart_write
;
rpc_restart_call
(
task
)
;
return
;
return
;
}
}
/* Call back common NFS writeback processing */
/* Call back common NFS writeback processing */
...
@@ -1645,7 +1607,7 @@ nfs4_commit_done(struct rpc_task *task)
...
@@ -1645,7 +1607,7 @@ nfs4_commit_done(struct rpc_task *task)
}
}
static
void
static
void
nfs4_proc_commit_setup
(
struct
nfs_write_data
*
data
,
u64
start
,
u32
len
,
int
how
)
nfs4_proc_commit_setup
(
struct
nfs_write_data
*
data
,
int
how
)
{
{
struct
rpc_task
*
task
=
&
data
->
task
;
struct
rpc_task
*
task
=
&
data
->
task
;
struct
rpc_message
msg
=
{
struct
rpc_message
msg
=
{
...
@@ -1657,22 +1619,11 @@ nfs4_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how)
...
@@ -1657,22 +1619,11 @@ nfs4_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how)
struct
inode
*
inode
=
data
->
inode
;
struct
inode
*
inode
=
data
->
inode
;
int
flags
;
int
flags
;
data
->
args
.
fh
=
NFS_FH
(
data
->
inode
);
data
->
args
.
offset
=
start
;
data
->
args
.
count
=
len
;
data
->
res
.
count
=
len
;
data
->
res
.
fattr
=
&
data
->
fattr
;
data
->
res
.
verf
=
&
data
->
verf
;
/* Set the initial flags for the task. */
/* Set the initial flags for the task. */
flags
=
(
how
&
FLUSH_SYNC
)
?
0
:
RPC_TASK_ASYNC
;
flags
=
(
how
&
FLUSH_SYNC
)
?
0
:
RPC_TASK_ASYNC
;
/* Finalize the task. */
/* Finalize the task. */
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs4_commit_done
,
flags
);
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs4_commit_done
,
flags
);
task
->
tk_calldata
=
data
;
/* Release requests */
task
->
tk_release
=
nfs_commit_release
;
rpc_call_setup
(
task
,
&
msg
,
0
);
rpc_call_setup
(
task
,
&
msg
,
0
);
}
}
...
...
fs/nfs/nfs4xdr.c
View file @
b1355604
...
@@ -1075,9 +1075,12 @@ encode_write(struct xdr_stream *xdr, struct nfs_writeargs *args)
...
@@ -1075,9 +1075,12 @@ encode_write(struct xdr_stream *xdr, struct nfs_writeargs *args)
{
{
uint32_t
*
p
;
uint32_t
*
p
;
RESERVE_SPACE
(
36
);
RESERVE_SPACE
(
4
);
WRITE32
(
OP_WRITE
);
WRITE32
(
OP_WRITE
);
WRITEMEM
(
args
->
stateid
.
data
,
sizeof
(
args
->
stateid
.
data
));
encode_stateid
(
xdr
,
args
->
state
,
args
->
lockowner
);
RESERVE_SPACE
(
16
);
WRITE64
(
args
->
offset
);
WRITE64
(
args
->
offset
);
WRITE32
(
args
->
stable
);
WRITE32
(
args
->
stable
);
WRITE32
(
args
->
count
);
WRITE32
(
args
->
count
);
...
...
fs/nfs/proc.c
View file @
b1355604
...
@@ -590,11 +590,10 @@ nfs_write_done(struct rpc_task *task)
...
@@ -590,11 +590,10 @@ nfs_write_done(struct rpc_task *task)
}
}
static
void
static
void
nfs_proc_write_setup
(
struct
nfs_write_data
*
data
,
unsigned
int
count
,
int
how
)
nfs_proc_write_setup
(
struct
nfs_write_data
*
data
,
int
how
)
{
{
struct
rpc_task
*
task
=
&
data
->
task
;
struct
rpc_task
*
task
=
&
data
->
task
;
struct
inode
*
inode
=
data
->
inode
;
struct
inode
*
inode
=
data
->
inode
;
struct
nfs_page
*
req
;
int
flags
;
int
flags
;
struct
rpc_message
msg
=
{
struct
rpc_message
msg
=
{
.
rpc_proc
=
&
nfs_procedures
[
NFSPROC_WRITE
],
.
rpc_proc
=
&
nfs_procedures
[
NFSPROC_WRITE
],
...
@@ -604,32 +603,18 @@ nfs_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
...
@@ -604,32 +603,18 @@ nfs_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
};
};
/* Note: NFSv2 ignores @stable and always uses NFS_FILE_SYNC */
/* Note: NFSv2 ignores @stable and always uses NFS_FILE_SYNC */
req
=
nfs_list_entry
(
data
->
pages
.
next
);
data
->
args
.
fh
=
NFS_FH
(
inode
);
data
->
args
.
offset
=
req_offset
(
req
);
data
->
args
.
pgbase
=
req
->
wb_pgbase
;
data
->
args
.
count
=
count
;
data
->
args
.
stable
=
NFS_FILE_SYNC
;
data
->
args
.
stable
=
NFS_FILE_SYNC
;
data
->
args
.
pages
=
data
->
pagevec
;
data
->
res
.
fattr
=
&
data
->
fattr
;
data
->
res
.
count
=
count
;
data
->
res
.
verf
=
&
data
->
verf
;
/* Set the initial flags for the task. */
/* Set the initial flags for the task. */
flags
=
(
how
&
FLUSH_SYNC
)
?
0
:
RPC_TASK_ASYNC
;
flags
=
(
how
&
FLUSH_SYNC
)
?
0
:
RPC_TASK_ASYNC
;
/* Finalize the task. */
/* Finalize the task. */
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs_write_done
,
flags
);
rpc_init_task
(
task
,
NFS_CLIENT
(
inode
),
nfs_write_done
,
flags
);
task
->
tk_calldata
=
data
;
rpc_call_setup
(
task
,
&
msg
,
0
);
/* Release requests */
task
->
tk_release
=
nfs_writedata_release
;
rpc_call_setup
(
&
data
->
task
,
&
msg
,
0
);
}
}
static
void
static
void
nfs_proc_commit_setup
(
struct
nfs_write_data
*
data
,
u64
start
,
u32
len
,
int
how
)
nfs_proc_commit_setup
(
struct
nfs_write_data
*
data
,
int
how
)
{
{
BUG
();
BUG
();
}
}
...
...
fs/nfs/write.c
View file @
b1355604
...
@@ -74,6 +74,8 @@
...
@@ -74,6 +74,8 @@
static
struct
nfs_page
*
nfs_update_request
(
struct
file
*
,
struct
inode
*
,
static
struct
nfs_page
*
nfs_update_request
(
struct
file
*
,
struct
inode
*
,
struct
page
*
,
struct
page
*
,
unsigned
int
,
unsigned
int
);
unsigned
int
,
unsigned
int
);
static
void
nfs_writeback_done_partial
(
struct
nfs_write_data
*
,
int
);
static
void
nfs_writeback_done_full
(
struct
nfs_write_data
*
,
int
);
static
kmem_cache_t
*
nfs_wdata_cachep
;
static
kmem_cache_t
*
nfs_wdata_cachep
;
static
mempool_t
*
nfs_wdata_mempool
;
static
mempool_t
*
nfs_wdata_mempool
;
...
@@ -95,7 +97,7 @@ static __inline__ void nfs_writedata_free(struct nfs_write_data *p)
...
@@ -95,7 +97,7 @@ static __inline__ void nfs_writedata_free(struct nfs_write_data *p)
mempool_free
(
p
,
nfs_wdata_mempool
);
mempool_free
(
p
,
nfs_wdata_mempool
);
}
}
void
nfs_writedata_release
(
struct
rpc_task
*
task
)
static
void
nfs_writedata_release
(
struct
rpc_task
*
task
)
{
{
struct
nfs_write_data
*
wdata
=
(
struct
nfs_write_data
*
)
task
->
tk_calldata
;
struct
nfs_write_data
*
wdata
=
(
struct
nfs_write_data
*
)
task
->
tk_calldata
;
nfs_writedata_free
(
wdata
);
nfs_writedata_free
(
wdata
);
...
@@ -117,12 +119,6 @@ static __inline__ void nfs_commit_free(struct nfs_write_data *p)
...
@@ -117,12 +119,6 @@ static __inline__ void nfs_commit_free(struct nfs_write_data *p)
mempool_free
(
p
,
nfs_commit_mempool
);
mempool_free
(
p
,
nfs_commit_mempool
);
}
}
void
nfs_commit_release
(
struct
rpc_task
*
task
)
{
struct
nfs_write_data
*
wdata
=
(
struct
nfs_write_data
*
)
task
->
tk_calldata
;
nfs_commit_free
(
wdata
);
}
/* Adjust the file length if we're writing beyond the end */
/* Adjust the file length if we're writing beyond the end */
static
void
nfs_grow_file
(
struct
page
*
page
,
unsigned
int
offset
,
unsigned
int
count
)
static
void
nfs_grow_file
(
struct
page
*
page
,
unsigned
int
offset
,
unsigned
int
count
)
{
{
...
@@ -186,6 +182,7 @@ nfs_writepage_sync(struct file *file, struct inode *inode, struct page *page,
...
@@ -186,6 +182,7 @@ nfs_writepage_sync(struct file *file, struct inode *inode, struct page *page,
.
inode
=
inode
,
.
inode
=
inode
,
.
args
=
{
.
args
=
{
.
fh
=
NFS_FH
(
inode
),
.
fh
=
NFS_FH
(
inode
),
.
lockowner
=
current
->
files
,
.
pages
=
&
page
,
.
pages
=
&
page
,
.
stable
=
NFS_FILE_SYNC
,
.
stable
=
NFS_FILE_SYNC
,
.
pgbase
=
offset
,
.
pgbase
=
offset
,
...
@@ -299,8 +296,7 @@ nfs_writepage(struct page *page, struct writeback_control *wbc)
...
@@ -299,8 +296,7 @@ nfs_writepage(struct page *page, struct writeback_control *wbc)
goto
out
;
goto
out
;
do_it:
do_it:
lock_kernel
();
lock_kernel
();
if
(
NFS_SERVER
(
inode
)
->
wsize
>=
PAGE_CACHE_SIZE
&&
!
IS_SYNC
(
inode
)
&&
if
(
!
IS_SYNC
(
inode
)
&&
inode_referenced
)
{
inode_referenced
)
{
err
=
nfs_writepage_async
(
NULL
,
inode
,
page
,
0
,
offset
);
err
=
nfs_writepage_async
(
NULL
,
inode
,
page
,
0
,
offset
);
if
(
err
>=
0
)
if
(
err
>=
0
)
err
=
0
;
err
=
0
;
...
@@ -365,7 +361,7 @@ nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
...
@@ -365,7 +361,7 @@ nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
/*
/*
* Insert a write request into an inode
* Insert a write request into an inode
*/
*/
static
inline
void
static
void
nfs_inode_remove_request
(
struct
nfs_page
*
req
)
nfs_inode_remove_request
(
struct
nfs_page
*
req
)
{
{
struct
nfs_inode
*
nfsi
;
struct
nfs_inode
*
nfsi
;
...
@@ -416,7 +412,7 @@ nfs_find_request(struct inode *inode, unsigned long index)
...
@@ -416,7 +412,7 @@ nfs_find_request(struct inode *inode, unsigned long index)
/*
/*
* Add a request to the inode's dirty list.
* Add a request to the inode's dirty list.
*/
*/
static
inline
void
static
void
nfs_mark_request_dirty
(
struct
nfs_page
*
req
)
nfs_mark_request_dirty
(
struct
nfs_page
*
req
)
{
{
struct
inode
*
inode
=
req
->
wb_inode
;
struct
inode
*
inode
=
req
->
wb_inode
;
...
@@ -444,7 +440,7 @@ nfs_dirty_request(struct nfs_page *req)
...
@@ -444,7 +440,7 @@ nfs_dirty_request(struct nfs_page *req)
/*
/*
* Add a request to the inode's commit list.
* Add a request to the inode's commit list.
*/
*/
static
inline
void
static
void
nfs_mark_request_commit
(
struct
nfs_page
*
req
)
nfs_mark_request_commit
(
struct
nfs_page
*
req
)
{
{
struct
inode
*
inode
=
req
->
wb_inode
;
struct
inode
*
inode
=
req
->
wb_inode
;
...
@@ -680,11 +676,7 @@ nfs_updatepage(struct file *file, struct page *page, unsigned int offset, unsign
...
@@ -680,11 +676,7 @@ nfs_updatepage(struct file *file, struct page *page, unsigned int offset, unsign
dentry
->
d_parent
->
d_name
.
name
,
dentry
->
d_name
.
name
,
dentry
->
d_parent
->
d_name
.
name
,
dentry
->
d_name
.
name
,
count
,
(
long
long
)(
page_offset
(
page
)
+
offset
));
count
,
(
long
long
)(
page_offset
(
page
)
+
offset
));
/*
if
(
IS_SYNC
(
inode
))
{
* If wsize is smaller than page size, update and write
* page synchronously.
*/
if
(
NFS_SERVER
(
inode
)
->
wsize
<
PAGE_CACHE_SIZE
||
IS_SYNC
(
inode
))
{
status
=
nfs_writepage_sync
(
file
,
inode
,
page
,
offset
,
count
);
status
=
nfs_writepage_sync
(
file
,
inode
,
page
,
offset
,
count
);
if
(
status
>
0
)
{
if
(
status
>
0
)
{
if
(
offset
==
0
&&
status
==
PAGE_CACHE_SIZE
)
if
(
offset
==
0
&&
status
==
PAGE_CACHE_SIZE
)
...
@@ -747,43 +739,149 @@ nfs_updatepage(struct file *file, struct page *page, unsigned int offset, unsign
...
@@ -747,43 +739,149 @@ nfs_updatepage(struct file *file, struct page *page, unsigned int offset, unsign
return
status
;
return
status
;
}
}
static
void
nfs_writepage_release
(
struct
nfs_page
*
req
)
{
end_page_writeback
(
req
->
wb_page
);
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
if
(
!
PageError
(
req
->
wb_page
))
{
if
(
NFS_NEED_RESCHED
(
req
))
{
nfs_mark_request_dirty
(
req
);
goto
out
;
}
else
if
(
NFS_NEED_COMMIT
(
req
))
{
nfs_mark_request_commit
(
req
);
goto
out
;
}
}
nfs_inode_remove_request
(
req
);
out:
nfs_clear_commit
(
req
);
nfs_clear_reschedule
(
req
);
#else
nfs_inode_remove_request
(
req
);
#endif
nfs_unlock_request
(
req
);
}
/*
/*
* Set up the argument/result storage required for the RPC call.
* Set up the argument/result storage required for the RPC call.
*/
*/
static
void
static
void
nfs_write_rpcsetup
(
struct
nfs_page
*
req
,
nfs_write_rpcsetup
(
struct
list_head
*
head
,
struct
nfs_write_data
*
data
,
int
how
)
struct
nfs_write_data
*
data
,
unsigned
int
count
,
unsigned
int
offset
,
int
how
)
{
{
struct
rpc_task
*
task
=
&
data
->
task
;
struct
rpc_task
*
task
=
&
data
->
task
;
struct
inode
*
inode
;
struct
inode
*
inode
;
struct
nfs_page
*
req
;
struct
page
**
pages
;
unsigned
int
count
;
/* Set up the RPC argument and reply structs
/* Set up the RPC argument and reply structs
* NB: take care not to mess about with data->commit et al. */
* NB: take care not to mess about with data->commit et al. */
pages
=
data
->
pagevec
;
data
->
req
=
req
;
count
=
0
;
while
(
!
list_empty
(
head
))
{
req
=
nfs_list_entry
(
head
->
next
);
nfs_list_remove_request
(
req
);
nfs_list_add_request
(
req
,
&
data
->
pages
);
SetPageWriteback
(
req
->
wb_page
);
*
pages
++
=
req
->
wb_page
;
count
+=
req
->
wb_bytes
;
}
req
=
nfs_list_entry
(
data
->
pages
.
next
);
data
->
inode
=
inode
=
req
->
wb_inode
;
data
->
inode
=
inode
=
req
->
wb_inode
;
data
->
cred
=
req
->
wb_cred
;
data
->
cred
=
req
->
wb_cred
;
NFS_PROTO
(
inode
)
->
write_setup
(
data
,
count
,
how
);
data
->
args
.
fh
=
NFS_FH
(
inode
);
data
->
args
.
offset
=
req_offset
(
req
)
+
offset
;
data
->
args
.
pgbase
=
req
->
wb_pgbase
+
offset
;
data
->
args
.
pages
=
data
->
pagevec
;
data
->
args
.
count
=
count
;
data
->
args
.
lockowner
=
req
->
wb_lockowner
;
data
->
args
.
state
=
req
->
wb_state
;
data
->
res
.
fattr
=
&
data
->
fattr
;
data
->
res
.
count
=
count
;
data
->
res
.
verf
=
&
data
->
verf
;
NFS_PROTO
(
inode
)
->
write_setup
(
data
,
how
);
data
->
task
.
tk_calldata
=
data
;
/* Release requests */
data
->
task
.
tk_release
=
nfs_writedata_release
;
dprintk
(
"NFS: %4d initiated write call (req %s/%Ld, %u bytes @ offset %Lu)
\n
"
,
dprintk
(
"NFS: %4d initiated write call (req %s/%Ld, %u bytes @ offset %Lu)
\n
"
,
task
->
tk_pid
,
task
->
tk_pid
,
inode
->
i_sb
->
s_id
,
inode
->
i_sb
->
s_id
,
(
long
long
)
NFS_FILEID
(
inode
),
(
long
long
)
NFS_FILEID
(
inode
),
count
,
count
,
(
unsigned
long
long
)
req_offset
(
req
));
(
unsigned
long
long
)
data
->
args
.
offset
);
}
static
void
nfs_execute_write
(
struct
nfs_write_data
*
data
)
{
struct
rpc_clnt
*
clnt
=
NFS_CLIENT
(
data
->
inode
);
sigset_t
oldset
;
rpc_clnt_sigmask
(
clnt
,
&
oldset
);
lock_kernel
();
rpc_execute
(
&
data
->
task
);
unlock_kernel
();
rpc_clnt_sigunmask
(
clnt
,
&
oldset
);
}
/*
* Generate multiple small requests to write out a single
* contiguous dirty area on one page.
*/
static
int
nfs_flush_multi
(
struct
list_head
*
head
,
struct
inode
*
inode
,
int
how
)
{
struct
nfs_page
*
req
=
nfs_list_entry
(
head
->
next
);
struct
page
*
page
=
req
->
wb_page
;
struct
nfs_write_data
*
data
;
unsigned
int
wsize
=
NFS_SERVER
(
inode
)
->
wsize
;
unsigned
int
nbytes
,
offset
;
int
requests
=
0
;
LIST_HEAD
(
list
);
nfs_list_remove_request
(
req
);
nbytes
=
req
->
wb_bytes
;
for
(;;)
{
data
=
nfs_writedata_alloc
();
if
(
!
data
)
goto
out_bad
;
list_add
(
&
data
->
pages
,
&
list
);
requests
++
;
if
(
nbytes
<=
wsize
)
break
;
nbytes
-=
wsize
;
}
atomic_set
(
&
req
->
wb_complete
,
requests
);
ClearPageError
(
page
);
SetPageWriteback
(
page
);
offset
=
0
;
nbytes
=
req
->
wb_bytes
;
do
{
data
=
list_entry
(
list
.
next
,
struct
nfs_write_data
,
pages
);
list_del_init
(
&
data
->
pages
);
data
->
pagevec
[
0
]
=
page
;
data
->
complete
=
nfs_writeback_done_partial
;
if
(
nbytes
>
wsize
)
{
nfs_write_rpcsetup
(
req
,
data
,
wsize
,
offset
,
how
);
offset
+=
wsize
;
nbytes
-=
wsize
;
}
else
{
nfs_write_rpcsetup
(
req
,
data
,
nbytes
,
offset
,
how
);
nbytes
=
0
;
}
nfs_execute_write
(
data
);
}
while
(
nbytes
!=
0
);
return
0
;
out_bad:
while
(
!
list_empty
(
&
list
))
{
data
=
list_entry
(
list
.
next
,
struct
nfs_write_data
,
pages
);
list_del
(
&
data
->
pages
);
nfs_writedata_free
(
data
);
}
nfs_mark_request_dirty
(
req
);
nfs_unlock_request
(
req
);
return
-
ENOMEM
;
}
}
/*
/*
...
@@ -794,25 +892,38 @@ nfs_write_rpcsetup(struct list_head *head, struct nfs_write_data *data, int how)
...
@@ -794,25 +892,38 @@ nfs_write_rpcsetup(struct list_head *head, struct nfs_write_data *data, int how)
* This is the case if nfs_updatepage detects a conflicting request
* This is the case if nfs_updatepage detects a conflicting request
* that has been written but not committed.
* that has been written but not committed.
*/
*/
static
int
static
int
nfs_flush_one
(
struct
list_head
*
head
,
struct
inode
*
inode
,
int
how
)
nfs_flush_one
(
struct
list_head
*
head
,
struct
inode
*
inode
,
int
how
)
{
{
struct
rpc_clnt
*
clnt
=
NFS_CLIENT
(
inode
);
struct
nfs_page
*
req
;
struct
page
**
pages
;
struct
nfs_write_data
*
data
;
struct
nfs_write_data
*
data
;
sigset_t
oldset
;
unsigned
int
count
;
if
(
NFS_SERVER
(
inode
)
->
wsize
<
PAGE_CACHE_SIZE
)
return
nfs_flush_multi
(
head
,
inode
,
how
);
data
=
nfs_writedata_alloc
();
data
=
nfs_writedata_alloc
();
if
(
!
data
)
if
(
!
data
)
goto
out_bad
;
goto
out_bad
;
pages
=
data
->
pagevec
;
count
=
0
;
while
(
!
list_empty
(
head
))
{
req
=
nfs_list_entry
(
head
->
next
);
nfs_list_remove_request
(
req
);
nfs_list_add_request
(
req
,
&
data
->
pages
);
ClearPageError
(
req
->
wb_page
);
SetPageWriteback
(
req
->
wb_page
);
*
pages
++
=
req
->
wb_page
;
count
+=
req
->
wb_bytes
;
}
req
=
nfs_list_entry
(
data
->
pages
.
next
);
data
->
complete
=
nfs_writeback_done_full
;
/* Set up the argument struct */
/* Set up the argument struct */
nfs_write_rpcsetup
(
head
,
data
,
how
);
nfs_write_rpcsetup
(
req
,
data
,
count
,
0
,
how
);
rpc_clnt_sigmask
(
clnt
,
&
oldset
);
nfs_execute_write
(
data
);
lock_kernel
();
rpc_execute
(
&
data
->
task
);
unlock_kernel
();
rpc_clnt_sigunmask
(
clnt
,
&
oldset
);
return
0
;
return
0
;
out_bad:
out_bad:
while
(
!
list_empty
(
head
))
{
while
(
!
list_empty
(
head
))
{
...
@@ -851,18 +962,107 @@ nfs_flush_list(struct list_head *head, int wpages, int how)
...
@@ -851,18 +962,107 @@ nfs_flush_list(struct list_head *head, int wpages, int how)
return
error
;
return
error
;
}
}
/*
* Handle a write reply that flushed part of a page.
*/
static
void
nfs_writeback_done_partial
(
struct
nfs_write_data
*
data
,
int
status
)
{
struct
nfs_page
*
req
=
data
->
req
;
struct
page
*
page
=
req
->
wb_page
;
dprintk
(
"NFS: write (%s/%Ld %d@%Ld)"
,
req
->
wb_inode
->
i_sb
->
s_id
,
(
long
long
)
NFS_FILEID
(
req
->
wb_inode
),
req
->
wb_bytes
,
(
long
long
)
req_offset
(
req
));
if
(
status
<
0
)
{
ClearPageUptodate
(
page
);
SetPageError
(
page
);
if
(
req
->
wb_file
)
req
->
wb_file
->
f_error
=
status
;
dprintk
(
", error = %d
\n
"
,
status
);
}
else
{
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
if
(
data
->
verf
.
committed
<
NFS_FILE_SYNC
)
{
if
(
!
NFS_NEED_COMMIT
(
req
))
{
nfs_defer_commit
(
req
);
memcpy
(
&
req
->
wb_verf
,
&
data
->
verf
,
sizeof
(
req
->
wb_verf
));
dprintk
(
" defer commit
\n
"
);
}
else
if
(
memcmp
(
&
req
->
wb_verf
,
&
data
->
verf
,
sizeof
(
req
->
wb_verf
)))
{
nfs_defer_reschedule
(
req
);
dprintk
(
" server reboot detected
\n
"
);
}
}
else
#endif
dprintk
(
" OK
\n
"
);
}
if
(
atomic_dec_and_test
(
&
req
->
wb_complete
))
nfs_writepage_release
(
req
);
}
/*
* Handle a write reply that flushes a whole page.
*
* FIXME: There is an inherent race with invalidate_inode_pages and
* writebacks since the page->count is kept > 1 for as long
* as the page has a write request pending.
*/
static
void
nfs_writeback_done_full
(
struct
nfs_write_data
*
data
,
int
status
)
{
struct
nfs_page
*
req
;
struct
page
*
page
;
/* Update attributes as result of writeback. */
while
(
!
list_empty
(
&
data
->
pages
))
{
req
=
nfs_list_entry
(
data
->
pages
.
next
);
nfs_list_remove_request
(
req
);
page
=
req
->
wb_page
;
dprintk
(
"NFS: write (%s/%Ld %d@%Ld)"
,
req
->
wb_inode
->
i_sb
->
s_id
,
(
long
long
)
NFS_FILEID
(
req
->
wb_inode
),
req
->
wb_bytes
,
(
long
long
)
req_offset
(
req
));
if
(
status
<
0
)
{
ClearPageUptodate
(
page
);
SetPageError
(
page
);
if
(
req
->
wb_file
)
req
->
wb_file
->
f_error
=
status
;
end_page_writeback
(
page
);
nfs_inode_remove_request
(
req
);
dprintk
(
", error = %d
\n
"
,
status
);
goto
next
;
}
end_page_writeback
(
page
);
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
if
(
data
->
args
.
stable
!=
NFS_UNSTABLE
||
data
->
verf
.
committed
==
NFS_FILE_SYNC
)
{
nfs_inode_remove_request
(
req
);
dprintk
(
" OK
\n
"
);
goto
next
;
}
memcpy
(
&
req
->
wb_verf
,
&
data
->
verf
,
sizeof
(
req
->
wb_verf
));
nfs_mark_request_commit
(
req
);
dprintk
(
" marked for commit
\n
"
);
#else
nfs_inode_remove_request
(
req
);
#endif
next:
nfs_unlock_request
(
req
);
}
}
/*
/*
* This function is called when the WRITE call is complete.
* This function is called when the WRITE call is complete.
*/
*/
void
void
nfs_writeback_done
(
struct
rpc_task
*
task
)
nfs_writeback_done
(
struct
rpc_task
*
task
)
{
{
struct
nfs_write_data
*
data
=
(
struct
nfs_write_data
*
)
task
->
tk_calldata
;
struct
nfs_write_data
*
data
=
(
struct
nfs_write_data
*
)
task
->
tk_calldata
;
struct
nfs_writeargs
*
argp
=
&
data
->
args
;
struct
nfs_writeargs
*
argp
=
&
data
->
args
;
struct
nfs_writeres
*
resp
=
&
data
->
res
;
struct
nfs_writeres
*
resp
=
&
data
->
res
;
struct
nfs_page
*
req
;
struct
page
*
page
;
dprintk
(
"NFS: %4d nfs_writeback_done (status %d)
\n
"
,
dprintk
(
"NFS: %4d nfs_writeback_done (status %d)
\n
"
,
task
->
tk_pid
,
task
->
tk_status
);
task
->
tk_pid
,
task
->
tk_status
);
...
@@ -904,53 +1104,22 @@ nfs_writeback_done(struct rpc_task *task)
...
@@ -904,53 +1104,22 @@ nfs_writeback_done(struct rpc_task *task)
/*
/*
* Process the nfs_page list
* Process the nfs_page list
*/
*/
while
(
!
list_empty
(
&
data
->
pages
))
{
data
->
complete
(
data
,
task
->
tk_status
);
req
=
nfs_list_entry
(
data
->
pages
.
next
);
}
nfs_list_remove_request
(
req
);
page
=
req
->
wb_page
;
dprintk
(
"NFS: write (%s/%Ld %d@%Ld)"
,
req
->
wb_inode
->
i_sb
->
s_id
,
(
long
long
)
NFS_FILEID
(
req
->
wb_inode
),
req
->
wb_bytes
,
(
long
long
)
req_offset
(
req
));
if
(
task
->
tk_status
<
0
)
{
ClearPageUptodate
(
page
);
SetPageError
(
page
);
if
(
req
->
wb_file
)
req
->
wb_file
->
f_error
=
task
->
tk_status
;
end_page_writeback
(
page
);
nfs_inode_remove_request
(
req
);
dprintk
(
", error = %d
\n
"
,
task
->
tk_status
);
goto
next
;
}
end_page_writeback
(
page
);
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
if
(
argp
->
stable
!=
NFS_UNSTABLE
||
data
->
verf
.
committed
==
NFS_FILE_SYNC
)
{
static
void
nfs_commit_release
(
struct
rpc_task
*
task
)
nfs_inode_remove_request
(
req
);
{
dprintk
(
" OK
\n
"
);
struct
nfs_write_data
*
wdata
=
(
struct
nfs_write_data
*
)
task
->
tk_calldata
;
goto
next
;
nfs_commit_free
(
wdata
);
}
memcpy
(
&
req
->
wb_verf
,
&
data
->
verf
,
sizeof
(
req
->
wb_verf
));
nfs_mark_request_commit
(
req
);
dprintk
(
" marked for commit
\n
"
);
#else
nfs_inode_remove_request
(
req
);
#endif
next:
nfs_unlock_request
(
req
);
}
}
}
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
/*
/*
* Set up the argument/result storage required for the RPC call.
* Set up the argument/result storage required for the RPC call.
*/
*/
static
void
static
void
nfs_commit_rpcsetup
(
struct
list_head
*
head
,
nfs_commit_rpcsetup
(
struct
list_head
*
head
,
struct
nfs_write_data
*
data
,
int
how
)
struct
nfs_write_data
*
data
,
int
how
)
{
{
struct
rpc_task
*
task
=
&
data
->
task
;
struct
rpc_task
*
task
=
&
data
->
task
;
struct
nfs_page
*
first
,
*
last
;
struct
nfs_page
*
first
,
*
last
;
...
@@ -979,7 +1148,18 @@ nfs_commit_rpcsetup(struct list_head *head, struct nfs_write_data *data, int how
...
@@ -979,7 +1148,18 @@ nfs_commit_rpcsetup(struct list_head *head, struct nfs_write_data *data, int how
data
->
inode
=
inode
;
data
->
inode
=
inode
;
data
->
cred
=
first
->
wb_cred
;
data
->
cred
=
first
->
wb_cred
;
NFS_PROTO
(
inode
)
->
commit_setup
(
data
,
start
,
len
,
how
);
data
->
args
.
fh
=
NFS_FH
(
data
->
inode
);
data
->
args
.
offset
=
start
;
data
->
args
.
count
=
len
;
data
->
res
.
count
=
len
;
data
->
res
.
fattr
=
&
data
->
fattr
;
data
->
res
.
verf
=
&
data
->
verf
;
NFS_PROTO
(
inode
)
->
commit_setup
(
data
,
how
);
data
->
task
.
tk_calldata
=
data
;
/* Release requests */
data
->
task
.
tk_release
=
nfs_commit_release
;
dprintk
(
"NFS: %4d initiated commit call
\n
"
,
task
->
tk_pid
);
dprintk
(
"NFS: %4d initiated commit call
\n
"
,
task
->
tk_pid
);
}
}
...
@@ -990,10 +1170,8 @@ nfs_commit_rpcsetup(struct list_head *head, struct nfs_write_data *data, int how
...
@@ -990,10 +1170,8 @@ nfs_commit_rpcsetup(struct list_head *head, struct nfs_write_data *data, int how
int
int
nfs_commit_list
(
struct
list_head
*
head
,
int
how
)
nfs_commit_list
(
struct
list_head
*
head
,
int
how
)
{
{
struct
rpc_clnt
*
clnt
;
struct
nfs_write_data
*
data
;
struct
nfs_write_data
*
data
;
struct
nfs_page
*
req
;
struct
nfs_page
*
req
;
sigset_t
oldset
;
data
=
nfs_commit_alloc
();
data
=
nfs_commit_alloc
();
...
@@ -1002,13 +1180,8 @@ nfs_commit_list(struct list_head *head, int how)
...
@@ -1002,13 +1180,8 @@ nfs_commit_list(struct list_head *head, int how)
/* Set up the argument struct */
/* Set up the argument struct */
nfs_commit_rpcsetup
(
head
,
data
,
how
);
nfs_commit_rpcsetup
(
head
,
data
,
how
);
clnt
=
NFS_CLIENT
(
data
->
inode
);
rpc_clnt_sigmask
(
clnt
,
&
oldset
);
nfs_execute_write
(
data
);
lock_kernel
();
rpc_execute
(
&
data
->
task
);
unlock_kernel
();
rpc_clnt_sigunmask
(
clnt
,
&
oldset
);
return
0
;
return
0
;
out_bad:
out_bad:
while
(
!
list_empty
(
head
))
{
while
(
!
list_empty
(
head
))
{
...
...
include/linux/nfs_fs.h
View file @
b1355604
...
@@ -335,10 +335,8 @@ extern int nfs_writepages(struct address_space *, struct writeback_control *);
...
@@ -335,10 +335,8 @@ extern int nfs_writepages(struct address_space *, struct writeback_control *);
extern
int
nfs_flush_incompatible
(
struct
file
*
file
,
struct
page
*
page
);
extern
int
nfs_flush_incompatible
(
struct
file
*
file
,
struct
page
*
page
);
extern
int
nfs_updatepage
(
struct
file
*
,
struct
page
*
,
unsigned
int
,
unsigned
int
);
extern
int
nfs_updatepage
(
struct
file
*
,
struct
page
*
,
unsigned
int
,
unsigned
int
);
extern
void
nfs_writeback_done
(
struct
rpc_task
*
task
);
extern
void
nfs_writeback_done
(
struct
rpc_task
*
task
);
extern
void
nfs_writedata_release
(
struct
rpc_task
*
task
);
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
extern
void
nfs_commit_release
(
struct
rpc_task
*
task
);
extern
void
nfs_commit_done
(
struct
rpc_task
*
);
extern
void
nfs_commit_done
(
struct
rpc_task
*
);
#endif
#endif
...
...
include/linux/nfs_xdr.h
View file @
b1355604
...
@@ -253,7 +253,8 @@ struct nfs_readres {
...
@@ -253,7 +253,8 @@ struct nfs_readres {
struct
nfs_writeargs
{
struct
nfs_writeargs
{
struct
nfs_fh
*
fh
;
struct
nfs_fh
*
fh
;
nfs4_stateid
stateid
;
fl_owner_t
lockowner
;
struct
nfs4_state
*
state
;
__u64
offset
;
__u64
offset
;
__u32
count
;
__u32
count
;
enum
nfs3_stable_how
stable
;
enum
nfs3_stable_how
stable
;
...
@@ -681,7 +682,6 @@ struct nfs_write_data {
...
@@ -681,7 +682,6 @@ struct nfs_write_data {
struct
rpc_task
task
;
struct
rpc_task
task
;
struct
inode
*
inode
;
struct
inode
*
inode
;
struct
rpc_cred
*
cred
;
struct
rpc_cred
*
cred
;
fl_owner_t
lockowner
;
struct
nfs_fattr
fattr
;
struct
nfs_fattr
fattr
;
struct
nfs_writeverf
verf
;
struct
nfs_writeverf
verf
;
struct
list_head
pages
;
/* Coalesced requests we wish to flush */
struct
list_head
pages
;
/* Coalesced requests we wish to flush */
...
@@ -742,8 +742,8 @@ struct nfs_rpc_ops {
...
@@ -742,8 +742,8 @@ struct nfs_rpc_ops {
struct
nfs_pathconf
*
);
struct
nfs_pathconf
*
);
u32
*
(
*
decode_dirent
)(
u32
*
,
struct
nfs_entry
*
,
int
plus
);
u32
*
(
*
decode_dirent
)(
u32
*
,
struct
nfs_entry
*
,
int
plus
);
void
(
*
read_setup
)
(
struct
nfs_read_data
*
);
void
(
*
read_setup
)
(
struct
nfs_read_data
*
);
void
(
*
write_setup
)
(
struct
nfs_write_data
*
,
unsigned
int
count
,
int
how
);
void
(
*
write_setup
)
(
struct
nfs_write_data
*
,
int
how
);
void
(
*
commit_setup
)
(
struct
nfs_write_data
*
,
u64
start
,
u32
len
,
int
how
);
void
(
*
commit_setup
)
(
struct
nfs_write_data
*
,
int
how
);
int
(
*
file_open
)
(
struct
inode
*
,
struct
file
*
);
int
(
*
file_open
)
(
struct
inode
*
,
struct
file
*
);
int
(
*
file_release
)
(
struct
inode
*
,
struct
file
*
);
int
(
*
file_release
)
(
struct
inode
*
,
struct
file
*
);
void
(
*
request_init
)(
struct
nfs_page
*
,
struct
file
*
);
void
(
*
request_init
)(
struct
nfs_page
*
,
struct
file
*
);
...
...
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