Commit Graph
233 Commits
Author SHA1 Message Date
Augustin Cavalier 15b255904d BFS & EXTFS: Use the new check_write_stat_permissions in write_stat hooks. 2025-07-07 15:11:21 -04:00
Pascal Abresch 8e086795b2 implement fdatasync
Change-Id: I2aefc1acebce93a2c53a6d3be5eef3b9e69480ec
Reviewed-on: https://review.haiku-os.org/c/haiku/+/8507
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: nephele nephele <[email protected]>
Reviewed-by: Jérôme Duval <[email protected]>
2025-07-07 15:20:18 +00:00
Augustin Cavalier 7998bc4204 BFS: Don't send duplicate attribute change notifications to queries on renames.
LiveUpdateRenameMove() sends create/remove notifications, so we
don't want to send duplicate ones in the LiveUpdate() hook.
2025-04-30 16:50:08 -04:00
Augustin Cavalier 4a87c95e0a kernel/fs: Handle O_RDONLY | O_TRUNC in the VFS rather than filesystems.
The POSIX specification says that the behavior of specifying O_TRUNC
with O_RDONLY is "undefined", but the Linux manpages ominously state
"On many systems the file is actually truncated." I tested this,
and indeed on Linux the file is actually truncated.

This doesn't seem like a very sensible behavior, so in this commit
it's changed to return B_NOT_ALLOWED (EPERM) if those flags are
specified together. The FAT driver already did this, but most other
filesystem drivers just checked write access permissions and
truncated the file anyway; so this is indeed a behavioral change.

Change-Id: If2e76782743ee91d934dc7e0c2f306f37b159a0f
Reviewed-on: https://review.haiku-os.org/c/haiku/+/8625
Reviewed-by: waddlesplash <[email protected]>
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: Axel Dörfler <[email protected]>
2024-12-09 01:00:33 +00:00
Augustin Cavalier 551a9b9a01 BFS: Keep references to vnodes during asynchronous I/O.
IORequest notifications begin by notifying the "finished" condition,
then invoking the request callback, then invoking the parent callback.

vfs_{read|write}_pages wait on the "finished" condition and then
return at once, potentially releasing their references to the vnode
in question, before the request callback is even invoked. The request
callback is what (eventually) invokes iterative_io_finished_hook,
which meant that we were accessing the Inode object after our reference
to it had already been released.

We can't really change IORequest notification order, as any one of the
notifications could delete the request, and indeed the first one does here.
So the solution is just to acquire another reference to the vnode and
release it in the finished hook.

Fixes #19122 and #8405.
2024-11-20 18:03:09 -05:00
Augustin Cavalier 0a44afc6bf BFS: Use the shared QueryParser.
Ideally should have no functional changes from the old one.

Change-Id: Id557d8fb069603221887447597ef0ffce5de07a6
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7705
Reviewed-by: waddlesplash <[email protected]>
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: Axel Dörfler <[email protected]>
2024-06-24 19:40:08 +00:00
Alexander von Gluck IV 425ac1b60a refactor: Swap %Ld for %lld in all format usages
* %Ld is an undocumented alias for %lld in glibc.
* muslc doesn't implement it for this reason.
* While we will likely never drop %Ld support,
  lets clean house and set a better example.

Change-Id: Id46dad3104abae483e80cc5c05d1464d3ecd8030
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6636
Reviewed-by: Adrien Destugues <[email protected]>
Reviewed-by: Alex von Gluck IV <[email protected]>
Tested-by: Commit checker robot <[email protected]>
2023-07-17 11:26:21 +00:00
Augustin Cavalier 50330091b0 bfs: Disable asynchronous IO routine when KDEBUG_RW_LOCK_DEBUG is enabled.
See inline comment: it relies on behavior that the assertions
cannot track.
2023-06-29 20:51:08 -04:00
Augustin Cavalier 35b40030a7 file_systems/fs_ops_support: Add open_mode_to_access.
This is duplicated across multiple filesystems, and could probably be
used in more still.

