[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Linux-NTFS-Dev] NTFS resizer

From: Anton Altaparmakov
Subject: Re: [Linux-NTFS-Dev] NTFS resizer
Date: Wed, 08 Aug 2001 12:45:22 +0100

At 11:30 08/08/01, Andrew Clausen wrote:
On Wed, Aug 08, 2001 at 12:42:42AM +0100, Anton Altaparmakov wrote:
> libntfs is in no way prepared to do any of this at this point. Just thought
> you should know... In particular there is _no_ support for extension mft
> records.

Hmmm.  Looking at the code.... I think things should be more file and
attribute centric, rather than mft-record centric.

I hadn't even started on files stuff hence the lack of support. For attributes I had only just started and then got busy with mkntfs and other things, so stopped there.

What you describe below is the kind of stuff that will need to be written, yes. I had started with the mft records because that is the layer below files and you need them to be able to do anything with attributes. libntfs was for me a playground to explore how to do things in the kernel driver and now I have a fairly good idea of how to do things in the kernel I started doing them and forgot all about libntfs for the moment. Once the kernel side is finished I will get back to the user space side. - I want to finish libntfs, cleanup mkntfs and then write ntfsck. But that is my extreme long term plans... And somewhere after that I was planning on writing a resizer myself but if you do it before hand even better. (-:

For example, things like:

ntfs_file* ntfs_file_get (ntfs_volume* vol, const MFT_REF mref);
attr* ntfs_file_add_attr (ntfs_file* file, ATTR_TYPES type)
BOOL ntfs_file_del_attr (ntfs_file* file, attr* attr);
attr* ntfs_file_get_attr (ntfs_file* file, ATTR_TYPES type);
BOOL ntfs_file_sync (ntfs_file* file);

BOOL ntfs_attr_can_set_resident (attr* attr);
BOOL ntfs_attr_set_resident (attr* attr, BOOL resident);
LCN ntfs_attr_get_cluster (attr* attr, VCN vcn);
inline BOOL ntfs_attr_set_cluster (attr* attr, VCN vcn, LCN lcn) {
        return ntfs_attr_set_run (attr, vcn, 1, lcn);
BOOL ntfs_attr_set_run (attr* attr, VCN vcn, VCN count, LCN lcn);

BOOL ntfs_attr_read (attr* attr, _u64 offset, _u64 count, _u8* buf);
BOOL ntfs_attr_write (attr* attr, _u64 offset, _u64 count, const _u8* buf);
inline BOOL ntfs_attr_trunc (attr* attr, _u64 offset, _u64 count) {
        return ntfs_attr_set_run (attr, offset, count, NTFS_LCN_SPARSE);

A convienient way for traversing attributes would be nice.

You traverse them in the mft record. Any copying back and forth into structures is stupid IMHO. That's what find_first_attr() and find_attr() are for (admittedly, they could use a better handling of the search context, i.e. dynamic allocation and a special function for cleaning it up or something like that).

You have a structure: the mft record. It contains all attributes nicely sorted. Why make linked lists or other constructs? Just work directly on it. That's what TNG does and that is IMO the most effective, most reliable, easiest to code and fastest code possible. Much like zero copy IO in the network drivers layer... (I know libntfs has some stuff about mapping attribute values but I have come to think that is probably not effective. Well it might be but done a different way altogether. The code overhead introduced by maintining the existing structures would be huge.)

Perhaps make attribute a linked list, with the head in ntfs_file?
(When you do ntfs_file_get(), you read in the important bits of the
attributes - basically, everything resident in the MFT...)

Keeping a linked list of pointers into the mft record just brings huge overhead because ANY time your write to the mft record you have to discard the list and redo from scratch or at least you have to verify it is still valid and update it if not.

Is this all sane?  I'm still really new to all this ;)

The file stuff is sane. Having convenient functions for accessing attributes is sane. But having linked lists of attributes is not.

At the low level it should work like this:

1. map_mft_record(inode struct, record number): returns the MFT_RECORD* and locks it so no other threads can access it at the same time.

2. do whatever you want with the attributes in this mft record writing whatever access functions you want for it.

3. unmap_mft_record(inode struct): releases the MFT_RECORD* back to the library.

This low level is then wrapped by the file access functions for example.

But then again my views are really based around a kernel centric implementation. The user space side doesn't have to work this way. It just would be nice if the two are consistent from a maintenance point of view... or at least that they are as consistent as possible.

Having said all that: if you were to implement something different and it works nicely than I would have no problem with using it. I would much rather use something that doesn't fit my design but DOES work nicely and has been written already rather than not have anything because I have not time to write it myself!


  "Nothing succeeds like success." - Alexandre Dumas
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Linux NTFS Maintainer / WWW: http://linux-ntfs.sf.net/
ICQ: 8561279 / WWW: http://www-stu.christs.cam.ac.uk/~aia21/

reply via email to

[Prev in Thread] Current Thread [Next in Thread]