yaffs: Cache object xattrib state.
authorCharles Manning <cdhmanning@gmail.com>
Wed, 8 Sep 2010 21:20:23 +0000 (09:20 +1200)
committerCharles Manning <cdhmanning@gmail.com>
Wed, 8 Sep 2010 21:20:23 +0000 (09:20 +1200)
We cache whether or not an object has xattributes.

This is done to get around the problem of the Linux VFS trying to check security
capabilities on every write. Assuming that most files don't have security
attributes, this code will save on a huge amount of reads and make writing
faster.

Signed-off-by: Charles Manning <cdhmanning@gmail.com>
yaffs_guts.c
yaffs_guts.h
yaffs_nameval.c
yaffs_nameval.h

index 75eeb84cf3d5d23459d9897fa2b1fbc9e5b9c88c..6ea5698b5052dd375e15bceba736a183209587cc 100644 (file)
@@ -66,7 +66,7 @@ static yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev, int number,
                                        yaffs_ObjectType type);
 
 
                                        yaffs_ObjectType type);
 
 
-static int yaffs_ApplyXMod(yaffs_Device *dev, char *buffer, yaffs_XAttrMod *xmod);
+static int yaffs_ApplyXMod(yaffs_Object *obj, char *buffer, yaffs_XAttrMod *xmod);
 
 static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj);
 static int yaffs_CheckStructures(void);
 
 static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj);
 static int yaffs_CheckStructures(void);
@@ -3112,7 +3112,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name, int force,
 
                /* process any xattrib modifications */
                if(xmod)
 
                /* process any xattrib modifications */
                if(xmod)
-                       yaffs_ApplyXMod(dev, (char *)buffer, xmod);
+                       yaffs_ApplyXMod(in, (char *)buffer, xmod);
 
 
                /* Tags */
 
 
                /* Tags */
@@ -4939,10 +4939,11 @@ static int yaffs_DoXMod(yaffs_Object *obj, int set, const YCHAR *name, const voi
                return -ENOSPC;
 }
 
                return -ENOSPC;
 }
 
