[haiku-commits] r33832 - haiku/trunk/src/add-ons/kernel/file_systems/bfs

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 29 Oct 2009 19:09:15 +0100 (CET)

Author: axeld
Date: 2009-10-29 19:09:15 +0100 (Thu, 29 Oct 2009)
New Revision: 33832
Changeset: http://dev.haiku-os.org/changeset/33832/haiku

Modified:
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/Attribute.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/Attribute.h
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.h
   haiku/trunk/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp
Log:
* Improved the status_change time check to actually filter out invalid times,
  before, st_ctim was never updated; since you cannot change st_ctim via an API,
  '0' cannot ever be set, either.
* Inode::WriteAttribute(), and Attribute::Write() now return whether they
  created an attribute or not, and thus B_ATTR_CREATED is now correctly set.
* Moved status_change update from bfs_write_attr() into Inode::WriteAttribute()
  where it can be handled more efficiently.
* Likewise, Inode::RemoveAttribute() now updates the status_change time as well,
  I simply forgot this before.
* Minor cleanup.


Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/Attribute.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/Attribute.cpp       
2009-10-29 17:50:56 UTC (rev 33831)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/Attribute.cpp       
2009-10-29 18:09:15 UTC (rev 33832)
@@ -205,13 +205,13 @@
 
 status_t
 Attribute::Write(Transaction& transaction, attr_cookie* cookie, off_t pos,
-       const uint8* buffer, size_t* _length)
+       const uint8* buffer, size_t* _length, bool* _created)
 {
        if (!cookie->create && fSmall == NULL && fAttribute == NULL)
                return B_NO_INIT;
 
        return fInode->WriteAttribute(transaction, cookie->name, cookie->type,
-               pos, buffer, _length);
+               pos, buffer, _length, _created);
 }
 
 

Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/Attribute.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/Attribute.h 2009-10-29 
17:50:56 UTC (rev 33831)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/Attribute.h 2009-10-29 
18:09:15 UTC (rev 33832)
@@ -39,8 +39,8 @@
                        status_t                Read(attr_cookie* cookie, off_t 
pos, uint8* buffer,
                                                                size_t* 
_length);
                        status_t                Write(Transaction& transaction, 
attr_cookie* cookie,
-                                                               off_t pos, 
const uint8* buffer,
-                                                               size_t* 
_length);
+                                                               off_t pos, 
const uint8* buffer, size_t* _length,
+                                                               bool* _created);
 
 private:
                        status_t                _Truncate();

Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp   2009-10-29 
17:50:56 UTC (rev 33831)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.cpp   2009-10-29 
18:09:15 UTC (rev 33832)
@@ -650,8 +650,12 @@
        nodeGetter.MakeWritable(transaction);
 
        status_t status = _RemoveSmallData(node, item, index);
-       if (status == B_OK)
+       if (status == B_OK) {
+               Node().status_change_time = HOST_ENDIAN_TO_BFS_INT64(
+                       bfs_inode::ToInode(real_time_clock_usecs()));
+
                status = WriteBack(transaction);
+       }
 
        return status;
 }
@@ -1033,7 +1037,7 @@
 */
 status_t
 Inode::WriteAttribute(Transaction& transaction, const char* name, int32 type,
-       off_t pos, const uint8* buffer, size_t* _length)
+       off_t pos, const uint8* buffer, size_t* _length, bool* _created)
 {
        if (pos < 0)
                return B_BAD_VALUE;
@@ -1042,6 +1046,7 @@
        uint8 oldBuffer[BPLUSTREE_MAX_KEY_LENGTH];
        uint8* oldData = NULL;
        size_t oldLength = 0;
+       bool created = false;
 
        // TODO: we actually depend on that the contents of "buffer" are 
constant.
        // If they get changed during the write (hey, user programs), we may 
mess
@@ -1071,7 +1076,9 @@
                                        oldLength = BPLUSTREE_MAX_KEY_LENGTH;
                                memcpy(oldData = oldBuffer, smallData->Data(), 
oldLength);
                        }
-               }
+               } else
+                       created = true;
+
                recursive_lock_unlock(&fSmallDataLock);
 
                // if the attribute doesn't exist yet (as a file), try to put 
it in the
@@ -1091,8 +1098,15 @@
                                status = CreateAttribute(transaction, name, 
type, &attribute);
                        if (status != B_OK)
                                RETURN_ERROR(status);
-               } else if (status == B_OK)
+
+                       created = true;
+               } else if (status == B_OK) {
+                       // Update status time on attribute write
+                       Node().status_change_time = HOST_ENDIAN_TO_BFS_INT64(
+                               bfs_inode::ToInode(real_time_clock_usecs()));
+
                        status = WriteBack(transaction);
+               }
        }
 
        if (attribute != NULL) {
@@ -1127,6 +1141,14 @@
                                                _length);
                                }
                        }
