2323#include "xattr.h"
2424#include "segment.h"
2525
26+ static void * xattr_alloc (struct f2fs_sb_info * sbi , int size , bool * is_inline )
27+ {
28+ if (likely (size == sbi -> inline_xattr_slab_size )) {
29+ * is_inline = true;
30+ return kmem_cache_zalloc (sbi -> inline_xattr_slab , GFP_NOFS );
31+ }
32+ * is_inline = false;
33+ return f2fs_kzalloc (sbi , size , GFP_NOFS );
34+ }
35+
36+ static void xattr_free (struct f2fs_sb_info * sbi , void * xattr_addr ,
37+ bool is_inline )
38+ {
39+ if (is_inline )
40+ kmem_cache_free (sbi -> inline_xattr_slab , xattr_addr );
41+ else
42+ kvfree (xattr_addr );
43+ }
44+
2645static int f2fs_xattr_generic_get (const struct xattr_handler * handler ,
2746 struct dentry * unused , struct inode * inode ,
2847 const char * name , void * buffer , size_t size )
@@ -301,7 +320,8 @@ static int read_xattr_block(struct inode *inode, void *txattr_addr)
301320static int lookup_all_xattrs (struct inode * inode , struct page * ipage ,
302321 unsigned int index , unsigned int len ,
303322 const char * name , struct f2fs_xattr_entry * * xe ,
304- void * * base_addr , int * base_size )
323+ void * * base_addr , int * base_size ,
324+ bool * is_inline )
305325{
306326 void * cur_addr , * txattr_addr , * last_txattr_addr ;
307327 void * last_addr = NULL ;
@@ -313,7 +333,7 @@ static int lookup_all_xattrs(struct inode *inode, struct page *ipage,
313333 return - ENODATA ;
314334
315335 * base_size = XATTR_SIZE (inode ) + XATTR_PADDING_SIZE ;
316- txattr_addr = f2fs_kzalloc (F2FS_I_SB (inode ), * base_size , GFP_NOFS );
336+ txattr_addr = xattr_alloc (F2FS_I_SB (inode ), * base_size , is_inline );
317337 if (!txattr_addr )
318338 return - ENOMEM ;
319339
@@ -362,7 +382,7 @@ static int lookup_all_xattrs(struct inode *inode, struct page *ipage,
362382 * base_addr = txattr_addr ;
363383 return 0 ;
364384out :
365- kvfree ( txattr_addr );
385+ xattr_free ( F2FS_I_SB ( inode ), txattr_addr , * is_inline );
366386 return err ;
367387}
368388
@@ -499,6 +519,7 @@ int f2fs_getxattr(struct inode *inode, int index, const char *name,
499519 unsigned int size , len ;
500520 void * base_addr = NULL ;
501521 int base_size ;
522+ bool is_inline ;
502523
503524 if (name == NULL )
504525 return - EINVAL ;
@@ -509,7 +530,7 @@ int f2fs_getxattr(struct inode *inode, int index, const char *name,
509530
510531 down_read (& F2FS_I (inode )-> i_xattr_sem );
511532 error = lookup_all_xattrs (inode , ipage , index , len , name ,
512- & entry , & base_addr , & base_size );
533+ & entry , & base_addr , & base_size , & is_inline );
513534 up_read (& F2FS_I (inode )-> i_xattr_sem );
514535 if (error )
515536 return error ;
@@ -532,7 +553,7 @@ int f2fs_getxattr(struct inode *inode, int index, const char *name,
532553 }
533554 error = size ;
534555out :
535- kvfree ( base_addr );
556+ xattr_free ( F2FS_I_SB ( inode ), base_addr , is_inline );
536557 return error ;
537558}
538559
@@ -764,3 +785,26 @@ int f2fs_setxattr(struct inode *inode, int index, const char *name,
764785 f2fs_update_time (sbi , REQ_TIME );
765786 return err ;
766787}
788+
789+ int f2fs_init_xattr_caches (struct f2fs_sb_info * sbi )
790+ {
791+ dev_t dev = sbi -> sb -> s_bdev -> bd_dev ;
792+ char slab_name [32 ];
793+
794+ sprintf (slab_name , "f2fs_xattr_entry-%u:%u" , MAJOR (dev ), MINOR (dev ));
795+
796+ sbi -> inline_xattr_slab_size = F2FS_OPTION (sbi ).inline_xattr_size *
797+ sizeof (__le32 ) + XATTR_PADDING_SIZE ;
798+
799+ sbi -> inline_xattr_slab = f2fs_kmem_cache_create (slab_name ,
800+ sbi -> inline_xattr_slab_size );
801+ if (!sbi -> inline_xattr_slab )
802+ return - ENOMEM ;
803+
804+ return 0 ;
805+ }
806+
807+ void f2fs_destroy_xattr_caches (struct f2fs_sb_info * sbi )
808+ {
809+ kmem_cache_destroy (sbi -> inline_xattr_slab );
810+ }
0 commit comments