Adjusted only BFS, EXT2, and NTFS in this commit, as they are the ones
which make use of fs_ops_support.h already and thus need to be modified
to avoid duplicate-definition errors.

Also tweak next_dirent to support being built under fs_shell.
(Possibly we should define ASSERT there, though?)
2023-01-27 23:53:53 -05:00
Augustin Cavalier e285b3071d Introduce a utility function for moving to the next dirent in read_dir.
This takes care of making sure the dirent buffer is properly aligned,
which it needs to be on some platforms (SPARC, ARM, etc.)

Change-Id: I9a6352b1e654c090a200770d51f96511ee024a99
2022-09-28 16:30:00 -04:00
waddlesplash 242fec2332 Revert "bfs: fix alignment of struct dirent"
This reverts commit 7fe1087ed4.

Reason for revert: could cause underflow

Change-Id: Ib2263f3ab17ae377b0565d020410bae616385cfe
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5577
Reviewed-by: waddlesplash <[email protected]>
2022-09-08 18:08:03 +00:00
David Karoly 7fe1087ed4 bfs: fix alignment of struct dirent
This is needed on ARMv7 as inode number is stored using STRD instruction
which can result in alignment fault even when SCTLR.A bit is disabled.

see ARMARM section A3.2.1, Unaligned data access

Change-Id: Ib17bf3f78e84ad7987d8158426bc9b27ded28a8e
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5623
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: Adrien Destugues <[email protected]>
2022-09-08 18:06:26 +00:00
Augustin Cavalier 711e2dc05b Adjust all struct dirent creations (again), this time to use offsetof().
The dirent struct is not packed, so offsetof(dirent, d_name) != sizeof(dirent).
Thus in order not to waste the alignment bytes (which are significant,
on x86_64 at least, sizeof(dirent)==32, but offsetof(...)=26.)

This is also the most portable way to handle things, and should
work just fine in cross-platform code that has a non-zero-sized d_name.
2021-12-01 17:05:40 -05:00
Augustin Cavalier 9d242fb955 file_systems & Tracker: Do not assume sizeof(dirent) contains 1 byte for the name.
At present, it does, but that is an oddity we have preserved from BeOS
that the next commit is going to remove. (This commit thus wastes 1 byte
without the following one.)

Most changes are pretty straightforward: only a +1 is needed,
and a few removed from sizing calculations. Some filesystems like UDF
originally passed back the length with the \0 included, so they have
been adjusted further. UFS2 had some other sizing problems which are also
corrected in this commit.
2021-11-18 16:24:04 -05:00
X512 36aafa560b fix build after CObjectDeleter interface change
Change-Id: I76e217abcd13c22c4d68170e07333cdde4d7a891
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3461
Reviewed-by: Adrien Destugues <[email protected]>
2020-12-10 11:39:49 +00:00
John Scipione 3d43a90508 bfs: Enable logging on DEBUG build
Fix DEBUG build errors by using B_PRI macros in BlockAllocator.cpp,
CheckVisitor.cpp, Inode.cpp, Journal.cpp, and kernel_interface.cpp

Add optional type parameter from BlockAllocator::IsValidBlockRun()
and actually PRINT it, type parameter is already optional on
BlockAllocator::CheckBlockRun().

Remove a couple of casts as we are printing the expected type, int32.

Cast mode_t to (unsigned int) and use %u because 32-bit Haiku didn't
like B_PRIu32.

Verified to compile on both regular and DEBUG builds on both 32-bit
and 64-bit.

Change-Id: I8bb39afd400768b7f69d36384974f0b91b3ef48c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3184
Reviewed-by: Adrien Destugues <[email protected]>
Reviewed-by: John Scipione <[email protected]>
2020-09-07 22:09:11 +00:00
Axel Dörfler 93845aec95 block_cache: Change signature of *_etc() functions
* This allows file systems to retrieve the actual error code on a
  failure, and report it to the user.
