@@ -335,35 +335,32 @@ static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx)
335335{
336336 int plus ;
337337 ssize_t res ;
338- struct folio * folio ;
339338 struct inode * inode = file_inode (file );
340339 struct fuse_mount * fm = get_fuse_mount (inode );
340+ struct fuse_conn * fc = fm -> fc ;
341341 struct fuse_io_args ia = {};
342- struct fuse_args_pages * ap = & ia .ap ;
343- struct fuse_folio_desc desc = { .length = PAGE_SIZE };
342+ struct fuse_args * args = & ia .ap .args ;
343+ void * buf ;
344+ size_t bufsize = clamp ((unsigned int ) ctx -> count , PAGE_SIZE , fc -> max_pages << PAGE_SHIFT );
344345 u64 attr_version = 0 , evict_ctr = 0 ;
345346 bool locked ;
346347
347- folio = folio_alloc ( GFP_KERNEL , 0 );
348- if (!folio )
348+ buf = kvmalloc ( bufsize , GFP_KERNEL );
349+ if (!buf )
349350 return - ENOMEM ;
350351
352+ args -> out_args [0 ].value = buf ;
353+
351354 plus = fuse_use_readdirplus (inode , ctx );
352- ap -> args .out_pages = true;
353- ap -> num_folios = 1 ;
354- ap -> folios = & folio ;
355- ap -> descs = & desc ;
356355 if (plus ) {
357356 attr_version = fuse_get_attr_version (fm -> fc );
358357 evict_ctr = fuse_get_evict_ctr (fm -> fc );
359- fuse_read_args_fill (& ia , file , ctx -> pos , PAGE_SIZE ,
360- FUSE_READDIRPLUS );
358+ fuse_read_args_fill (& ia , file , ctx -> pos , bufsize , FUSE_READDIRPLUS );
361359 } else {
362- fuse_read_args_fill (& ia , file , ctx -> pos , PAGE_SIZE ,
363- FUSE_READDIR );
360+ fuse_read_args_fill (& ia , file , ctx -> pos , bufsize , FUSE_READDIR );
364361 }
365362 locked = fuse_lock_inode (inode );
366- res = fuse_simple_request (fm , & ap -> args );
363+ res = fuse_simple_request (fm , args );
367364 fuse_unlock_inode (inode , locked );
368365 if (res >= 0 ) {
369366 if (!res ) {
@@ -372,16 +369,14 @@ static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx)
372369 if (ff -> open_flags & FOPEN_CACHE_DIR )
373370 fuse_readdir_cache_end (file , ctx -> pos );
374371 } else if (plus ) {
375- res = parse_dirplusfile (folio_address (folio ), res ,
376- file , ctx , attr_version ,
372+ res = parse_dirplusfile (buf , res , file , ctx , attr_version ,
377373 evict_ctr );
378374 } else {
379- res = parse_dirfile (folio_address (folio ), res , file ,
380- ctx );
375+ res = parse_dirfile (buf , res , file , ctx );
381376 }
382377 }
383378
384- folio_put ( folio );
379+ kvfree ( buf );
385380 fuse_invalidate_atime (inode );
386381 return res ;
387382}
0 commit comments