aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/write.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r--fs/nfs/write.c112
1 files changed, 66 insertions, 46 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 89527a487ed7..522efff3e2c5 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -196,7 +196,7 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
196 } 196 }
197 /* Update file length */ 197 /* Update file length */
198 nfs_grow_file(page, offset, count); 198 nfs_grow_file(page, offset, count);
199 nfs_unlock_request(req); 199 nfs_clear_page_tag_locked(req);
200 return 0; 200 return 0;
201} 201}
202 202
@@ -252,7 +252,6 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
252 struct page *page) 252 struct page *page)
253{ 253{
254 struct inode *inode = page->mapping->host; 254 struct inode *inode = page->mapping->host;
255 struct nfs_inode *nfsi = NFS_I(inode);
256 struct nfs_page *req; 255 struct nfs_page *req;
257 int ret; 256 int ret;
258 257
@@ -263,10 +262,10 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
263 spin_unlock(&inode->i_lock); 262 spin_unlock(&inode->i_lock);
264 return 0; 263 return 0;
265 } 264 }
266 if (nfs_lock_request_dontget(req)) 265 if (nfs_set_page_tag_locked(req))
267 break; 266 break;
268 /* Note: If we hold the page lock, as is the case in nfs_writepage, 267 /* Note: If we hold the page lock, as is the case in nfs_writepage,
269 * then the call to nfs_lock_request_dontget() will always 268 * then the call to nfs_set_page_tag_locked() will always
270 * succeed provided that someone hasn't already marked the 269 * succeed provided that someone hasn't already marked the
271 * request as dirty (in which case we don't care). 270 * request as dirty (in which case we don't care).
272 */ 271 */
@@ -280,7 +279,7 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
280 if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) { 279 if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
281 /* This request is marked for commit */ 280 /* This request is marked for commit */
282 spin_unlock(&inode->i_lock); 281 spin_unlock(&inode->i_lock);
283 nfs_unlock_request(req); 282 nfs_clear_page_tag_locked(req);
284 nfs_pageio_complete(pgio); 283 nfs_pageio_complete(pgio);
285 return 0; 284 return 0;
286 } 285 }
@@ -288,8 +287,6 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
288 spin_unlock(&inode->i_lock); 287 spin_unlock(&inode->i_lock);
289 BUG(); 288 BUG();
290 } 289 }
291 radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index,
292 NFS_PAGE_TAG_LOCKED);
293 spin_unlock(&inode->i_lock); 290 spin_unlock(&inode->i_lock);
294 nfs_pageio_add_request(pgio, req); 291 nfs_pageio_add_request(pgio, req);
295 return 0; 292 return 0;
@@ -381,6 +378,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
381 set_page_private(req->wb_page, (unsigned long)req); 378 set_page_private(req->wb_page, (unsigned long)req);
382 nfsi->npages++; 379 nfsi->npages++;
383 kref_get(&req->wb_kref); 380 kref_get(&req->wb_kref);
381 radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
384 return 0; 382 return 0;
385} 383}
386 384
@@ -490,7 +488,7 @@ int nfs_reschedule_unstable_write(struct nfs_page *req)
490/* 488/*
491 * Wait for a request to complete. 489 * Wait for a request to complete.
492 * 490 *
493 * Interruptible by signals only if mounted with intr flag. 491 * Interruptible by fatal signals only.
494 */ 492 */
495static int nfs_wait_on_requests_locked(struct inode *inode, pgoff_t idx_start, unsigned int npages) 493static int nfs_wait_on_requests_locked(struct inode *inode, pgoff_t idx_start, unsigned int npages)
496{ 494{
@@ -596,7 +594,7 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
596 spin_lock(&inode->i_lock); 594 spin_lock(&inode->i_lock);
597 req = nfs_page_find_request_locked(page); 595 req = nfs_page_find_request_locked(page);
598 if (req) { 596 if (req) {
599 if (!nfs_lock_request_dontget(req)) { 597 if (!nfs_set_page_tag_locked(req)) {
600 int error; 598 int error;
601 599
602 spin_unlock(&inode->i_lock); 600 spin_unlock(&inode->i_lock);
@@ -646,7 +644,7 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
646 || req->wb_page != page 644 || req->wb_page != page
647 || !nfs_dirty_request(req) 645 || !nfs_dirty_request(req)
648 || offset > rqend || end < req->wb_offset) { 646 || offset > rqend || end < req->wb_offset) {
649 nfs_unlock_request(req); 647 nfs_clear_page_tag_locked(req);
650 return ERR_PTR(-EBUSY); 648 return ERR_PTR(-EBUSY);
651 } 649 }
652 650
@@ -755,7 +753,7 @@ static void nfs_writepage_release(struct nfs_page *req)
755 nfs_clear_page_tag_locked(req); 753 nfs_clear_page_tag_locked(req);
756} 754}
757 755
758static inline int flush_task_priority(int how) 756static int flush_task_priority(int how)
759{ 757{
760 switch (how & (FLUSH_HIGHPRI|FLUSH_LOWPRI)) { 758 switch (how & (FLUSH_HIGHPRI|FLUSH_LOWPRI)) {
761 case FLUSH_HIGHPRI: 759 case FLUSH_HIGHPRI:
@@ -775,15 +773,31 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
775 unsigned int count, unsigned int offset, 773 unsigned int count, unsigned int offset,
776 int how) 774 int how)
777{ 775{
778 struct inode *inode; 776 struct inode *inode = req->wb_context->path.dentry->d_inode;
779 int flags; 777 int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
778 int priority = flush_task_priority(how);
779 struct rpc_task *task;
780 struct rpc_message msg = {
781 .rpc_argp = &data->args,
782 .rpc_resp = &data->res,
783 .rpc_cred = req->wb_context->cred,
784 };
785 struct rpc_task_setup task_setup_data = {
786 .rpc_client = NFS_CLIENT(inode),
787 .task = &data->task,
788 .rpc_message = &msg,
789 .callback_ops = call_ops,
790 .callback_data = data,
791 .flags = flags,
792 .priority = priority,
793 };
780 794
781 /* Set up the RPC argument and reply structs 795 /* Set up the RPC argument and reply structs
782 * NB: take care not to mess about with data->commit et al. */ 796 * NB: take care not to mess about with data->commit et al. */
783 797
784 data->req = req; 798 data->req = req;
785 data->inode = inode = req->wb_context->path.dentry->d_inode; 799 data->inode = inode = req->wb_context->path.dentry->d_inode;
786 data->cred = req->wb_context->cred; 800 data->cred = msg.rpc_cred;
787 801
788 data->args.fh = NFS_FH(inode); 802 data->args.fh = NFS_FH(inode);
789 data->args.offset = req_offset(req) + offset; 803 data->args.offset = req_offset(req) + offset;
@@ -791,6 +805,12 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
791 data->args.pages = data->pagevec; 805 data->args.pages = data->pagevec;
792 data->args.count = count; 806 data->args.count = count;
793 data->args.context = req->wb_context; 807 data->args.context = req->wb_context;
808 data->args.stable = NFS_UNSTABLE;
809 if (how & FLUSH_STABLE) {
810 data->args.stable = NFS_DATA_SYNC;
811 if (!NFS_I(inode)->ncommit)
812 data->args.stable = NFS_FILE_SYNC;
813 }
794 814
795 data->res.fattr = &data->fattr; 815 data->res.fattr = &data->fattr;
796 data->res.count = count; 816 data->res.count = count;
@@ -798,12 +818,7 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
798 nfs_fattr_init(&data->fattr); 818 nfs_fattr_init(&data->fattr);
799 819
800 /* Set up the initial task struct. */ 820 /* Set up the initial task struct. */
801 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; 821 NFS_PROTO(inode)->write_setup(data, &msg);
802 rpc_init_task(&data->task, NFS_CLIENT(inode), flags, call_ops, data);
803 NFS_PROTO(inode)->write_setup(data, how);
804
805 data->task.tk_priority = flush_task_priority(how);
806 data->task.tk_cookie = (unsigned long)inode;
807 822
808 dprintk("NFS: %5u initiated write call " 823 dprintk("NFS: %5u initiated write call "
809 "(req %s/%Ld, %u bytes @ offset %Lu)\n", 824 "(req %s/%Ld, %u bytes @ offset %Lu)\n",
@@ -812,16 +827,10 @@ static void nfs_write_rpcsetup(struct nfs_page *req,
812 (long long)NFS_FILEID(inode), 827 (long long)NFS_FILEID(inode),
813 count, 828 count,
814 (unsigned long long)data->args.offset); 829 (unsigned long long)data->args.offset);
815}
816
817static void nfs_execute_write(struct nfs_write_data *data)
818{
819 struct rpc_clnt *clnt = NFS_CLIENT(data->inode);
820 sigset_t oldset;
821 830
822 rpc_clnt_sigmask(clnt, &oldset); 831 task = rpc_run_task(&task_setup_data);
823 rpc_execute(&data->task); 832 if (!IS_ERR(task))
824 rpc_clnt_sigunmask(clnt, &oldset); 833 rpc_put_task(task);
825} 834}
826 835
827/* 836/*
@@ -868,7 +877,6 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned
868 wsize, offset, how); 877 wsize, offset, how);
869 offset += wsize; 878 offset += wsize;
870 nbytes -= wsize; 879 nbytes -= wsize;
871 nfs_execute_write(data);
872 } while (nbytes != 0); 880 } while (nbytes != 0);
873 881
874 return 0; 882 return 0;
@@ -916,7 +924,6 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned i
916 /* Set up the argument struct */ 924 /* Set up the argument struct */
917 nfs_write_rpcsetup(req, data, &nfs_write_full_ops, count, 0, how); 925 nfs_write_rpcsetup(req, data, &nfs_write_full_ops, count, 0, how);
918 926
919 nfs_execute_write(data);
920 return 0; 927 return 0;
921 out_bad: 928 out_bad:
922 while (!list_empty(head)) { 929 while (!list_empty(head)) {
@@ -932,7 +939,7 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned i
932static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, 939static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
933 struct inode *inode, int ioflags) 940 struct inode *inode, int ioflags)
934{ 941{
935 int wsize = NFS_SERVER(inode)->wsize; 942 size_t wsize = NFS_SERVER(inode)->wsize;
936 943
937 if (wsize < PAGE_CACHE_SIZE) 944 if (wsize < PAGE_CACHE_SIZE)
938 nfs_pageio_init(pgio, inode, nfs_flush_multi, wsize, ioflags); 945 nfs_pageio_init(pgio, inode, nfs_flush_multi, wsize, ioflags);
@@ -1146,19 +1153,33 @@ static void nfs_commit_rpcsetup(struct list_head *head,
1146 struct nfs_write_data *data, 1153 struct nfs_write_data *data,
1147 int how) 1154 int how)
1148{ 1155{
1149 struct nfs_page *first; 1156 struct nfs_page *first = nfs_list_entry(head->next);
1150 struct inode *inode; 1157 struct inode *inode = first->wb_context->path.dentry->d_inode;
1151 int flags; 1158 int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
1159 int priority = flush_task_priority(how);
1160 struct rpc_task *task;
1161 struct rpc_message msg = {
1162 .rpc_argp = &data->args,
1163 .rpc_resp = &data->res,
1164 .rpc_cred = first->wb_context->cred,
1165 };
1166 struct rpc_task_setup task_setup_data = {
1167 .task = &data->task,
1168 .rpc_client = NFS_CLIENT(inode),
1169 .rpc_message = &msg,
1170 .callback_ops = &nfs_commit_ops,
1171 .callback_data = data,
1172 .flags = flags,
1173 .priority = priority,
1174 };
1152 1175
1153 /* Set up the RPC argument and reply structs 1176 /* Set up the RPC argument and reply structs
1154 * NB: take care not to mess about with data->commit et al. */ 1177 * NB: take care not to mess about with data->commit et al. */
1155 1178
1156 list_splice_init(head, &data->pages); 1179 list_splice_init(head, &data->pages);
1157 first = nfs_list_entry(data->pages.next);
1158 inode = first->wb_context->path.dentry->d_inode;
1159 1180
1160 data->inode = inode; 1181 data->inode = inode;
1161 data->cred = first->wb_context->cred; 1182 data->cred = msg.rpc_cred;
1162 1183
1163 data->args.fh = NFS_FH(data->inode); 1184 data->args.fh = NFS_FH(data->inode);
1164 /* Note: we always request a commit of the entire inode */ 1185 /* Note: we always request a commit of the entire inode */
@@ -1170,14 +1191,13 @@ static void nfs_commit_rpcsetup(struct list_head *head,
1170 nfs_fattr_init(&data->fattr); 1191 nfs_fattr_init(&data->fattr);
1171 1192
1172 /* Set up the initial task struct. */ 1193 /* Set up the initial task struct. */
1173 flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; 1194 NFS_PROTO(inode)->commit_setup(data, &msg);
1174 rpc_init_task(&data->task, NFS_CLIENT(inode), flags, &nfs_commit_ops, data);
1175 NFS_PROTO(inode)->commit_setup(data, how);
1176 1195
1177 data->task.tk_priority = flush_task_priority(how);
1178 data->task.tk_cookie = (unsigned long)inode;
1179
1180 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); 1196 dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid);
1197
1198 task = rpc_run_task(&task_setup_data);
1199 if (!IS_ERR(task))
1200 rpc_put_task(task);
1181} 1201}
1182 1202
1183/* 1203/*
@@ -1197,7 +1217,6 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
1197 /* Set up the argument struct */ 1217 /* Set up the argument struct */
1198 nfs_commit_rpcsetup(head, data, how); 1218 nfs_commit_rpcsetup(head, data, how);
1199 1219
1200 nfs_execute_write(data);
1201 return 0; 1220 return 0;
1202 out_bad: 1221 out_bad:
1203 while (!list_empty(head)) { 1222 while (!list_empty(head)) {
@@ -1436,7 +1455,8 @@ out:
1436 return ret; 1455 return ret;
1437} 1456}
1438 1457
1439int nfs_wb_page_priority(struct inode *inode, struct page *page, int how) 1458static int nfs_wb_page_priority(struct inode *inode, struct page *page,
1459 int how)
1440{ 1460{
1441 loff_t range_start = page_offset(page); 1461 loff_t range_start = page_offset(page);
1442 loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1); 1462 loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1);