* All affected file systems have been adjusted to the API change.
  This is a binary incompatible change.

Change-Id: Id73392aaf9c6cb7d643ff9adcb8bf80f3037874c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2913
Reviewed-by: Axel Dörfler <[email protected]>
Reviewed-by: Adrien Destugues <[email protected]>
2020-06-20 18:10:03 +00:00
Jérôme Duval f9b218aa8a file_systems: fs_read_link() doesn't use a user buffer
introduced in hrev26728 and hrev54107.

Change-Id: I3e98d54e829bcce559c43a8ee1abe4d889c0a571
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2819
Reviewed-by: waddlesplash <[email protected]>
2020-05-26 23:00:54 +00:00
Kyle Ambroff-Kao e1b7c1c7ac storage/SymLink: Fix Be API regression in ReadLink
After this patch, "UnitTester BSymLink" passes.

BSymLink::ReadLink() in BeOS would always return the length of the
link unless an error occurred. Before this patch, Haiku instead seemed
to emulate posix readlink() behavior, returning the number of bytes
copied into the output buffer.

BeOS also did not guarantee that the string written into the output
buffer is NULL terminated if the output buffer cannot contain the
entire link contents, but the Haiku implementation does since it is is
a basic safety issue.

This patch fixes this and updates the Haiku API docs to describe the
behavior explicitly.

Fixing this required changing behavior in bfs_read_link, which
required changes in many more places.

docs/user/storage/SymLink.dox:
src/kits/storage/SymLink.cpp:
* Don't return B_BUFFER_OVERFLOW if the provided buffer is not large
  enough to hold the link contents.
* Update documentation to clearly describe behavior.

src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp:
* Change bfs_read_link() to always return the link length. This is
  called by common_read_link in the VFS, which is called by
  _kern_read_link().

src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp:
src/add-ons/kernel/file_systems/exfat/kernel_interface.cpp:
src/add-ons/kernel/file_systems/ext2/kernel_interface.cpp:
src/add-ons/kernel/file_systems/iso9660/kernel_interface.cpp:
src/add-ons/kernel/file_systems/netfs/client/netfs.cpp:
src/add-ons/kernel/file_systems/nfs/nfs_add_on.c:
src/add-ons/kernel/file_systems/ramfs/kernel_interface.cpp:
src/add-ons/kernel/file_systems/reiserfs/Iterators.cpp:
src/add-ons/kernel/file_systems/reiserfs/Iterators.h:
src/add-ons/kernel/file_systems/reiserfs/Volume.cpp:
src/add-ons/kernel/file_systems/reiserfs/Volume.h:
* Update the implementation of read_link for these filesystems. Some
  of them were incorrect, and some had just copied the posix behavior of
  bfs from before this patch.
* Use user_memcpy in ext2_read_link()
* Use user_memcpy in nfs fs_read_link()
* Use user_memcpy in reiserfs StreamReader::_ReadIndirectItem and
  StreamReader::_ReadDirectItem
* Remove unused method Volume::ReadObject in reiserfs.

src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingLeafNode.cpp:
src/add-ons/kernel/file_systems/packagefs/package_links/PackageLinkSymlink.cpp:
* Update UnpackingLeafNode::ReadSymlink and
  PackageSymLink::ReadSymLink() to set the bufferSize out parameter to
  the symlink length. Both of these are called by
  packagefs_read_symlink.
* Use user_memcpy

src/add-ons/kernel/file_systems/netfs/client/netfs.cpp:
* netfs seems mostly unimplemented. Added a FIXME note for future
  implementers so that they know to implement the correct behavior.

src/system/libroot/posix/unistd/link.c:
* readlinkat() was just wrapping _kern_read_link() because before this
  patch it had expected posix behavior. But now it does not, so we
  need to return the number of bytes written to the output
  buffer.

