[haiku-commits] haiku: hrev50884 - in src: add-ons/kernel/file_systems/bfs tools/bfs_shell bin/mkfs

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 19 Jan 2017 22:15:24 +0100 (CET)

hrev50884 adds 6 changesets to branch 'master'
old head: 991d9dbf6dd562590f62b82d1015fa9cd515264e
new head: 91cdfd96f8729cdfd5f80f1ab54e7d7600f5ecd5
overview: 
http://cgit.haiku-os.org/haiku/log/?qt=range&q=91cdfd96f872+%5E991d9dbf6dd5

----------------------------------------------------------------------------

e5022f23b3cc: Coding style cleanup, no functional change.

a2eb6bbda477: bfs: Minor cleanup.
  
  * Added helper methods for operator/equation characters.

f79179975d5e: bfs: Query parser needs to filter out escape char.
  
  * When escaping operator/quote characters, the character was properly
    ignored. However, the escape char was left in the string which
    altered the query.
  * This fixes bug #10976.

3af0b8555ecd: bfs_shell: Fixed (missing) use of the FSSH_B_PRI* macros.
  
  * This closes ticket #12657.

9e71fa0e2117: mkfs: Added an example to the help text.

91cdfd96f872: bfs: Never publish the index root node.
  
  * This caused the volume to be un-unmountable when you created an index
    on a non-indexed volume.

                                   [ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

6 files changed, 377 insertions(+), 328 deletions(-)
src/add-ons/kernel/file_systems/bfs/Inode.cpp  |  15 +-
src/add-ons/kernel/file_systems/bfs/Inode.h    |   4 +
src/add-ons/kernel/file_systems/bfs/Query.cpp  | 628 +++++++++++----------
src/add-ons/kernel/file_systems/bfs/Volume.cpp |  10 +-
src/bin/mkfs/main.cpp                          |   9 +-
src/tools/bfs_shell/command_checkfs.cpp        |  39 +-

############################################################################

Commit:      e5022f23b3cc87b2123206fb3fc4e5f5eec14e35
URL:         http://cgit.haiku-os.org/haiku/commit/?id=e5022f23b3cc
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Thu Jan 19 19:48:07 2017 UTC

Coding style cleanup, no functional change.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/file_systems/bfs/Query.cpp 
b/src/add-ons/kernel/file_systems/bfs/Query.cpp
index 1ec3c20..a8d127c 100644
--- a/src/add-ons/kernel/file_systems/bfs/Query.cpp
+++ b/src/add-ons/kernel/file_systems/bfs/Query.cpp
@@ -74,31 +74,32 @@ union value {
 */
 class Term {
 public:
-                                               Term(int8 op) : fOp(op), 
fParent(NULL) {}
-       virtual                         ~Term() {}
+                                                               Term(int8 op) : 
fOp(op), fParent(NULL) {}
+       virtual                                         ~Term() {}
 
-                       int8            Op() const { return fOp; }
+                       int8                            Op() const { return 
fOp; }
 
-                       void            SetParent(Term* parent) { fParent = 
parent; }
-                       Term*           Parent() const { return fParent; }
+                       void                            SetParent(Term* parent) 
{ fParent = parent; }
+                       Term*                           Parent() const { return 
fParent; }
 
-       virtual status_t        Match(Inode* inode, const char* attribute = 
NULL,
-                                                       int32 type = 0, const 
uint8* key = NULL,
-                                                       size_t size = 0) = 0;
-       virtual void            Complement() = 0;
+       virtual status_t                        Match(Inode* inode,
+                                                                       const 
char* attribute = NULL,
+                                                                       int32 
type = 0, const uint8* key = NULL,
+                                                                       size_t 
size = 0) = 0;
+       virtual void                            Complement() = 0;
 
-       virtual void            CalculateScore(Index& index) = 0;
-       virtual int32           Score() const = 0;
+       virtual void                            CalculateScore(Index& index) = 
0;
+       virtual int32                           Score() const = 0;
 
-       virtual status_t        InitCheck() = 0;
+       virtual status_t                        InitCheck() = 0;
 
 #ifdef DEBUG
-       virtual void            PrintToStream() = 0;
+       virtual void                            PrintToStream() = 0;
 #endif
 
 protected:
-                       int8            fOp;
-                       Term*           fParent;
+                       int8                            fOp;
+                       Term*                           fParent;
 };
 
 
@@ -115,51 +116,54 @@ protected:
 */
 class Equation : public Term {
 public:
-                                               Equation(char** expression);
-       virtual                         ~Equation();
+                                                               Equation(char** 
_expression);
+       virtual                                         ~Equation();
 
-       virtual status_t        InitCheck();
+       virtual status_t                        InitCheck();
 
-                       status_t        ParseQuotedString(char** _start, char** 
_end);
-                       char*           CopyString(char* start, char* end);
+       virtual status_t                        Match(Inode* inode,
+                                                                       const 
char* attribute = NULL,
+                                                                       int32 
type = 0, const uint8* key = NULL,
+                                                                       size_t 
size = 0);
+       virtual void                            Complement();
 
-       virtual status_t        Match(Inode* inode, const char* attribute = 
NULL,
-                                                       int32 type = 0, const 
uint8* key = NULL,
-                                                       size_t size = 0);
-       virtual void            Complement();
+                       status_t                        PrepareQuery(Volume* 
volume, Index& index,
+                                                                       
TreeIterator** iterator,
+                                                                       bool 
queryNonIndexed);
+                       status_t                        GetNextMatching(Volume* 
volume,
+                                                                       
TreeIterator* iterator,
+                                                                       struct 
dirent* dirent, size_t bufferSize);
 
-                       status_t        PrepareQuery(Volume* volume, Index& 
index,
-                                                       TreeIterator** 
iterator, bool queryNonIndexed);
-                       status_t        GetNextMatching(Volume* volume, 
TreeIterator* iterator,
-                                                       struct dirent* dirent, 
size_t bufferSize);
-
-       virtual void            CalculateScore(Index &index);
-       virtual int32           Score() const { return fScore; }
+       virtual void                            CalculateScore(Index &index);
+       virtual int32                           Score() const { return fScore; }
 
 #ifdef DEBUG
-       virtual void            PrintToStream();
+       virtual void                            PrintToStream();
 #endif
 
 private:
-                                               Equation(const Equation& other);
-                                               Equation& operator=(const 
Equation& other);
-                                                       // no implementation
-
-                       status_t        ConvertValue(type_code type);
-                       bool            CompareTo(const uint8* value, uint16 
size);
-                       uint8*          Value() const { return (uint8*)&fValue; 
}
-                       status_t        MatchEmptyString();
-
-                       char*           fAttribute;
-                       char*           fString;
-                       union value fValue;
-                       type_code       fType;
-                       size_t          fSize;
-                       bool            fIsPattern;
-                       bool            fIsSpecialTime;
-
-                       int32           fScore;
-                       bool            fHasIndex;
+                                                               Equation(const 
Equation& other);
+                                                               Equation& 
operator=(const Equation& other);
+                                                                       // no 
implementation
+
+                       status_t                        
_ParseQuotedString(char** _start, char** _end);
+                       char*                           _CopyString(char* 
start, char* end);
+                       status_t                        _ConvertValue(type_code 
type);
+                       bool                            _CompareTo(const uint8* 
value, uint16 size);
+                       uint8*                          _Value() const { return 
(uint8*)&fValue; }
+                       status_t                        _MatchEmptyString();
+
+private:
+                       char*                           fAttribute;
+                       char*                           fString;
+                       union value                     fValue;
+                       type_code                       fType;
+                       size_t                          fSize;
+                       bool                            fIsPattern;
+                       bool                            fIsSpecialTime;
+
+                       int32                           fScore;
+                       bool                            fHasIndex;
 };
 
 
@@ -168,40 +172,42 @@ private:
 */
 class Operator : public Term {
 public:
-                                               Operator(Term* left, int8 op, 
Term* right);
-       virtual                         ~Operator();
+                                                               Operator(Term* 
left, int8 op, Term* right);
+       virtual                                         ~Operator();
 
-                       Term*           Left() const { return fLeft; }
-                       Term*           Right() const { return fRight; }
+                       Term*                           Left() const { return 
fLeft; }
+                       Term*                           Right() const { return 
fRight; }
 
-       virtual status_t        Match(Inode* inode, const char* attribute = 
NULL,
-                                                       int32 type = 0, const 
uint8* key = NULL,
-                                                       size_t size = 0);
-       virtual void            Complement();
+       virtual status_t                        Match(Inode* inode,
+                                                                       const 
char* attribute = NULL,
+                                                                       int32 
type = 0, const uint8* key = NULL,
+                                                                       size_t 
size = 0);
+       virtual void                            Complement();
 
-       virtual void            CalculateScore(Index& index);
-       virtual int32           Score() const;
+       virtual void                            CalculateScore(Index& index);
+       virtual int32                           Score() const;
 
-       virtual status_t        InitCheck();
+       virtual status_t                        InitCheck();
 
 #ifdef DEBUG
-       virtual void            PrintToStream();
+       virtual void                            PrintToStream();
 #endif
 
 private:
-                                               Operator(const Operator& other);
-                                               Operator& operator=(const 
Operator& other);
-                                                       // no implementation
+                                                               Operator(const 
Operator& other);
+                                                               Operator& 
operator=(const Operator& other);
+                                                                       // no 
implementation
 
-                       Term*           fLeft;
-                       Term*           fRight;
+private:
+                       Term*                           fLeft;
+                       Term*                           fRight;
 };
 
 
 //     #pragma mark -
 
 
-Equation::Equation(char** expr)
+Equation::Equation(char** _expression)
        :
        Term(OP_EQUATION),
        fAttribute(NULL),
@@ -209,7 +215,7 @@ Equation::Equation(char** expr)
        fType(0),
        fIsPattern(false)
 {
-       char* string = *expr;
+       char* string = *_expression;
        char* start = string;
        char* end = NULL;
 
@@ -220,7 +226,7 @@ Equation::Equation(char** expr)
 
        if (*start == '"' || *start == '\'') {
                // string is quoted (start has to be on the beginning of a 
string)
-               if (ParseQuotedString(&start, &end) < B_OK)
+               if (_ParseQuotedString(&start, &end) < B_OK)
                        return;
 
                // set string to a valid start of the equation symbol
@@ -228,7 +234,7 @@ Equation::Equation(char** expr)
                skipWhitespace(&string);
                if (*string != '=' && *string != '<' && *string != '>'
                        && *string != '!') {
-                       *expr = string;
+                       *_expression = string;
                        return;
                }
        } else {
@@ -274,7 +280,7 @@ Equation::Equation(char** expr)
 
                // any invalid characters will be rejected
                default:
-                       *expr = string;
+                       *_expression = string;
                        return;
        }
 
@@ -286,14 +292,14 @@ Equation::Equation(char** expr)
 
        // allocate & copy the attribute string
 
-       fAttribute = CopyString(start, end);
+       fAttribute = _CopyString(start, end);
        if (fAttribute == NULL)
                return;
 
        start = string;
        if (*start == '"' || *start == '\'') {
                // string is quoted (start has to be on the beginning of a 
string)
-               if (ParseQuotedString(&start, &end) < B_OK)
+               if (_ParseQuotedString(&start, &end) < B_OK)
                        return;
 
                string = end + 2;
@@ -306,19 +312,19 @@ Equation::Equation(char** expr)
                skipWhitespaceReverse(&end, start);
        }
 
-       // at this point, "start" will point to the first character of the 
value,
+       // At this point, "start" will point to the first character of the 
value,
        // "end" will point to its last character, and "start" to the first non-
-       // whitespace character after the value string
+       // whitespace character after the value string.
 
-       fString = CopyString(start, end);
+       fString = _CopyString(start, end);
        if (fString == NULL)
                return;
 
-       // patterns are only allowed for these operations (and strings)
+       // Patterns are only allowed for these operations (and strings)
        if (fOp == OP_EQUAL || fOp == OP_UNEQUAL) {
                fIsPattern = isPattern(fString);
                if (fIsPattern && isValidPattern(fString) < B_OK) {
-                       // we only want to have valid patterns; setting fString
+                       // Only valid patterns are allowed; setting fString
                        // to NULL will cause InitCheck() to fail
                        free(fString);
                        fString = NULL;
@@ -333,7 +339,7 @@ Equation::Equation(char** expr)
        // too one day.
        fIsSpecialTime = !strcmp(fAttribute, "last_modified");
 
-       *expr = string;
+       *_expression = string;
 }
 
 
@@ -354,184 +360,6 @@ Equation::InitCheck()
 }
 
 
-status_t
-Equation::ParseQuotedString(char** _start, char** _end)
-{
-       char* start = *_start;
-       char quote = *start++;
-       char* end = start;
-
-       for (; *end && *end != quote; end++) {
-               if (*end == '\\')
-                       end++;
-       }
-       if (*end == '\0')
-               return B_BAD_VALUE;
-
-       *_start = start;
-       *_end = end - 1;
-
-       return B_OK;
-}
-
-
-char*
-Equation::CopyString(char* start, char* end)
-{
-       // end points to the last character of the string - and the length
-       // also has to include the null-termination
-       int32 length = end + 2 - start;
-       // just to make sure; since that's the max. attribute name length and
-       // the max. string in an index, it make sense to have it that way
-       if (length > INODE_FILE_NAME_LENGTH || length <= 0)
-               return NULL;
-
-       char* copy = (char*)malloc(length);
-       if (copy == NULL)
-               return NULL;
-
-       memcpy(copy, start, length - 1);
-       copy[length - 1] = '\0';
-
-       return copy;
-}
-
-
-status_t
-Equation::ConvertValue(type_code type)
-{
-       // Has the type already been converted?
-       if (type == fType)
-               return B_OK;
-
-       char* string = fString;
-
-       switch (type) {
-               case B_MIME_STRING_TYPE:
-                       type = B_STRING_TYPE;
-                       // supposed to fall through
-               case B_STRING_TYPE:
-                       strncpy(fValue.String, string, INODE_FILE_NAME_LENGTH);
-                       fValue.String[INODE_FILE_NAME_LENGTH - 1] = '\0';
-                       fSize = strlen(fValue.String);
-                       break;
-               case B_INT32_TYPE:
-                       fValue.Int32 = strtol(string, &string, 0);
-                       fSize = sizeof(int32);
-                       break;
-               case B_UINT32_TYPE:
-                       fValue.Int32 = strtoul(string, &string, 0);
-                       fSize = sizeof(uint32);
-                       break;
-               case B_INT64_TYPE:
-                       fValue.Int64 = strtoll(string, &string, 0);
-                       fSize = sizeof(int64);
-                       break;
-               case B_UINT64_TYPE:
-                       fValue.Uint64 = strtoull(string, &string, 0);
-                       fSize = sizeof(uint64);
-                       break;
-               case B_FLOAT_TYPE:
-                       fValue.Float = strtod(string, &string);
-                       fSize = sizeof(float);
-                       break;
-               case B_DOUBLE_TYPE:
-                       fValue.Double = strtod(string, &string);
-                       fSize = sizeof(double);
-                       break;
-               default:
-                       FATAL(("query value conversion to 0x%x requested!\n", 
(int)type));
-                       // should we fail here or just do a safety int32 
conversion?
-                       return B_ERROR;
-       }
-
-       fType = type;
-
-       // patterns are only allowed for string types
-       if (fType != B_STRING_TYPE && fIsPattern)
-               fIsPattern = false;
-
-       return B_OK;
-}
-
-
-/*!    Returns true when the key matches the equation. You have to
-       call ConvertValue() before this one.
-*/
-bool
-Equation::CompareTo(const uint8* value, uint16 size)
-{
-       int32 compare;
-
-       // fIsPattern is only true if it's a string type, and fOp OP_EQUAL, or
-       // OP_UNEQUAL
-       if (fIsPattern) {
-               // we have already validated the pattern, so we don't check for 
failing
-               // here - if something is broken, and matchString() returns an 
error,
-               // we just don't match
-               compare = matchString(fValue.String, (char*)value) == MATCH_OK 
? 0 : 1;
-       } else if (fIsSpecialTime) {
-               // the index is a shifted int64 index, but we have to match
-               // against an unshifted value (i.e. the last_modified index)
-               int64 timeValue = *(int64*)value >> INODE_TIME_SHIFT;
-               compare = compareKeys(fType, &timeValue, sizeof(int64), 
&fValue.Int64,
-                       sizeof(int64));
-       } else
-               compare = compareKeys(fType, value, size, Value(), fSize);
-
-       switch (fOp) {
-               case OP_EQUAL:
-                       return compare == 0;
-               case OP_UNEQUAL:
-                       return compare != 0;
-               case OP_LESS_THAN:
-                       return compare < 0;
-               case OP_LESS_THAN_OR_EQUAL:
-                       return compare <= 0;
-               case OP_GREATER_THAN:
-                       return compare > 0;
-               case OP_GREATER_THAN_OR_EQUAL:
-                       return compare >= 0;
-       }
-       FATAL(("Unknown/Unsupported operation: %d\n", fOp));
-       return false;
-}
-
-
-void
-Equation::Complement()
-{
-       D(if (fOp <= OP_EQUATION || fOp > OP_LESS_THAN_OR_EQUAL) {
-               FATAL(("op out of range!"));
-               return;
-       });
-
-       int8 complementOp[] = {OP_UNEQUAL, OP_EQUAL, OP_LESS_THAN_OR_EQUAL,
-                       OP_GREATER_THAN_OR_EQUAL, OP_LESS_THAN, 
OP_GREATER_THAN};
-       fOp = complementOp[fOp - OP_EQUAL];
-}
-
-
-status_t
-Equation::MatchEmptyString()
-{
-       // There is no matching attribute, we will just bail out if we
-       // already know that our value is not of a string type.
-       // If not, it will be converted to a string - and then be compared with 
"".
-       // That's why we have to call ConvertValue() here - but it will be
-       // a cheap call for the next time
-       // TODO: Should we do this only for OP_UNEQUAL?
-       if (fType != 0 && fType != B_STRING_TYPE)
-               return NO_MATCH;
-
-       status_t status = ConvertValue(B_STRING_TYPE);
-       if (status == B_OK)
-               status = CompareTo((const uint8*)"", fSize) ? MATCH_OK : 
NO_MATCH;
-
-       return status;
-}
-
-
 /*!    Matches the inode's attribute value with the equation.
        Returns MATCH_OK if it matches, NO_MATCH if not, < 0 if something went
        wrong.
@@ -550,7 +378,7 @@ Equation::Match(Inode* inode, const char* attributeName, 
int32 type,
        if (attributeName != NULL && !strcmp(fAttribute, attributeName)) {
                if (key == NULL) {
                        if (type == B_STRING_TYPE)
-                               return MatchEmptyString();
+                               return _MatchEmptyString();
 
                        return NO_MATCH;
                }
@@ -623,13 +451,13 @@ Equation::Match(Inode* inode, const char* attributeName, 
int32 type,
                                }
                                inode->ReleaseAttribute(attribute);
                        } else
-                               return MatchEmptyString();
+                               return _MatchEmptyString();
                }
        }
        // prepare own value for use, if it is possible to convert it
-       status_t status = ConvertValue(type);
+       status_t status = _ConvertValue(type);
        if (status == B_OK)
-               status = CompareTo(buffer, size) ? MATCH_OK : NO_MATCH;
+               status = _CompareTo(buffer, size) ? MATCH_OK : NO_MATCH;
 
        if (locked)
                recursive_lock_unlock(&inode->SmallDataLock());
@@ -639,36 +467,16 @@ Equation::Match(Inode* inode, const char* attributeName, 
int32 type,
 
 
 void
-Equation::CalculateScore(Index &index)
+Equation::Complement()
 {
-       // As always, these values could be tuned and refined.
-       // And the code could also need some real world testing :-)
-
-       // do we have to operate on a "foreign" index?
-       if (fOp == OP_UNEQUAL || index.SetTo(fAttribute) < B_OK) {
-               fScore = 0;
+       D(if (fOp <= OP_EQUATION || fOp > OP_LESS_THAN_OR_EQUAL) {
+               FATAL(("op out of range!"));
                return;
-       }
-
-       // if we have a pattern, how much does it help our search?
-       if (fIsPattern)
-               fScore = getFirstPatternSymbol(fString) << 3;
-       else {
-               // Score by operator
-               if (fOp == OP_EQUAL)
-                       // higher than pattern="255 chars+*"
-                       fScore = 2048;
-               else
-                       // the pattern search is regarded cheaper when you have 
at
-                       // least one character to set your index to
-                       fScore = 5;
-       }
+       });
 
-       // take index size into account (1024 is the current node size
-       // in our B+trees)
-       // 2048 * 2048 == 4194304 is the maximum score (for an empty
-       // tree, since the header + 1 node are already 2048 bytes)
-       fScore = fScore * ((2048 * 1024LL) / index.Node()->Size());
+       int8 complementOp[] = {OP_UNEQUAL, OP_EQUAL, OP_LESS_THAN_OR_EQUAL,
+                       OP_GREATER_THAN_OR_EQUAL, OP_LESS_THAN, 
OP_GREATER_THAN};
+       fOp = complementOp[fOp - OP_EQUAL];
 }
 
 
@@ -701,7 +509,7 @@ Equation::PrepareQuery(Volume* /*volume*/, Index& index,
                type = index.Type();
        }
 
