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 75eeb84..6ea5698 100644 (file)
@@ -66,7 +66,7 @@ static yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev, int number,
                                        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);
@@ -3112,7 +3112,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name, int force,
 
                /* process any xattrib modifications */
                if(xmod)
-                       yaffs_ApplyXMod(dev, (char *)buffer, xmod);
+                       yaffs_ApplyXMod(in, (char *)buffer, xmod);
 
 
                /* Tags */
@@ -4939,10 +4939,11 @@ static int yaffs_DoXMod(yaffs_Object *obj, int set, const YCHAR *name, const voi
                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);
+       yaffs_Device *dev = obj->myDev;
        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);
 
+       obj->hasXattr = nval_hasvalues(x_buffer, x_size);
+       obj->xattrKnown = 1;
+
        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 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;
@@ -4984,6 +4998,11 @@ static int yaffs_DoXFetch(yaffs_Object *obj, const YCHAR *name, void *value, int
        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
index f9b5ac1..dea450f 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 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 */
 
index 4b28513..2081f21 100644 (file)
@@ -190,6 +190,7 @@ int nval_list(const char *xb, int xb_size, char *buf, int bsize)
        return ncopied;
 }
 
+#if 0
 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;
 }
+#endif
+
+
+int nval_hasvalues(const char *xb, int xb_size)
+{
+       return nval_used(xb, xb_size) > 0;
+}
index a9d4a0a..4255f3b 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_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