src/build/libroot/fs.cpp:
* Update _kern_read_link() in the compatibility code to emulate the
  Haiku behavior on the host system. This is done by using an
  intermediate buffer that is guaranteed to fit the link contents and
  returning its length. The intermediate buffer is copied into the
  output buffer until there is no more room.

src/tests/kits/storage/SymLinkTest.cpp:
* This patch also resolves some test failures similar to those
  resolved in ee8cf35f0 which fixed tests for BNode. The tests were
  failing because Haiku's error checking is just better.

  BeOS allowed constructing a BSymLink with BSymLink(BDirectory*,
  const char*) with the entry name of "". The same is true of the
  equivilant SetTo() method. The BSymLink object will appear valid
  until you attempt to use it by, for example, calling the ReadLink
  method, which will return B_BAD_VALUE.

  Haiku does a more appropriate thing and returns B_ENTRY_NOT_FOUND,
  for this constructor and the equivilant SetTo(BDirectory*, const
  char*) method. This patch fixes these test assertions to match Haiku
  behavior.

docs/develop/file_systems/overview.txt:
* Add notes for future filesystem driver implementers to call this
  mistake when implementing fs_vnode_ops::read_symlink.

docs/user/drivers/fs_interface.dox:
* Fix documentation for fs_vnode_ops::read_symlink

Change-Id: I8bcb8b2a0c9333059c84ace15844c32d4efeed9d
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2502
Reviewed-by: waddlesplash <[email protected]>
Reviewed-by: Axel Dörfler <[email protected]>
2020-04-30 10:13:41 +00:00
Adrien Destugues 82f4ed7f38 bfs: add stub for ResizeVisitor.
This allows to have all the tools (resizefs, fs_shell, etc) merged, and
split out the remaining BFS resize changes in a way that makes some
sense. We can easily merge all the basic infrastructure (ioctls, etc)
without any of the actual resizing code (I'll leave that to
professionals).
2020-01-01 12:07:55 +01:00
ahenriksson 0b3f78e73b fs_shell: 'resizefs' command
Change-Id: Ie4c18c76cd1a69945739817ecd99409b7611dd7a
Reviewed-on: https://review.haiku-os.org/c/haiku/+/939
Reviewed-by: Jérôme Duval <[email protected]>
2020-01-01 10:24:30 +00:00
Adrien Destugues 354311b57b filesystems: bump priority of BFS over others
If multipole filesystems think they can handle a volume, it makes sense
to assume the native one is to be used.

Makes my partitions with a BFS superblock and a leftover ext2 superblock
on them mountable again without manually specifying the filesystem type.

Fixes #15045.

Change-Id: Icb694472aa3de0a79e5f7d3c54976038e1e2590a
Reviewed-on: https://review.haiku-os.org/c/haiku/+/1801
Reviewed-by: waddlesplash <[email protected]>
2019-08-30 19:18:20 +00:00
ahenriksson aa7750382a bfs: split checkfs code into FileSystemVisitor and CheckVisitor
Another FileSystemVisitor implementation will be used for resizing

Change-Id: I2d5f47dcbefb4c76834487b194a99c6f5ae7de50
Reviewed-on: https://review.haiku-os.org/c/923
Reviewed-by: Jérôme Duval <[email protected]>
2019-02-19 18:44:43 +00:00
François Revol 5d558f271c BFS: Use separate name & pretty name for big-endian
Change-Id: I7e3a99e3cff35ae5f8cd84fa7243579bf93de904
Reviewed-on: https://review.haiku-os.org/644
Reviewed-by: waddlesplash <[email protected]>
2018-10-27 17:48:25 +00:00
Axel Dörfler 44c76b26e8 bfs: Made updating the boot block more secure.
* It now also checks the length/offset indepdently from each other,
  so that they cannot benefit from integer overflow.
* This fixes bug #12943.
2017-01-10 09:07:21 +01:00
Axel Dörfler 6f7fc2204b NodeMonitor: Added B_WATCH_CHILDREN flag.
* Added a directory argument for notify_{stat/attribute}_changed().
* This allows to watch only a directory, and get the notifications for
  all of its files, not just add/remove entry notifications.
2016-03-28 14:31:27 +02:00
Michael Lotz 44b69ccbdb bfs: Use negative caching on directory lookup failures. 2015-08-20 21:25:56 +02:00
Axel Dörfler de9c061339 bfs: Use the QueryParserUtils instead of its own copy.
* Ingo copied the methods into a shared location, and then obviously
  "forgot" to let BFS use them. As a side note for Ingo: the complete
  error GCC reported was "std::fssh_size_t" not defined with the macro
  wrapper as code location. The actual problem was a "using std::size_t"
  in some C++ header that accidentally got included after the wrapper.
* The shared Query code is not yet used. That'll be done another time.
* Renamed BFS_SHELL define to FS_SHELL, such that QueryParserUtils can be
  used in any file system shell, not just the bfs_shell.
2014-07-09 22:54:39 +02:00
Axel Dörfler 547cd462f8 trim: Added is_called_via_syscall() function.
* And use it in get_trim_data_from_user(), formerly known as copy_*().
* This fixes differentiating between user and kernel buffers.
2013-11-07 19:06:13 +01:00
Axel Dörfler 99086aa323 trim: Target SCSI UNMAP command instead of WRITE SAME.
* The UNMAP command is theoretically much faster, as it can get many block
  ranges instead of just a single range.
* Furthermore, the ATA TRIM command resembles it much better.
* Therefore, fs_trim_data now gets an array of ranges, and we use SCSI UNMAP
  to trim.
* Updated BFS code to collect array ranges to fully support the new
  fs_trim_data possibilities.
2013-11-07 19:03:47 +01:00
Axel Dörfler 0a0ba4b5f0 Added B_TRIM_DEVICE support to BFS.
* It currently ignores the offset/size, though, and always trims everything.
* Now only SCSI support is missing.
2013-11-07 19:03:15 +01:00
Michael Lotz a01dd96346 Return more than a single dirent at a time in bfs_read_dir().
Return as many dirents as fit into the provided buffer. The readdir()
implementation in libroot tries to get many dirents and caches them to
reduce the amount of syscalls and the associated overhead.

This reduces the syscall count dramatically for use cases where a lot
of directories are enumerated. A "git status" on a Haiku repository for
example goes from over 50k read dir syscalls down to just under 7k.
The performance gain is only around a moderate 5% in that use case
though.
2013-04-28 13:36:20 +02:00
Alex Smith caa1e8b742 Fix CID 712419, 712420, 712421, 712422: Unintentional sign extension to 64 bits. 2012-07-31 12:08:45 +01:00
Jerome Duval eb5f363978 Fixes some occurrences of 'variable set but not used', disables Werror for problematic items. 2012-02-23 20:32:11 +01:00
Michael Lotz a735bdebb9 Align all filesystem relevant places to use B_UNSUPPORTED for unsupported
instead of a mix of B_NOT_SUPPORTED and B_UNSUPPORTED. This allows checking for
a specific error code. Probably one of those should be phased out...


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@43025 a95241bf-73f2-0310-859d-f6bbb57e9c96
2011-10-31 10:18:03 +00:00
Ingo Weinhold 90ade5e298 * Added file_system_module_info::uninitialize() analogously to
partition_module_info::uninitialize().
* Implemented the hook for BFS.
* Implemented KFileSystem::Uninitialize().

Fixes failure to initialize a BFS initialized device with an intel partition
map.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42142 a95241bf-73f2-0310-859d-f6bbb57e9c96
2011-06-13 01:53:11 +00:00
Jérôme Duval f53ec236e2 changed ioctl hook return code when the opcode isn't supported.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40784 a95241bf-73f2-0310-859d-f6bbb57e9c96
2011-03-02 18:24:19 +00:00
Axel Dörfler 48ec4fbb40 * Applied patch by Rohit Yadav that fixes #6750, thanks a lot!
* This changes Inode::CheckPermissions(), and bfs_write_stat() based on Ingo's
  solution in his file corruption test file system.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39378 a95241bf-73f2-0310-859d-f6bbb57e9c96
