@@ -139,27 +139,6 @@ struct xattr_iter_handlers {
139139 unsigned int len );
140140};
141141
142- static int inline_xattr_iter_begin (struct erofs_xattr_iter * it ,
143- struct inode * inode )
144- {
145- struct erofs_inode * const vi = EROFS_I (inode );
146- unsigned int xattr_header_sz ;
147-
148- xattr_header_sz = sizeof (struct erofs_xattr_ibody_header ) +
149- sizeof (u32 ) * vi -> xattr_shared_count ;
150- if (xattr_header_sz >= vi -> xattr_isize ) {
151- DBG_BUGON (xattr_header_sz > vi -> xattr_isize );
152- return - ENOATTR ;
153- }
154-
155- it -> pos = erofs_iloc (inode ) + vi -> inode_isize + xattr_header_sz ;
156- it -> kaddr = erofs_bread (& it -> buf , erofs_blknr (it -> sb , it -> pos ),
157- EROFS_KMAP );
158- if (IS_ERR (it -> kaddr ))
159- return PTR_ERR (it -> kaddr );
160- return vi -> xattr_isize - xattr_header_sz ;
161- }
162-
163142/*
164143 * Regardless of success or failure, `xattr_foreach' will end up with
165144 * `pos' pointing to the next xattr item rather than an arbitrary position.
@@ -333,47 +312,6 @@ static const struct xattr_iter_handlers find_xattr_handlers = {
333312 .value = xattr_copyvalue
334313};
335314
336- static int inline_getxattr (struct inode * inode , struct erofs_xattr_iter * it )
337- {
338- int ret ;
339- unsigned int remaining ;
340-
341- ret = inline_xattr_iter_begin (it , inode );
342- if (ret < 0 )
343- return ret ;
344-
345- remaining = ret ;
346- while (remaining ) {
347- ret = xattr_foreach (it , & find_xattr_handlers , & remaining );
348- if (ret != - ENOATTR )
349- break ;
350- }
351- return ret ? ret : it -> buffer_ofs ;
352- }
353-
354- static int shared_getxattr (struct inode * inode , struct erofs_xattr_iter * it )
355- {
356- struct erofs_inode * const vi = EROFS_I (inode );
357- struct super_block * const sb = it -> sb ;
358- struct erofs_sb_info * sbi = EROFS_SB (sb );
359- unsigned int i ;
360- int ret = - ENOATTR ;
361-
362- for (i = 0 ; i < vi -> xattr_shared_count ; ++ i ) {
363- it -> pos = erofs_pos (sb , sbi -> xattr_blkaddr ) +
364- vi -> xattr_shared_xattrs [i ] * sizeof (__le32 );
365- it -> kaddr = erofs_bread (& it -> buf , erofs_blknr (sb , it -> pos ),
366- EROFS_KMAP );
367- if (IS_ERR (it -> kaddr ))
368- return PTR_ERR (it -> kaddr );
369-
370- ret = xattr_foreach (it , & find_xattr_handlers , NULL );
371- if (ret != - ENOATTR )
372- break ;
373- }
374- return ret ? ret : it -> buffer_ofs ;
375- }
376-
377315static bool erofs_xattr_user_list (struct dentry * dentry )
378316{
379317 return test_opt (& EROFS_SB (dentry -> d_sb )-> opt , XATTR_USER );
@@ -384,39 +322,6 @@ static bool erofs_xattr_trusted_list(struct dentry *dentry)
384322 return capable (CAP_SYS_ADMIN );
385323}
386324
387- int erofs_getxattr (struct inode * inode , int index ,
388- const char * name ,
389- void * buffer , size_t buffer_size )
390- {
391- int ret ;
392- struct erofs_xattr_iter it ;
393-
394- if (!name )
395- return - EINVAL ;
396-
397- ret = erofs_init_inode_xattrs (inode );
398- if (ret )
399- return ret ;
400-
401- it .index = index ;
402- it .name = (struct qstr )QSTR_INIT (name , strlen (name ));
403- if (it .name .len > EROFS_NAME_LEN )
404- return - ERANGE ;
405-
406- it .sb = inode -> i_sb ;
407- it .buf = __EROFS_BUF_INITIALIZER ;
408- erofs_init_metabuf (& it .buf , it .sb );
409- it .buffer = buffer ;
410- it .buffer_size = buffer_size ;
411- it .buffer_ofs = 0 ;
412-
413- ret = inline_getxattr (inode , & it );
414- if (ret == - ENOATTR )
415- ret = shared_getxattr (inode , & it );
416- erofs_put_metabuf (& it .buf );
417- return ret ;
418- }
419-
420325static int erofs_xattr_generic_get (const struct xattr_handler * handler ,
421326 struct dentry * unused , struct inode * inode ,
422327 const char * name , void * buffer , size_t size )
@@ -521,32 +426,49 @@ static const struct xattr_iter_handlers list_xattr_handlers = {
521426 .value = NULL
522427};
523428
524- static int inline_listxattr (struct erofs_xattr_iter * it )
429+ static int erofs_xattr_iter_inline (struct erofs_xattr_iter * it ,
430+ struct inode * inode , bool getxattr )
525431{
432+ struct erofs_inode * const vi = EROFS_I (inode );
433+ const struct xattr_iter_handlers * op ;
434+ unsigned int xattr_header_sz , remaining ;
526435 int ret ;
527- unsigned int remaining ;
528436
529- ret = inline_xattr_iter_begin (it , d_inode (it -> dentry ));
530- if (ret < 0 )
531- return ret ;
437+ xattr_header_sz = sizeof (struct erofs_xattr_ibody_header ) +
438+ sizeof (u32 ) * vi -> xattr_shared_count ;
439+ if (xattr_header_sz >= vi -> xattr_isize ) {
440+ DBG_BUGON (xattr_header_sz > vi -> xattr_isize );
441+ return - ENOATTR ;
442+ }
443+
444+ it -> pos = erofs_iloc (inode ) + vi -> inode_isize + xattr_header_sz ;
445+ it -> kaddr = erofs_bread (& it -> buf , erofs_blknr (it -> sb , it -> pos ),
446+ EROFS_KMAP );
447+ if (IS_ERR (it -> kaddr ))
448+ return PTR_ERR (it -> kaddr );
449+
450+ remaining = vi -> xattr_isize - xattr_header_sz ;
451+ op = getxattr ? & find_xattr_handlers : & list_xattr_handlers ;
532452
533- remaining = ret ;
534453 while (remaining ) {
535- ret = xattr_foreach (it , & list_xattr_handlers , & remaining );
536- if (ret )
454+ ret = xattr_foreach (it , op , & remaining );
455+ if (( getxattr && ret != - ENOATTR ) || (! getxattr && ret ) )
537456 break ;
538457 }
539- return ret ? ret : it -> buffer_ofs ;
458+ return ret ;
540459}
541460
542- static int shared_listxattr (struct erofs_xattr_iter * it )
461+ static int erofs_xattr_iter_shared (struct erofs_xattr_iter * it ,
462+ struct inode * inode , bool getxattr )
543463{
544- struct inode * const inode = d_inode (it -> dentry );
545464 struct erofs_inode * const vi = EROFS_I (inode );
546465 struct super_block * const sb = it -> sb ;
547466 struct erofs_sb_info * sbi = EROFS_SB (sb );
548467 unsigned int i ;
549- int ret = 0 ;
468+ const struct xattr_iter_handlers * op ;
469+ int ret = - ENOATTR ;
470+
471+ op = getxattr ? & find_xattr_handlers : & list_xattr_handlers ;
550472
551473 for (i = 0 ; i < vi -> xattr_shared_count ; ++ i ) {
552474 it -> pos = erofs_pos (sb , sbi -> xattr_blkaddr ) +
@@ -556,20 +478,52 @@ static int shared_listxattr(struct erofs_xattr_iter *it)
556478 if (IS_ERR (it -> kaddr ))
557479 return PTR_ERR (it -> kaddr );
558480
559- ret = xattr_foreach (it , & list_xattr_handlers , NULL );
560- if (ret )
481+ ret = xattr_foreach (it , op , NULL );
482+ if (( getxattr && ret != - ENOATTR ) || (! getxattr && ret ) )
561483 break ;
562484 }
563- return ret ? ret : it -> buffer_ofs ;
485+ return ret ;
564486}
565487
566- ssize_t erofs_listxattr (struct dentry * dentry ,
567- char * buffer , size_t buffer_size )
488+ int erofs_getxattr (struct inode * inode , int index , const char * name ,
489+ void * buffer , size_t buffer_size )
568490{
569491 int ret ;
570492 struct erofs_xattr_iter it ;
571493
572- ret = erofs_init_inode_xattrs (d_inode (dentry ));
494+ if (!name )
495+ return - EINVAL ;
496+
497+ ret = erofs_init_inode_xattrs (inode );
498+ if (ret )
499+ return ret ;
500+
501+ it .index = index ;
502+ it .name = (struct qstr )QSTR_INIT (name , strlen (name ));
503+ if (it .name .len > EROFS_NAME_LEN )
504+ return - ERANGE ;
505+
506+ it .sb = inode -> i_sb ;
507+ it .buf = __EROFS_BUF_INITIALIZER ;
508+ erofs_init_metabuf (& it .buf , it .sb );
509+ it .buffer = buffer ;
510+ it .buffer_size = buffer_size ;
511+ it .buffer_ofs = 0 ;
512+
513+ ret = erofs_xattr_iter_inline (& it , inode , true);
514+ if (ret == - ENOATTR )
515+ ret = erofs_xattr_iter_shared (& it , inode , true);
516+ erofs_put_metabuf (& it .buf );
517+ return ret ? ret : it .buffer_ofs ;
518+ }
519+
520+ ssize_t erofs_listxattr (struct dentry * dentry , char * buffer , size_t buffer_size )
521+ {
522+ int ret ;
523+ struct erofs_xattr_iter it ;
524+ struct inode * inode = d_inode (dentry );
525+
526+ ret = erofs_init_inode_xattrs (inode );
573527 if (ret == - ENOATTR )
574528 return 0 ;
575529 if (ret )
@@ -583,11 +537,13 @@ ssize_t erofs_listxattr(struct dentry *dentry,
583537 it .buffer_size = buffer_size ;
584538 it .buffer_ofs = 0 ;
585539
586- ret = inline_listxattr (& it );
587- if (ret >= 0 || ret == - ENOATTR )
588- ret = shared_listxattr (& it );
540+ ret = erofs_xattr_iter_inline (& it , inode , false);
541+ if (!ret || ret == - ENOATTR )
542+ ret = erofs_xattr_iter_shared (& it , inode , false);
543+ if (ret == - ENOATTR )
544+ ret = 0 ;
589545 erofs_put_metabuf (& it .buf );
590- return ret ;
546+ return ret ? ret : it . buffer_ofs ;
591547}
592548
593549void erofs_xattr_prefixes_cleanup (struct super_block * sb )
0 commit comments