fs/9p: add new feature of xattr cache
Subsystems (4)
RFC PATCH v2 1/1 fs/9p: add new feature of xattr cache
Hi, All.
Recently, I check the code many times and test it. I find two bug, the first one: In function __v9fs_xattr_get_cached, can't clear flag of the xattr_item if need to query again; the second one, in the same function, if buffer_size is 0, miss handle if the flag of xattr_item is enotsupp.
And I divide the flag of xattr_item into two classes: the xattr item
data flags and xattr item flags. The flag of xattr item data is exclusion, the flag of xattr item is shared.
changes since v1:
- fix bug: in the function __v9fs_xattr_get_cached,if buffer_size is 0, miss handling if the flag of xattr_item is enotsupp
changes since RFC:
- fix bug: in the function __v9fs_xattr_get_cached, can't clear flag of the xattr_item if need to query again
- redesign the flag of xattr_item, divide the flag of xattr_item into two classes
Please review, any input welcome.
----------------------------------------------------------------------
From e3a0c4749f0f59c5c04e412d52946072db5830f2 Mon Sep 17 00:00:00 2001
From: juncheng bai <[email protected]>
Date: Mon, 1 Jun 2015 17:28:35 +0800
Subject: [PATCH RFC v2] fs/9p: add feature of xattr cache
first: this can be optimized with the application of extended attributes especially, read more than writing.
second: if specify mount option:fscache or loose, the vfs layer will search the extended attribute:security.capacility at every time to write
through the mount option:xattrcache, we can be flexible to enable this feature
In this implementation, multipath applications can read and write multiple extended attributes at the same time; More than one applications can read the same extended attribute.
--- Documentation/filesystems/9p.txt | 3 + fs/9p/Makefile | 1 + fs/9p/v9fs.c | 38 ++++++- fs/9p/v9fs.h | 15 +++ fs/9p/v9fs_vfs.h | 1 + fs/9p/vfs_inode.c | 8 ++ fs/9p/xattr.c | 214 ++++++++++++++++++++++++++++++++++-- fs/9p/xattr.h | 2 + fs/9p/xattr_cache.c | 228 +++++++++++++++++++++++++++++++++++++++ fs/9p/xattr_cache.h | 100 +++++++++++++++++ include/net/9p/9p.h | 1 + 11 files changed, 602 insertions(+), 9 deletions(-) create mode 100644 fs/9p/xattr_cache.c create mode 100644 fs/9p/xattr_cache.h
Documentation/filesystems/9p.txt +3 -0
@@ -91,6 +91,7 @@ OPTIONS 0x200 = display Fid debug 0x400 = display packet debug 0x800 = display fscache tracing debug + 0x1000 = display xattrcache tracing debug rfdno=n the file descriptor for reading with trans=fd
@@ -133,6 +134,8 @@ OPTIONS cache tags for existing cache sessions can be listed at /sys/fs/9p/caches. (applies only to cache=fscache) + xattrcache enable extended attributes cache + RESOURCES =========
fs/9p/Makefile +1 -0
@@ -11,6 +11,7 @@ obj-$(CONFIG_9P_FS) := 9p.o v9fs.o \ fid.o \ xattr.o \ + xattr_cache.o \ xattr_user.o \ xattr_trusted.o
fs/9p/v9fs.c +36 -2
@@ -38,10 +38,12 @@#include "v9fs.h" #include "v9fs_vfs.h" #include "cache.h" +#include "xattr_cache.h" static DEFINE_SPINLOCK (v9fs_sessionlist_lock);static LIST_HEAD (v9fs_sessionlist);struct kmem_cache *v9fs_inode_cache; +struct kmem_cache *v9fs_xattr_cache;/* * Option Parsing (code inspired by NFS code)
@@ -59,6 +61,8 @@ enum { Opt_cache_loose, Opt_fscache, Opt_mmap,/* Access options */ Opt_access, Opt_posixacl, +/* xattr cache */ + Opt_xcache,/* Error token */ Opt_err };
@@ -78,6 +82,7 @@ static const match_table_t tokens = { {Opt_cachetag, "cachetag=%s"}, {Opt_access, "access=%s"}, {Opt_posixacl, "posixacl"}, + {Opt_xcache, "xattrcache"}, {Opt_err, NULL} };
@@ -126,6 +131,7 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)#ifdef CONFIG_9P_FSCACHE v9ses->cachetag =NULL ;#endif + v9ses->xcache =0 ;if (!opts)return 0 ;
@@ -297,7 +303,9 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) "Not defined CONFIG_9P_FS_POSIX_ACL. Ignoring posixacl option\n");#endif break ; - +case Opt_xcache: + v9ses->xcache =1 ; +break ;default :continue ; }
@@ -589,6 +597,17 @@ static int v9fs_init_inode_cache(void)return 0 ; } +static int v9fs_init_xattr_cache (void ) +{ + v9fs_xattr_cache =kmem_cache_create ("v9fs_xattr_cache" , +sizeof (struct xattr_item ), +0 ,0 ,NULL ); +if (!v9fs_xattr_cache) +return -ENOMEM ; + +return 0 ; +} +/** * v9fs_destroy_inode_cache - destroy the cache of 9P inode *
@@ -603,16 +622,30 @@ static void v9fs_destroy_inode_cache(void)kmem_cache_destroy (v9fs_inode_cache); } +static void v9fs_destroy_xattr_cache (void ) +{ +kmem_cache_destroy (v9fs_xattr_cache); +} +static int v9fs_cache_register (void ) {int ret; ret =v9fs_init_inode_cache ();if (ret <0 )return ret; + + ret =v9fs_init_xattr_cache (); +if (ret <0 ) { +v9fs_destroy_inode_cache (); +return ret; + } +#ifdef CONFIG_9P_FSCACHE ret =fscache_register_netfs (&v9fs_cache_netfs); -if (ret <0 ) +if (ret <0 ) {v9fs_destroy_inode_cache (); +v9fs_destroy_xattr_cache (); + }#endif return ret; }
@@ -620,6 +653,7 @@ static int v9fs_cache_register(void)static void v9fs_cache_unregister (void ) {v9fs_destroy_inode_cache (); +v9fs_destroy_xattr_cache ();#ifdef CONFIG_9P_FSCACHE fscache_unregister_netfs (&v9fs_cache_netfs);#endif
fs/9p/v9fs.h +15 -0
@@ -101,6 +101,7 @@ struct v9fs_session_info {unsigned short debug;unsigned int afid;unsigned int cache; +unsigned short xcache;#ifdef CONFIG_9P_FSCACHE char *cachetag;struct fscache_cookie *fscache;
@@ -121,6 +122,15 @@ struct v9fs_session_info {/* cache_validity flags */ #define V9FS_INO_INVALID_ATTR 0x01 +/** +* @xal_head: fast path, the xattr has beed queried from backend +* @xaf_head: slow path, the xattr is looking up from backend +* +* Ensure implementation query request as soon as possible from xal_head +* +* Return from query, if there is not error, except -ENOTSUPP and -ERANGE, +* move xattr_item from xaf_head to xal_head, or set V9FS_XI_Removing +*/ struct v9fs_inode {#ifdef CONFIG_9P_FSCACHE spinlock_t fscache_lock;
@@ -131,6 +141,11 @@ struct v9fs_inode {struct p9_fid *writeback_fid;struct mutex v_mutex;struct inode vfs_inode; + +rwlock_t xal_lock; +struct list_head xal_head; +spinlock_t xaf_lock; +struct list_head xaf_head; };static inline struct v9fs_inode *V9FS_I (const struct inode *inode)
fs/9p/v9fs_vfs.h +1 -0
@@ -53,6 +53,7 @@ extern const struct file_operations v9fs_cached_file_operations_dotl;extern const struct file_operations v9fs_mmap_file_operations;extern const struct file_operations v9fs_mmap_file_operations_dotl;extern struct kmem_cache *v9fs_inode_cache; +extern struct kmem_cache *v9fs_xattr_cache;struct inode *v9fs_alloc_inode (struct super_block *sb);void v9fs_destroy_inode (struct inode *inode);
fs/9p/vfs_inode.c +8 -0
@@ -249,6 +249,12 @@ struct inode *v9fs_alloc_inode(struct super_block *sb) v9inode->writeback_fid =NULL ; v9inode->cache_validity =0 ;mutex_init (&v9inode->v_mutex); + +rwlock_init (&v9inode->xal_lock); +INIT_LIST_HEAD (&v9inode->xal_head); +spin_lock_init (&v9inode->xaf_lock); +INIT_LIST_HEAD (&v9inode->xaf_head); +return &v9inode->vfs_inode; }
@@ -260,6 +266,8 @@ struct inode *v9fs_alloc_inode(struct super_block *sb)static void v9fs_i_callback (struct rcu_head *head) { struct inode *inode = container_of(head, struct inode, i_rcu); + +v9fs_free_inode_xattr_items (inode);kmem_cache_free (v9fs_inode_cache,V9FS_I (inode)); }
fs/9p/xattr.c +207 -7
246 lines not on this page · raw message
fs/9p/xattr.h +2 -0
@@ -18,6 +18,8 @@#include <net/9p/9p.h> #include <net/9p/client.h> +#include "xattr_cache.h" +extern const struct xattr_handler *v9fs_xattr_handlers[];extern struct xattr_handler v9fs_xattr_user_handler;extern struct xattr_handler v9fs_xattr_trusted_handler;
fs/9p/xattr_cache.c new file +228 -0
228 lines not on this page · raw message
fs/9p/xattr_cache.h new file +100 -0
100 lines not on this page · raw message
include/net/9p/9p.h +1 -0
@@ -59,6 +59,7 @@ enum p9_debug_flags {P9_DEBUG_PKT = (1 <<10 ),P9_DEBUG_FSC = (1 <<11 ),P9_DEBUG_VPKT = (1 <<12 ), + P9_DEBUG_XCACHE = (1<<13), };#ifdef CONFIG_NET_9P_DEBUG
Signature · 1 line
1.9.5.msysgit.1