Skip to content

Commit 3627452

Browse files
committed
Merge branch 'writeback'
2 parents 7f94ed2 + e033fb5 commit 3627452

File tree

18 files changed

+438
-282
lines changed

18 files changed

+438
-282
lines changed

fs/nfs/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ obj-$(CONFIG_NFS_FS) += nfs.o
66

77
CFLAGS_nfstrace.o += -I$(src)
88
nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
9-
direct.o pagelist.o read.o symlink.o unlink.o \
9+
io.o direct.o pagelist.o read.o symlink.o unlink.o \
1010
write.o namespace.o mount_clnt.o nfstrace.o
1111
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
1212
nfs-$(CONFIG_SYSCTL) += sysctl.o

fs/nfs/dir.c

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2231,21 +2231,37 @@ static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, st
22312231
return NULL;
22322232
}
22332233

2234-
static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res)
2234+
static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res, bool may_block)
22352235
{
22362236
struct nfs_inode *nfsi = NFS_I(inode);
22372237
struct nfs_access_entry *cache;
2238-
int err = -ENOENT;
2238+
bool retry = true;
2239+
int err;
22392240

22402241
spin_lock(&inode->i_lock);
2241-
if (nfsi->cache_validity & NFS_INO_INVALID_ACCESS)
2242-
goto out_zap;
2243-
cache = nfs_access_search_rbtree(inode, cred);
2244-
if (cache == NULL)
2245-
goto out;
2246-
if (!nfs_have_delegated_attributes(inode) &&
2247-
!time_in_range_open(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo))
2248-
goto out_stale;
2242+
for(;;) {
2243+
if (nfsi->cache_validity & NFS_INO_INVALID_ACCESS)
2244+
goto out_zap;
2245+
cache = nfs_access_search_rbtree(inode, cred);
2246+
err = -ENOENT;
2247+
if (cache == NULL)
2248+
goto out;
2249+
/* Found an entry, is our attribute cache valid? */
2250+
if (!nfs_attribute_cache_expired(inode) &&
2251+
!(nfsi->cache_validity & NFS_INO_INVALID_ATTR))
2252+
break;
2253+
err = -ECHILD;
2254+
if (!may_block)
2255+
goto out;
2256+
if (!retry)
2257+
goto out_zap;
2258+
spin_unlock(&inode->i_lock);
2259+
err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
2260+
if (err)
2261+
return err;
2262+
spin_lock(&inode->i_lock);
2263+
retry = false;
2264+
}
22492265
res->jiffies = cache->jiffies;
22502266
res->cred = cache->cred;
22512267
res->mask = cache->mask;
@@ -2254,12 +2270,6 @@ static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, str
22542270
out:
22552271
spin_unlock(&inode->i_lock);
22562272
return err;
2257-
out_stale:
2258-
rb_erase(&cache->rb_node, &nfsi->access_cache);
2259-
list_del(&cache->lru);
2260-
spin_unlock(&inode->i_lock);
2261-
nfs_access_free_entry(cache);
2262-
return -ENOENT;
22632273
out_zap:
22642274
spin_unlock(&inode->i_lock);
22652275
nfs_access_zap_cache(inode);
@@ -2286,13 +2296,12 @@ static int nfs_access_get_cached_rcu(struct inode *inode, struct rpc_cred *cred,
22862296
cache = NULL;
22872297
if (cache == NULL)
22882298
goto out;
2289-
if (!nfs_have_delegated_attributes(inode) &&
2290-
!time_in_range_open(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo))
2299+
err = nfs_revalidate_inode_rcu(NFS_SERVER(inode), inode);
2300+
if (err)
22912301
goto out;
22922302
res->jiffies = cache->jiffies;
22932303
res->cred = cache->cred;
22942304
res->mask = cache->mask;
2295-
err = 0;
22962305
out:
22972306
rcu_read_unlock();
22982307
return err;
@@ -2381,18 +2390,19 @@ EXPORT_SYMBOL_GPL(nfs_access_set_mask);
23812390
static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
23822391
{
23832392
struct nfs_access_entry cache;
2393+
bool may_block = (mask & MAY_NOT_BLOCK) == 0;
23842394
int status;
23852395

23862396
trace_nfs_access_enter(inode);
23872397

23882398
status = nfs_access_get_cached_rcu(inode, cred, &cache);
23892399
if (status != 0)
2390-
status = nfs_access_get_cached(inode, cred, &cache);
2400+
status = nfs_access_get_cached(inode, cred, &cache, may_block);
23912401
if (status == 0)
23922402
goto out_cached;
23932403

23942404
status = -ECHILD;
2395-
if (mask & MAY_NOT_BLOCK)
2405+
if (!may_block)
23962406
goto out;
23972407

23982408
/* Be clever: ask server to check for all possible rights */

fs/nfs/direct.c

Lines changed: 32 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,12 @@ static void nfs_direct_set_hdr_verf(struct nfs_direct_req *dreq,
196196
WARN_ON_ONCE(verfp->committed < 0);
197197
}
198198

199+
static int nfs_direct_cmp_verf(const struct nfs_writeverf *v1,
200+
const struct nfs_writeverf *v2)
201+
{
202+
return nfs_write_verifier_cmp(&v1->verifier, &v2->verifier);
203+
}
204+
199205
/*
200206
* nfs_direct_cmp_hdr_verf - compare verifier for pgio header
201207
* @dreq - direct request possibly spanning multiple servers
@@ -215,7 +221,7 @@ static int nfs_direct_set_or_cmp_hdr_verf(struct nfs_direct_req *dreq,
215221
nfs_direct_set_hdr_verf(dreq, hdr);
216222
return 0;
217223
}
218-
return memcmp(verfp, &hdr->verf, sizeof(struct nfs_writeverf));
224+
return nfs_direct_cmp_verf(verfp, &hdr->verf);
219225
}
220226

221227
/*
@@ -238,7 +244,7 @@ static int nfs_direct_cmp_commit_data_verf(struct nfs_direct_req *dreq,
238244
if (verfp->committed < 0)
239245
return 1;
240246

241-
return memcmp(verfp, &data->verf, sizeof(struct nfs_writeverf));
247+
return nfs_direct_cmp_verf(verfp, &data->verf);
242248
}
243249

244250
/**
@@ -368,22 +374,10 @@ static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq)
368374
* Synchronous I/O uses a stack-allocated iocb. Thus we can't trust
369375
* the iocb is still valid here if this is a synchronous request.
370376
*/
371-
static void nfs_direct_complete(struct nfs_direct_req *dreq, bool write)
377+
static void nfs_direct_complete(struct nfs_direct_req *dreq)
372378
{
373379
struct inode *inode = dreq->inode;
374380

375-
if (dreq->iocb && write) {
376-
loff_t pos = dreq->iocb->ki_pos + dreq->count;
377-
378-
spin_lock(&inode->i_lock);
379-
if (i_size_read(inode) < pos)
380-
i_size_write(inode, pos);
381-
spin_unlock(&inode->i_lock);
382-
}
383-
384-
if (write)
385-
nfs_zap_mapping(inode, inode->i_mapping);
386-
387381
inode_dio_end(inode);
388382

389383
if (dreq->iocb) {
@@ -438,7 +432,7 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
438432
}
439433
out_put:
440434
if (put_dreq(dreq))
441-
nfs_direct_complete(dreq, false);
435+
nfs_direct_complete(dreq);
442436
hdr->release(hdr);
443437
}
444438

@@ -544,7 +538,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
544538
}
545539

546540
if (put_dreq(dreq))
547-
nfs_direct_complete(dreq, false);
541+
nfs_direct_complete(dreq);
548542
return 0;
549543
}
550544

@@ -585,17 +579,12 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter)
585579
if (!count)
586580
goto out;
587581

588-
inode_lock(inode);
589-
result = nfs_sync_mapping(mapping);
590-
if (result)
591-
goto out_unlock;
592-
593582
task_io_account_read(count);
594583

595584
result = -ENOMEM;
596585
dreq = nfs_direct_req_alloc();
597586
if (dreq == NULL)
598-
goto out_unlock;
587+
goto out;
599588

600589
dreq->inode = inode;
601590
dreq->bytes_left = dreq->max_count = count;
@@ -610,24 +599,21 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter)
610599
if (!is_sync_kiocb(iocb))
611600
dreq->iocb = iocb;
612601

602+
nfs_start_io_direct(inode);
603+
613604
NFS_I(inode)->read_io += count;
614605
result = nfs_direct_read_schedule_iovec(dreq, iter, iocb->ki_pos);
615606

616-
inode_unlock(inode);
607+
nfs_end_io_direct(inode);
617608

618609
if (!result) {
619610
result = nfs_direct_wait(dreq);
620611
if (result > 0)
621612
iocb->ki_pos += result;
622613
}
623614

624-
nfs_direct_req_release(dreq);
625-
return result;
626-
627615
out_release:
628616
nfs_direct_req_release(dreq);
629-
out_unlock:
630-
inode_unlock(inode);
631617
out:
632618
return result;
633619
}
@@ -659,6 +645,8 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
659645
nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo);
660646

661647
dreq->count = 0;
648+
dreq->verf.committed = NFS_INVALID_STABLE_HOW;
649+
nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo);
662650
for (i = 0; i < dreq->mirror_count; i++)
663651
dreq->mirrors[i].count = 0;
664652
get_dreq(dreq);
@@ -777,7 +765,8 @@ static void nfs_direct_write_schedule_work(struct work_struct *work)
777765
nfs_direct_write_reschedule(dreq);
778766
break;
779767
default:
780-
nfs_direct_complete(dreq, true);
768+
nfs_zap_mapping(dreq->inode, dreq->inode->i_mapping);
769+
nfs_direct_complete(dreq);
781770
}
782771
}
783772

@@ -993,6 +982,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
993982
ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
994983
{
995984
ssize_t result = -EINVAL;
985+
size_t count;
996986
struct file *file = iocb->ki_filp;
997987
struct address_space *mapping = file->f_mapping;
998988
struct inode *inode = mapping->host;
@@ -1003,34 +993,24 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
1003993
dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n",
1004994
file, iov_iter_count(iter), (long long) iocb->ki_pos);
1005995

1006-
nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES,
1007-
iov_iter_count(iter));
996+
result = generic_write_checks(iocb, iter);
997+
if (result <= 0)
998+
return result;
999+
count = result;
1000+
nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count);
10081001

10091002
pos = iocb->ki_pos;
10101003
end = (pos + iov_iter_count(iter) - 1) >> PAGE_SHIFT;
10111004

1012-
inode_lock(inode);
1013-
1014-
result = nfs_sync_mapping(mapping);
1015-
if (result)
1016-
goto out_unlock;
1017-
1018-
if (mapping->nrpages) {
1019-
result = invalidate_inode_pages2_range(mapping,
1020-
pos >> PAGE_SHIFT, end);
1021-
if (result)
1022-
goto out_unlock;
1023-
}
1024-
1025-
task_io_account_write(iov_iter_count(iter));
1005+
task_io_account_write(count);
10261006

10271007
result = -ENOMEM;
10281008
dreq = nfs_direct_req_alloc();
10291009
if (!dreq)
1030-
goto out_unlock;
1010+
goto out;
10311011

10321012
dreq->inode = inode;
1033-
dreq->bytes_left = dreq->max_count = iov_iter_count(iter);
1013+
dreq->bytes_left = dreq->max_count = count;
10341014
dreq->io_start = pos;
10351015
dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
10361016
l_ctx = nfs_get_lock_context(dreq->ctx);
@@ -1042,37 +1022,28 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
10421022
if (!is_sync_kiocb(iocb))
10431023
dreq->iocb = iocb;
10441024

1025+
nfs_start_io_direct(inode);
1026+
10451027
result = nfs_direct_write_schedule_iovec(dreq, iter, pos);
10461028

10471029
if (mapping->nrpages) {
10481030
invalidate_inode_pages2_range(mapping,
10491031
pos >> PAGE_SHIFT, end);
10501032
}
10511033

1052-
inode_unlock(inode);
1034+
nfs_end_io_direct(inode);
10531035

10541036
if (!result) {
10551037
result = nfs_direct_wait(dreq);
10561038
if (result > 0) {
1057-
struct inode *inode = mapping->host;
1058-
10591039
iocb->ki_pos = pos + result;
1060-
spin_lock(&inode->i_lock);
1061-
if (i_size_read(inode) < iocb->ki_pos)
1062-
i_size_write(inode, iocb->ki_pos);
1063-
spin_unlock(&inode->i_lock);
1064-
10651040
/* XXX: should check the generic_write_sync retval */
10661041
generic_write_sync(iocb, result);
10671042
}
10681043
}
1069-
nfs_direct_req_release(dreq);
1070-
return result;
1071-
10721044
out_release:
10731045
nfs_direct_req_release(dreq);
1074-
out_unlock:
1075-
inode_unlock(inode);
1046+
out:
10761047
return result;
10771048
}
10781049

0 commit comments

Comments
 (0)