diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-02 09:57:54 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-10 23:40:38 -0400 |
commit | 587142f85f796cf0b823dd3080e815f02ff6b952 (patch) | |
tree | 891e9389d09916ff2c307dc5ada1c65303660c8d /fs/nfs/write.c | |
parent | 4e56e082dd89266d320ccfbc7bd0102186a765ac (diff) |
NFS: Replace NFS_I(inode)->req_lock with inode->i_lock
There is no justification for keeping a special spinlock for the exclusive
use of the NFS writeback code.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 84 |
1 files changed, 40 insertions, 44 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 9ef9ec746bfb..73ac992ece85 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -124,12 +124,12 @@ static struct nfs_page *nfs_page_find_request_locked(struct page *page) | |||
124 | 124 | ||
125 | static struct nfs_page *nfs_page_find_request(struct page *page) | 125 | static struct nfs_page *nfs_page_find_request(struct page *page) |
126 | { | 126 | { |
127 | struct inode *inode = page->mapping->host; | ||
127 | struct nfs_page *req = NULL; | 128 | struct nfs_page *req = NULL; |
128 | spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock; | ||
129 | 129 | ||
130 | spin_lock(req_lock); | 130 | spin_lock(&inode->i_lock); |
131 | req = nfs_page_find_request_locked(page); | 131 | req = nfs_page_find_request_locked(page); |
132 | spin_unlock(req_lock); | 132 | spin_unlock(&inode->i_lock); |
133 | return req; | 133 | return req; |
134 | } | 134 | } |
135 | 135 | ||
@@ -251,16 +251,16 @@ static void nfs_end_page_writeback(struct page *page) | |||
251 | static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, | 251 | 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; | ||
255 | struct nfs_inode *nfsi = NFS_I(inode); | ||
254 | struct nfs_page *req; | 256 | struct nfs_page *req; |
255 | struct nfs_inode *nfsi = NFS_I(page->mapping->host); | ||
256 | spinlock_t *req_lock = &nfsi->req_lock; | ||
257 | int ret; | 257 | int ret; |
258 | 258 | ||
259 | spin_lock(req_lock); | 259 | spin_lock(&inode->i_lock); |
260 | for(;;) { | 260 | for(;;) { |
261 | req = nfs_page_find_request_locked(page); | 261 | req = nfs_page_find_request_locked(page); |
262 | if (req == NULL) { | 262 | if (req == NULL) { |
263 | spin_unlock(req_lock); | 263 | spin_unlock(&inode->i_lock); |
264 | return 1; | 264 | return 1; |
265 | } | 265 | } |
266 | if (nfs_lock_request_dontget(req)) | 266 | if (nfs_lock_request_dontget(req)) |
@@ -270,28 +270,28 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, | |||
270 | * succeed provided that someone hasn't already marked the | 270 | * succeed provided that someone hasn't already marked the |
271 | * request as dirty (in which case we don't care). | 271 | * request as dirty (in which case we don't care). |
272 | */ | 272 | */ |
273 | spin_unlock(req_lock); | 273 | spin_unlock(&inode->i_lock); |
274 | ret = nfs_wait_on_request(req); | 274 | ret = nfs_wait_on_request(req); |
275 | nfs_release_request(req); | 275 | nfs_release_request(req); |
276 | if (ret != 0) | 276 | if (ret != 0) |
277 | return ret; | 277 | return ret; |
278 | spin_lock(req_lock); | 278 | spin_lock(&inode->i_lock); |
279 | } | 279 | } |
280 | if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) { | 280 | if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) { |
281 | /* This request is marked for commit */ | 281 | /* This request is marked for commit */ |
282 | spin_unlock(req_lock); | 282 | spin_unlock(&inode->i_lock); |
283 | nfs_unlock_request(req); | 283 | nfs_unlock_request(req); |
284 | nfs_pageio_complete(pgio); | 284 | nfs_pageio_complete(pgio); |
285 | return 1; | 285 | return 1; |
286 | } | 286 | } |
287 | if (nfs_set_page_writeback(page) != 0) { | 287 | if (nfs_set_page_writeback(page) != 0) { |
288 | spin_unlock(req_lock); | 288 | spin_unlock(&inode->i_lock); |
289 | BUG(); | 289 | BUG(); |
290 | } | 290 | } |
291 | radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, | 291 | radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, |
292 | NFS_PAGE_TAG_LOCKED); | 292 | NFS_PAGE_TAG_LOCKED); |
293 | ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); | 293 | ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); |
294 | spin_unlock(req_lock); | 294 | spin_unlock(&inode->i_lock); |
295 | nfs_pageio_add_request(pgio, req); | 295 | nfs_pageio_add_request(pgio, req); |
296 | return ret; | 296 | return ret; |
297 | } | 297 | } |
@@ -412,7 +412,7 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
412 | 412 | ||
413 | BUG_ON (!NFS_WBACK_BUSY(req)); | 413 | BUG_ON (!NFS_WBACK_BUSY(req)); |
414 | 414 | ||
415 | spin_lock(&nfsi->req_lock); | 415 | spin_lock(&inode->i_lock); |
416 | set_page_private(req->wb_page, 0); | 416 | set_page_private(req->wb_page, 0); |
417 | ClearPagePrivate(req->wb_page); | 417 | ClearPagePrivate(req->wb_page); |
418 | radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); | 418 | radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); |
@@ -420,11 +420,11 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
420 | __set_page_dirty_nobuffers(req->wb_page); | 420 | __set_page_dirty_nobuffers(req->wb_page); |
421 | nfsi->npages--; | 421 | nfsi->npages--; |
422 | if (!nfsi->npages) { | 422 | if (!nfsi->npages) { |
423 | spin_unlock(&nfsi->req_lock); | 423 | spin_unlock(&inode->i_lock); |
424 | nfs_end_data_update(inode); | 424 | nfs_end_data_update(inode); |
425 | iput(inode); | 425 | iput(inode); |
426 | } else | 426 | } else |
427 | spin_unlock(&nfsi->req_lock); | 427 | spin_unlock(&inode->i_lock); |
428 | nfs_clear_request(req); | 428 | nfs_clear_request(req); |
429 | nfs_release_request(req); | 429 | nfs_release_request(req); |
430 | } | 430 | } |
@@ -458,13 +458,13 @@ nfs_mark_request_commit(struct nfs_page *req) | |||
458 | struct inode *inode = req->wb_context->path.dentry->d_inode; | 458 | struct inode *inode = req->wb_context->path.dentry->d_inode; |
459 | struct nfs_inode *nfsi = NFS_I(inode); | 459 | struct nfs_inode *nfsi = NFS_I(inode); |
460 | 460 | ||
461 | spin_lock(&nfsi->req_lock); | 461 | spin_lock(&inode->i_lock); |
462 | nfsi->ncommit++; | 462 | nfsi->ncommit++; |
463 | set_bit(PG_NEED_COMMIT, &(req)->wb_flags); | 463 | set_bit(PG_NEED_COMMIT, &(req)->wb_flags); |
464 | radix_tree_tag_set(&nfsi->nfs_page_tree, | 464 | radix_tree_tag_set(&nfsi->nfs_page_tree, |
465 | req->wb_index, | 465 | req->wb_index, |
466 | NFS_PAGE_TAG_COMMIT); | 466 | NFS_PAGE_TAG_COMMIT); |
467 | spin_unlock(&nfsi->req_lock); | 467 | spin_unlock(&inode->i_lock); |
468 | inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); | 468 | inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); |
469 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); | 469 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); |
470 | } | 470 | } |
@@ -534,10 +534,10 @@ static int nfs_wait_on_requests_locked(struct inode *inode, pgoff_t idx_start, u | |||
534 | BUG_ON(!NFS_WBACK_BUSY(req)); | 534 | BUG_ON(!NFS_WBACK_BUSY(req)); |
535 | 535 | ||
536 | kref_get(&req->wb_kref); | 536 | kref_get(&req->wb_kref); |
537 | spin_unlock(&nfsi->req_lock); | 537 | spin_unlock(&inode->i_lock); |
538 | error = nfs_wait_on_request(req); | 538 | error = nfs_wait_on_request(req); |
539 | nfs_release_request(req); | 539 | nfs_release_request(req); |
540 | spin_lock(&nfsi->req_lock); | 540 | spin_lock(&inode->i_lock); |
541 | if (error < 0) | 541 | if (error < 0) |
542 | return error; | 542 | return error; |
543 | res++; | 543 | res++; |
@@ -602,7 +602,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | |||
602 | { | 602 | { |
603 | struct address_space *mapping = page->mapping; | 603 | struct address_space *mapping = page->mapping; |
604 | struct inode *inode = mapping->host; | 604 | struct inode *inode = mapping->host; |
605 | struct nfs_inode *nfsi = NFS_I(inode); | ||
606 | struct nfs_page *req, *new = NULL; | 605 | struct nfs_page *req, *new = NULL; |
607 | pgoff_t rqend, end; | 606 | pgoff_t rqend, end; |
608 | 607 | ||
@@ -612,13 +611,13 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | |||
612 | /* Loop over all inode entries and see if we find | 611 | /* Loop over all inode entries and see if we find |
613 | * A request for the page we wish to update | 612 | * A request for the page we wish to update |
614 | */ | 613 | */ |
615 | spin_lock(&nfsi->req_lock); | 614 | spin_lock(&inode->i_lock); |
616 | req = nfs_page_find_request_locked(page); | 615 | req = nfs_page_find_request_locked(page); |
617 | if (req) { | 616 | if (req) { |
618 | if (!nfs_lock_request_dontget(req)) { | 617 | if (!nfs_lock_request_dontget(req)) { |
619 | int error; | 618 | int error; |
620 | 619 | ||
621 | spin_unlock(&nfsi->req_lock); | 620 | spin_unlock(&inode->i_lock); |
622 | error = nfs_wait_on_request(req); | 621 | error = nfs_wait_on_request(req); |
623 | nfs_release_request(req); | 622 | nfs_release_request(req); |
624 | if (error < 0) { | 623 | if (error < 0) { |
@@ -628,7 +627,7 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | |||
628 | } | 627 | } |
629 | continue; | 628 | continue; |
630 | } | 629 | } |
631 | spin_unlock(&nfsi->req_lock); | 630 | spin_unlock(&inode->i_lock); |
632 | if (new) | 631 | if (new) |
633 | nfs_release_request(new); | 632 | nfs_release_request(new); |
634 | break; | 633 | break; |
@@ -639,14 +638,14 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | |||
639 | nfs_lock_request_dontget(new); | 638 | nfs_lock_request_dontget(new); |
640 | error = nfs_inode_add_request(inode, new); | 639 | error = nfs_inode_add_request(inode, new); |
641 | if (error) { | 640 | if (error) { |
642 | spin_unlock(&nfsi->req_lock); | 641 | spin_unlock(&inode->i_lock); |
643 | nfs_unlock_request(new); | 642 | nfs_unlock_request(new); |
644 | return ERR_PTR(error); | 643 | return ERR_PTR(error); |
645 | } | 644 | } |
646 | spin_unlock(&nfsi->req_lock); | 645 | spin_unlock(&inode->i_lock); |
647 | return new; | 646 | return new; |
648 | } | 647 | } |
649 | spin_unlock(&nfsi->req_lock); | 648 | spin_unlock(&inode->i_lock); |
650 | 649 | ||
651 | new = nfs_create_request(ctx, inode, page, offset, bytes); | 650 | new = nfs_create_request(ctx, inode, page, offset, bytes); |
652 | if (IS_ERR(new)) | 651 | if (IS_ERR(new)) |
@@ -974,9 +973,9 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata) | |||
974 | } | 973 | } |
975 | 974 | ||
976 | if (nfs_write_need_commit(data)) { | 975 | if (nfs_write_need_commit(data)) { |
977 | spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock; | 976 | struct inode *inode = page->mapping->host; |
978 | 977 | ||
979 | spin_lock(req_lock); | 978 | spin_lock(&inode->i_lock); |
980 | if (test_bit(PG_NEED_RESCHED, &req->wb_flags)) { | 979 | if (test_bit(PG_NEED_RESCHED, &req->wb_flags)) { |
981 | /* Do nothing we need to resend the writes */ | 980 | /* Do nothing we need to resend the writes */ |
982 | } else if (!test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags)) { | 981 | } else if (!test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags)) { |
@@ -987,7 +986,7 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata) | |||
987 | clear_bit(PG_NEED_COMMIT, &req->wb_flags); | 986 | clear_bit(PG_NEED_COMMIT, &req->wb_flags); |
988 | dprintk(" server reboot detected\n"); | 987 | dprintk(" server reboot detected\n"); |
989 | } | 988 | } |
990 | spin_unlock(req_lock); | 989 | spin_unlock(&inode->i_lock); |
991 | } else | 990 | } else |
992 | dprintk(" OK\n"); | 991 | dprintk(" OK\n"); |
993 | 992 | ||
@@ -1277,13 +1276,12 @@ static const struct rpc_call_ops nfs_commit_ops = { | |||
1277 | 1276 | ||
1278 | int nfs_commit_inode(struct inode *inode, int how) | 1277 | int nfs_commit_inode(struct inode *inode, int how) |
1279 | { | 1278 | { |
1280 | struct nfs_inode *nfsi = NFS_I(inode); | ||
1281 | LIST_HEAD(head); | 1279 | LIST_HEAD(head); |
1282 | int res; | 1280 | int res; |
1283 | 1281 | ||
1284 | spin_lock(&nfsi->req_lock); | 1282 | spin_lock(&inode->i_lock); |
1285 | res = nfs_scan_commit(inode, &head, 0, 0); | 1283 | res = nfs_scan_commit(inode, &head, 0, 0); |
1286 | spin_unlock(&nfsi->req_lock); | 1284 | spin_unlock(&inode->i_lock); |
1287 | if (res) { | 1285 | if (res) { |
1288 | int error = nfs_commit_list(inode, &head, how); | 1286 | int error = nfs_commit_list(inode, &head, how); |
1289 | if (error < 0) | 1287 | if (error < 0) |
@@ -1301,7 +1299,6 @@ static inline int nfs_commit_list(struct inode *inode, struct list_head *head, i | |||
1301 | long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_control *wbc, int how) | 1299 | long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_control *wbc, int how) |
1302 | { | 1300 | { |
1303 | struct inode *inode = mapping->host; | 1301 | struct inode *inode = mapping->host; |
1304 | struct nfs_inode *nfsi = NFS_I(inode); | ||
1305 | pgoff_t idx_start, idx_end; | 1302 | pgoff_t idx_start, idx_end; |
1306 | unsigned int npages = 0; | 1303 | unsigned int npages = 0; |
1307 | LIST_HEAD(head); | 1304 | LIST_HEAD(head); |
@@ -1323,7 +1320,7 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr | |||
1323 | } | 1320 | } |
1324 | } | 1321 | } |
1325 | how &= ~FLUSH_NOCOMMIT; | 1322 | how &= ~FLUSH_NOCOMMIT; |
1326 | spin_lock(&nfsi->req_lock); | 1323 | spin_lock(&inode->i_lock); |
1327 | do { | 1324 | do { |
1328 | ret = nfs_wait_on_requests_locked(inode, idx_start, npages); | 1325 | ret = nfs_wait_on_requests_locked(inode, idx_start, npages); |
1329 | if (ret != 0) | 1326 | if (ret != 0) |
@@ -1334,18 +1331,19 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr | |||
1334 | if (pages == 0) | 1331 | if (pages == 0) |
1335 | break; | 1332 | break; |
1336 | if (how & FLUSH_INVALIDATE) { | 1333 | if (how & FLUSH_INVALIDATE) { |
1337 | spin_unlock(&nfsi->req_lock); | 1334 | spin_unlock(&inode->i_lock); |
1338 | nfs_cancel_commit_list(&head); | 1335 | nfs_cancel_commit_list(&head); |
1339 | ret = pages; | 1336 | ret = pages; |
1340 | spin_lock(&nfsi->req_lock); | 1337 | spin_lock(&inode->i_lock); |
1341 | continue; | 1338 | continue; |
1342 | } | 1339 | } |
1343 | pages += nfs_scan_commit(inode, &head, 0, 0); | 1340 | pages += nfs_scan_commit(inode, &head, 0, 0); |
1344 | spin_unlock(&nfsi->req_lock); | 1341 | spin_unlock(&inode->i_lock); |
1345 | ret = nfs_commit_list(inode, &head, how); | 1342 | ret = nfs_commit_list(inode, &head, how); |
1346 | spin_lock(&nfsi->req_lock); | 1343 | spin_lock(&inode->i_lock); |
1344 | |||
1347 | } while (ret >= 0); | 1345 | } while (ret >= 0); |
1348 | spin_unlock(&nfsi->req_lock); | 1346 | spin_unlock(&inode->i_lock); |
1349 | return ret; | 1347 | return ret; |
1350 | } | 1348 | } |
1351 | 1349 | ||
@@ -1439,7 +1437,6 @@ int nfs_set_page_dirty(struct page *page) | |||
1439 | { | 1437 | { |
1440 | struct address_space *mapping = page->mapping; | 1438 | struct address_space *mapping = page->mapping; |
1441 | struct inode *inode; | 1439 | struct inode *inode; |
1442 | spinlock_t *req_lock; | ||
1443 | struct nfs_page *req; | 1440 | struct nfs_page *req; |
1444 | int ret; | 1441 | int ret; |
1445 | 1442 | ||
@@ -1448,18 +1445,17 @@ int nfs_set_page_dirty(struct page *page) | |||
1448 | inode = mapping->host; | 1445 | inode = mapping->host; |
1449 | if (!inode) | 1446 | if (!inode) |
1450 | goto out_raced; | 1447 | goto out_raced; |
1451 | req_lock = &NFS_I(inode)->req_lock; | 1448 | spin_lock(&inode->i_lock); |
1452 | spin_lock(req_lock); | ||
1453 | req = nfs_page_find_request_locked(page); | 1449 | req = nfs_page_find_request_locked(page); |
1454 | if (req != NULL) { | 1450 | if (req != NULL) { |
1455 | /* Mark any existing write requests for flushing */ | 1451 | /* Mark any existing write requests for flushing */ |
1456 | ret = !test_and_set_bit(PG_NEED_FLUSH, &req->wb_flags); | 1452 | ret = !test_and_set_bit(PG_NEED_FLUSH, &req->wb_flags); |
1457 | spin_unlock(req_lock); | 1453 | spin_unlock(&inode->i_lock); |
1458 | nfs_release_request(req); | 1454 | nfs_release_request(req); |
1459 | return ret; | 1455 | return ret; |
1460 | } | 1456 | } |
1461 | ret = __set_page_dirty_nobuffers(page); | 1457 | ret = __set_page_dirty_nobuffers(page); |
1462 | spin_unlock(req_lock); | 1458 | spin_unlock(&inode->i_lock); |
1463 | return ret; | 1459 | return ret; |
1464 | out_raced: | 1460 | out_raced: |
1465 | return !TestSetPageDirty(page); | 1461 | return !TestSetPageDirty(page); |