-       if (ConvertValue(type) < B_OK)
+       if (_ConvertValue(type) < B_OK)
                return B_BAD_VALUE;
 
        BPlusTree* tree = index.Node()->Tree();
@@ -753,7 +561,7 @@ Equation::PrepareQuery(Volume* /*volume*/, Index& index,
                        if (status == B_ENTRY_NOT_FOUND)
                                return B_OK;
                } else {
-                       status = (*iterator)->Find(Value(), keySize);
+                       status = (*iterator)->Find(_Value(), keySize);
                        if (fOp == OP_EQUAL && !fIsPattern)
                                return status;
                        else if (status == B_ENTRY_NOT_FOUND
@@ -787,7 +595,7 @@ Equation::GetNextMatching(Volume* volume, TreeIterator* 
iterator,
                // only compare against the index entry when this is the correct
                // index for the equation
                if (fHasIndex && duplicate < 2
-                       && !CompareTo((uint8*)&indexValue, keyLength)) {
+                       && !_CompareTo((uint8*)&indexValue, keyLength)) {
                        // They aren't equal? Let the operation decide what to 
do. Since
                        // we always start at the beginning of the index (or 
the correct
                        // position), only some needs to be stopped if the 
entry doesn't
@@ -876,6 +684,204 @@ Equation::GetNextMatching(Volume* volume, TreeIterator* 
iterator,
 }
 
 
+void
+Equation::CalculateScore(Index &index)
+{
+       // As always, these values could be tuned and refined.
+       // And the code could also need some real world testing :-)
+
+       // do we have to operate on a "foreign" index?
+       if (fOp == OP_UNEQUAL || index.SetTo(fAttribute) < B_OK) {
+               fScore = 0;
+               return;
+       }
+
+       // if we have a pattern, how much does it help our search?
+       if (fIsPattern)
+               fScore = getFirstPatternSymbol(fString) << 3;
+       else {
+               // Score by operator
+               if (fOp == OP_EQUAL)
+                       // higher than pattern="255 chars+*"
+                       fScore = 2048;
+               else
+                       // the pattern search is regarded cheaper when you have 
at
+                       // least one character to set your index to
+                       fScore = 5;
+       }
+
+       // take index size into account (1024 is the current node size
+       // in our B+trees)
+       // 2048 * 2048 == 4194304 is the maximum score (for an empty
+       // tree, since the header + 1 node are already 2048 bytes)
+       fScore = fScore * ((2048 * 1024LL) / index.Node()->Size());
+}
+
+
+status_t
+Equation::_ParseQuotedString(char** _start, char** _end)
+{
+       char* start = *_start;
+       char quote = *start++;
+       char* end = start;
+
+       for (; *end && *end != quote; end++) {
+               if (*end == '\\')
+                       end++;
+       }
+       if (*end == '\0')
+               return B_BAD_VALUE;
+
+       *_start = start;
+       *_end = end - 1;
+
+       return B_OK;
+}
+
+
+char*
+Equation::_CopyString(char* start, char* end)
+{
+       // end points to the last character of the string - and the length
+       // also has to include the null-termination
+       int32 length = end + 2 - start;
+       // just to make sure; since that's the max. attribute name length and
+       // the max. string in an index, it make sense to have it that way
+       if (length > INODE_FILE_NAME_LENGTH || length <= 0)
+               return NULL;
+
+       char* copy = (char*)malloc(length);
+       if (copy == NULL)
+               return NULL;
+
+       memcpy(copy, start, length - 1);
+       copy[length - 1] = '\0';
+
+       return copy;
+}
+
+
+status_t
+Equation::_ConvertValue(type_code type)
+{
+       // Has the type already been converted?
+       if (type == fType)
+               return B_OK;
+
+       char* string = fString;
+
+       switch (type) {
+               case B_MIME_STRING_TYPE:
+                       type = B_STRING_TYPE;
+                       // supposed to fall through
+               case B_STRING_TYPE:
+                       strncpy(fValue.String, string, INODE_FILE_NAME_LENGTH);
+                       fValue.String[INODE_FILE_NAME_LENGTH - 1] = '\0';
+                       fSize = strlen(fValue.String);
+                       break;
+               case B_INT32_TYPE:
+                       fValue.Int32 = strtol(string, &string, 0);
+                       fSize = sizeof(int32);
+                       break;
+               case B_UINT32_TYPE:
+                       fValue.Int32 = strtoul(string, &string, 0);
+                       fSize = sizeof(uint32);
+                       break;
+               case B_INT64_TYPE:
+                       fValue.Int64 = strtoll(string, &string, 0);
+                       fSize = sizeof(int64);
+                       break;
+               case B_UINT64_TYPE:
+                       fValue.Uint64 = strtoull(string, &string, 0);
+                       fSize = sizeof(uint64);
+                       break;
+               case B_FLOAT_TYPE:
+                       fValue.Float = strtod(string, &string);
+                       fSize = sizeof(float);
+                       break;
+               case B_DOUBLE_TYPE:
+                       fValue.Double = strtod(string, &string);
+                       fSize = sizeof(double);
+                       break;
+               default:
+                       FATAL(("query value conversion to 0x%x requested!\n", 
(int)type));
+                       // should we fail here or just do a safety int32 
conversion?
+                       return B_ERROR;
+       }
+
+       fType = type;
+
+       // patterns are only allowed for string types
+       if (fType != B_STRING_TYPE && fIsPattern)
+               fIsPattern = false;
+
+       return B_OK;
+}
+
+
+/*!    Returns true when the key matches the equation. You have to
+       call ConvertValue() before this one.
+*/
+bool
+Equation::_CompareTo(const uint8* value, uint16 size)
+{
+       int32 compare;
+
+       // fIsPattern is only true if it's a string type, and fOp OP_EQUAL, or
+       // OP_UNEQUAL
+       if (fIsPattern) {
+               // we have already validated the pattern, so we don't check for 
failing
+               // here - if something is broken, and matchString() returns an 
error,
+               // we just don't match
+               compare = matchString(fValue.String, (char*)value) == MATCH_OK 
? 0 : 1;
+       } else if (fIsSpecialTime) {
+               // the index is a shifted int64 index, but we have to match
+               // against an unshifted value (i.e. the last_modified index)
+               int64 timeValue = *(int64*)value >> INODE_TIME_SHIFT;
+               compare = compareKeys(fType, &timeValue, sizeof(int64), 
&fValue.Int64,
+                       sizeof(int64));
+       } else
+               compare = compareKeys(fType, value, size, _Value(), fSize);
+
+       switch (fOp) {
+               case OP_EQUAL:
+                       return compare == 0;
+               case OP_UNEQUAL:
+                       return compare != 0;
+               case OP_LESS_THAN:
+                       return compare < 0;
+               case OP_LESS_THAN_OR_EQUAL:
+                       return compare <= 0;
+               case OP_GREATER_THAN:
+                       return compare > 0;
+               case OP_GREATER_THAN_OR_EQUAL:
+                       return compare >= 0;
+       }
+       FATAL(("Unknown/Unsupported operation: %d\n", fOp));
+       return false;
+}
+
+
+status_t
+Equation::_MatchEmptyString()
+{
+       // There is no matching attribute, we will just bail out if we
+       // already know that our value is not of a string type.
+       // If not, it will be converted to a string - and then be compared with 
"".
+       // That's why we have to call ConvertValue() here - but it will be
+       // a cheap call for the next time
+       // TODO: Should we do this only for OP_UNEQUAL?
+       if (fType != 0 && fType != B_STRING_TYPE)
+               return NO_MATCH;
+
+       status_t status = _ConvertValue(B_STRING_TYPE);
+       if (status == B_OK)
+               status = _CompareTo((const uint8*)"", fSize) ? MATCH_OK : 
NO_MATCH;
+
+       return status;
+}
+
+
 //     #pragma mark -
 
 

############################################################################

Commit:      a2eb6bbda477e7b89d0d6fbeaa0d05e2342e8e87
URL:         http://cgit.haiku-os.org/haiku/commit/?id=a2eb6bbda477
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Thu Jan 19 19:59:13 2017 UTC

bfs: Minor cleanup.

* Added helper methods for operator/equation characters.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/file_systems/bfs/Query.cpp 
b/src/add-ons/kernel/file_systems/bfs/Query.cpp
index a8d127c..93be7e1 100644
--- a/src/add-ons/kernel/file_systems/bfs/Query.cpp
+++ b/src/add-ons/kernel/file_systems/bfs/Query.cpp
@@ -148,6 +148,8 @@ private:
 
                        status_t                        
_ParseQuotedString(char** _start, char** _end);
                        char*                           _CopyString(char* 
start, char* end);
+       inline  bool                            _IsEquationChar(char c) const;
+       inline  bool                            _IsOperatorChar(char c) const;
                        status_t                        _ConvertValue(type_code 
type);
                        bool                            _CompareTo(const uint8* 
value, uint16 size);
                        uint8*                          _Value() const { return 
(uint8*)&fValue; }
@@ -232,16 +234,17 @@ Equation::Equation(char** _expression)
                // set string to a valid start of the equation symbol
                string = end + 2;
                skipWhitespace(&string);
-               if (*string != '=' && *string != '<' && *string != '>'
-                       && *string != '!') {
+               if (!_IsEquationChar(string[0])) {
                        *_expression = string;
                        return;
                }
        } else {
                // search the (in)equation for the actual equation symbol (and 
for other operators
                // in case the equation is malformed)
-               while (*string && *string != '=' && *string != '<' && *string 
!= '>'
-                       && *string != '!' && *string != '&' && *string != '|') {
+               while (string[0] != 0 && !_IsOperatorChar(string[0])
+                       && !_IsEquationChar(string[0])) {
+                       if (string[0] == '\\' && string[1] != 0)
+                               string++;
                        string++;
                }
 
@@ -305,7 +308,7 @@ Equation::Equation(char** _expression)
                string = end + 2;
                skipWhitespace(&string);
        } else {
-               while (*string && *string != '&' && *string != '|' && *string 
!= ')')
+               while (string[0] && !_IsOperatorChar(string[0]) && string[0] != 
')')
                        string++;
 
                end = string - 1;
@@ -761,6 +764,20 @@ Equation::_CopyString(char* start, char* end)
 }
 
 
+bool
+Equation::_IsEquationChar(char c) const
+{
+       return c == '=' || c == '<' || c == '>' || c == '!';
+}
+
+
+bool
+Equation::_IsOperatorChar(char c) const
+{
+       return c == '&' || c == '|';
+}
+
+
 status_t
 Equation::_ConvertValue(type_code type)
 {

############################################################################

Commit:      f79179975d5e0a92191000708e0375b77eac051a
URL:         http://cgit.haiku-os.org/haiku/commit/?id=f79179975d5e
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Thu Jan 19 20:36:13 2017 UTC

Ticket:      https://dev.haiku-os.org/ticket/10976

bfs: Query parser needs to filter out escape char.

* When escaping operator/quote characters, the character was properly
  ignored. However, the escape char was left in the string which
  altered the query.
* This fixes bug #10976.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/file_systems/bfs/Query.cpp 
b/src/add-ons/kernel/file_systems/bfs/Query.cpp
index 93be7e1..7cd5003 100644
--- a/src/add-ons/kernel/file_systems/bfs/Query.cpp
+++ b/src/add-ons/kernel/file_systems/bfs/Query.cpp
@@ -757,7 +757,16 @@ Equation::_CopyString(char* start, char* end)
        if (copy == NULL)
                return NULL;
 
-       memcpy(copy, start, length - 1);
+       // Filter out remaining escaping slashes
+       for (int32 i = 0; i < length; i++) {
+               char c = start++[0];
+               if (c == '\\' && i < length) {
+                       length--;
+                       i--;
+                       continue;
+               }
+               copy[i] = c;
+       }
        copy[length - 1] = '\0';
 
        return copy;

############################################################################

Commit:      3af0b8555ecd0a887f47a52285aa818ee0cd7a81
URL:         http://cgit.haiku-os.org/haiku/commit/?id=3af0b8555ecd
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Thu Jan 19 20:48:34 2017 UTC

Ticket:      https://dev.haiku-os.org/ticket/12657

bfs_shell: Fixed (missing) use of the FSSH_B_PRI* macros.

* This closes ticket #12657.

----------------------------------------------------------------------------

diff --git a/src/tools/bfs_shell/command_checkfs.cpp 
b/src/tools/bfs_shell/command_checkfs.cpp
index 35a6648..5dc0a7b 100644
--- a/src/tools/bfs_shell/command_checkfs.cpp
+++ b/src/tools/bfs_shell/command_checkfs.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2012, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2008-2017, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 
@@ -54,12 +54,15 @@ command_checkfs(int argc, const char* const* argv)
        // check all files and report errors
        while (_kern_ioctl(rootDir, BFS_IOCTL_CHECK_NEXT_NODE, &result,
                        sizeof(result)) == B_OK) {
-               if (++counter % 50 == 0)
-                       fssh_dprintf("%9Ld nodes processed\x1b[1A\n", counter);
+               if (++counter % 50 == 0) {
+                       fssh_dprintf("%9" FSSH_B_PRIu64 " nodes 
processed\x1b[1A\n",
+                               counter);
+               }
 
                if (result.pass == BFS_CHECK_PASS_BITMAP) {
                        if (result.errors) {
-                               fssh_dprintf("%s (inode = %lld)", result.name, 
result.inode);
+                               fssh_dprintf("%s (inode = %" FSSH_B_PRIdINO 
")", result.name,
+                                       result.inode);
                                if ((result.errors & BFS_MISSING_BLOCKS) != 0)
                                        fssh_dprintf(", some blocks weren't 
allocated");
                                if ((result.errors & BFS_BLOCKS_ALREADY_SET) != 
0)
@@ -105,24 +108,26 @@ command_checkfs(int argc, const char* const* argv)
 
        _kern_close(rootDir);
 
-       fssh_dprintf("        %" B_PRIu64 " nodes checked,\n\t%" B_PRIu64 " 
blocks "
-               "not allocated,\n\t%" B_PRIu64 " blocks already set,\n\t%" 
B_PRIu64
-               " blocks could be freed\n\n", counter, result.stats.missing,
+       fssh_dprintf("        %" FSSH_B_PRIu64 " nodes checked,\n\t%" 
FSSH_B_PRIu64
+               " blocks not allocated,\n\t%" FSSH_B_PRIu64 " blocks already 
set,\n\t%"
+               B_PRIu64 " blocks could be freed\n\n", counter, 
result.stats.missing,
                result.stats.already_set, result.stats.freed);
-       fssh_dprintf("\tfiles\t\t%" B_PRIu64 "\n\tdirectories\t%" B_PRIu64 "\n"
-               "\tattributes\t%" B_PRIu64 "\n\tattr. dirs\t%" B_PRIu64 "\n"
-               "\tindices\t\t%" B_PRIu64 "\n", files, directories, attributes,
+       fssh_dprintf("\tfiles\t\t%" FSSH_B_PRIu64 "\n\tdirectories\t%"
+               FSSH_B_PRIu64 "\n"
+               "\tattributes\t%" FSSH_B_PRIu64 "\n\tattr. dirs\t%" 
FSSH_B_PRIu64 "\n"
+               "\tindices\t\t%" FSSH_B_PRIu64 "\n", files, directories, 
attributes,
                attributeDirectories, indices);
 
-       fssh_dprintf("\n\tdirect block runs\t\t%" B_PRIu64 " (%lld)\n",
-               result.stats.direct_block_runs,
+       fssh_dprintf("\n\tdirect block runs\t\t%" FSSH_B_PRIu64 " (%" 
FSSH_B_PRIu64
+               ")\n", result.stats.direct_block_runs,
                result.stats.blocks_in_direct * result.stats.block_size);
-       fssh_dprintf("\tindirect block runs\t\t%" B_PRIu64 " (in %" B_PRIu64
-               " array blocks, %lld)\n", result.stats.indirect_block_runs,
-               result.stats.indirect_array_blocks,
+       fssh_dprintf("\tindirect block runs\t\t%" FSSH_B_PRIu64 " (in %"
+               FSSH_B_PRIu64 " array blocks, %" FSSH_B_PRIu64 ")\n",
+               result.stats.indirect_block_runs, 
result.stats.indirect_array_blocks,
                result.stats.blocks_in_indirect * result.stats.block_size);
-       fssh_dprintf("\tdouble indirect block runs\t%" B_PRIu64 " (in %" 
B_PRIu64
-               " array blocks, %lld)\n", 
result.stats.double_indirect_block_runs,
+       fssh_dprintf("\tdouble indirect block runs\t%" FSSH_B_PRIu64 " (in %"
+               FSSH_B_PRIu64 " array blocks, %" FSSH_B_PRIu64 ")\n",
+               result.stats.double_indirect_block_runs,
                result.stats.double_indirect_array_blocks,
                result.stats.blocks_in_double_indirect * 
result.stats.block_size);
 

############################################################################

Commit:      9e71fa0e2117848fb29371ebc3fd6ce86f3e3a64
URL:         http://cgit.haiku-os.org/haiku/commit/?id=9e71fa0e2117
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Thu Jan 19 20:52:01 2017 UTC

mkfs: Added an example to the help text.

----------------------------------------------------------------------------

diff --git a/src/bin/mkfs/main.cpp b/src/bin/mkfs/main.cpp
index fd4db49..26218c9 100644
--- a/src/bin/mkfs/main.cpp
+++ b/src/bin/mkfs/main.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Haiku Inc. All rights reserved.
+ * Copyright 2008-2017 Haiku Inc. All rights reserved.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -33,7 +33,12 @@ print_help(bool out)
                "  -h, --help              - print this help text\n"
                "  -o, --options    <opt>  - set fs specific options\n"
                "  -q, --dont-ask          - do not ask before initializing\n"
-               "  -v, --verbose           - set verbose output\n",
+               "  -v, --verbose           - set verbose output\n"
+               "\n"
+               "Example:\n"
+               "  mkfs -t bfs -o 'block_size 4096; noindex' ./test.image 
Data\n"
+               "\tThis will initialize \"test.image\" with BFS with a block\n"
+               "\tsize of 4096 bytes, without index, and named \"Data\".\n",
                kProgramName);
 }
 

############################################################################

Revision:    hrev50884
Commit:      91cdfd96f8729cdfd5f80f1ab54e7d7600f5ecd5
URL:         http://cgit.haiku-os.org/haiku/commit/?id=91cdfd96f872
Author:      Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
Date:        Thu Jan 19 21:13:40 2017 UTC

bfs: Never publish the index root node.

* This caused the volume to be un-unmountable when you created an index
  on a non-indexed volume.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp 
b/src/add-ons/kernel/file_systems/bfs/Inode.cpp
index df0ceb6..fce958f 100644
--- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp
+++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp
@@ -143,7 +143,7 @@ public:
                                                        
InodeAllocator(Transaction& transaction);
                                                        ~InodeAllocator();
 
-                       status_t                New(block_run* parentRun, 
mode_t mode,
+                       status_t                New(block_run* parentRun, 
mode_t mode, uint32 flags,
                                                                block_run& run, 
fs_vnode_ops* vnodeOps,
                                                                Inode** _inode);
                        status_t                CreateTree();
@@ -191,8 +191,8 @@ InodeAllocator::~InodeAllocator()
 
 
 status_t
-InodeAllocator::New(block_run* parentRun, mode_t mode, block_run& run,
-       fs_vnode_ops* vnodeOps, Inode** _inode)
+InodeAllocator::New(block_run* parentRun, mode_t mode, uint32 publishFlags,
+       block_run& run, fs_vnode_ops* vnodeOps, Inode** _inode)
 {
        Volume* volume = fTransaction->GetVolume();
 
@@ -211,7 +211,8 @@ InodeAllocator::New(block_run* parentRun, mode_t mode, 
block_run& run,
        if (fInode == NULL)
                RETURN_ERROR(B_NO_MEMORY);
 
-       if (!volume->IsInitializing()) {
+       if (!volume->IsInitializing()
+               && (publishFlags & BFS_DO_NOT_PUBLISH_VNODE) == 0) {
                status = new_vnode(volume->FSVolume(), fInode->ID(), fInode,
                        vnodeOps != NULL ? vnodeOps : &gBFSVnodeOps);
                if (status < B_OK) {
@@ -272,7 +273,8 @@ InodeAllocator::Keep(fs_vnode_ops* vnodeOps, uint32 
publishFlags)
 
        // Symbolic links are not published -- the caller needs to do this once
        // the contents have been written.
-       if (!fInode->IsSymLink() && volume->ID() >= 0) {
+       if (!fInode->IsSymLink() && !volume->IsInitializing()
+               && (publishFlags & BFS_DO_NOT_PUBLISH_VNODE) == 0) {
                status = publish_vnode(volume->FSVolume(), fInode->ID(), fInode,
                        vnodeOps != NULL ? vnodeOps : &gBFSVnodeOps, 
fInode->Mode(),
                        publishFlags);
@@ -2688,7 +2690,8 @@ Inode::Create(Transaction& transaction, Inode* parent, 
const char* name,
        InodeAllocator allocator(transaction);
        block_run run;
        Inode* inode;
-       status = allocator.New(&parentRun, mode, run, vnodeOps, &inode);
+       status = allocator.New(&parentRun, mode, publishFlags, run, vnodeOps,
+               &inode);
        if (status < B_OK)
                return status;
 
diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.h 
b/src/add-ons/kernel/file_systems/bfs/Inode.h
index 1d20f54..546f00d 100644
--- a/src/add-ons/kernel/file_systems/bfs/Inode.h
+++ b/src/add-ons/kernel/file_systems/bfs/Inode.h
@@ -23,6 +23,10 @@ class NodeGetter;
 class Transaction;
 
 
+// To be used in Inode::Create() as publishFlags
+#define BFS_DO_NOT_PUBLISH_VNODE       0x80000000
+
+
 class Inode : public TransactionListener {
        typedef DoublyLinkedListLink<Inode> Link;
 
diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.cpp 
b/src/add-ons/kernel/file_systems/bfs/Volume.cpp
index d3f88dd..d3b5e12 100644
--- a/src/add-ons/kernel/file_systems/bfs/Volume.cpp
+++ b/src/add-ons/kernel/file_systems/bfs/Volume.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2012, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2001-2017, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
  * This file may be used under the terms of the MIT License.
  */
 
@@ -503,7 +503,7 @@ Volume::CreateIndicesRoot(Transaction& transaction)
        off_t id;
        status_t status = Inode::Create(transaction, NULL, NULL,
                S_INDEX_DIR | S_STR_INDEX | S_DIRECTORY | 0700, 0, 0, NULL, &id,
-               &fIndicesNode);
+               &fIndicesNode, NULL, BFS_DO_NOT_PUBLISH_VNODE);
        if (status < B_OK)
                RETURN_ERROR(status);
 
@@ -770,15 +770,15 @@ Volume::Initialize(int fd, const char* name, uint32 
blockSize,
        status = CreateVolumeID(transaction);
        if (status < B_OK)
                return status;
-       
+
        status = _EraseUnusedBootBlock();
        if (status < B_OK)
                return status;
-       
+
        status = WriteSuperBlock();
        if (status < B_OK)
                return status;
-               
+
        status = transaction.Done();
        if (status < B_OK)
                return status;



Other related posts:

  • » [haiku-commits] haiku: hrev50884 - in src: add-ons/kernel/file_systems/bfs tools/bfs_shell bin/mkfs - axeld