=D0=92 =D0=9F=D1=82=D0=BD, 30/09/2005 =D0=B2 14:06 +0100, Anton Altaparmako=
v =D0=BF=D0=B8=D1=88=D0=B5=D1=82:
> On Fri, 2005-09-30 at 15:56 +0300, Yura Pakhuchiy wrote:
> > =D0=92 =D0=9F=D1=82=D0=BD, 30/09/2005 =D0=B2 13:30 +0100, Anton Altapar=
makov =D0=BF=D0=B8=D1=88=D0=B5=D1=82:
> > > On Fri, 2005-09-30 at 14:46 +0300, Yura Pakhuchiy wrote:
> > > > =D0=92 =D0=9F=D1=82=D0=BD, 30/09/2005 =D0=B2 11:02 +0100, Anton Alt=
aparmakov =D0=BF=D0=B8=D1=88=D0=B5=D1=82:
> > > > > > --- attrib.c 28 Sep 2005 13:47:47 -0000 1.178
> > > > > > +++ attrib.c 30 Sep 2005 09:52:05 -0000 1.179
> > > > > > @@ -2554,7 +2554,7 @@ int ntfs_resident_attr_record_add(ntfs_i
> > > > > > }
> > > > > > =20
> > > > > > /* Locate place where record should be. */
> > > > > > - ctx =3D ntfs_attr_get_search_ctx(ni, NULL);
> > > > > > + ctx =3D ntfs_attr_get_search_ctx(NULL, ni->mrec);
> > > > > > if (!ctx)
> > > > > > return -1;
> > > > > > if (!ntfs_attr_lookup(type, name, name_len,
> > > > > > @@ -2679,7 +2679,7 @@ int ntfs_non_resident_attr_record_add(nt
> > > > > > }
> > > > > > =20
> > > > > > /* Locate place where record should be. */
> > > > > > - ctx =3D ntfs_attr_get_search_ctx(ni, NULL);
> > > > > > + ctx =3D ntfs_attr_get_search_ctx(NULL, ni->mrec);
> > > > > > if (!ctx)
> > > > > > return -1;
> > > > > > if (!ntfs_attr_lookup(type, name, name_len, CASE_SENSITIVE,
> > > > > > @@ -3342,7 +3342,7 @@ int ntfs_attr_record_move_to(ntfs_attr_s
> > > > > > =20
> > > > > > /* Find place in MFT record where attribute will be moved. */
> > > > > > a =3D ctx->attr;
> > > > > > - nctx =3D ntfs_attr_get_search_ctx(ni, NULL);
> > > > > > + nctx =3D ntfs_attr_get_search_ctx(NULL, ni->mrec);
> > > > > > if (!nctx) {
> > > > > > err =3D errno;
> > > > > > Dprintf("%s(): Couldn't obtain search context.\n",
> > > > >=20
> > > > > The above three will now always fail when name !=3D NULL in the c=
all to
> > > > > ntfs_attr_lookup(). You must use ntfs_attr_find() instead.
> > > >=20
> > > > Why you add such check? What problems can happen in case sensitive
> > > > lookup?
> > >=20
> > > You _cannot_ perform case insensitive lookup without an upcase table =
by
> > > definition of what case insensitive means. attr_find/lookup _have_ t=
o
> > > do case insensitive comparison of the name. They cannot do this if n=
o
> > > upcase table is present.
> > >=20
> > > As I said in earlier message the correct fix would be to add either t=
he
> > > volume or the upcase table + length to somewhere, either the search
> > > context itself so there would be "ntfs_inode_get_search_ctx(ntfs_inod=
e
> > > *ni)" and "ntfs_mft_get_search_ctx(ntfs_volume *vol, MFT_RECORD *mrec=
)".
> > > Or alternatively modify ntfs_attr_find() to also take the upcase tabl=
e
> > > (or the volume I suppose but that will cause problems with places tha=
t
> > > do not have a volume) and then you can pass it in when you have acqui=
red
> > > the context with (NULL, mrec)...
> > >=20
> > > Basically ntfs_attr_find() MUST AT ALL TIMES have access to upcase ta=
ble
> > > if a name is provided for the comparisons. At present if you get a
> > > search context with (NULL, mrec) you do NOT have an upcase table in
> > > _lookup/find so they cannot execute correctly.
> > >=20
> > > Just read ntfs_attr_find():
> > >=20
> > > if (name =3D=3D AT_UNNAMED) {
> > > /* The search failed if the found attribute is named. */
> > > if (a->name_length) {
> > > errno =3D ENOENT;
> > > return -1;
> > > }
> > > } else if (name && !ntfs_names_are_equal(name, name_len,
> > > (ntfschar*)((char*)a + le16_to_cpu(a->name_offset)),
> > > a->name_length, ic, upcase, upcase_len)) {
> > > register int rc;
> > >=20
> > > rc =3D ntfs_names_collate(name, name_len,
> > > (ntfschar*)((char*)a +
> > > le16_to_cpu(a->name_offset)),
> > > a->name_length, 1, IGNORE_CASE,
> > > upcase, upcase_len);
> > >=20
> > >=20
> > > ************************************
> > > THIS REQUIRES UPCASE TABLE
> > > ************************************
> > >=20
> > >=20
> > > /*
> > > * If @name collates before a->name, there is no
> > > * matching attribute.
> > > */
> > > if (rc =3D=3D -1) {
> > > errno =3D ENOENT;
> > > return -1;
> > > }
> > > /* If the strings are not equal, continue search. */
> > > if (rc)
> > > continue;
> > > rc =3D ntfs_names_collate(name, name_len,
> > > (ntfschar*)((char*)a +
> > > le16_to_cpu(a->name_offset)),
> > > a->name_length, 1, CASE_SENSITIVE,
> > > upcase, upcase_len);
> > > if (rc =3D=3D -1) {
> > > errno =3D ENOENT;
> > > return -1;
> > > }
> > > if (rc)
> > > continue;
> > > }
> > >=20
> > > Sorry but which part of this do you not understand? What you were do=
ing
> > > worked only by chance/accident/coincidence. It WOULD cause data
> > > corruption and I am not having it.
> >=20
> > Now I understand problem, didn't thought earlier that ntfs_attr_find ma=
y
> > need upcase table even for case sensitive lookups.=20
>=20
> Ah! Yes, it does. FWIW I had forgotten/not noticed that, too, until I
> came to look into the problem and when I discovered it, I wrote and
> committed the mega patch (last week it was I think?). In the kernel you
> _always_ have the inode so the problem never arises...
>=20
> > Thank you for
> > explanation. I commit version you proposed to use.
>=20
> You are welcome! (-:
>=20
> Sorry about the "somewhat" heated earlier email...
No problem. I think that my emails was also not perfectly correct, since
earlier I did not understand that megapatch and very disliked it because
of that.
--=20
Best regards,
Yura
|