-static int yaffs_ApplyXMod(yaffs_Device *dev, char *buffer, yaffs_XAttrMod *xmod)
+static int yaffs_ApplyXMod(yaffs_Object *obj, char *buffer, yaffs_XAttrMod *xmod)
 {
        int retval = 0;
        int x_offs = sizeof(yaffs_ObjectHeader);
 {
        int retval = 0;
        int x_offs = sizeof(yaffs_ObjectHeader);
+       yaffs_Device *dev = obj->myDev;
        int x_size = dev->nDataBytesPerChunk - sizeof(yaffs_ObjectHeader);
 
        char * x_buffer = buffer + x_offs;
        int x_size = dev->nDataBytesPerChunk - sizeof(yaffs_ObjectHeader);
 
        char * x_buffer = buffer + x_offs;
@@ -4952,6 +4953,9 @@ static int yaffs_ApplyXMod(yaffs_Device *dev, char *buffer, yaffs_XAttrMod *xmod
        else
                retval = nval_del(x_buffer, x_size, xmod->name);
 
        else
                retval = nval_del(x_buffer, x_size, xmod->name);
 
+       obj->hasXattr = nval_hasvalues(x_buffer, x_size);
+       obj->xattrKnown = 1;
+
        xmod->result = retval;
 
        return retval;
        xmod->result = retval;
 
        return retval;
@@ -4973,6 +4977,16 @@ static int yaffs_DoXFetch(yaffs_Object *obj, const YCHAR *name, void *value, int
        if(obj->hdrChunk < 1)
                return -ENODATA;
 
        if(obj->hdrChunk < 1)
                return -ENODATA;
 
+       /* If we know that the object has no xattribs then don't do all the
+        * reading and parsing.
+        */
+       if(obj->xattrKnown && !obj->hasXattr){
+               if(name)
+                       return -ENODATA;
+               else
+                       return 0;
+       }
+
        buffer = yaffs_GetTempBuffer(dev, __LINE__);
        if(!buffer)
                return -ENOMEM;
        buffer = yaffs_GetTempBuffer(dev, __LINE__);
        if(!buffer)
                return -ENOMEM;
@@ -4984,6 +4998,11 @@ static int yaffs_DoXFetch(yaffs_Object *obj, const YCHAR *name, void *value, int
        else{
                x_buffer =  buffer + x_offs;
 
        else{
                x_buffer =  buffer + x_offs;
 
+               if (!obj->xattrKnown){
+                       obj->hasXattr = nval_hasvalues(x_buffer, x_size);
+                       obj->xattrKnown = 1;
+               }
+
                if(name)
                        retval = nval_get(x_buffer, x_size, name, value, size);
                else
                if(name)
                        retval = nval_get(x_buffer, x_size, name, value, size);
                else
index f9b5ac192424b50a7ecda2509f35a14f05da867b..dea450f3ac7d50b00d56ae4563b3a88a0de57fe4 100644 (file)
@@ -423,6 +423,9 @@ struct yaffs_ObjectStruct {
        __u8 beingCreated:1;    /* This object is still being created so skip some checks. */
        __u8 isShadowed:1;      /* This object is shadowed on the way to being renamed. */
 
        __u8 beingCreated:1;    /* This object is still being created so skip some checks. */
        __u8 isShadowed:1;      /* This object is shadowed on the way to being renamed. */
 
+       __u8 xattrKnown:1;      /* We know if this has object has xattribs or not. */
+       __u8 hasXattr:1;        /* This object has xattribs. Valid if xattrKnown. */
+
        __u8 serial;            /* serial number of chunk in NAND. Cached here */
        __u16 sum;              /* sum of the name to speed searching */
 
        __u8 serial;            /* serial number of chunk in NAND. Cached here */
        __u16 sum;              /* sum of the name to speed searching */
 
index 4b285130a6f4a1b808c6d1398519ac2939d8071b..2081f21dacd3a3e21e666c00fcecc0d3c59400d6 100644 (file)
@@ -190,6 +190,7 @@ int nval_list(const char *xb, int xb_size, char *buf, int bsize)
        return ncopied;
 }
 
        return ncopied;
 }
 
+#if 0
 int nval_load(char *xb, int xb_size, const char *src, int src_size)
 {
        int tx_size;
 int nval_load(char *xb, int xb_size, const char *src, int src_size)
 {
        int tx_size;
@@ -218,3 +219,10 @@ int nval_save(const char *xb, int xb_size, char *dest, int dest_size)
        memcpy(dest,xb,tx_size);
        return tx_size;
 }
        memcpy(dest,xb,tx_size);
        return tx_size;
 }
+#endif
+
+
+int nval_hasvalues(const char *xb, int xb_size)
+{
+       return nval_used(xb, xb_size) > 0;
+}
index a9d4a0ae2384693c5a13e2b8587abc002d0b828b..4255f3b053e85592d9ce253f7c9e0d219511be26 100644 (file)
@@ -21,7 +21,5 @@ int nval_del(char *xb, int xb_size, const YCHAR *name);
 int nval_set(char *xb, int xb_size, const YCHAR *name, const char *buf, int bsize, int flags);
 int nval_get(const char *xb, int xb_size, const YCHAR *name, char *buf, int bsize);
 int nval_list(const char *xb, int xb_size, char *buf, int bsize);
 int nval_set(char *xb, int xb_size, const YCHAR *name, const char *buf, int bsize, int flags);
 int nval_get(const char *xb, int xb_size, const YCHAR *name, char *buf, int bsize);
 int nval_list(const char *xb, int xb_size, char *buf, int bsize);
-int nval_load(char *xb, int xb_size, const char *src, int src_size);
-int nval_save(const char *xb, int xb_size, char *dest, int dest_size);
-
+int nval_hasvalues(const char *xb, int xb_size);
 #endif
 #endif