[Haiku-commits] r31309 - haiku/trunk/src/system/libroot/os

stippi at mail.berlios.de stippi at mail.berlios.de
Mon Jun 29 11:08:44 CEST 2009


Author: stippi
Date: 2009-06-29 11:08:43 +0200 (Mon, 29 Jun 2009)
New Revision: 31309
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=31309&view=rev

Modified:
   haiku/trunk/src/system/libroot/os/fs_attr.c
Log:
* Properly document why fs_write_attr() does what it does.
* As even the author of fs_attr.c was trying to use fs_write_attr() in an
  unsupported way in the cp copy_attributes() implementation, try to be
  more forgiving and support writing attributes at an offset. The method is
  required to behave inconsistent in that replacing bytes at offset 0 is
  not supported as replacing bytes at any other offset. Writing at offset 0
  will clobber the existing attribute to stay compatible with BeOS.

NOTE: BFS itself still does not support writing attributes at an offset which
are withing the "small data section". To work around this problem, programs
which copy attributes in a loop must make sure that their buffer is large
enough that such "small data section" attributes require only one loop
iteration.


Modified: haiku/trunk/src/system/libroot/os/fs_attr.c
===================================================================
--- haiku/trunk/src/system/libroot/os/fs_attr.c	2009-06-29 09:08:34 UTC (rev 31308)
+++ haiku/trunk/src/system/libroot/os/fs_attr.c	2009-06-29 09:08:43 UTC (rev 31309)
@@ -51,11 +51,35 @@
 fs_write_attr(int fd, const char *attribute, uint32 type,
 	off_t pos, const void *buffer, size_t writeBytes)
 {
+	// NOTE: This call is deprecated in Haiku and has a number of problems:
+	// On BeOS, it was documented that the "pos" argument is ignored.
+	// However, a number of programs tried to use this call to write large
+	// attributes in a loop anyways. These programs all relied on the broken
+	// or at least inconsistent behaviour to truncate/clobber an existing
+	// attribute. In another words, writing 5 bytes at position 0 into an
+	// attribute that was already 10 bytes long resulted in an attribute of
+	// only 5 bytes length.
+	// The implementation of this function tries to stay compatible with
+	// BeOS in that it clobbers the existing attribute when you write at offset
+	// 0, but it also tries to support programs which continue to write more
+	// chunks.
+	// The new Haiku way is to use fs_open_attr() to get a regular file handle
+	// and use that for writing, then use fs_close_attr() when done. As you
+	// see from this implementation, it saves 2 syscalls per writing a chunk
+	// of data.
+
 	ssize_t bytes;
+	int attr = -1;
 
-	int attr = _kern_create_attr(fd, attribute, type, O_WRONLY | O_TRUNC);
-	if (attr < 0)
-		RETURN_AND_SET_ERRNO(attr);
+	// If pos is 0, we try to avoid one syscall that with good chances
+	// will fail anyways and take the shortcut to creating the attr directly.
+	if (pos > 0)
+		attr = _kern_open_attr(fd, attribute, O_WRONLY);
+	if (attr < 0) {
+		attr = _kern_create_attr(fd, attribute, type, O_WRONLY | O_TRUNC);
+		if (attr < 0)
+			RETURN_AND_SET_ERRNO(attr);
+	}
 
 	bytes = _kern_write(attr, pos, buffer, writeBytes);
 	_kern_close(attr);




More information about the Haiku-commits mailing list