Re: Identifying sparse files using getattrlist()
Re: Identifying sparse files using getattrlist()
- Subject: Re: Identifying sparse files using getattrlist()
- From: rohan a <email@hidden>
- Date: Wed, 4 Nov 2009 16:06:49 +0530
Hi Alastair,
Thanks for the help. This worked like a gem :)
I am new with this and not much of a kernel guy yet.
The man page for getattrlist() says this :
A sparse file may have an allocated size on disk that is less than
its logical length (that is, ATTR_FILE_ALLOCSIZE < ATTR_FILE_TOTALSIZE
). Hence the confusion.
Thanks
On Wed, Nov 4, 2009 at 3:42 PM, Alastair Houghton
<email@hidden> wrote:
> On 4 Nov 2009, at 08:41, rohan a wrote:
>
>> However, for a sparse file this continues to return same sizes for
>> stat size and real size. This is an Apple UFS partition.
>
> As I said before, the thing to do is to look at the kernel sources. It's
> amazing how much of their own time some people are prepared to waste... it
> took me less than five minutes to figure out the answer to your question,
> and in the meantime I bet you've spent a lot longer than that on it.
>
> Anyway, the answer is that (a) stat() won't return the information you want,
> and (b) you're using the wrong attribute for getattrlist(). You want
> ATTR_FILE_DATAALLOCSIZE, not ATTR_FILE_ALLOCSIZE.
>
> FYI, you can work this out by looking at vfs_attrlist.c (in bsd/vfs), where
> you'll see that getattrlist() uses vnode_getattr(), which you can see from
> the table in bsd/ufs/ffs/ffs_vnops.c maps to ufs_getattr(). (That's kind of
> unsurprising, so you could skip that part if you wanted.)
>
> Anyway, ufs_getattr() is in ufs_vnops.c (in bsd/ufs/ufs/ufs_vnops.c), and
> there you can see it copying the data out of its inode structure. The
> potentially interesting lines are:
>
> VATTR_RETURN(vap, va_data_size, ip->i_din.di_size);
>
> and
>
> VATTR_RETURN(vap, va_data_alloc, dbtob((u_quad_t)ip->i_blocks,
> devBlockSize));
>
> So next we need to look in inode.h to see what the ip->i_din.di_size and
> ip->i_blocks fields actually contain. We find that i_blocks is just a
> #define:
>
> #define i_blocks i_din.di_blocks
>
> So now we're interested in the i_din member of struct inode, which is a
> struct dinode. struct dinode is in dinode.h, so we open that up and
> discover:
>
> u_int64_t di_size; /* 8: File byte count. */
>
> and
>
> u_int32_t di_blocks; /* 104: Blocks actually held. */
>
> in struct dinode.
>
> So va_data_alloc is what you're interested in, and if you look back at the
> vfs_attrlist.c file, you'll find that at the top there is a list mapping the
> getattrlist() constants to the va_ names.
>
> In case you're wondering how the ATTR_FILE_TOTALSIZE works for ufs when
> ufs_getattr() clearly doesn't bother returning it, for that you need to look
> in kpi_vfs.c, at vnode_getattr(), where you'll see that the vnode_getattr()
> function fills in various things automatically if the underlying filesystem
> didn't do it.
>
> All of this also explains why stat(), which uses vn_stat() (in vfs_vnops.c),
> won't work. stat() asks for va_data_size and va_total_alloc. UFS doesn't
> return va_total_alloc, so it's computed in vnode_getattr() by copying from
> va_data_size. Hence you're going to get the same data in both places.
>
> I suppose there's an argument that va_total_alloc should be computed from
> va_data_alloc rather than va_data_size if the former is defined, but you'd
> have to take that up with Apple, and I don't fancy your chances because UFS
> is pretty old and largely unused at this point.
>
> Anyway, it took me longer to write this e-mail than it did to work all that
> out, and even if it had taken you twice as long as it took me to find all of
> this, it would have been faster for you...
>
> Kind regards,
>
> Alastair.
>
> --
> http://alastairs-place.net
>
>
>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden