From 7106362e9c7cba9664d8b9c7c6d3cfb47a6f508d Mon Sep 17 00:00:00 2001 From: Gerasim Troeglazov <3deyes@gmail.com> Date: Fri, 2 Mar 2007 07:48:19 +0000 Subject: [PATCH] Fixed build for R5 and dano targets. Bug fixes for fs_rename and fs_walk functions. Added simple identify functions for haiku. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20302 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/file_systems/ntfs/Jamfile | 9 +- .../kernel/file_systems/ntfs/attributes.c | 77 +++- .../kernel/file_systems/ntfs/attributes.h | 16 + .../kernel/file_systems/ntfs/fs_func.c | 368 +++++++++++++----- .../file_systems/ntfs/kernel_interface.cpp | 270 ------------- src/add-ons/kernel/file_systems/ntfs/lock.h | 44 +++ src/add-ons/kernel/file_systems/ntfs/ntfs.h | 23 +- .../kernel/file_systems/ntfs/ntfsdir.c | 302 +++++++++----- .../kernel/file_systems/ntfs/ntfsdir.h | 30 +- .../kernel/file_systems/ntfs/volume_util.c | 2 +- .../kernel/file_systems/ntfs/volume_util.h | 2 +- 11 files changed, 664 insertions(+), 479 deletions(-) delete mode 100644 src/add-ons/kernel/file_systems/ntfs/kernel_interface.cpp diff --git a/src/add-ons/kernel/file_systems/ntfs/Jamfile b/src/add-ons/kernel/file_systems/ntfs/Jamfile index 4fa17a2dab..921c9f1dd6 100644 --- a/src/add-ons/kernel/file_systems/ntfs/Jamfile +++ b/src/add-ons/kernel/file_systems/ntfs/Jamfile @@ -2,8 +2,10 @@ SubDir HAIKU_TOP src add-ons kernel file_systems ntfs ; SubDirHdrs [ FDirName $(SUBDIR) libntfs ] ; -SubDirCcFlags -DHAVE_CONFIG_H=1 -D_READ_ONLY_=1 ; -SubDirC++Flags -DHAVE_CONFIG_H=1 -D_READ_ONLY_=1 ; +SetSubDirSupportedPlatformsBeOSCompatible ; + +SubDirCcFlags -DHAVE_CONFIG_H=1 ; +SubDirC++Flags -DHAVE_CONFIG_H=1 ; UsePrivateHeaders kernel ; @@ -14,8 +16,7 @@ KernelAddon ntfs : ntfsdir.c volume_util.c fs_func.c - kernel_interface.cpp - kernel_cpp.cpp + kernel_interface.c : libntfs.a ; diff --git a/src/add-ons/kernel/file_systems/ntfs/attributes.c b/src/add-ons/kernel/file_systems/ntfs/attributes.c index d7291f353b..d3817bd016 100644 --- a/src/add-ons/kernel/file_systems/ntfs/attributes.c +++ b/src/add-ons/kernel/file_systems/ntfs/attributes.c @@ -54,8 +54,13 @@ status_t set_mime(vnode *node, const char *filename) } +#ifdef __HAIKU__ status_t fs_open_attrib_dir(void *_ns, void *_node, void **_cookie) +#else +int +fs_open_attrib_dir(void *_ns, void *_node, void **_cookie) +#endif { nspace *ns = (nspace *)_ns; int result = B_NO_ERROR; @@ -80,8 +85,13 @@ exit: return result; } +#ifdef __HAIKU__ status_t fs_close_attrib_dir(void *_ns, void *_node, void *_cookie) +#else +int +fs_close_attrib_dir(void *_ns, void *_node, void *_cookie) +#endif { nspace *ns = (nspace *)_ns; @@ -98,9 +108,13 @@ fs_close_attrib_dir(void *_ns, void *_node, void *_cookie) return B_NO_ERROR; } - +#ifdef __HAIKU__ status_t fs_free_attrib_dir_cookie(void *_ns, void *_node, void *_cookie) +#else +int +fs_free_attrib_dir_cookie(void *_ns, void *_node, void *_cookie) +#endif { nspace *ns = (nspace *)_ns; int result = B_NO_ERROR; @@ -127,9 +141,13 @@ exit: return result; } - +#ifdef __HAIKU__ status_t fs_rewind_attrib_dir(void *_ns, void *_node, void *_cookie) +#else +int +fs_rewind_attrib_dir(void *_ns, void *_node, void *_cookie) +#endif { nspace *ns = (nspace *)_ns; int result = B_NO_ERROR; @@ -156,8 +174,13 @@ exit: } +#ifdef __HAIKU__ status_t fs_read_attrib_dir(void *_ns, void *_node, void *_cookie, struct dirent *entry, size_t bufsize, uint32 *num) +#else +int +fs_read_attrib_dir(void *_ns, void *_node, void *_cookie, long *num, struct dirent *entry, size_t bufsize) +#endif { nspace *ns = (nspace *)_ns; vnode *node = (vnode *)_node; @@ -187,7 +210,28 @@ fs_read_attrib_dir(void *_ns, void *_node, void *_cookie, struct dirent *entry, return B_NO_ERROR; } +#ifndef __HAIKU__ +int +fs_read_attrib_stat(void *_ns, void *_node, const char *name, struct attr_info *buf) +{ + nspace *ns = (nspace *)_ns; + vnode *node = (vnode *)_node; + if (strcmp(name, "BEOS:TYPE")) + return ENOENT; + + if (node->mime == NULL) { + return ENOENT; + } + + buf->type = MIME_STRING_TYPE; + buf->size = strlen(node->mime) + 1; + + return 0; +} +#endif + +#ifdef __HAIKU__ status_t fs_open_attrib(void *_ns, void *_node, const char *name, int openMode, fs_cookie *_cookie) { @@ -219,22 +263,25 @@ exit: return result; } +#endif - +#ifdef __HAIKU__ status_t fs_close_attrib(void *_ns, void *_node, fs_cookie cookie) { return B_NO_ERROR; } +#endif - +#ifdef __HAIKU__ status_t fs_free_attrib_cookie(void *_ns, void *_node, fs_cookie cookie) { return B_NO_ERROR; } +#endif - +#ifdef __HAIKU__ status_t fs_read_attrib_stat(void *_ns, void *_node, fs_cookie _cookie, struct stat *stat) { @@ -267,10 +314,15 @@ exit: return B_NO_ERROR; } +#endif - +#ifdef __HAIKU__ status_t fs_read_attrib(void *_ns, void *_node, fs_cookie _cookie, off_t pos, void *buffer, size_t *_length) +#else +int +fs_read_attrib(void *_ns, void *_node, const char *name, int type, void *buffer, size_t *_length, off_t pos) +#endif { nspace *ns = (nspace *)_ns; vnode *node = (vnode *)_node; @@ -280,10 +332,12 @@ fs_read_attrib(void *_ns, void *_node, fs_cookie _cookie, off_t pos, void *buffe ERRPRINT("fs_read_attr - ENTER\n"); +#ifdef __HAIKU_ if (_cookie != &kBeOSTypeCookie) { result = ENOENT; goto exit; } +#endif if (node->mime == NULL) { result = ENOENT; @@ -309,9 +363,13 @@ exit: } +#ifdef __HAIKU__ status_t -fs_write_attrib(void *_ns, void *_node, fs_cookie _cookie, off_t pos, - const void *buffer, size_t *_length) +fs_write_attrib(void *_ns, void *_node, fs_cookie _cookie, off_t pos,const void *buffer, size_t *_length) +#else +int +fs_write_attrib(void *_ns, void *_node, const char *name, int type, const void *buffer, size_t *_length, off_t pos) +#endif { nspace *ns = (nspace *)_ns; int result = B_NO_ERROR; @@ -321,11 +379,12 @@ fs_write_attrib(void *_ns, void *_node, fs_cookie _cookie, off_t pos, ERRPRINT("fs_write_attr - ENTER\n"); *_length = 0; - +#ifdef __HAIKU_ if (_cookie != &kBeOSTypeCookie) { result = ENOSYS; goto exit; } +#endif exit: ERRPRINT("fs_write_attrib - EXIT, result is %s\n", strerror(result)); diff --git a/src/add-ons/kernel/file_systems/ntfs/attributes.h b/src/add-ons/kernel/file_systems/ntfs/attributes.h index 886c3eeb7a..712aa64407 100644 --- a/src/add-ons/kernel/file_systems/ntfs/attributes.h +++ b/src/add-ons/kernel/file_systems/ntfs/attributes.h @@ -14,6 +14,9 @@ status_t set_mime(vnode *node, const char *filename); + +#ifdef __HAIKU__ + status_t fs_open_attrib_dir(void *_vol, void *_node, void **_cookie); status_t fs_close_attrib_dir(void *_vol, void *_node, void *_cookie); status_t fs_free_attrib_dir_cookie(void *_vol, void *_node, void *_cookie); @@ -26,4 +29,17 @@ status_t fs_read_attrib_stat(void *_vol, void *_node, fs_cookie _cookie, struct status_t fs_read_attrib(void *_vol, void *_node, fs_cookie _cookie, off_t pos,void *buffer, size_t *_length); status_t fs_write_attrib(void *_vol, void *_node, fs_cookie _cookie, off_t pos, const void *buffer, size_t *_length); +#else + +int fs_open_attrib_dir(void *_vol, void *_node, void **_cookie); +int fs_close_attrib_dir(void *_vol, void *_node, void *_cookie); +int fs_free_attrib_dir_cookie(void *_vol, void *_node, void *_cookie); +int fs_rewind_attrib_dir(void *_vol, void *_node, void *_cookie); +int fs_read_attrib_dir(void *_vol, void *_node, void *_cookie, long *num, struct dirent *buf, size_t bufsize); +int fs_read_attrib_stat(void *_vol, void *_node, const char *name, struct attr_info *buf); +int fs_read_attrib(void *_vol, void *_node, const char *name, int type, void *buf, size_t *len, off_t pos); +int fs_write_attrib(void *_vol, void *_node, const char *name, int type, const void *buf, size_t *len, off_t pos); + +#endif //__HAIKU__ + #endif diff --git a/src/add-ons/kernel/file_systems/ntfs/fs_func.c b/src/add-ons/kernel/file_systems/ntfs/fs_func.c index d01ccbae62..5fc1567ec2 100644 --- a/src/add-ons/kernel/file_systems/ntfs/fs_func.c +++ b/src/add-ons/kernel/file_systems/ntfs/fs_func.c @@ -2,7 +2,7 @@ * Copyright (c) 2000-2004 Anton Altaparmakov * Copyright (c) 2002-2006 Szabolcs Szakacsits * - * Copyright (c) 2006 Troeglazov Gerasim (3dEyes**) + * Copyright (c) 2006-2007 Troeglazov Gerasim (3dEyes**) * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published by @@ -34,84 +34,85 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "ntfs.h" #include "attributes.h" #include "lock.h" #include "volume_util.h" - -status_t fs_mount( mount_id nsid, const char *device, ulong flags, const char *args, void **data, vnode_id *vnid ); -status_t fs_unmount(void *_ns); -status_t fs_rfsstat(void *_ns, struct fs_info *); -status_t fs_wfsstat(void *_vol, const struct fs_info *fss, uint32 mask); -status_t fs_sync(void *_ns); -status_t fs_walk(void *_ns, void *_base, const char *file, vnode_id *vnid,int *_type); -status_t fs_get_vnode_name(void *_ns, void *_node, char *buffer, size_t bufferSize); -status_t fs_read_vnode(void *_ns, vnode_id vnid, void **_node, bool reenter); -status_t fs_write_vnode(void *_ns, void *_node, bool reenter); -status_t fs_remove_vnode( void *_ns, void *_node, bool reenter ); -status_t fs_access( void *ns, void *node, int mode ); -status_t fs_rstat(void *_ns, void *_node, struct stat *st); -status_t fs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask); -status_t fs_create(void *_ns, void *_dir, const char *name, int omode, int perms, void **_cookie, vnode_id *_vnid); -status_t fs_open(void *_ns, void *_node, int omode, void **cookie); -status_t fs_close(void *ns, void *node, void *cookie); -status_t fs_free_cookie(void *ns, void *node, void *cookie); -status_t fs_read(void *_ns, void *_node, void *cookie, off_t pos, void *buf, size_t *len); -status_t fs_write(void *ns, void *node, void *cookie, off_t pos, const void *buf, size_t *len); -status_t fs_mkdir(void *_ns, void *_node, const char *name, int perms, vnode_id *_vnid); -status_t fs_rmdir(void *_ns, void *dir, const char *name); -status_t fs_opendir(void* _ns, void* _node, void** cookie); -status_t fs_readdir( void *_ns, void *_node, void *_cookie, struct dirent *buf, size_t bufsize, uint32 *num ); -status_t fs_rewinddir(void *_ns, void *_node, void *cookie); -status_t fs_closedir(void *_ns, void *_node, void *cookie); -status_t fs_free_dircookie(void *_ns, void *_node, void *cookie); -status_t fs_readlink(void *_ns, void *_node, char *buf, size_t *bufsize); -status_t fs_fsync(void *_ns, void *_node); -status_t fs_rename(void *_ns, void *_odir, const char *oldname, void *_ndir, const char *newname); -status_t fs_unlink(void *_ns, void *_node, const char *name); -status_t fs_create_symlink(void *_ns, void *_dir, const char *name, const char *target, int mode); - -void fs_free_identify_partition_cookie(partition_data *partition, void *_cookie); -status_t fs_scan_partition(int fd, partition_data *partition, void *_cookie); -float fs_identify_partition(int fd, partition_data *partition, void **_cookie); +#include "fs_func.h" #ifndef _READ_ONLY_ static status_t do_unlink(nspace *vol, vnode *dir, const char *name, bool isdir); #endif -//not emplemented now +#ifdef __HAIKU__ + +typedef struct identify_cookie { + NTFS_BOOT_SECTOR boot; +} identify_cookie; + float fs_identify_partition(int fd, partition_data *partition, void **_cookie) { - return 0.0f; + NTFS_BOOT_SECTOR boot; + identify_cookie *cookie; + uint8 *buf=(uint8*)&boot; + + // read in the boot sector + ERRPRINT("fs_identify_partition: read in the boot sector\n"); + if (read_pos(fd, 0, (void*)&boot, 512) != 512) { + return -1; + } + + // only check boot signature on hard disks to account for broken mtools + // behavior + + // check boot signature + if (((buf[0x1fe] != 0x55) || (buf[0x1ff] != 0xaa)) && (buf[0x15] == 0xf8)) + return -1; + + //check boot signature NTFS + if (memcmp(buf+3, "NTFS ", 8)!=0) + return -1; + + //allocate identify_cookie + cookie = (identify_cookie *)malloc(sizeof(identify_cookie)); + if (!cookie) + return -1; + + memcpy(&(cookie->boot),&boot,512); + + *_cookie = cookie; + + return 0.8f; } -//not emplemented now status_t fs_scan_partition(int fd, partition_data *partition, void *_cookie) { + identify_cookie *cookie = (identify_cookie *)_cookie; + partition->status = B_PARTITION_VALID; + partition->flags |= B_PARTITION_FILE_SYSTEM; + partition->content_size = sle64_to_cpu(cookie->boot.number_of_sectors) * le16_to_cpu(cookie->boot.bpb.bytes_per_sector); + partition->block_size = le16_to_cpu(cookie->boot.bpb.bytes_per_sector); + partition->content_name = strdup("NTFS Volume"); return B_OK; } -//not emplemented now void fs_free_identify_partition_cookie(partition_data *partition, void *_cookie) { + identify_cookie *cookie = (identify_cookie *)_cookie; + free(cookie); } +#endif //__HAIKU__ - +#ifdef __HAIKU__ status_t fs_mount( mount_id nsid, const char *device, ulong flags, const char *args, void **data, vnode_id *vnid ) +#else +int +fs_mount(nspace_id nsid, const char *device, ulong flags, void *parms, size_t len, void **data, vnode_id *vnid) +#endif { nspace *ns; vnode *newNode = NULL; @@ -119,7 +120,7 @@ fs_mount( mount_id nsid, const char *device, ulong flags, const char *args, void status_t result = B_NO_ERROR; ERRPRINT("fs_mount - ENTER\n"); - + ns = ntfs_malloc(sizeof(nspace)); if (!ns) { result = ENOMEM; @@ -138,11 +139,17 @@ fs_mount( mount_id nsid, const char *device, ulong flags, const char *args, void strcpy(ns->devicePath,device); sprintf(lockname, "ntfs_lock %lx", ns->id); - if ((result = recursive_lock_init(&(ns->vlock), lockname)) != 0) { + +#ifdef __HAIKU__ + if ((result = recursive_lock_init(&(ns->vlock), lockname)) != 0) +#else + if ((result = new_lock(&(ns->vlock), lockname)) != B_OK) +#endif + { ERRPRINT("fs_mount - error creating lock (%s)\n", strerror(result)); goto exit; } - + ns->ntvol=utils_mount_volume(device,0,true); if(ns->ntvol!=NULL) result = B_NO_ERROR; @@ -183,8 +190,13 @@ exit: return result; } +#ifdef __HAIKU__ status_t fs_unmount(void *_ns) +#else +int +fs_unmount(void *_ns) +#endif { nspace *ns = (nspace*)_ns; status_t result = B_NO_ERROR; @@ -192,8 +204,12 @@ fs_unmount(void *_ns) ERRPRINT("fs_unmount - ENTER\n"); ntfs_device_umount( ns->ntvol, true ); - + +#ifdef __HAIKU__ recursive_lock_destroy(&(ns->vlock)); +#else + free_lock(&(ns->vlock)); +#endif free( ns ); @@ -202,8 +218,13 @@ fs_unmount(void *_ns) return result; } +#ifdef __HAIKU__ status_t fs_rfsstat( void *_ns, struct fs_info * fss ) +#else +int +fs_rfsstat( void *_ns, struct fs_info * fss ) +#endif { nspace *ns = (nspace*)_ns; int i; @@ -242,15 +263,24 @@ fs_rfsstat( void *_ns, struct fs_info * fss ) } #ifndef _READ_ONLY_ +#ifdef __HAIKU__ status_t fs_wfsstat(void *_vol, const struct fs_info * fss, uint32 mask) +#else +int +fs_wfsstat(void *_vol, struct fs_info *fss, long mask) +#endif { nspace* ns = (nspace*)_vol; status_t result = B_NO_ERROR; LOCK_VOL(ns); +#ifdef __HAIKU__ if (mask & FS_WRITE_FSINFO_NAME) { +#else + if (mask & WFSSTAT_NAME) { +#endif result = ntfs_change_label( ns->ntvol, (char*)fss->volume_name ); goto exit; } @@ -263,8 +293,13 @@ exit: } #endif +#ifdef __HAIKU__ status_t fs_walk(void *_ns, void *_base, const char *file, vnode_id *vnid,int *_type) +#else +int +fs_walk(void *_ns, void *_base, const char *file, char **newpath, vnode_id *vnid) +#endif { nspace *ns = (nspace*)_ns; vnode *baseNode = (vnode*)_base; @@ -317,6 +352,9 @@ fs_walk(void *_ns, void *_base, const char *file, vnode_id *vnid,int *_type) if( get_vnode( ns->id, *vnid, (void**)&newNode ) !=0 ) result = ENOENT; + + if(newNode!=NULL) + newNode->parent_vnid = baseNode->vnid; } exit: @@ -328,7 +366,7 @@ exit: return result; } - +#ifdef __HAIKU__ status_t fs_get_vnode_name(void *_ns, void *_node, char *buffer, size_t bufferSize) { @@ -366,12 +404,17 @@ exit: return result; } +#endif - +#ifdef __HAIKU__ status_t fs_read_vnode(void *_ns, vnode_id vnid, void **node, bool reenter) +#else +int +fs_read_vnode(void *_ns, vnode_id vnid, char reenter, void **node) +#endif { nspace *ns = (nspace*)_ns; vnode *newNode = NULL; @@ -424,8 +467,13 @@ exit: return result; } +#ifdef __HAIKU__ status_t fs_write_vnode( void *_ns, void *_node, bool reenter ) +#else +int +fs_write_vnode( void *_ns, void *_node, char reenter ) +#endif { nspace *ns = (nspace*)_ns; vnode *node = (vnode*)_node; @@ -448,8 +496,13 @@ fs_write_vnode( void *_ns, void *_node, bool reenter ) } #ifndef _READ_ONLY_ +#ifdef __HAIKU__ status_t fs_remove_vnode( void *_ns, void *_node, bool reenter ) +#else +int +fs_remove_vnode( void *_ns, void *_node, char reenter ) +#endif { nspace *ns = (nspace*)_ns; vnode *node = (vnode*)_node; @@ -471,9 +524,14 @@ fs_remove_vnode( void *_ns, void *_node, bool reenter ) return result; } #endif - + +#ifdef __HAIKU__ status_t fs_rstat( void *_ns, void *_node, struct stat *stbuf ) +#else +int +fs_rstat( void *_ns, void *_node, struct stat *stbuf ) +#endif { nspace *ns = (nspace*)_ns; vnode *node = (vnode*)_node; @@ -570,8 +628,13 @@ exit: } #ifndef _READ_ONLY_ +#ifdef __HAIKU__ status_t fs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask) +#else +int +fs_wstat(void *_vol, void *_node, struct stat *st, long mask) +#endif { nspace *ns = (nspace*)_vol; vnode *node = (vnode*)_node; @@ -588,8 +651,11 @@ fs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask) goto exit; } +#ifdef __HAIKU__ if ( mask & FS_WRITE_STAT_SIZE ) { - +#else + if (mask & WSTAT_SIZE) { +#endif ERRPRINT("fs_wstat: setting file size to %Lx\n", st->st_size); if ( ni->mrec->flags & MFT_RECORD_IS_DIRECTORY ) { @@ -606,22 +672,31 @@ fs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask) ntfs_attr_close(na); ntfs_mark_free_space_outdated(ns); - - //notify_listener(B_STAT_CHANGED, ns->id, 0, 0, MREF(ni->mft_no), NULL); + +#ifdef __HAIKU__ notify_stat_changed(ns->id, MREF(ni->mft_no), mask); - +#else + notify_listener(B_STAT_CHANGED, ns->id, 0, 0, MREF(ni->mft_no), NULL); +#endif + } } +#ifdef __HAIKU__ if (mask & FS_WRITE_STAT_MTIME) { - +#else + if (mask & WSTAT_MTIME) { +#endif ERRPRINT("fs_wstat: setting modification time\n"); ni->last_access_time = st->st_atime; ni->last_data_change_time = st->st_mtime; ni->last_mft_change_time = st->st_ctime; - //notify_listener(B_STAT_CHANGED, ns->id, 0, 0, MREF(ni->mft_no), NULL); +#ifdef __HAIKU__ notify_stat_changed(ns->id, MREF(ni->mft_no), mask); +#else + notify_listener(B_STAT_CHANGED, ns->id, 0, 0, MREF(ni->mft_no), NULL); +#endif } exit: @@ -629,7 +704,7 @@ exit: if(ni) ntfs_inode_close(ni); - ERRPRINT("dosfs_wstat: EXIT with (%s)\n", strerror(err)); + ERRPRINT("dosfs_wstat: EXIT with (%s)\n", strerror(result)); UNLOCK_VOL(ns); @@ -638,16 +713,23 @@ exit: #endif #ifndef _READ_ONLY_ +#ifdef __HAIKU__ status_t fs_sync(void *_ns) +#else +int +fs_sync(void *_ns) +#endif { nspace *ns = (nspace *)_ns; LOCK_VOL(ns); ERRPRINT("fs_sync - ENTER\n"); - -// flush_device(DEV_FD(ns->ntvol->dev), 0); + +#ifndef __HAIKU__ + flush_device(DEV_FD(ns->ntvol->dev), 0); +#endif ERRPRINT("fs_sync - EXIT\n"); @@ -658,8 +740,13 @@ fs_sync(void *_ns) #endif #ifndef _READ_ONLY_ +#ifdef __HAIKU__ status_t fs_fsync(void *_ns, void *_node) +#else +int +fs_fsync(void *_ns, void *_node) +#endif { nspace *ns = (nspace*)_ns; vnode *node = (vnode*)_node; @@ -696,9 +783,13 @@ exit: } #endif - +#ifdef __HAIKU__ status_t fs_open(void *_ns, void *_node, int omode, void **_cookie) +#else +int +fs_open(void *_ns, void *_node, int omode, void **_cookie) +#endif { nspace *ns = (nspace*)_ns; vnode *node = (vnode*)_node; @@ -758,8 +849,13 @@ exit: #ifndef _READ_ONLY_ +#ifdef __HAIKU__ status_t fs_create(void *_ns, void *_dir, const char *name, int omode, int perms, void **_cookie, vnode_id *_vnid) +#else +int +fs_create(void *_ns, void *_dir, const char *name, int omode, int perms, vnode_id *_vnid, void **_cookie) +#endif { nspace *ns = (nspace*)_ns; vnode *dir = (vnode*)_dir; @@ -842,9 +938,14 @@ fs_create(void *_ns, void *_dir, const char *name, int omode, int perms, void ** result = B_NO_ERROR; result = publish_vnode(ns->id, *_vnid, (void*)newNode); - ntfs_mark_free_space_outdated(ns); + ntfs_mark_free_space_outdated(ns); + +#ifdef __HAIKU__ notify_entry_created(ns->id, MREF( bi->mft_no ), name, *_vnid); - //notify_listener(B_ENTRY_CREATED, ns->id, MREF( bi->mft_no ), 0, *_vnid, name); +#else + notify_listener(B_ENTRY_CREATED, ns->id, MREF( bi->mft_no ), 0, *_vnid, name); +#endif + } else result = errno; } @@ -873,9 +974,13 @@ exit: } #endif - +#ifdef __HAIKU__ status_t fs_read( void *_ns, void *_node, void *_cookie, off_t offset, void *buf, size_t *len ) +#else +int +fs_read( void *_ns, void *_node, void *_cookie, off_t offset, void *buf, size_t *len ) +#endif { nspace *ns = (nspace*)_ns; vnode *node = (vnode*)_node; @@ -952,8 +1057,13 @@ exit2: #ifndef _READ_ONLY_ +#ifdef __HAIKU__ status_t fs_write( void *_ns, void *_node, void *_cookie, off_t offset, const void *buf, size_t *len ) +#else +int +fs_write( void *_ns, void *_node, void *_cookie, off_t offset, const void *buf, size_t *len ) +#endif { nspace *ns = (nspace*)_ns; vnode *node = (vnode*)_node; @@ -1005,9 +1115,12 @@ fs_write( void *_ns, void *_node, void *_cookie, off_t offset, const void *buf, if(ntfs_attr_truncate(na, offset + size)) size = na->data_size - offset; else +#ifdef __HAIKU__ notify_stat_changed(ns->id, MREF(ni->mft_no), B_STAT_SIZE); +#else + notify_listener(B_STAT_CHANGED, ns->id, 0, 0, MREF(ni->mft_no), NULL); +#endif } - //notify_listener(B_STAT_CHANGED, ns->id, 0, 0, MREF(ni->mft_no), NULL); } while (size) { result = ntfs_attr_pwrite(na, offset, size, buf); @@ -1042,8 +1155,13 @@ exit2: } #endif +#ifdef __HAIKU__ status_t fs_close(void *ns, void *node, void *cookie) +#else +int +fs_close(void *ns, void *node, void *cookie) +#endif { ERRPRINT("fs_close - ENTER\n"); @@ -1051,8 +1169,13 @@ fs_close(void *ns, void *node, void *cookie) return B_NO_ERROR; } +#ifdef __HAIKU__ status_t fs_free_cookie( void *ns, void *node, void *cookie ) +#else +int +fs_free_cookie( void *ns, void *node, void *cookie ) +#endif { ERRPRINT("fs_free_cookie - ENTER\n"); @@ -1063,9 +1186,13 @@ fs_free_cookie( void *ns, void *node, void *cookie ) return B_NO_ERROR; } - +#ifdef __HAIKU__ status_t fs_access( void *ns, void *node, int mode ) +#else +int +fs_access( void *ns, void *node, int mode ) +#endif { ERRPRINT("fs_access - ENTER\n"); @@ -1073,8 +1200,13 @@ fs_access( void *ns, void *node, int mode ) return B_NO_ERROR; } +#ifdef __HAIKU__ status_t fs_readlink(void *_ns, void *_node, char *buff, size_t *buff_size) +#else +int +fs_readlink(void *_ns, void *_node, char *buff, size_t *buff_size) +#endif { nspace *ns = (nspace*)_ns; vnode *node = (vnode*)_node; @@ -1169,8 +1301,13 @@ exit: } #ifndef _READ_ONLY_ +#ifdef __HAIKU__ status_t fs_create_symlink(void *_ns, void *_dir, const char *name, const char *target, int mode) +#else +int +fs_create_symlink(void *_ns, void *_dir, const char *name, const char *target) +#endif { nspace *ns = (nspace*)_ns; vnode *dir = (vnode*)_dir; @@ -1231,12 +1368,15 @@ fs_create_symlink(void *_ns, void *_dir, const char *name, const char *target, i set_mime(symnode, name); if ((result = publish_vnode(ns->id, MREF(sym->mft_no), symnode)) != 0) - ERRPRINT("fs_symlink - new_vnode failed for vnid %Ld: %s\n", MREF(sym->mft_no), strerror(res)); + ERRPRINT("fs_symlink - new_vnode failed for vnid %Ld: %s\n", MREF(sym->mft_no), strerror(result)); put_vnode(ns->id, MREF(sym->mft_no) ); - -// notify_listener(B_ENTRY_CREATED, ns->id, MREF(dir->ntnode->mft_no), 0, MREF(sym->mft_no), name); + +#ifdef __HAIKU__ notify_entry_created(ns->id, MREF( bi->mft_no ), name, MREF(sym->mft_no)); +#else + notify_listener(B_ENTRY_CREATED, ns->id, MREF(bi->mft_no), 0, MREF(sym->mft_no), name); +#endif exit: @@ -1254,8 +1394,13 @@ exit: #endif #ifndef _READ_ONLY_ +#ifdef __HAIKU__ status_t fs_mkdir(void *_ns, void *_node, const char *name, int perms, vnode_id *_vnid) +#else +int +fs_mkdir(void *_ns, void *_node, const char *name, int perms) +#endif { nspace *ns = (nspace*)_ns; vnode *dir = (vnode*)_node; @@ -1280,13 +1425,14 @@ fs_mkdir(void *_ns, void *_node, const char *name, int perms, vnode_id *_vnid) result = ENOENT; goto exit; } - -// if (is_vnode_removed(ns->id, MREF(dir->ntnode->mft_no)) > 0) -// { -// ERRPRINT("fs_mkdir - called in removed directory\n"); -// result = EPERM; -// goto exit; -// } + +#ifndef __HAIKU__ + if (is_vnode_removed(ns->id, MREF(bi->mft_no)) > 0) { + ERRPRINT("fs_mkdir - called in removed directory\n"); + result = EPERM; + goto exit; + } +#endif if (! bi->mrec->flags & MFT_RECORD_IS_DIRECTORY) { result = EINVAL; @@ -1316,15 +1462,19 @@ fs_mkdir(void *_ns, void *_node, const char *name, int perms, vnode_id *_vnid) set_mime(newNode, ".***"); result = publish_vnode(ns->id, vnid, (void*)newNode); - +#ifdef __HAIKU__ *_vnid = vnid; - +#endif put_vnode(ns->id, MREF(ni->mft_no)); ntfs_mark_free_space_outdated(ns); - -// notify_listener(B_ENTRY_CREATED, ns->id, MREF( bi->mft_no ), 0, vnid, name); + +#ifdef __HAIKU__ notify_entry_created(ns->id, MREF( bi->mft_no ), name, vnid); +#else + notify_listener(B_ENTRY_CREATED, ns->id, MREF( bi->mft_no ), 0, vnid, name); +#endif + } else result = errno; @@ -1345,8 +1495,13 @@ exit: #endif #ifndef _READ_ONLY_ +#ifdef __HAIKU__ status_t fs_rename(void *_ns, void *_odir, const char *oldname, void *_ndir, const char *newname) +#else +int +fs_rename(void *_ns, void *_odir, const char *oldname, void *_ndir, const char *newname) +#endif { nspace *ns = (nspace*)_ns; vnode *odir = (vnode*)_odir; @@ -1460,11 +1615,15 @@ fs_rename(void *_ns, void *_odir, const char *oldname, void *_ndir, const char * ntfs_delete(oi, odi, uoldname, uoldname_len); onode->parent_vnid = MREF( ndi->mft_no ); - + +#ifdef __HAIKU__ notify_entry_moved(ns->id, MREF( odi->mft_no ), oldname, MREF( ndi->mft_no ), newname, onode->vnid ); notify_attribute_changed(ns->id, onode->vnid, "BEOS:TYPE", B_ATTR_CHANGED); - //notify_listener(B_ENTRY_MOVED, ns->id, MREF( odir->ntnode->mft_no ), MREF( ndir->ntnode->mft_no ), MREF( onode->ntnode->mft_no ), newname); - //notify_listener(B_ATTR_CHANGED, ns->id, 0, 0, nvnid, "BEOS:TYPE"); +#else + notify_listener(B_ENTRY_MOVED, ns->id, MREF( odi->mft_no ), MREF( ndi->mft_no ), MREF( onode->vnid ), newname); + notify_listener(B_ATTR_CHANGED, ns->id, 0, 0, onode->vnid, "BEOS:TYPE"); +#endif + put_vnode(ns->id, onode->vnid ); } else { //renaming @@ -1505,11 +1664,13 @@ fs_rename(void *_ns, void *_odir, const char *oldname, void *_ndir, const char * } ntfs_delete(oi, odi, uoldname, uoldname_len); - +#ifdef __HAIKU__ notify_entry_moved(ns->id, MREF( odi->mft_no ), oldname, MREF( odi->mft_no ), newname, onode->vnid ); notify_attribute_changed(ns->id, onode->vnid, "BEOS:TYPE", B_ATTR_CHANGED); - //notify_listener(B_ENTRY_MOVED, ns->id, MREF( odir->ntnode->mft_no ), MREF( ndir->ntnode->mft_no ), MREF( onode->ntnode->mft_no ), newname); - //notify_listener(B_ATTR_CHANGED, ns->id, 0, 0, nvnid, "BEOS:TYPE"); +#else + notify_listener(B_ENTRY_MOVED, ns->id, MREF( odi->mft_no ), MREF( odi->mft_no ), MREF( onode->vnid ), newname); + notify_listener(B_ATTR_CHANGED, ns->id, 0, 0, onode->vnid, "BEOS:TYPE"); +#endif put_vnode(ns->id, onode->vnid ); } @@ -1597,9 +1758,14 @@ do_unlink(nspace *vol, vnode *dir, const char *name, bool isdir) else ni = NULL; - node->parent_vnid = dir->vnid; - //notify_listener(B_ENTRY_REMOVED, vol->id, MREF(dir->ntnode->mft_no), 0, vnid, NULL); + node->parent_vnid = dir->vnid; + +#ifdef __HAIKU__ notify_entry_removed(vol->id, dir->vnid, name, vnid); +#else + notify_listener(B_ENTRY_REMOVED, vol->id, MREF(dir->vnid), 0, vnid, NULL); +#endif + result = remove_vnode(vol->id, vnid); exit2: put_vnode(vol->id, vnid); @@ -1618,8 +1784,13 @@ exit1: #endif #ifndef _READ_ONLY_ +#ifdef __HAIKU__ status_t fs_rmdir(void *_ns, void *_node, const char *name) +#else +int +fs_rmdir(void *_ns, void *_node, const char *name) +#endif { nspace *ns = (nspace*)_ns; vnode *dir = (vnode*)_node; @@ -1659,8 +1830,13 @@ exit1: #endif #ifndef _READ_ONLY_ +#ifdef __HAIKU__ status_t fs_unlink(void *_ns, void *_node, const char *name) +#else +int +fs_unlink(void *_ns, void *_node, const char *name) +#endif { nspace *ns = (nspace*)_ns; vnode *dir = (vnode*)_node; diff --git a/src/add-ons/kernel/file_systems/ntfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/ntfs/kernel_interface.cpp deleted file mode 100644 index d6eb7d472c..0000000000 --- a/src/add-ons/kernel/file_systems/ntfs/kernel_interface.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/* kernel_interface - file system interface to Haiku's vnode layer - * - * Copyright (c) 2006 Troeglazov Gerasim (3dEyes**) - * - * This program/include file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program/include file is distributed in the hope that it will be - * useful, but WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (in the main directory of the Linux-NTFS - * distribution in the file COPYING); if not, write to the Free Software - * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - - -extern "C"{ - - status_t fs_mount( mount_id nsid, const char *device, ulong flags, const char *args, void **data, vnode_id *vnid ); - status_t fs_unmount(void *_ns); - status_t fs_rfsstat(void *_ns, struct fs_info *); - status_t fs_wfsstat(void *_vol, const struct fs_info *fss, uint32 mask); - status_t fs_sync(void *_ns); - status_t fs_walk(void *_ns, void *_base, const char *file, vnode_id *vnid,int *_type); - status_t fs_get_vnode_name(void *_ns, void *_node, char *buffer, size_t bufferSize); - status_t fs_read_vnode(void *_ns, vnode_id vnid, void **_node, bool reenter); - status_t fs_write_vnode(void *_ns, void *_node, bool reenter); - status_t fs_remove_vnode( void *_ns, void *_node, bool reenter ); - status_t fs_access( void *ns, void *node, int mode ); - status_t fs_rstat(void *_ns, void *_node, struct stat *st); - status_t fs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask); - status_t fs_create(void *_ns, void *_dir, const char *name, int omode, int perms, void **_cookie, vnode_id *_vnid); - status_t fs_open(void *_ns, void *_node, int omode, void **cookie); - status_t fs_close(void *ns, void *node, void *cookie); - status_t fs_free_cookie(void *ns, void *node, void *cookie); - status_t fs_read(void *_ns, void *_node, void *cookie, off_t pos, void *buf, size_t *len); - status_t fs_write(void *ns, void *node, void *cookie, off_t pos, const void *buf, size_t *len); - status_t fs_mkdir(void *_ns, void *_node, const char *name, int perms, vnode_id *_vnid); - status_t fs_rmdir(void *_ns, void *dir, const char *name); - status_t fs_opendir(void* _ns, void* _node, void** cookie); - status_t fs_readdir( void *_ns, void *_node, void *_cookie, struct dirent *buf, size_t bufsize, uint32 *num ); - status_t fs_rewinddir(void *_ns, void *_node, void *cookie); - status_t fs_closedir(void *_ns, void *_node, void *cookie); - status_t fs_free_dircookie(void *_ns, void *_node, void *cookie); - status_t fs_readlink(void *_ns, void *_node, char *buf, size_t *bufsize); - status_t fs_fsync(void *_ns, void *_node); - - status_t fs_rename(void *_ns, void *_odir, const char *oldname, void *_ndir, const char *newname); - status_t fs_unlink(void *_ns, void *_node, const char *name); - status_t fs_create_symlink(void *_ns, void *_dir, const char *name, const char *target, int mode); - - status_t fs_open_attrib_dir(void *_vol, void *_node, void **_cookie); - status_t fs_close_attrib_dir(void *_vol, void *_node, void *_cookie); - status_t fs_free_attrib_dir_cookie(void *_vol, void *_node, void *_cookie); - status_t fs_rewind_attrib_dir(void *_vol, void *_node, void *_cookie); - status_t fs_read_attrib_dir(void *_vol, void *_node, void *_cookie, struct dirent *buf, size_t bufsize, uint32 *num); - status_t fs_open_attrib(void *_vol, void *_node, const char *name, int openMode,fs_cookie *_cookie); - status_t fs_close_attrib(void *_vol, void *_node, fs_cookie cookie); - status_t fs_free_attrib_cookie(void *_vol, void *_node, fs_cookie cookie); - status_t fs_read_attrib_stat(void *_vol, void *_node, fs_cookie _cookie, struct stat *stat); - status_t fs_read_attrib(void *_vol, void *_node, fs_cookie _cookie, off_t pos,void *buffer, size_t *_length); - status_t fs_write_attrib(void *_vol, void *_node, fs_cookie _cookie, off_t pos, const void *buffer, size_t *_length); - - void fs_free_identify_partition_cookie(partition_data *partition, void *_cookie); - status_t fs_scan_partition(int fd, partition_data *partition, void *_cookie); - float fs_identify_partition(int fd, partition_data *partition, void **_cookie); -}; - - -static status_t -ntfs_std_ops(int32 op, ...) -{ - switch (op) { - case B_MODULE_INIT: - return B_OK; - case B_MODULE_UNINIT: - return B_OK; - default: - return B_ERROR; - } -} - - -static file_system_module_info sNTFSFileSystem = { - { - "file_systems/ntfs" B_CURRENT_FS_API_VERSION, - 0, - ntfs_std_ops, - }, - - "ntfs File System", - - // scanning - fs_identify_partition, - fs_scan_partition, - fs_free_identify_partition_cookie, - NULL, // free_partition_content_cookie() - - &fs_mount, - &fs_unmount, - &fs_rfsstat, -#ifdef _READ_ONLY_ - NULL, -#else - &fs_wfsstat, -#endif - NULL, - - /* vnode operations */ - &fs_walk, - &fs_get_vnode_name, - &fs_read_vnode, - &fs_write_vnode, -#ifdef _READ_ONLY_ - NULL, -#else - &fs_remove_vnode, -#endif - - /* VM file access */ - NULL, // &fs_can_page - NULL, // &fs_read_pages - NULL, // &fs_write_pages - - NULL, // &fs_get_file_map - - NULL, // &fs_ioctl - NULL, // &fs_set_flags - NULL, // &fs_select - NULL, // &fs_deselect - -#ifdef _READ_ONLY_ - NULL, -#else - &fs_fsync, -#endif - - &fs_readlink, - -#ifdef _READ_ONLY_ - NULL, - NULL, - NULL, - NULL, - NULL, -#else - NULL, // write link - &fs_create_symlink, - NULL, // &fs_link, - &fs_unlink, - &fs_rename, -#endif - - &fs_access, - &fs_rstat, -#ifdef _READ_ONLY_ - NULL, -#else - &fs_wstat, -#endif - - /* file operations */ -#ifdef _READ_ONLY_ - NULL, -#else - &fs_create, -#endif - &fs_open, - &fs_close, - &fs_free_cookie, - &fs_read, -#ifdef _READ_ONLY_ - NULL, -#else - &fs_write, -#endif - - /* directory operations */ -#ifdef _READ_ONLY_ - NULL, - NULL, -#else - &fs_mkdir, - &fs_rmdir, -#endif - &fs_opendir, - &fs_closedir, - &fs_free_dircookie, - &fs_readdir, - &fs_rewinddir, - - /* attribute directory operations */ - &fs_open_attrib_dir, - &fs_close_attrib_dir, - &fs_free_attrib_dir_cookie, - &fs_read_attrib_dir, - &fs_rewind_attrib_dir, - - /* attribute operations */ - NULL, //&fs_create_attr, - &fs_open_attrib, - &fs_close_attrib, - &fs_free_attrib_cookie, - &fs_read_attrib, - &fs_write_attrib, - - &fs_read_attrib_stat, - NULL, //&fs_write_attr_stat, - NULL, //&fs_rename_attr, - NULL, //&fs_remove_attr, - - /* index directory & index operations */ - NULL, // &fs_open_index_dir - NULL, // &fs_close_index_dir - NULL, // &fs_free_index_dir_cookie - NULL, // &fs_read_index_dir - NULL, // &fs_rewind_index_dir - - NULL, // &fs_create_index - NULL, // &fs_remove_index - NULL, // &fs_stat_index - - /* query operations */ - NULL, // &fs_open_query - NULL, // &fs_close_query - NULL, // &fs_free_query_cookie - NULL, // &fs_read_query - NULL, // &fs_rewind_query -}; - -module_info *modules[] = { - (module_info *)&sNTFSFileSystem, - NULL, -}; diff --git a/src/add-ons/kernel/file_systems/ntfs/lock.h b/src/add-ons/kernel/file_systems/ntfs/lock.h index 2cb264e623..abfb327a3f 100644 --- a/src/add-ons/kernel/file_systems/ntfs/lock.h +++ b/src/add-ons/kernel/file_systems/ntfs/lock.h @@ -5,10 +5,54 @@ #include +#ifdef __HAIKU__ + typedef recursive_lock lock; #define LOCK(l) recursive_lock_lock(&l); #define UNLOCK(l) recursive_lock_unlock(&l); +#else + +typedef struct lock lock; +typedef struct mlock mlock; + +struct lock { + sem_id s; + long c; +}; + +struct mlock { + sem_id s; +}; + +extern int new_lock(lock *l, const char *name); +extern int free_lock(lock *l); + +static inline status_t LOCK(lock *l) +{ + if (atomic_add(&(l->c), -1) <= 0) + return acquire_sem(l->s); + return B_OK; +} + +static inline status_t UNLOCK(lock *l) +{ + if (atomic_add(&(l->c), 1) < 0) + return release_sem(l->s); + return B_OK; +} + + +#define LOCK(l) if (atomic_add(&l.c, -1) <= 0) acquire_sem(l.s); +#define UNLOCK(l) if (atomic_add(&l.c, 1) < 0) release_sem(l.s); + +extern int new_mlock(mlock *l, long c, const char *name); +extern int free_mlock(mlock *l); + +#define LOCKM(l,cnt) acquire_sem_etc(l.s, cnt, 0, 0) +#define UNLOCKM(l,cnt) release_sem_etc(l.s, cnt, 0) + +#endif //__HAIKU__ #endif diff --git a/src/add-ons/kernel/file_systems/ntfs/ntfs.h b/src/add-ons/kernel/file_systems/ntfs/ntfs.h index bcf2694a83..324429ea23 100644 --- a/src/add-ons/kernel/file_systems/ntfs/ntfs.h +++ b/src/add-ons/kernel/file_systems/ntfs/ntfs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Troeglazov Gerasim (3dEyes**) + * Copyright (c) 2006-2007 Troeglazov Gerasim (3dEyes**) * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published @@ -24,15 +24,28 @@ extern "C" { #endif -#include -#include +#ifdef __HAIKU__ + #include +#include +#include #include #include #include #include #include #include +#include +#include + +#else + +#include "fsproto.h" +#include "lock.h" + +#define publish_vnode new_vnode + +#endif #include "config.h" #include "attrib.h" @@ -98,7 +111,11 @@ typedef struct nspace { ntfs_volume *ntvol; char devicePath[MAX_PATH]; +#ifdef __HAIKU__ mount_id id; +#else + nspace_id id; +#endif int free_cluster_count; char volumeLabel[MAX_PATH]; diff --git a/src/add-ons/kernel/file_systems/ntfs/ntfsdir.c b/src/add-ons/kernel/file_systems/ntfs/ntfsdir.c index c972a1d478..c101e59490 100644 --- a/src/add-ons/kernel/file_systems/ntfs/ntfsdir.c +++ b/src/add-ons/kernel/file_systems/ntfs/ntfsdir.c @@ -1,6 +1,6 @@ /* ntfsdir.c - directory functions * - * Copyright (c) 2006 Troeglazov Gerasim (3dEyes**) + * Copyright (c) 2006-2007 Troeglazov Gerasim (3dEyes**) * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published @@ -32,56 +32,109 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "ntfs.h" #include "attributes.h" #include "lock.h" #include "ntfsdir.h" //callback function for readdir() -static int _ntfs_dirent_filler(void *_dirent, const ntfschar *name, - const int name_len, const int name_type, const s64 pos, - const MFT_REF mref, const unsigned dt_type); - -static int _ntfs_dirent_filler(void *_dirent, const ntfschar *name, +static +int _ntfs_dirent_dot_filler(void *_dirent, const ntfschar *name, const int name_len, const int name_type, const s64 pos, const MFT_REF mref, const unsigned dt_type) { char *filename = NULL; dircookie *cookie = (dircookie*)_dirent; - if (name_type == FILE_NAME_DOS) + if (name_type == FILE_NAME_DOS)return 0; + + if (ntfs_ucstombs(name, name_len, &filename, 0) < 0) + { + ERRPRINT("Skipping unrepresentable filename\n"); return 0; - - if (MREF(mref) == FILE_root || MREF(mref) >= FILE_first_user || cookie->show_sys_files) { - if(cookie->readed==1) { - cookie->pos=pos; - cookie->readed = 0; - return -1; - } else { - if (ntfs_ucstombs(name, name_len, &filename, 0) < 0) - return -1; - strcpy(cookie->name,filename); - cookie->ino=MREF(mref); - cookie->readed = 1; - return 0; - } + } + + if(strcmp(filename,".")==0 || strcmp(filename,"..")==0) + if (MREF(mref) == FILE_root || MREF(mref) >= FILE_first_user || false) + { + struct direntry *ent = (direntry*)ntfs_calloc(sizeof(direntry)); + ent->name = (char*)ntfs_calloc(strlen(filename)+1); + strcpy(ent->name,filename); + ent->dev=cookie->dev; + ent->ino=MREF(mref); + ent->next = NULL; + + if(cookie->root==NULL) + { + cookie->root = ent; + cookie->walk = ent; + } + + if(cookie->last != NULL) + cookie->last->next = ent; + + cookie->last = ent; + } else { + + free(filename); + return -1; + } + + free(filename); + return 0; +} + +static +int _ntfs_dirent_filler(void *_dirent, const ntfschar *name, + const int name_len, const int name_type, const s64 pos, + const MFT_REF mref, const unsigned dt_type) +{ + char *filename = NULL; + dircookie *cookie = (dircookie*)_dirent; + + if (name_type == FILE_NAME_DOS)return 0; + + if (ntfs_ucstombs(name, name_len, &filename, 0) < 0) + { + ERRPRINT("Skipping unrepresentable filename\n"); + return 0; + } + + if(strcmp(filename,".")==0 || strcmp(filename,"..")==0) + return 0; + + if (MREF(mref) == FILE_root || MREF(mref) >= FILE_first_user || false) + { + struct direntry *ent = (direntry*)ntfs_calloc(sizeof(direntry)); + ent->name = (char*)ntfs_calloc(strlen(filename)+1); + strcpy(ent->name,filename); + ent->dev=cookie->dev; + ent->ino=MREF(mref); + ent->next = NULL; + + if(cookie->root==NULL) + { + cookie->root = ent; + cookie->walk = ent; + } + + if(cookie->last != NULL) + cookie->last->next = ent; + + cookie->last = ent; } + free(filename); return 0; } +#ifdef __HAIKU__ status_t fs_free_dircookie( void *_ns, void *node, void *cookie ) +#else +int +fs_free_dircookie( void *_ns, void *node, void *cookie ) +#endif { nspace *ns = (nspace*)_ns; @@ -97,20 +150,25 @@ fs_free_dircookie( void *_ns, void *node, void *cookie ) return B_NO_ERROR; } - +#ifdef __HAIKU__ status_t fs_opendir( void *_ns, void *_node, void **_cookie ) +#else +int +fs_opendir( void *_ns, void *_node, void **_cookie ) +#endif { nspace *ns = (nspace*)_ns; vnode *node = (vnode*)_node; - dircookie *cookie = (dircookie*)ntfs_calloc( sizeof(dircookie) ); int result = B_NO_ERROR; ntfs_inode *ni=NULL; - + dircookie *cookie = (dircookie*)ntfs_calloc( sizeof(dircookie) ); + u64 pos=0; + LOCK_VOL(ns); ERRPRINT("fs_opendir - ENTER\n"); - + ni = ntfs_inode_open(ns->ntvol, node->vnid); if(ni==NULL) { result = ENOENT; @@ -121,37 +179,66 @@ fs_opendir( void *_ns, void *_node, void **_cookie ) result = EMFILE; goto exit; } - - if ( cookie != NULL ) { - cookie->pos = 0; - cookie->ino = 0; - cookie->readed = 0; - cookie->name[0] = 0; - cookie->show_sys_files = ns->show_sys_files; + + if ( cookie != NULL ) + { + cookie->dev = ns->id; + cookie->pos = 0; + //cookie->walk_dir = ni; + cookie->vnid = node->vnid; + cookie->root = NULL; + cookie->last = NULL; + cookie->walk = NULL; *_cookie = (void*)cookie; } else result = ENOMEM; -exit: +exit: + if(ni) - ntfs_inode_close(ni); + ntfs_inode_close(ni); ERRPRINT("fs_opendir - EXIT\n"); - + UNLOCK_VOL(ns); - + return result; } +#ifdef __HAIKU__ status_t fs_closedir( void *_ns, void *node, void *_cookie ) +#else +int +fs_closedir( void *_ns, void *node, void *_cookie ) +#endif { - nspace *ns = (nspace*)_ns; + nspace *ns = (nspace*)_ns; + dircookie *cookie = (dircookie*)_cookie; + struct direntry *entry,*entrynext; LOCK_VOL(ns); ERRPRINT("fs_closedir - ENTER\n"); - + + entry=cookie->root; + if(entry) + for(;;) + { + entrynext = entry->next; + + if(entry->name) + free(entry->name); + + if(entry) + free(entry); + + entry = entrynext; + + if(!entry) + break; + } + ERRPRINT("fs_closedir - EXIT\n"); UNLOCK_VOL(ns); @@ -159,55 +246,81 @@ fs_closedir( void *_ns, void *node, void *_cookie ) return B_NO_ERROR; } - +#ifdef __HAIKU__ status_t fs_readdir( void *_ns, void *_node, void *_cookie, struct dirent *buf, size_t bufsize, uint32 *num ) +#else +int +fs_readdir(void *_ns, void *_node, void *_cookie, long *num, struct dirent *buf, size_t bufsize) +#endif { + int result = B_NO_ERROR; nspace *ns = (nspace*)_ns; vnode *node = (vnode*)_node; dircookie *cookie = (dircookie*)_cookie; - uint32 nameLength = bufsize - sizeof(buf) + 1, realLen; - int result = B_NO_ERROR; ntfs_inode *ni=NULL; + uint32 nameLength = bufsize - sizeof(buf) + 1, realLen; + u64 pos=0; LOCK_VOL(ns); - ERRPRINT("fs_readdir - ENTER\n"); + ERRPRINT("fs_readdir - ENTER:\n"); - if (!ns || !node || !cookie || !num || bufsize < sizeof(buf)) { - result = EINVAL; - goto exit; + if (!ns || !node || !cookie || !num || bufsize < sizeof(buf)) + { + result = -1; + goto quit; } - - if(cookie->readed == 1) { - result = ENOENT; - goto exit; - } - - ni = ntfs_inode_open(ns->ntvol, node->vnid); - if(ni==NULL) { - result = ENOENT; - goto exit; - } - - result = ntfs_readdir(ni, &cookie->pos, cookie, (ntfs_filldir_t)_ntfs_dirent_filler); - if(result==0) { - realLen = nameLength>255?255:nameLength; - buf->d_dev = ns->id; - buf->d_ino = cookie->ino; - memcpy(buf->d_name,cookie->name, realLen+1); - buf->d_reclen = sizeof(buf) + realLen - 1; - result = B_NO_ERROR; + + if(cookie->pos==0) + { + ni = ntfs_inode_open(ns->ntvol, node->vnid); + if(ni==NULL) { + result = ENOENT; + goto quit; + } + ntfs_readdir(ni, &pos, cookie, (ntfs_filldir_t)_ntfs_dirent_dot_filler); + cookie->pos+=2; } else - result = ENOENT; - - ERRPRINT("fs_readdir - FILE: [%s]\n",buf->d_name); - -exit: - if(ni) - ntfs_inode_close(ni); + if(cookie->pos==2) + { + ni = ntfs_inode_open(ns->ntvol, node->vnid); + if(ni==NULL) { + result = ENOENT; + goto quit; + } + ntfs_readdir(ni, &pos, cookie, (ntfs_filldir_t)_ntfs_dirent_filler); + cookie->pos++; + } + + if(cookie->root==NULL || cookie->last==NULL) + { + result = -1; + goto quit; + } + + if(cookie->walk==NULL) + { + result = ENOENT; + goto quit; + } + + + realLen = ( strlen(cookie->walk->name)>=nameLength?(nameLength):(strlen(cookie->walk->name)) )+1; + buf->d_dev = cookie->walk->dev; + buf->d_ino = cookie->walk->ino; + memcpy(buf->d_name,cookie->walk->name, realLen); + buf->d_reclen = sizeof(buf) + realLen - 1; + + cookie->walk = cookie->walk->next; + + + ERRPRINT("fs_readdir - FILE: %s\n",buf->d_name); + +quit: + if ( result == B_NO_ERROR ) *num = 1; else @@ -215,29 +328,36 @@ exit: if ( result == ENOENT ) result = B_NO_ERROR; + + if(ni) + ntfs_inode_close(ni); - ERRPRINT("fs_readdir - EXIT result (%s)\n", strerror(result)); + ERRPRINT("fs_readdir - EXIT, result is %s\n", strerror(result)); UNLOCK_VOL(ns); return result; } - + +#ifdef __HAIKU__ status_t fs_rewinddir( void *_ns, void *_node, void *_cookie ) +#else +int +fs_rewinddir( void *_ns, void *_node, void *_cookie ) +#endif { nspace *ns = (nspace*)_ns; - dircookie *cookie = (dircookie*)_cookie; int result = EINVAL; - + dircookie *cookie = (dircookie*)_cookie; + LOCK_VOL(ns); ERRPRINT("fs_rewinddir - ENTER\n"); - if ( cookie != NULL ) { - cookie->pos = 0; - cookie->ino = 0; - cookie->readed = 0; - cookie->name[0] = 0; + if ( cookie != NULL ) + { + //cookie->pos = 0; + cookie->walk = cookie->root; result = B_NO_ERROR; } ERRPRINT("fs_rewinddir - EXIT, result is %s\n", strerror(result)); diff --git a/src/add-ons/kernel/file_systems/ntfs/ntfsdir.h b/src/add-ons/kernel/file_systems/ntfs/ntfsdir.h index 463ebf9dff..4642e9c80f 100644 --- a/src/add-ons/kernel/file_systems/ntfs/ntfsdir.h +++ b/src/add-ons/kernel/file_systems/ntfs/ntfsdir.h @@ -22,19 +22,41 @@ #define _NTFSDIR_H +typedef struct direntry +{ + char *name; + dev_t dev; + ino_t ino; + struct direntry *next; +} direntry; + typedef struct dircookie { + dev_t dev; + vnode_id vnid; + struct direntry * root; + struct direntry * last; + struct direntry * walk; u64 pos; - int readed; - ino_t ino; - BOOL show_sys_files; - char name[MAX_PATH]; } dircookie; + +#ifdef __HAIKU__ + status_t fs_free_dircookie( void *_ns, void *node, void *cookie ); status_t fs_opendir( void *_ns, void *_node, void **_cookie ); status_t fs_closedir( void *_ns, void *node, void *_cookie ); status_t fs_rewinddir( void *_ns, void *_node, void *_cookie ); status_t fs_readdir( void *_ns, void *_node, void *_cookie, struct dirent *buf, size_t bufsize, uint32 *num ); +#else + +int fs_free_dircookie( void *_ns, void *node, void *cookie ); +int fs_opendir( void *_ns, void *_node, void **_cookie ); +int fs_closedir( void *_ns, void *node, void *_cookie ); +int fs_rewinddir( void *_ns, void *_node, void *_cookie ); +int fs_readdir(void *_ns, void *_node, void *cookie, long *num, struct dirent *buf, size_t bufsize); + +#endif //__HAIKU__ + #endif diff --git a/src/add-ons/kernel/file_systems/ntfs/volume_util.c b/src/add-ons/kernel/file_systems/ntfs/volume_util.c index 6972119df3..9450470db1 100644 --- a/src/add-ons/kernel/file_systems/ntfs/volume_util.c +++ b/src/add-ons/kernel/file_systems/ntfs/volume_util.c @@ -1,6 +1,6 @@ /* volume_util.c - volume functions * - * Copyright (c) 2006 Troeglazov Gerasim (3dEyes**) + * Copyright (c) 2006-2007 Troeglazov Gerasim (3dEyes**) * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published diff --git a/src/add-ons/kernel/file_systems/ntfs/volume_util.h b/src/add-ons/kernel/file_systems/ntfs/volume_util.h index 6ae61354d7..f50248e1fb 100644 --- a/src/add-ons/kernel/file_systems/ntfs/volume_util.h +++ b/src/add-ons/kernel/file_systems/ntfs/volume_util.h @@ -1,6 +1,6 @@ /* volume_util.h - volume functions * - * Copyright (c) 2006 Troeglazov Gerasim (3dEyes**) + * Copyright (c) 2006-2007 Troeglazov Gerasim (3dEyes**) * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published