@@ -199,6 +199,23 @@ void nfs_readdir_clear_array(struct page *page)
199
199
kunmap_atomic (array );
200
200
}
201
201
202
+ static struct page *
203
+ nfs_readdir_page_array_alloc (u64 last_cookie , gfp_t gfp_flags )
204
+ {
205
+ struct page * page = alloc_page (gfp_flags );
206
+ if (page )
207
+ nfs_readdir_page_init_array (page , last_cookie );
208
+ return page ;
209
+ }
210
+
211
+ static void nfs_readdir_page_array_free (struct page * page )
212
+ {
213
+ if (page ) {
214
+ nfs_readdir_clear_array (page );
215
+ put_page (page );
216
+ }
217
+ }
218
+
202
219
static void nfs_readdir_array_set_eof (struct nfs_cache_array * array )
203
220
{
204
221
array -> page_is_eof = 1 ;
@@ -694,12 +711,14 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry,
694
711
static int nfs_readdir_page_filler (struct nfs_readdir_descriptor * desc ,
695
712
struct nfs_entry * entry ,
696
713
struct page * * xdr_pages ,
697
- struct page * fillme , unsigned int buflen )
714
+ unsigned int buflen ,
715
+ struct page * * arrays ,
716
+ size_t narrays )
698
717
{
699
718
struct address_space * mapping = desc -> file -> f_mapping ;
700
719
struct xdr_stream stream ;
701
720
struct xdr_buf buf ;
702
- struct page * scratch , * new , * page = fillme ;
721
+ struct page * scratch , * new , * page = * arrays ;
703
722
int status ;
704
723
705
724
scratch = alloc_page (GFP_KERNEL );
@@ -725,15 +744,25 @@ static int nfs_readdir_page_filler(struct nfs_readdir_descriptor *desc,
725
744
if (status != - ENOSPC )
726
745
continue ;
727
746
728
- if (page -> mapping != mapping )
729
- break ;
730
- new = nfs_readdir_page_get_next (mapping , page -> index + 1 ,
731
- entry -> prev_cookie );
732
- if (!new )
733
- break ;
734
- if (page != fillme )
735
- nfs_readdir_page_unlock_and_put (page );
736
- page = new ;
747
+ if (page -> mapping != mapping ) {
748
+ if (!-- narrays )
749
+ break ;
750
+ new = nfs_readdir_page_array_alloc (entry -> prev_cookie ,
751
+ GFP_KERNEL );
752
+ if (!new )
753
+ break ;
754
+ arrays ++ ;
755
+ * arrays = page = new ;
756
+ } else {
757
+ new = nfs_readdir_page_get_next (mapping ,
758
+ page -> index + 1 ,
759
+ entry -> prev_cookie );
760
+ if (!new )
761
+ break ;
762
+ if (page != * arrays )
763
+ nfs_readdir_page_unlock_and_put (page );
764
+ page = new ;
765
+ }
737
766
status = nfs_readdir_add_to_array (entry , page );
738
767
} while (!status && !entry -> eof );
739
768
@@ -750,7 +779,7 @@ static int nfs_readdir_page_filler(struct nfs_readdir_descriptor *desc,
750
779
break ;
751
780
}
752
781
753
- if (page != fillme )
782
+ if (page != * arrays )
754
783
nfs_readdir_page_unlock_and_put (page );
755
784
756
785
put_page (scratch );
@@ -790,10 +819,11 @@ static struct page **nfs_readdir_alloc_pages(size_t npages)
790
819
}
791
820
792
821
static int nfs_readdir_xdr_to_array (struct nfs_readdir_descriptor * desc ,
793
- struct page * page , __be32 * verf_arg ,
794
- __be32 * verf_res )
822
+ __be32 * verf_arg , __be32 * verf_res ,
823
+ struct page * * arrays , size_t narrays )
795
824
{
796
825
struct page * * pages ;
826
+ struct page * page = * arrays ;
797
827
struct nfs_entry * entry ;
798
828
size_t array_size ;
799
829
struct inode * inode = file_inode (desc -> file );
@@ -835,7 +865,8 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc,
835
865
break ;
836
866
}
837
867
838
- status = nfs_readdir_page_filler (desc , entry , pages , page , pglen );
868
+ status = nfs_readdir_page_filler (desc , entry , pages , pglen ,
869
+ arrays , narrays );
839
870
} while (!status && nfs_readdir_page_needs_filling (page ));
840
871
841
872
nfs_readdir_free_pages (pages , array_size );
@@ -884,8 +915,8 @@ static int find_and_lock_cache_page(struct nfs_readdir_descriptor *desc)
884
915
if (!desc -> page )
885
916
return - ENOMEM ;
886
917
if (nfs_readdir_page_needs_filling (desc -> page )) {
887
- res = nfs_readdir_xdr_to_array (desc , desc -> page ,
888
- nfsi -> cookieverf , verf );
918
+ res = nfs_readdir_xdr_to_array (desc , nfsi -> cookieverf , verf ,
919
+ & desc -> page , 1 );
889
920
if (res < 0 ) {
890
921
nfs_readdir_page_unlock_and_put_cached (desc );
891
922
if (res == - EBADCOOKIE || res == - ENOTSYNC ) {
@@ -976,37 +1007,39 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc)
976
1007
*/
977
1008
static int uncached_readdir (struct nfs_readdir_descriptor * desc )
978
1009
{
979
- struct page * page = NULL ;
1010
+ struct page * * arrays ;
1011
+ size_t i , sz = 512 ;
980
1012
__be32 verf [NFS_DIR_VERIFIER_SIZE ];
981
- int status ;
1013
+ int status = - ENOMEM ;
982
1014
983
- dfprintk (DIRCACHE , "NFS: uncached_readdir() searching for cookie %Lu \n" ,
1015
+ dfprintk (DIRCACHE , "NFS: uncached_readdir() searching for cookie %llu \n" ,
984
1016
(unsigned long long )desc -> dir_cookie );
985
1017
986
- page = alloc_page (GFP_HIGHUSER );
987
- if (!page ) {
988
- status = - ENOMEM ;
1018
+ arrays = kcalloc (sz , sizeof (* arrays ), GFP_KERNEL );
1019
+ if (!arrays )
1020
+ goto out ;
1021
+ arrays [0 ] = nfs_readdir_page_array_alloc (desc -> dir_cookie , GFP_KERNEL );
1022
+ if (!arrays [0 ])
989
1023
goto out ;
990
- }
991
1024
992
1025
desc -> page_index = 0 ;
993
1026
desc -> last_cookie = desc -> dir_cookie ;
994
- desc -> page = page ;
995
1027
desc -> duped = 0 ;
996
1028
997
- nfs_readdir_page_init_array (page , desc -> dir_cookie );
998
- status = nfs_readdir_xdr_to_array (desc , page , desc -> verf , verf );
999
- if (status < 0 )
1000
- goto out_release ;
1029
+ status = nfs_readdir_xdr_to_array (desc , desc -> verf , verf , arrays , sz );
1001
1030
1002
- nfs_do_filldir (desc );
1031
+ for (i = 0 ; !desc -> eof && i < sz && arrays [i ]; i ++ ) {
1032
+ desc -> page = arrays [i ];
1033
+ nfs_do_filldir (desc );
1034
+ }
1035
+ desc -> page = NULL ;
1003
1036
1004
- out_release :
1005
- nfs_readdir_clear_array ( desc -> page );
1006
- nfs_readdir_page_put ( desc );
1007
- out :
1008
- dfprintk ( DIRCACHE , "NFS: %s: returns %d\n" ,
1009
- __func__ , status );
1037
+
1038
+ for ( i = 0 ; i < sz && arrays [ i ]; i ++ )
1039
+ nfs_readdir_page_array_free ( arrays [ i ] );
1040
+ out :
1041
+ kfree ( arrays );
1042
+ dfprintk ( DIRCACHE , "NFS: %s: returns %d\n" , __func__ , status );
1010
1043
return status ;
1011
1044
}
1012
1045
0 commit comments