aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2015-02-18 10:28:37 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-02-18 10:28:37 -0500
commit65d2918e716afb89359cfa59734d76c1ff8700cb (patch)
tree4685404f96642243d62c3a1a823340913d087090 /fs/nfs
parentbf40e5561fd288a505d5d8d8bf45eef96fe7253d (diff)
parent338d00cfef07d74a072f96821c64b20f98517d72 (diff)
Merge branch 'cleanups'
Merge cleanups requested by Linus. * cleanups: (3 commits) pnfs: Refactor the *_layout_mark_request_commit to use pnfs_layout_mark_request_commit nfs: Can call nfs_clear_page_commit() instead nfs: Provide and use helper functions for marking a page as unstable
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/delegation.c23
-rw-r--r--fs/nfs/file.c1
-rw-r--r--fs/nfs/filelayout/filelayout.c53
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayout.c43
-rw-r--r--fs/nfs/inode.c1
-rw-r--r--fs/nfs/internal.h14
-rw-r--r--fs/nfs/nfs4state.c70
-rw-r--r--fs/nfs/nfs4super.c1
-rw-r--r--fs/nfs/pagelist.c6
-rw-r--r--fs/nfs/pnfs.h4
-rw-r--r--fs/nfs/pnfs_nfs.c30
-rw-r--r--fs/nfs/super.c24
-rw-r--r--fs/nfs/write.c59
13 files changed, 161 insertions, 168 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 4464eb06b0b6..a1f0685b42ff 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -85,25 +85,30 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_
85{ 85{
86 struct inode *inode = state->inode; 86 struct inode *inode = state->inode;
87 struct file_lock *fl; 87 struct file_lock *fl;
88 struct file_lock_context *flctx = inode->i_flctx;
89 struct list_head *list;
88 int status = 0; 90 int status = 0;
89 91
90 if (inode->i_flock == NULL) 92 if (flctx == NULL)
91 goto out; 93 goto out;
92 94
93 /* Protect inode->i_flock using the i_lock */ 95 list = &flctx->flc_posix;
94 spin_lock(&inode->i_lock); 96 spin_lock(&flctx->flc_lock);
95 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 97restart:
96 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) 98 list_for_each_entry(fl, list, fl_list) {
97 continue;
98 if (nfs_file_open_context(fl->fl_file) != ctx) 99 if (nfs_file_open_context(fl->fl_file) != ctx)
99 continue; 100 continue;
100 spin_unlock(&inode->i_lock); 101 spin_unlock(&flctx->flc_lock);
101 status = nfs4_lock_delegation_recall(fl, state, stateid); 102 status = nfs4_lock_delegation_recall(fl, state, stateid);
102 if (status < 0) 103 if (status < 0)
103 goto out; 104 goto out;
104 spin_lock(&inode->i_lock); 105 spin_lock(&flctx->flc_lock);
105 } 106 }
106 spin_unlock(&inode->i_lock); 107 if (list == &flctx->flc_posix) {
108 list = &flctx->flc_flock;
109 goto restart;
110 }
111 spin_unlock(&flctx->flc_lock);
107out: 112out:
108 return status; 113 return status;
109} 114}
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 2ab6f00dba5b..94712fc781fa 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -646,7 +646,6 @@ static const struct vm_operations_struct nfs_file_vm_ops = {
646 .fault = filemap_fault, 646 .fault = filemap_fault,
647 .map_pages = filemap_map_pages, 647 .map_pages = filemap_map_pages,
648 .page_mkwrite = nfs_vm_page_mkwrite, 648 .page_mkwrite = nfs_vm_page_mkwrite,
649 .remap_pages = generic_file_remap_pages,
650}; 649};
651 650
652static int nfs_need_sync_write(struct file *filp, struct inode *inode) 651static int nfs_need_sync_write(struct file *filp, struct inode *inode)
diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c
index 3c9769441f36..91e88a7ecef0 100644
--- a/fs/nfs/filelayout/filelayout.c
+++ b/fs/nfs/filelayout/filelayout.c
@@ -960,52 +960,19 @@ filelayout_mark_request_commit(struct nfs_page *req,
960{ 960{
961 struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg); 961 struct nfs4_filelayout_segment *fl = FILELAYOUT_LSEG(lseg);
962 u32 i, j; 962 u32 i, j;
963 struct list_head *list;
964 struct pnfs_commit_bucket *buckets;
965 963
966 if (fl->commit_through_mds) { 964 if (fl->commit_through_mds) {
967 list = &cinfo->mds->list; 965 nfs_request_add_commit_list(req, &cinfo->mds->list, cinfo);
968 spin_lock(cinfo->lock); 966 } else {
969 goto mds_commit; 967 /* Note that we are calling nfs4_fl_calc_j_index on each page
970 } 968 * that ends up being committed to a data server. An attractive
971 969 * alternative is to add a field to nfs_write_data and nfs_page
972 /* Note that we are calling nfs4_fl_calc_j_index on each page 970 * to store the value calculated in filelayout_write_pagelist
973 * that ends up being committed to a data server. An attractive 971 * and just use that here.
974 * alternative is to add a field to nfs_write_data and nfs_page
975 * to store the value calculated in filelayout_write_pagelist
976 * and just use that here.
977 */
978 j = nfs4_fl_calc_j_index(lseg, req_offset(req));
979 i = select_bucket_index(fl, j);
980 spin_lock(cinfo->lock);
981 buckets = cinfo->ds->buckets;
982 list = &buckets[i].written;
983 if (list_empty(list)) {
984 /* Non-empty buckets hold a reference on the lseg. That ref
985 * is normally transferred to the COMMIT call and released
986 * there. It could also be released if the last req is pulled
987 * off due to a rewrite, in which case it will be done in
988 * pnfs_generic_clear_request_commit
989 */ 972 */
990 buckets[i].wlseg = pnfs_get_lseg(lseg); 973 j = nfs4_fl_calc_j_index(lseg, req_offset(req));
991 } 974 i = select_bucket_index(fl, j);
992 set_bit(PG_COMMIT_TO_DS, &req->wb_flags); 975 pnfs_layout_mark_request_commit(req, lseg, cinfo, i);
993 cinfo->ds->nwritten++;
994
995mds_commit:
996 /* nfs_request_add_commit_list(). We need to add req to list without
997 * dropping cinfo lock.
998 */
999 set_bit(PG_CLEAN, &(req)->wb_flags);
1000 nfs_list_add_request(req, list);
1001 cinfo->mds->ncommit++;
1002 spin_unlock(cinfo->lock);
1003 if (!cinfo->dreq) {
1004 inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
1005 inc_bdi_stat(page_file_mapping(req->wb_page)->backing_dev_info,
1006 BDI_RECLAIMABLE);
1007 __mark_inode_dirty(req->wb_context->dentry->d_inode,
1008 I_DIRTY_DATASYNC);
1009 } 976 }
1010} 977}
1011 978
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index f29fb7d7e8f8..315cc68945b9 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -1332,47 +1332,6 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
1332 return PNFS_ATTEMPTED; 1332 return PNFS_ATTEMPTED;
1333} 1333}
1334 1334
1335static void
1336ff_layout_mark_request_commit(struct nfs_page *req,
1337 struct pnfs_layout_segment *lseg,
1338 struct nfs_commit_info *cinfo,
1339 u32 ds_commit_idx)
1340{
1341 struct list_head *list;
1342 struct pnfs_commit_bucket *buckets;
1343
1344 spin_lock(cinfo->lock);
1345 buckets = cinfo->ds->buckets;
1346 list = &buckets[ds_commit_idx].written;
1347 if (list_empty(list)) {
1348 /* Non-empty buckets hold a reference on the lseg. That ref
1349 * is normally transferred to the COMMIT call and released
1350 * there. It could also be released if the last req is pulled
1351 * off due to a rewrite, in which case it will be done in
1352 * pnfs_common_clear_request_commit
1353 */
1354 WARN_ON_ONCE(buckets[ds_commit_idx].wlseg != NULL);
1355 buckets[ds_commit_idx].wlseg = pnfs_get_lseg(lseg);
1356 }
1357 set_bit(PG_COMMIT_TO_DS, &req->wb_flags);
1358 cinfo->ds->nwritten++;
1359
1360 /* nfs_request_add_commit_list(). We need to add req to list without
1361 * dropping cinfo lock.
1362 */
1363 set_bit(PG_CLEAN, &(req)->wb_flags);
1364 nfs_list_add_request(req, list);
1365 cinfo->mds->ncommit++;
1366 spin_unlock(cinfo->lock);
1367 if (!cinfo->dreq) {
1368 inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
1369 inc_bdi_stat(page_file_mapping(req->wb_page)->backing_dev_info,
1370 BDI_RECLAIMABLE);
1371 __mark_inode_dirty(req->wb_context->dentry->d_inode,
1372 I_DIRTY_DATASYNC);
1373 }
1374}
1375
1376static u32 calc_ds_index_from_commit(struct pnfs_layout_segment *lseg, u32 i) 1335static u32 calc_ds_index_from_commit(struct pnfs_layout_segment *lseg, u32 i)
1377{ 1336{
1378 return i; 1337 return i;
@@ -1540,7 +1499,7 @@ static struct pnfs_layoutdriver_type flexfilelayout_type = {
1540 .pg_write_ops = &ff_layout_pg_write_ops, 1499 .pg_write_ops = &ff_layout_pg_write_ops,
1541 .get_ds_info = ff_layout_get_ds_info, 1500 .get_ds_info = ff_layout_get_ds_info,
1542 .free_deviceid_node = ff_layout_free_deveiceid_node, 1501 .free_deviceid_node = ff_layout_free_deveiceid_node,
1543 .mark_request_commit = ff_layout_mark_request_commit, 1502 .mark_request_commit = pnfs_layout_mark_request_commit,
1544 .clear_request_commit = pnfs_generic_clear_request_commit, 1503 .clear_request_commit = pnfs_generic_clear_request_commit,
1545 .scan_commit_lists = pnfs_generic_scan_commit_lists, 1504 .scan_commit_lists = pnfs_generic_scan_commit_lists,
1546 .recover_commit_reqs = pnfs_generic_recover_commit_reqs, 1505 .recover_commit_reqs = pnfs_generic_recover_commit_reqs,
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index e211f975a69a..83107be3dd01 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -388,7 +388,6 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
388 if (S_ISREG(inode->i_mode)) { 388 if (S_ISREG(inode->i_mode)) {
389 inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops; 389 inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops;
390 inode->i_data.a_ops = &nfs_file_aops; 390 inode->i_data.a_ops = &nfs_file_aops;
391 inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info;
392 } else if (S_ISDIR(inode->i_mode)) { 391 } else if (S_ISDIR(inode->i_mode)) {
393 inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops; 392 inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops;
394 inode->i_fop = &nfs_dir_operations; 393 inode->i_fop = &nfs_dir_operations;
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 21469e6e3834..b802fb3a2d99 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -430,7 +430,6 @@ int nfs_show_options(struct seq_file *, struct dentry *);
430int nfs_show_devname(struct seq_file *, struct dentry *); 430int nfs_show_devname(struct seq_file *, struct dentry *);
431int nfs_show_path(struct seq_file *, struct dentry *); 431int nfs_show_path(struct seq_file *, struct dentry *);
432int nfs_show_stats(struct seq_file *, struct dentry *); 432int nfs_show_stats(struct seq_file *, struct dentry *);
433void nfs_put_super(struct super_block *);
434int nfs_remount(struct super_block *sb, int *flags, char *raw_data); 433int nfs_remount(struct super_block *sb, int *flags, char *raw_data);
435 434
436/* write.c */ 435/* write.c */
@@ -599,6 +598,19 @@ void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize)
599} 598}
600 599
601/* 600/*
601 * Record the page as unstable and mark its inode as dirty.
602 */
603static inline
604void nfs_mark_page_unstable(struct page *page)
605{
606 struct inode *inode = page_file_mapping(page)->host;
607
608 inc_zone_page_state(page, NR_UNSTABLE_NFS);
609 inc_bdi_stat(inode_to_bdi(inode), BDI_RECLAIMABLE);
610 __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
611}
612
613/*
602 * Determine the number of bytes of data the page contains 614 * Determine the number of bytes of data the page contains
603 */ 615 */
604static inline 616static inline
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 590f096fd011..5ad908e9ce9c 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1373,49 +1373,55 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
1373 struct nfs_inode *nfsi = NFS_I(inode); 1373 struct nfs_inode *nfsi = NFS_I(inode);
1374 struct file_lock *fl; 1374 struct file_lock *fl;
1375 int status = 0; 1375 int status = 0;
1376 struct file_lock_context *flctx = inode->i_flctx;
1377 struct list_head *list;
1376 1378
1377 if (inode->i_flock == NULL) 1379 if (flctx == NULL)
1378 return 0; 1380 return 0;
1379 1381
1382 list = &flctx->flc_posix;
1383
1380 /* Guard against delegation returns and new lock/unlock calls */ 1384 /* Guard against delegation returns and new lock/unlock calls */
1381 down_write(&nfsi->rwsem); 1385 down_write(&nfsi->rwsem);
1382 /* Protect inode->i_flock using the BKL */ 1386 spin_lock(&flctx->flc_lock);
1383 spin_lock(&inode->i_lock); 1387restart:
1384 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 1388 list_for_each_entry(fl, list, fl_list) {
1385 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
1386 continue;
1387 if (nfs_file_open_context(fl->fl_file)->state != state) 1389 if (nfs_file_open_context(fl->fl_file)->state != state)
1388 continue; 1390 continue;
1389 spin_unlock(&inode->i_lock); 1391 spin_unlock(&flctx->flc_lock);
1390 status = ops->recover_lock(state, fl); 1392 status = ops->recover_lock(state, fl);
1391 switch (status) { 1393 switch (status) {
1392 case 0: 1394 case 0:
1393 break; 1395 break;
1394 case -ESTALE: 1396 case -ESTALE:
1395 case -NFS4ERR_ADMIN_REVOKED: 1397 case -NFS4ERR_ADMIN_REVOKED:
1396 case -NFS4ERR_STALE_STATEID: 1398 case -NFS4ERR_STALE_STATEID:
1397 case -NFS4ERR_BAD_STATEID: 1399 case -NFS4ERR_BAD_STATEID:
1398 case -NFS4ERR_EXPIRED: 1400 case -NFS4ERR_EXPIRED:
1399 case -NFS4ERR_NO_GRACE: 1401 case -NFS4ERR_NO_GRACE:
1400 case -NFS4ERR_STALE_CLIENTID: 1402 case -NFS4ERR_STALE_CLIENTID:
1401 case -NFS4ERR_BADSESSION: 1403 case -NFS4ERR_BADSESSION:
1402 case -NFS4ERR_BADSLOT: 1404 case -NFS4ERR_BADSLOT:
1403 case -NFS4ERR_BAD_HIGH_SLOT: 1405 case -NFS4ERR_BAD_HIGH_SLOT:
1404 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: 1406 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1405 goto out; 1407 goto out;
1406 default: 1408 default:
1407 printk(KERN_ERR "NFS: %s: unhandled error %d\n", 1409 pr_err("NFS: %s: unhandled error %d\n",
1408 __func__, status); 1410 __func__, status);
1409 case -ENOMEM: 1411 case -ENOMEM:
1410 case -NFS4ERR_DENIED: 1412 case -NFS4ERR_DENIED:
1411 case -NFS4ERR_RECLAIM_BAD: 1413 case -NFS4ERR_RECLAIM_BAD:
1412 case -NFS4ERR_RECLAIM_CONFLICT: 1414 case -NFS4ERR_RECLAIM_CONFLICT:
1413 /* kill_proc(fl->fl_pid, SIGLOST, 1); */ 1415 /* kill_proc(fl->fl_pid, SIGLOST, 1); */
1414 status = 0; 1416 status = 0;
1415 } 1417 }
1416 spin_lock(&inode->i_lock); 1418 spin_lock(&flctx->flc_lock);
1417 } 1419 }
1418 spin_unlock(&inode->i_lock); 1420 if (list == &flctx->flc_posix) {
1421 list = &flctx->flc_flock;
1422 goto restart;
1423 }
1424 spin_unlock(&flctx->flc_lock);
1419out: 1425out:
1420 up_write(&nfsi->rwsem); 1426 up_write(&nfsi->rwsem);
1421 return status; 1427 return status;
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 48cea3c30e5d..75090feeafad 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -53,7 +53,6 @@ static const struct super_operations nfs4_sops = {
53 .destroy_inode = nfs_destroy_inode, 53 .destroy_inode = nfs_destroy_inode,
54 .write_inode = nfs4_write_inode, 54 .write_inode = nfs4_write_inode,
55 .drop_inode = nfs_drop_inode, 55 .drop_inode = nfs_drop_inode,
56 .put_super = nfs_put_super,
57 .statfs = nfs_statfs, 56 .statfs = nfs_statfs,
58 .evict_inode = nfs4_evict_inode, 57 .evict_inode = nfs4_evict_inode,
59 .umount_begin = nfs_umount_begin, 58 .umount_begin = nfs_umount_begin,
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 960c99f75d3f..d57190a0d533 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -933,11 +933,15 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev,
933 struct nfs_pageio_descriptor *pgio) 933 struct nfs_pageio_descriptor *pgio)
934{ 934{
935 size_t size; 935 size_t size;
936 struct file_lock_context *flctx;
936 937
937 if (prev) { 938 if (prev) {
938 if (!nfs_match_open_context(req->wb_context, prev->wb_context)) 939 if (!nfs_match_open_context(req->wb_context, prev->wb_context))
939 return false; 940 return false;
940 if (req->wb_context->dentry->d_inode->i_flock != NULL && 941 flctx = req->wb_context->dentry->d_inode->i_flctx;
942 if (flctx != NULL &&
943 !(list_empty_careful(&flctx->flc_posix) &&
944 list_empty_careful(&flctx->flc_flock)) &&
941 !nfs_match_lock_context(req->wb_lock_context, 945 !nfs_match_lock_context(req->wb_lock_context,
942 prev->wb_lock_context)) 946 prev->wb_lock_context))
943 return false; 947 return false;
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 797cd6253adf..635f0865671c 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -344,6 +344,10 @@ void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds,
344struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net, 344struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net,
345 struct xdr_stream *xdr, 345 struct xdr_stream *xdr,
346 gfp_t gfp_flags); 346 gfp_t gfp_flags);
347void pnfs_layout_mark_request_commit(struct nfs_page *req,
348 struct pnfs_layout_segment *lseg,
349 struct nfs_commit_info *cinfo,
350 u32 ds_commit_idx);
347 351
348static inline bool nfs_have_layout(struct inode *inode) 352static inline bool nfs_have_layout(struct inode *inode)
349{ 353{
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
index fdc4f6562bb7..54e36b38fb5f 100644
--- a/fs/nfs/pnfs_nfs.c
+++ b/fs/nfs/pnfs_nfs.c
@@ -838,3 +838,33 @@ out_err:
838 return NULL; 838 return NULL;
839} 839}
840EXPORT_SYMBOL_GPL(nfs4_decode_mp_ds_addr); 840EXPORT_SYMBOL_GPL(nfs4_decode_mp_ds_addr);
841
842void
843pnfs_layout_mark_request_commit(struct nfs_page *req,
844 struct pnfs_layout_segment *lseg,
845 struct nfs_commit_info *cinfo,
846 u32 ds_commit_idx)
847{
848 struct list_head *list;
849 struct pnfs_commit_bucket *buckets;
850
851 spin_lock(cinfo->lock);
852 buckets = cinfo->ds->buckets;
853 list = &buckets[ds_commit_idx].written;
854 if (list_empty(list)) {
855 /* Non-empty buckets hold a reference on the lseg. That ref
856 * is normally transferred to the COMMIT call and released
857 * there. It could also be released if the last req is pulled
858 * off due to a rewrite, in which case it will be done in
859 * pnfs_common_clear_request_commit
860 */
861 WARN_ON_ONCE(buckets[ds_commit_idx].wlseg != NULL);
862 buckets[ds_commit_idx].wlseg = pnfs_get_lseg(lseg);
863 }
864 set_bit(PG_COMMIT_TO_DS, &req->wb_flags);
865 cinfo->ds->nwritten++;
866 spin_unlock(cinfo->lock);
867
868 nfs_request_add_commit_list(req, list, cinfo);
869}
870EXPORT_SYMBOL_GPL(pnfs_layout_mark_request_commit);
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 368d9395d2e7..322b2de02988 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -311,7 +311,6 @@ const struct super_operations nfs_sops = {
311 .destroy_inode = nfs_destroy_inode, 311 .destroy_inode = nfs_destroy_inode,
312 .write_inode = nfs_write_inode, 312 .write_inode = nfs_write_inode,
313 .drop_inode = nfs_drop_inode, 313 .drop_inode = nfs_drop_inode,
314 .put_super = nfs_put_super,
315 .statfs = nfs_statfs, 314 .statfs = nfs_statfs,
316 .evict_inode = nfs_evict_inode, 315 .evict_inode = nfs_evict_inode,
317 .umount_begin = nfs_umount_begin, 316 .umount_begin = nfs_umount_begin,
@@ -2572,7 +2571,7 @@ struct dentry *nfs_fs_mount_common(struct nfs_server *server,
2572 error = nfs_bdi_register(server); 2571 error = nfs_bdi_register(server);
2573 if (error) { 2572 if (error) {
2574 mntroot = ERR_PTR(error); 2573 mntroot = ERR_PTR(error);
2575 goto error_splat_bdi; 2574 goto error_splat_super;
2576 } 2575 }
2577 server->super = s; 2576 server->super = s;
2578 } 2577 }
@@ -2604,9 +2603,6 @@ error_splat_root:
2604 dput(mntroot); 2603 dput(mntroot);
2605 mntroot = ERR_PTR(error); 2604 mntroot = ERR_PTR(error);
2606error_splat_super: 2605error_splat_super:
2607 if (server && !s->s_root)
2608 bdi_unregister(&server->backing_dev_info);
2609error_splat_bdi:
2610 deactivate_locked_super(s); 2606 deactivate_locked_super(s);
2611 goto out; 2607 goto out;
2612} 2608}
@@ -2654,27 +2650,19 @@ out:
2654EXPORT_SYMBOL_GPL(nfs_fs_mount); 2650EXPORT_SYMBOL_GPL(nfs_fs_mount);
2655 2651
2656/* 2652/*
2657 * Ensure that we unregister the bdi before kill_anon_super
2658 * releases the device name
2659 */
2660void nfs_put_super(struct super_block *s)
2661{
2662 struct nfs_server *server = NFS_SB(s);
2663
2664 bdi_unregister(&server->backing_dev_info);
2665}
2666EXPORT_SYMBOL_GPL(nfs_put_super);
2667
2668/*
2669 * Destroy an NFS2/3 superblock 2653 * Destroy an NFS2/3 superblock
2670 */ 2654 */
2671void nfs_kill_super(struct super_block *s) 2655void nfs_kill_super(struct super_block *s)
2672{ 2656{
2673 struct nfs_server *server = NFS_SB(s); 2657 struct nfs_server *server = NFS_SB(s);
2658 dev_t dev = s->s_dev;
2659
2660 generic_shutdown_super(s);
2674 2661
2675 kill_anon_super(s);
2676 nfs_fscache_release_super_cookie(s); 2662 nfs_fscache_release_super_cookie(s);
2663
2677 nfs_free_server(server); 2664 nfs_free_server(server);
2665 free_anon_bdev(dev);
2678} 2666}
2679EXPORT_SYMBOL_GPL(nfs_kill_super); 2667EXPORT_SYMBOL_GPL(nfs_kill_super);
2680 2668
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index ceacfeeb28c2..595d81e354d1 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -789,13 +789,8 @@ nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst,
789 nfs_list_add_request(req, dst); 789 nfs_list_add_request(req, dst);
790 cinfo->mds->ncommit++; 790 cinfo->mds->ncommit++;
791 spin_unlock(cinfo->lock); 791 spin_unlock(cinfo->lock);
792 if (!cinfo->dreq) { 792 if (!cinfo->dreq)
793 inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); 793 nfs_mark_page_unstable(req->wb_page);
794 inc_bdi_stat(page_file_mapping(req->wb_page)->backing_dev_info,
795 BDI_RECLAIMABLE);
796 __mark_inode_dirty(req->wb_context->dentry->d_inode,
797 I_DIRTY_DATASYNC);
798 }
799} 794}
800EXPORT_SYMBOL_GPL(nfs_request_add_commit_list); 795EXPORT_SYMBOL_GPL(nfs_request_add_commit_list);
801 796
@@ -858,7 +853,7 @@ static void
858nfs_clear_page_commit(struct page *page) 853nfs_clear_page_commit(struct page *page)
859{ 854{
860 dec_zone_page_state(page, NR_UNSTABLE_NFS); 855 dec_zone_page_state(page, NR_UNSTABLE_NFS);
861 dec_bdi_stat(page_file_mapping(page)->backing_dev_info, BDI_RECLAIMABLE); 856 dec_bdi_stat(inode_to_bdi(page_file_mapping(page)->host), BDI_RECLAIMABLE);
862} 857}
863 858
864/* Called holding inode (/cinfo) lock */ 859/* Called holding inode (/cinfo) lock */
@@ -1097,6 +1092,7 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
1097{ 1092{
1098 struct nfs_open_context *ctx = nfs_file_open_context(file); 1093 struct nfs_open_context *ctx = nfs_file_open_context(file);
1099 struct nfs_lock_context *l_ctx; 1094 struct nfs_lock_context *l_ctx;
1095 struct file_lock_context *flctx = file_inode(file)->i_flctx;
1100 struct nfs_page *req; 1096 struct nfs_page *req;
1101 int do_flush, status; 1097 int do_flush, status;
1102 /* 1098 /*
@@ -1115,7 +1111,9 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
1115 do_flush = req->wb_page != page || req->wb_context != ctx; 1111 do_flush = req->wb_page != page || req->wb_context != ctx;
1116 /* for now, flush if more than 1 request in page_group */ 1112 /* for now, flush if more than 1 request in page_group */
1117 do_flush |= req->wb_this_page != req; 1113 do_flush |= req->wb_this_page != req;
1118 if (l_ctx && ctx->dentry->d_inode->i_flock != NULL) { 1114 if (l_ctx && flctx &&
1115 !(list_empty_careful(&flctx->flc_posix) &&
1116 list_empty_careful(&flctx->flc_flock))) {
1119 do_flush |= l_ctx->lockowner.l_owner != current->files 1117 do_flush |= l_ctx->lockowner.l_owner != current->files
1120 || l_ctx->lockowner.l_pid != current->tgid; 1118 || l_ctx->lockowner.l_pid != current->tgid;
1121 } 1119 }
@@ -1176,6 +1174,13 @@ out:
1176 return PageUptodate(page) != 0; 1174 return PageUptodate(page) != 0;
1177} 1175}
1178 1176
1177static bool
1178is_whole_file_wrlock(struct file_lock *fl)
1179{
1180 return fl->fl_start == 0 && fl->fl_end == OFFSET_MAX &&
1181 fl->fl_type == F_WRLCK;
1182}
1183
1179/* If we know the page is up to date, and we're not using byte range locks (or 1184/* If we know the page is up to date, and we're not using byte range locks (or
1180 * if we have the whole file locked for writing), it may be more efficient to 1185 * if we have the whole file locked for writing), it may be more efficient to
1181 * extend the write to cover the entire page in order to avoid fragmentation 1186 * extend the write to cover the entire page in order to avoid fragmentation
@@ -1186,17 +1191,36 @@ out:
1186 */ 1191 */
1187static int nfs_can_extend_write(struct file *file, struct page *page, struct inode *inode) 1192static int nfs_can_extend_write(struct file *file, struct page *page, struct inode *inode)
1188{ 1193{
1194 int ret;
1195 struct file_lock_context *flctx = inode->i_flctx;
1196 struct file_lock *fl;
1197
1189 if (file->f_flags & O_DSYNC) 1198 if (file->f_flags & O_DSYNC)
1190 return 0; 1199 return 0;
1191 if (!nfs_write_pageuptodate(page, inode)) 1200 if (!nfs_write_pageuptodate(page, inode))
1192 return 0; 1201 return 0;
1193 if (NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE)) 1202 if (NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE))
1194 return 1; 1203 return 1;
1195 if (inode->i_flock == NULL || (inode->i_flock->fl_start == 0 && 1204 if (!flctx || (list_empty_careful(&flctx->flc_flock) &&
1196 inode->i_flock->fl_end == OFFSET_MAX && 1205 list_empty_careful(&flctx->flc_posix)))
1197 inode->i_flock->fl_type != F_RDLCK)) 1206 return 0;
1198 return 1; 1207
1199 return 0; 1208 /* Check to see if there are whole file write locks */
1209 ret = 0;
1210 spin_lock(&flctx->flc_lock);
1211 if (!list_empty(&flctx->flc_posix)) {
1212 fl = list_first_entry(&flctx->flc_posix, struct file_lock,
1213 fl_list);
1214 if (is_whole_file_wrlock(fl))
1215 ret = 1;
1216 } else if (!list_empty(&flctx->flc_flock)) {
1217 fl = list_first_entry(&flctx->flc_flock, struct file_lock,
1218 fl_list);
1219 if (fl->fl_type == F_WRLCK)
1220 ret = 1;
1221 }
1222 spin_unlock(&flctx->flc_lock);
1223 return ret;
1200} 1224}
1201 1225
1202/* 1226/*
@@ -1576,11 +1600,8 @@ void nfs_retry_commit(struct list_head *page_list,
1576 req = nfs_list_entry(page_list->next); 1600 req = nfs_list_entry(page_list->next);
1577 nfs_list_remove_request(req); 1601 nfs_list_remove_request(req);
1578 nfs_mark_request_commit(req, lseg, cinfo, ds_commit_idx); 1602 nfs_mark_request_commit(req, lseg, cinfo, ds_commit_idx);
1579 if (!cinfo->dreq) { 1603 if (!cinfo->dreq)
1580 dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); 1604 nfs_clear_page_commit(req->wb_page);
1581 dec_bdi_stat(page_file_mapping(req->wb_page)->backing_dev_info,
1582 BDI_RECLAIMABLE);
1583 }
1584 nfs_unlock_and_release_request(req); 1605 nfs_unlock_and_release_request(req);
1585 } 1606 }
1586} 1607}