+
+                       if (status == B_OK) {
+                               // Update status time on attribute write
+                               Node().status_change_time = 
HOST_ENDIAN_TO_BFS_INT64(
+                                       
bfs_inode::ToInode(real_time_clock_usecs()));
+
+                               status = WriteBack(transaction);
+                       }
                } else
                        status = B_ERROR;
 
@@ -1149,6 +1171,10 @@
                                length, this);
                }
        }
+
+       if (_created != NULL)
+               *_created = created;
+
        return status;
 }
 
@@ -1182,7 +1208,13 @@
        if (status == B_ENTRY_NOT_FOUND && !Attributes().IsZero()) {
                // remove the attribute file if it exists
                status = _RemoveAttribute(transaction, name, hasIndex, &index);
+               if (status == B_OK) {
+                       Node().status_change_time = HOST_ENDIAN_TO_BFS_INT64(
+                               bfs_inode::ToInode(real_time_clock_usecs()));
+                       WriteBack(transaction);
+               }
        }
+
        return status;
 }
 

Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.h     2009-10-29 
17:50:56 UTC (rev 33831)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/Inode.h     2009-10-29 
18:09:15 UTC (rev 33832)
@@ -107,7 +107,8 @@
                                                                off_t pos, 
uint8* buffer, size_t* _length);
                        status_t                WriteAttribute(Transaction& 
transaction,
                                                                const char* 
name, int32 type, off_t pos,
-                                                               const uint8* 
buffer, size_t* _length);
+                                                               const uint8* 
buffer, size_t* _length,
+                                                               bool* _created);
                        status_t                RemoveAttribute(Transaction& 
transaction,
                                                                const char* 
name);
 

Modified: haiku/trunk/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp        
2009-10-29 17:50:56 UTC (rev 33831)
+++ haiku/trunk/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp        
2009-10-29 18:09:15 UTC (rev 33832)
@@ -43,15 +43,9 @@
        stat.st_crtim.tv_sec = bfs_inode::ToSecs(node.CreateTime());
        stat.st_crtim.tv_nsec = bfs_inode::ToUsecs(node.CreateTime());
 
-       // if on-disk ctime is invalid (pointer value from previous [ab]use of
-       // the first 4 bytes) or 0, fall back to mtime:
-       // N.B.: This has the drawback that explicitly setting a ctime of 0
-       //       will not work, but I suppose no one will do that, since ctime
-       //       is usually just set to the current time whenever something 
happens
-       //       to the inode.
-       // TODO: find out if this sanity check should be dropped!
+       // For BeOS compatibility, if on-disk ctime is invalid, fall back to 
mtime:
        bigtime_t changeTime = node.StatusChangeTime();
-       if (((uint64)changeTime & 0xFFFF00000000FFFFULL) != 0 || changeTime == 
0)
+       if (changeTime < node.LastModifiedTime())
                stat.st_ctim = stat.st_mtim;
        else {
                stat.st_ctim.tv_sec = bfs_inode::ToSecs(changeTime);
@@ -1196,11 +1190,10 @@
                                }
                        }
 
-                       if (newDirectory != oldDirectory) {
-                               
oldDirectory->ContainerContentsChanged(transaction);
-                               
newDirectory->ContainerContentsChanged(transaction);
-                       } else
-                               
newDirectory->ContainerContentsChanged(transaction);
+                       if (status == B_OK && newDirectory != oldDirectory)
+                               status = 
oldDirectory->ContainerContentsChanged(transaction);
+                       if (status == B_OK)
+                               status = 
newDirectory->ContainerContentsChanged(transaction);
 
                        if (status == B_OK)
                                status = inode->WriteBack(transaction);
@@ -1808,20 +1801,14 @@
        Transaction transaction(volume, inode->BlockNumber());
        Attribute attribute(inode, cookie);
 
+       bool created;
        status_t status = attribute.Write(transaction, cookie, pos,
-               (const uint8*)buffer, _length);
+               (const uint8*)buffer, _length, &created);
        if (status == B_OK) {
-               // Update status time on attribute write
-               inode->Node().status_change_time = HOST_ENDIAN_TO_BFS_INT64(
-                       bfs_inode::ToInode(real_time_clock_usecs()));
-               inode->WriteBack(transaction);
-
                status = transaction.Done();
                if (status == B_OK) {
                        notify_attribute_changed(volume->ID(), inode->ID(), 
cookie->name,
-                               B_ATTR_CHANGED);
-                               // TODO: B_ATTR_CREATED is not yet taken into 
account
-                               // (we don't know what Attribute::Write() does 
exactly)
+                               created ? B_ATTR_CREATED : B_ATTR_CHANGED);
                        notify_stat_changed(volume->ID(), inode->ID(), 
B_STAT_CHANGE_TIME);
                }
        }
@@ -1877,7 +1864,7 @@
        Inode* inode = (Inode*)_node->private_node;
 
        status_t status = inode->CheckPermissions(W_OK);
-       if (status < B_OK)
+       if (status != B_OK)
                return status;
 
        Transaction transaction(volume, inode->BlockNumber());


Other related posts: