Fixed bug in fs_readdir function. Removed read-only assembling mode. Added settings file for addon tweaking: hide_sys_files, read_only, no_atime.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20332 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Gerasim Troeglazov 2007-03-05 07:01:21 +00:00
parent 4e0e80ed6c
commit 570ab00aa7
8 changed files with 169 additions and 269 deletions

View File

@ -382,10 +382,8 @@ fs_write_attrib(void *_ns, void *_node, const char *name, int type, const void *
#ifdef __HAIKU_
if (_cookie != &kBeOSTypeCookie) {
result = ENOSYS;
goto exit;
}
#endif
exit:
ERRPRINT("fs_write_attrib - EXIT, result is %s\n", strerror(result));

View File

@ -33,6 +33,7 @@
#include <KernelExport.h>
#include <time.h>
#include <malloc.h>
#include <driver_settings.h>
#include "ntfs.h"
#include "attributes.h"
@ -113,6 +114,8 @@ fs_mount(nspace_id nsid, const char *device, ulong flags, void *parms, size_t le
nspace *ns;
vnode *newNode = NULL;
char lockname[32];
void *handle;
unsigned long mnt_flags = 0;
status_t result = B_NO_ERROR;
ERRPRINT("fs_mount - ENTER\n");
@ -122,11 +125,15 @@ fs_mount(nspace_id nsid, const char *device, ulong flags, void *parms, size_t le
result = ENOMEM;
goto exit;
}
*ns = (nspace) {
.state = NF_FreeClustersOutdate | NF_FreeMFTOutdate,
.show_sys_files = false,
.ro = false
};
ns->flags = flags;
strcpy(ns->devicePath,device);
@ -141,8 +148,21 @@ fs_mount(nspace_id nsid, const char *device, ulong flags, void *parms, size_t le
ERRPRINT("fs_mount - error creating lock (%s)\n", strerror(result));
goto exit;
}
handle = load_driver_settings("ntfs");
ns->show_sys_files = ! (strcasecmp(get_driver_parameter(handle, "hide_sys_files", "true", "true"), "true") == 0);
ns->ro = strcasecmp(get_driver_parameter(handle, "read_only", "false", "false"), "false") != 0;
ns->noatime = strcasecmp(get_driver_parameter(handle, "no_atime", "true", "true"), "true") == 0;
unload_driver_settings(handle);
if (ns->ro || ns->flags & B_MOUNT_READ_ONLY) {
mnt_flags |= MS_RDONLY;
ns->flags |= B_MOUNT_READ_ONLY;
}
if (ns->noatime)
mnt_flags |= MS_NOATIME;
ns->ntvol=utils_mount_volume(device,0,true);
ns->ntvol=utils_mount_volume(device,mnt_flags,true);
if(ns->ntvol!=NULL)
result = B_NO_ERROR;
else
@ -254,7 +274,6 @@ fs_rfsstat( void *_ns, struct fs_info * fss )
return B_NO_ERROR;
}
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_wfsstat(void *_vol, const struct fs_info * fss, uint32 mask)
@ -266,6 +285,11 @@ fs_wfsstat(void *_vol, struct fs_info *fss, long mask)
nspace* ns = (nspace*)_vol;
status_t result = B_NO_ERROR;
if (ns->flags & B_FS_IS_READONLY) {
ERRPRINT("ntfs is read-only\n");
return EROFS;
}
LOCK_VOL(ns);
#ifdef __HAIKU__
@ -274,7 +298,7 @@ fs_wfsstat(void *_vol, struct fs_info *fss, long mask)
if (mask & WFSSTAT_NAME) {
#endif
result = ntfs_change_label( ns->ntvol, (char*)fss->volume_name );
goto exit;
goto exit;
}
exit:
@ -283,7 +307,6 @@ exit:
return result;
}
#endif
#ifdef __HAIKU__
status_t
@ -487,7 +510,6 @@ fs_write_vnode( void *_ns, void *_node, char reenter )
return result;
}
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_remove_vnode( void *_ns, void *_node, bool reenter )
@ -515,7 +537,6 @@ fs_remove_vnode( void *_ns, void *_node, char reenter )
return result;
}
#endif
#ifdef __HAIKU__
status_t
@ -598,8 +619,13 @@ fs_rstat( void *_ns, void *_node, struct stat *stbuf )
free(intx_file);
}
ntfs_attr_close(na);
stbuf->st_mode |= 0666;
stbuf->st_mode |= 0666;
}
if (ns->flags & B_FS_IS_READONLY) {
stbuf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
}
stbuf->st_uid = 0;
stbuf->st_gid = 0;
stbuf->st_atime = ni->last_access_time;
@ -619,7 +645,6 @@ exit:
}
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask)
@ -702,9 +727,8 @@ exit:
return result;
}
#endif
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_sync(void *_ns)
@ -719,19 +743,14 @@ fs_sync(void *_ns)
ERRPRINT("fs_sync - ENTER\n");
#ifndef __HAIKU__
flush_device(DEV_FD(ns->ntvol->dev), 0);
#endif
ERRPRINT("fs_sync - EXIT\n");
UNLOCK_VOL(ns);
return B_NO_ERROR;
}
#endif
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_fsync(void *_ns, void *_node)
@ -773,7 +792,6 @@ exit:
return result;
}
#endif
#ifdef __HAIKU__
status_t
@ -840,7 +858,6 @@ 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)
@ -859,9 +876,14 @@ fs_create(void *_ns, void *_dir, const char *name, int omode, int perms, vnode_i
ntfschar *uname = NULL;
status_t result = B_NO_ERROR;
int uname_len;
if (ns->flags & B_FS_IS_READONLY) {
ERRPRINT("ntfs is read-only\n");
return EROFS;
}
LOCK_VOL(ns);
ERRPRINT("fs_create - ENTER: name=%s\n",name);
if(_ns==NULL || _dir==NULL) {
@ -964,7 +986,6 @@ exit:
return result;
}
#endif
#ifdef __HAIKU__
status_t
@ -1048,7 +1069,6 @@ 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 )
@ -1066,6 +1086,11 @@ fs_write( void *_ns, void *_node, void *_cookie, off_t offset, const void *buf,
size_t size=*len;
status_t result = B_NO_ERROR;
if (ns->flags & B_FS_IS_READONLY) {
ERRPRINT("ntfs is read-only\n");
return EROFS;
}
LOCK_VOL(ns);
ERRPRINT("fs_write - ENTER, offset=%d, len=%d\n",(int)offset, (int)(*len));
@ -1145,7 +1170,7 @@ exit2:
return result;
}
#endif
#ifdef __HAIKU__
status_t
@ -1292,7 +1317,6 @@ exit:
return result;
}
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_create_symlink(void *_ns, void *_dir, const char *name, const char *target, int mode)
@ -1383,9 +1407,8 @@ exit:
return result;
}
#endif
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_mkdir(void *_ns, void *_node, const char *name, int perms, vnode_id *_vnid)
@ -1402,6 +1425,11 @@ fs_mkdir(void *_ns, void *_node, const char *name, int perms)
ntfs_inode *ni = NULL;
ntfs_inode *bi = NULL;
status_t result = B_NO_ERROR;
if (ns->flags & B_FS_IS_READONLY) {
ERRPRINT("ntfs is read-only\n");
return EROFS;
}
LOCK_VOL(ns);
@ -1484,9 +1512,7 @@ exit:
return result;
}
#endif
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_rename(void *_ns, void *_odir, const char *oldname, void *_ndir, const char *newname)
@ -1515,6 +1541,10 @@ fs_rename(void *_ns, void *_odir, const char *oldname, void *_ndir, const char *
status_t result = B_NO_ERROR;
if (ns->flags & B_FS_IS_READONLY) {
ERRPRINT("ntfs is read-only\n");
return EROFS;
}
LOCK_VOL(ns);
@ -1683,9 +1713,7 @@ exit:
return result;
}
#endif
#ifndef _READ_ONLY_
status_t
do_unlink(nspace *vol, vnode *dir, const char *name, bool isdir)
{
@ -1772,9 +1800,8 @@ exit1:
return result;
}
#endif
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_rmdir(void *_ns, void *_node, const char *name)
@ -1787,6 +1814,11 @@ fs_rmdir(void *_ns, void *_node, const char *name)
vnode *dir = (vnode*)_node;
status_t result = B_NO_ERROR;
if (ns->flags & B_FS_IS_READONLY) {
ERRPRINT("ntfs is read-only\n");
return EROFS;
}
LOCK_VOL(ns);
ERRPRINT("fs_rmdir - ENTER: name %s\n", name==NULL?"NULL":name);
@ -1818,9 +1850,8 @@ exit1:
return result;
}
#endif
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_unlink(void *_ns, void *_node, const char *name)
@ -1833,6 +1864,11 @@ fs_unlink(void *_ns, void *_node, const char *name)
vnode *dir = (vnode*)_node;
status_t result = B_NO_ERROR;
if (ns->flags & B_FS_IS_READONLY) {
ERRPRINT("ntfs is read-only\n");
return EROFS;
}
LOCK_VOL(ns);
ERRPRINT("fs_unlink - ENTER: name %s\n", name==NULL?"NULL":name);
@ -1864,5 +1900,4 @@ exit:
return result;
}
#endif

View File

@ -116,8 +116,6 @@ int fs_create_symlink(void *ns, void *_dir, const char *name, const char *path
#endif //__HAIKU__
#ifndef _READ_ONLY_
status_t do_unlink(nspace *vol, vnode *dir, const char *name, bool isdir);
#endif
status_t do_unlink(nspace *vol, vnode *dir, const char *name, bool isdir);
#endif

View File

@ -95,11 +95,7 @@ static file_system_module_info sNTFSFileSystem = {
&fs_mount,
&fs_unmount,
&fs_rfsstat,
#ifdef _READ_ONLY_
NULL,
#else
&fs_wfsstat,
#endif
NULL,
/* vnode operations */
@ -107,11 +103,7 @@ static file_system_module_info sNTFSFileSystem = {
&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
@ -125,58 +117,29 @@ static file_system_module_info sNTFSFileSystem = {
NULL, // &fs_select
NULL, // &fs_deselect
#ifdef _READ_ONLY_
NULL,
#else
&fs_fsync,
#endif
&fs_readlink,
#ifdef _READ_ONLY_
NULL,
NULL,
NULL,
NULL,
#else
&fs_readlink,
&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,

View File

@ -119,18 +119,21 @@ typedef struct nspace
int free_cluster_count;
char volumeLabel[MAX_PATH];
int state;
s64 free_clusters;
long free_mft;
BOOL ro;
BOOL show_sys_files;
BOOL silent;
BOOL force;
BOOL debug;
BOOL noatime;
BOOL no_detach;
ulong flags;
int state;
s64 free_clusters;
long free_mft;
BOOL ro;
BOOL show_sys_files;
BOOL silent;
BOOL force;
BOOL debug;
BOOL noatime;
BOOL no_detach;
lock vlock;
lock vlock;
} nspace;

View File

@ -1,6 +1,6 @@
/* ntfsdir.c - directory functions
*
* Copyright (c) 2006-2007 Troeglazov Gerasim (3dEyes**)
* 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
@ -38,8 +38,11 @@
#include "ntfsdir.h"
//callback function for readdir()
static
int _ntfs_dirent_dot_filler(void *_dirent, const ntfschar *name,
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,
const int name_len, const int name_type, const s64 pos,
const MFT_REF mref, const unsigned dt_type)
{
@ -48,81 +51,24 @@ int _ntfs_dirent_dot_filler(void *_dirent, const ntfschar *name,
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) {
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;
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;
}
}
free(filename);
return 0;
}
#ifdef __HAIKU__
status_t
fs_free_dircookie( void *_ns, void *node, void *cookie )
@ -155,14 +101,14 @@ fs_opendir( void *_ns, void *_node, void **_cookie )
{
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) );
LOCK_VOL(ns);
ERRPRINT("fs_opendir - ENTER\n");
ni = ntfs_inode_open(ns->ntvol, node->vnid);
if(ni==NULL) {
result = ENOENT;
@ -173,28 +119,25 @@ fs_opendir( void *_ns, void *_node, void **_cookie )
result = EMFILE;
goto exit;
}
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->pos = 0;
cookie->ino = 0;
cookie->readed = 0;
cookie->name[0] = 0;
cookie->show_sys_files = ns->show_sys_files;
*_cookie = (void*)cookie;
} else {
result = ENOMEM;
}
exit:
else
result = ENOMEM;
exit:
if(ni)
ntfs_inode_close(ni);
ntfs_inode_close(ni);
ERRPRINT("fs_opendir - EXIT\n");
UNLOCK_VOL(ns);
return result;
}
@ -206,32 +149,12 @@ int
fs_closedir( void *_ns, void *node, void *_cookie )
#endif
{
nspace *ns = (nspace*)_ns;
dircookie *cookie = (dircookie*)_cookie;
struct direntry *entry,*entrynext;
nspace *ns = (nspace*)_ns;
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);
@ -247,68 +170,51 @@ 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;
ntfs_inode *ni=NULL;
uint32 nameLength = bufsize - sizeof(buf) + 1, realLen;
u64 pos=0;
int result = B_NO_ERROR;
ntfs_inode *ni=NULL;
LOCK_VOL(ns);
ERRPRINT("fs_readdir - ENTER:\n");
ERRPRINT("fs_readdir - ENTER\n");
if (!ns || !node || !cookie || !num || bufsize < sizeof(buf)) {
result = -1;
goto quit;
result = EINVAL;
goto exit;
}
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 {
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->readed == 1) {
result = ENOENT;
goto exit;
}
if(cookie->walk==NULL) {
result = ENOENT;
goto quit;
}
ni = ntfs_inode_open(ns->ntvol, node->vnid);
if(ni==NULL) {
result = ENOENT;
goto exit;
}
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;
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;
}
else
result = ENOENT;
cookie->walk = cookie->walk->next;
ERRPRINT("fs_readdir - FILE: [%s]\n",buf->d_name);
exit:
if(ni)
ntfs_inode_close(ni);
ERRPRINT("fs_readdir - FILE: %s\n",buf->d_name);
quit:
if ( result == B_NO_ERROR )
*num = 1;
else
@ -316,11 +222,8 @@ quit:
if ( result == ENOENT )
result = B_NO_ERROR;
if(ni)
ntfs_inode_close(ni);
ERRPRINT("fs_readdir - EXIT, result is %s\n", strerror(result));
ERRPRINT("fs_readdir - EXIT result (%s)\n", strerror(result));
UNLOCK_VOL(ns);
@ -336,15 +239,17 @@ fs_rewinddir( void *_ns, void *_node, void *_cookie )
#endif
{
nspace *ns = (nspace*)_ns;
int result = EINVAL;
dircookie *cookie = (dircookie*)_cookie;
int result = EINVAL;
LOCK_VOL(ns);
ERRPRINT("fs_rewinddir - ENTER\n");
if ( cookie != NULL ) {
cookie->pos = 0;
cookie->walk = cookie->root;
cookie->pos = 0;
cookie->ino = 0;
cookie->readed = 0;
cookie->name[0] = 0;
result = B_NO_ERROR;
}
ERRPRINT("fs_rewinddir - EXIT, result is %s\n", strerror(result));

View File

@ -22,25 +22,15 @@
#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 );

View File

@ -0,0 +1,8 @@
# Sample settings file for the ntfs plugin
#
# This file should be moved to the directory
# /boot/home/config/settings/kernel/drivers/
#
hide_sys_files true
read_only false
no_atime true