2010-11-09 20:25:43 +00:00
Jérôme Duval d63f4274b6 added a file system call preallocate() as described in #6285, currently unused
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39006 a95241bf-73f2-0310-859d-f6bbb57e9c96
2010-10-18 18:48:54 +00:00
Jérôme Duval 950f37b206 * renamed bfs_inode::ToUsecs() to bfs_inode::ToNsecs, as it really converts to nanoseconds.
* added a comment explaining the nanoseconds conversion


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38965 a95241bf-73f2-0310-859d-f6bbb57e9c96
2010-10-13 18:49:03 +00:00
Axel Dörfler 75148e0193 * Applied patch by Janito that fixes broken reverting when a rename operation
failed on last chance. Thanks!


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38103 a95241bf-73f2-0310-859d-f6bbb57e9c96
2010-08-14 18:41:52 +00:00
Ingo Weinhold 386be45abc Fixed 64 bit warnings.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36928 a95241bf-73f2-0310-859d-f6bbb57e9c96
2010-05-24 21:41:20 +00:00
Ingo Weinhold 9d570af7c8 Changed the type of the "op" parameter of the fs_vnode_ops::ioctl() hook and
the _kern_ioctl() syscall from ulong to uint32.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36927 a95241bf-73f2-0310-859d-f6bbb57e9c96
2010-05-24 21:04:22 +00:00
Axel Dörfler 1a1a8f33d1 * Applied patch by Janito that solves a TODO and utilizes the actual device
block size to align the file map.
* This closes ticket #5707, thanks!


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36144 a95241bf-73f2-0310-859d-f6bbb57e9c96
2010-04-11 12:05:59 +00:00
Axel Dörfler d501707d8a * Removed the cookie field of the check_control structure; that really was
a stupid idea. Instead, the already existing fCheckCookie member is used.
* bfs_ioctl() now accesses all userland buffers safely, this should help with
  #3264, and move the crash where it belongs.
* Changes not yet tested; they only affect checkfs.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35743 a95241bf-73f2-0310-859d-f6bbb57e9c96
2010-03-03 19:38:56 +00:00
Axel Dörfler b2397539da * BFS now correctly reports the B_FS_HAS_QUERY flag (ie. if you disable the
indices it will no longer be set).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34909 a95241bf-73f2-0310-859d-f6bbb57e9c96
2010-01-05 17:37:33 +00:00
Axel Dörfler 4ea6fb8bd4 * Changed the query code again to send B_ENTRY_REMOVED/B_ENTRY_CREATED
notifications if an inode in a query result was moved/renamed - this time all
  the information is correct, though.
* While I did not introduce B_ENTRY_MOVED for queries yet, this should make
  adding it very simple (left as an excercise for the reader ;-))


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34317 a95241bf-73f2-0310-859d-f6bbb57e9c96
2009-11-27 16:36:52 +00:00
Axel Dörfler f2505b1583 * Implemented O_DIRECTORY in BFS.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34280 a95241bf-73f2-0310-859d-f6bbb57e9c96
2009-11-26 14:19:01 +00:00
Ingo Weinhold 8859eeab53 Replaced "%Ld" and "%lld" in printf()s by the new B_PRI* macros to avoid
warnings when building with a 64 bit compiler.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34216 a95241bf-73f2-0310-859d-f6bbb57e9c96
2009-11-24 19:48:32 +00:00
Axel Dörfler b6670723e1 * Only remove the inode from the Volume::RemovedNodes() list when it has gone
through the VFS.
* This fixes bug #4942.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34007 a95241bf-73f2-0310-859d-f6bbb57e9c96
2009-11-12 12:52:51 +00:00