All of lore.kernel.org
 help / color / mirror / Atom feed
* Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
@ 2005-07-29 11:23 Srinivas G.
  2005-07-29 12:02 ` linux-os (Dick Johnson)
  2005-07-29 13:11 ` Norbert van Nobelen
  0 siblings, 2 replies; 15+ messages in thread
From: Srinivas G. @ 2005-07-29 11:23 UTC (permalink / raw)
  To: linux-kernel-Mailing-list

Dear All,

We have developed a Block Device Driver to handle the flash media
devices in Linux 2.6.x kernel. It is working fine. We are able to mount
the SD cards that are formatted on Windows systems, but we unable mount
the cards that are formatted using the DIGITAL CAMERA. 

We have found one thing that the Windows and Digital Camera both are
formatting the SD cards in FAT12 only. But why we are not able to mount
the SD cards on Linux Box that are formatted using the Digital Camera.

Could any one explain the problem? It is great help to us.
Thanks in advance and we are looking forward a POSITIVE reply.

Thanks and Regards,
Srinivas G

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
  2005-07-29 11:23 Srinivas G.
@ 2005-07-29 12:02 ` linux-os (Dick Johnson)
  2005-07-29 13:37   ` Lennart Sorensen
  2005-07-29 13:11 ` Norbert van Nobelen
  1 sibling, 1 reply; 15+ messages in thread
From: linux-os (Dick Johnson) @ 2005-07-29 12:02 UTC (permalink / raw)
  To: Srinivas G.; +Cc: linux-kernel-Mailing-list


On Fri, 29 Jul 2005, Srinivas G. wrote:

> Dear All,
>
> We have developed a Block Device Driver to handle the flash media
> devices in Linux 2.6.x kernel. It is working fine. We are able to mount
> the SD cards that are formatted on Windows systems, but we unable mount
> the cards that are formatted using the DIGITAL CAMERA.
>
> We have found one thing that the Windows and Digital Camera both are
> formatting the SD cards in FAT12 only. But why we are not able to mount
> the SD cards on Linux Box that are formatted using the Digital Camera.
>
> Could any one explain the problem? It is great help to us.
> Thanks in advance and we are looking forward a POSITIVE reply.
>
> Thanks and Regards,
> Srinivas G

Execute linux `fdisk` on the device. You may find that the
ID byte is wrong.

Also, why do you need a special block device driver? The SanDisk
and CompacFlash devices should look like IDE drives.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.12 on an i686 machine (5537.79 BogoMips).
Warning : 98.36% of all statistics are fiction.
.
I apologize for the following. I tried to kill it with the above dot :

****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
  2005-07-29 11:23 Srinivas G.
  2005-07-29 12:02 ` linux-os (Dick Johnson)
@ 2005-07-29 13:11 ` Norbert van Nobelen
  1 sibling, 0 replies; 15+ messages in thread
From: Norbert van Nobelen @ 2005-07-29 13:11 UTC (permalink / raw)
  To: Srinivas G.; +Cc: linux-kernel

What camera is this?

On Friday 29 July 2005 13:23, Srinivas G. wrote:
> Dear All,
>
> We have developed a Block Device Driver to handle the flash media
> devices in Linux 2.6.x kernel. It is working fine. We are able to mount
> the SD cards that are formatted on Windows systems, but we unable mount
> the cards that are formatted using the DIGITAL CAMERA.
>
> We have found one thing that the Windows and Digital Camera both are
> formatting the SD cards in FAT12 only. But why we are not able to mount
> the SD cards on Linux Box that are formatted using the Digital Camera.
>
> Could any one explain the problem? It is great help to us.
> Thanks in advance and we are looking forward a POSITIVE reply.
>
> Thanks and Regards,
> Srinivas G
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
  2005-07-29 12:02 ` linux-os (Dick Johnson)
@ 2005-07-29 13:37   ` Lennart Sorensen
  0 siblings, 0 replies; 15+ messages in thread
From: Lennart Sorensen @ 2005-07-29 13:37 UTC (permalink / raw)
  To: linux-os (Dick Johnson); +Cc: Srinivas G., linux-kernel-Mailing-list

On Fri, Jul 29, 2005 at 08:02:14AM -0400, linux-os (Dick Johnson) wrote:
> Execute linux `fdisk` on the device. You may find that the
> ID byte is wrong.
> 
> Also, why do you need a special block device driver? The SanDisk
> and CompacFlash devices should look like IDE drives.

SD usually is secure digital (MMC compatible somewhat I believe).  It
does not provide IDE unlike CompactFlash.  SD uses a serial interface if
I remember correctly.

Len Sorensen

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
@ 2005-07-29 17:35 Mukund JB.
  2005-07-29 17:43 ` Lennart Sorensen
  2005-07-29 18:05 ` linux-os (Dick Johnson)
  0 siblings, 2 replies; 15+ messages in thread
From: Mukund JB. @ 2005-07-29 17:35 UTC (permalink / raw)
  To: Lennart Sorensen, linux-os (Dick Johnson)
  Cc: Srinivas G., linux-kernel-Mailing-list

[-- Attachment #1: Type: text/plain, Size: 2128 bytes --]


Dear Lennart, Dick Johnson, Erik Mouw & All,

Thanks for all ur precious support. 

The cannon camera (other devices too) formatted SD is indeed a partition
FAT12. When I said 
sfdisk -l, it showed the fs ID as 1. 1 is indeed the FAT12 fs ID.

Attached are the logs for win and camera device sfdisk -Vl /dev/tfa0.

The SD card formatted in camera is partitioned FAT12 disk.
Also, the SD card formatted in windows is partitioned FAT12 disk.
(see the attachment)

on ur suggestion I verified whether camera partition device has a valid
FS ID. I verified. It is FAT12. It is the same for windows 
formatted device. The FS ID of both the formats is 1. i.e. FAT12.

I has notion that my driver is not supporting partition devices. This
makes this clean that my driver is supporting the partition devices
(windows formatted SD). If both are partitioned where is the difference?


So, can someone please help me telling what else could be missing that
is creating this problem?

Regards,
Mukund Jampala


>-----Original Message-----
>From: linux-kernel-owner@vger.kernel.org [mailto:linux-kernel-
>owner@vger.kernel.org] On Behalf Of Lennart Sorensen
>Sent: Friday, July 29, 2005 7:08 PM
>To: linux-os (Dick Johnson)
>Cc: Srinivas G.; linux-kernel-Mailing-list
>Subject: Re: Unable to mount the SD card formatted using the DIGITAL
CAMREA
>on Linux box
>
>On Fri, Jul 29, 2005 at 08:02:14AM -0400, linux-os (Dick Johnson)
wrote:
>> Execute linux `fdisk` on the device. You may find that the
>> ID byte is wrong.
>>
>> Also, why do you need a special block device driver? The SanDisk
>> and CompacFlash devices should look like IDE drives.
>
>SD usually is secure digital (MMC compatible somewhat I believe).  It
>does not provide IDE unlike CompactFlash.  SD uses a serial interface
if
>I remember correctly.
>
>Len Sorensen
>-
>To unsubscribe from this list: send the line "unsubscribe linux-kernel"
in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>Please read the FAQ at  http://www.tux.org/lkml/

[-- Attachment #2: win-camera-sdfisk-details.txt --]
[-- Type: text/plain, Size: 1063 bytes --]


camera formatted info
----------------------
Disk /dev/tfa0: 448 cylinders, 2 heads, 32 sectors/track
Units = cylinders of 32768 bytes, blocks of 1024 bytes, counting from 0

   Device Boot Start     End   #cyls    #blocks   Id  System
/dev/tfa0p1   *      0+    449     450-     14371+   1  FAT12
/dev/tfa0p2          0       -       0          0    0  Empty
/dev/tfa0p3          0       -       0          0    0  Empty
/dev/tfa0p4          0       -       0          0    0  Empty
Warning: partition 1 extends past end of disk

Windows formatted info
----------------------
Disk /dev/tfa0: 448 cylinders, 2 heads, 32 sectors/track
Units = cylinders of 32768 bytes, blocks of 1024 bytes, counting from 0

   Device Boot Start     End   #cyls    #blocks   Id  System
/dev/tfa0p1   *      0+    449     450-     14371+   1  FAT12
/dev/tfa0p2          0       -       0          0    0  Empty
/dev/tfa0p3          0       -       0          0    0  Empty
/dev/tfa0p4          0       -       0          0    0  Empty
Warning: partition 1 extends past end of disk

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
  2005-07-29 17:35 Mukund JB.
@ 2005-07-29 17:43 ` Lennart Sorensen
  2005-07-29 18:05 ` linux-os (Dick Johnson)
  1 sibling, 0 replies; 15+ messages in thread
From: Lennart Sorensen @ 2005-07-29 17:43 UTC (permalink / raw)
  To: Mukund JB.
  Cc: linux-os (Dick Johnson), Srinivas G., linux-kernel-Mailing-list

On Fri, Jul 29, 2005 at 11:05:50PM +0530, Mukund JB. wrote:
> camera formatted info
> ----------------------
> Disk /dev/tfa0: 448 cylinders, 2 heads, 32 sectors/track
> Units = cylinders of 32768 bytes, blocks of 1024 bytes, counting from 0
> 
>    Device Boot Start     End   #cyls    #blocks   Id  System
> /dev/tfa0p1   *      0+    449     450-     14371+   1  FAT12
> /dev/tfa0p2          0       -       0          0    0  Empty
> /dev/tfa0p3          0       -       0          0    0  Empty
> /dev/tfa0p4          0       -       0          0    0  Empty
> Warning: partition 1 extends past end of disk

Why excactly does the partition table say 450 cylinders when the kernel
believes it to be 448 cylinders?  Someone is wrong.  Either the device
was partitioned wrong and hence formated wrong, or whatever driver the
kernel is using to read it is broken and returns the wrong size for the
device.

I have never heard of /dev/tfa0p* either.  What is that?

> Windows formatted info
> ----------------------
> Disk /dev/tfa0: 448 cylinders, 2 heads, 32 sectors/track
> Units = cylinders of 32768 bytes, blocks of 1024 bytes, counting from 0
> 
>    Device Boot Start     End   #cyls    #blocks   Id  System
> /dev/tfa0p1   *      0+    449     450-     14371+   1  FAT12
> /dev/tfa0p2          0       -       0          0    0  Empty
> /dev/tfa0p3          0       -       0          0    0  Empty
> /dev/tfa0p4          0       -       0          0    0  Empty
> Warning: partition 1 extends past end of disk

Identical.  Sure makes it look like a driver error on the linux side in
that case.

Len Sorensen

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
  2005-07-29 17:35 Mukund JB.
  2005-07-29 17:43 ` Lennart Sorensen
@ 2005-07-29 18:05 ` linux-os (Dick Johnson)
  2005-07-29 18:09   ` linux-os (Dick Johnson)
  1 sibling, 1 reply; 15+ messages in thread
From: linux-os (Dick Johnson) @ 2005-07-29 18:05 UTC (permalink / raw)
  To: Mukund JB.; +Cc: Lennart Sorensen, Srinivas G., linux-kernel-Mailing-list



camera formatted info
----------------------
Disk /dev/tfa0: 448 cylinders, 2 heads, 32 sectors/track
Units = cylinders of 32768 bytes, blocks of 1024 bytes, counting from 0

    Device Boot Start     End   #cyls    #blocks   Id  System
/dev/tfa0p1   *      0+    449     450-     14371+   1  FAT12
/dev/tfa0p2          0       -       0          0    0  Empty
/dev/tfa0p3          0       -       0          0    0  Empty
/dev/tfa0p4          0       -       0          0    0  Empty
Warning: partition 1 extends past end of disk

If it's 488 cylinders, then it should start at 0 and end at 447,
not 449.

It looks like some kind of driver error to begin with. The
fact that it sometimes works should be overlooked until the
driver returns the correct number of cylinders (the same
number that the formatting utility gets). Check to see if
your driver could return a different disk size under different
conditions.

On Fri, 29 Jul 2005, Mukund JB. wrote:

>
> Dear Lennart, Dick Johnson, Erik Mouw & All,
>
> Thanks for all ur precious support.
>
> The cannon camera (other devices too) formatted SD is indeed a partition
> FAT12. When I said
> sfdisk -l, it showed the fs ID as 1. 1 is indeed the FAT12 fs ID.
>
> Attached are the logs for win and camera device sfdisk -Vl /dev/tfa0.
>
> The SD card formatted in camera is partitioned FAT12 disk.
> Also, the SD card formatted in windows is partitioned FAT12 disk.
> (see the attachment)
>
> on ur suggestion I verified whether camera partition device has a valid
> FS ID. I verified. It is FAT12. It is the same for windows
> formatted device. The FS ID of both the formats is 1. i.e. FAT12.
>
> I has notion that my driver is not supporting partition devices. This
> makes this clean that my driver is supporting the partition devices
> (windows formatted SD). If both are partitioned where is the difference?
>
>
> So, can someone please help me telling what else could be missing that
> is creating this problem?
>
> Regards,
> Mukund Jampala
>
>
>> -----Original Message-----
>> From: linux-kernel-owner@vger.kernel.org [mailto:linux-kernel-
>> owner@vger.kernel.org] On Behalf Of Lennart Sorensen
>> Sent: Friday, July 29, 2005 7:08 PM
>> To: linux-os (Dick Johnson)
>> Cc: Srinivas G.; linux-kernel-Mailing-list
>> Subject: Re: Unable to mount the SD card formatted using the DIGITAL
> CAMREA
>> on Linux box
>>
>> On Fri, Jul 29, 2005 at 08:02:14AM -0400, linux-os (Dick Johnson)
> wrote:
>>> Execute linux `fdisk` on the device. You may find that the
>>> ID byte is wrong.
>>>
>>> Also, why do you need a special block device driver? The SanDisk
>>> and CompacFlash devices should look like IDE drives.
>>
>> SD usually is secure digital (MMC compatible somewhat I believe).  It
>> does not provide IDE unlike CompactFlash.  SD uses a serial interface
> if
>> I remember correctly.
>>
>> Len Sorensen
>> -
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel"
> in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/
>

Cheers,
Dick Johnson
Penguin : Linux version 2.6.12 on an i686 machine (5537.79 BogoMips).
Warning : 98.36% of all statistics are fiction.
.
I apologize for the following. I tried to kill it with the above dot :

****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
  2005-07-29 18:05 ` linux-os (Dick Johnson)
@ 2005-07-29 18:09   ` linux-os (Dick Johnson)
  0 siblings, 0 replies; 15+ messages in thread
From: linux-os (Dick Johnson) @ 2005-07-29 18:09 UTC (permalink / raw)
  To: Mukund JB.; +Cc: Lennart Sorensen, Srinivas G., linux-kernel-Mailing-list


On Fri, 29 Jul 2005, linux-os (Dick Johnson) wrote:

>
>
> camera formatted info
> ----------------------
> Disk /dev/tfa0: 448 cylinders, 2 heads, 32 sectors/track
> Units = cylinders of 32768 bytes, blocks of 1024 bytes, counting from 0
>
>    Device Boot Start     End   #cyls    #blocks   Id  System
> /dev/tfa0p1   *      0+    449     450-     14371+   1  FAT12
> /dev/tfa0p2          0       -       0          0    0  Empty
> /dev/tfa0p3          0       -       0          0    0  Empty
> /dev/tfa0p4          0       -       0          0    0  Empty
> Warning: partition 1 extends past end of disk
>
> If it's 488 cylinders, then it should start at 0 and end at 447,
> not 449.
>

Sorry typo, 487, not 447.


> It looks like some kind of driver error to begin with. The
> fact that it sometimes works should be overlooked until the
> driver returns the correct number of cylinders (the same
> number that the formatting utility gets). Check to see if
> your driver could return a different disk size under different
> conditions.
>
> On Fri, 29 Jul 2005, Mukund JB. wrote:
>
>>
>> Dear Lennart, Dick Johnson, Erik Mouw & All,
>>
>> Thanks for all ur precious support.
>>
>> The cannon camera (other devices too) formatted SD is indeed a partition
>> FAT12. When I said
>> sfdisk -l, it showed the fs ID as 1. 1 is indeed the FAT12 fs ID.
>>
>> Attached are the logs for win and camera device sfdisk -Vl /dev/tfa0.
>>
>> The SD card formatted in camera is partitioned FAT12 disk.
>> Also, the SD card formatted in windows is partitioned FAT12 disk.
>> (see the attachment)
>>
>> on ur suggestion I verified whether camera partition device has a valid
>> FS ID. I verified. It is FAT12. It is the same for windows
>> formatted device. The FS ID of both the formats is 1. i.e. FAT12.
>>
>> I has notion that my driver is not supporting partition devices. This
>> makes this clean that my driver is supporting the partition devices
>> (windows formatted SD). If both are partitioned where is the difference?
>>
>>
>> So, can someone please help me telling what else could be missing that
>> is creating this problem?
>>
>> Regards,
>> Mukund Jampala
>>
>>
>>> -----Original Message-----
>>> From: linux-kernel-owner@vger.kernel.org [mailto:linux-kernel-
>>> owner@vger.kernel.org] On Behalf Of Lennart Sorensen
>>> Sent: Friday, July 29, 2005 7:08 PM
>>> To: linux-os (Dick Johnson)
>>> Cc: Srinivas G.; linux-kernel-Mailing-list
>>> Subject: Re: Unable to mount the SD card formatted using the DIGITAL
>> CAMREA
>>> on Linux box
>>>
>>> On Fri, Jul 29, 2005 at 08:02:14AM -0400, linux-os (Dick Johnson)
>> wrote:
>>>> Execute linux `fdisk` on the device. You may find that the
>>>> ID byte is wrong.
>>>>
>>>> Also, why do you need a special block device driver? The SanDisk
>>>> and CompacFlash devices should look like IDE drives.
>>>
>>> SD usually is secure digital (MMC compatible somewhat I believe).  It
>>> does not provide IDE unlike CompactFlash.  SD uses a serial interface
>> if
>>> I remember correctly.
>>>
>>> Len Sorensen
>>> -
>>> To unsubscribe from this list: send the line "unsubscribe linux-kernel"
>> in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>> Please read the FAQ at  http://www.tux.org/lkml/
>>
>
> Cheers,
> Dick Johnson
> Penguin : Linux version 2.6.12 on an i686 machine (5537.79 BogoMips).
> Warning : 98.36% of all statistics are fiction.
> .
> I apologize for the following. I tried to kill it with the above dot :
>
> ****************************************************************
> The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.
>
> Thank you.
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

Cheers,
Dick Johnson
Penguin : Linux version 2.6.12 on an i686 machine (5537.79 BogoMips).
Warning : 98.36% of all statistics are fiction.
.
I apologize for the following. I tried to kill it with the above dot :

****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
@ 2005-08-01 11:31 Mukund JB.
  2005-08-01 12:08 ` linux-os (Dick Johnson)
  2005-08-02 13:42 ` Lennart Sorensen
  0 siblings, 2 replies; 15+ messages in thread
From: Mukund JB. @ 2005-08-01 11:31 UTC (permalink / raw)
  To: linux-os (Dick Johnson)
  Cc: Lennart Sorensen, Srinivas G., linux-kernel-Mailing-list

[-- Attachment #1: Type: text/plain, Size: 7278 bytes --]

Dear all,

Below are my driver messages logged at initialization time & sfdisk call
time. 

when module is initialized................

TIFM INFO | TI init Routine Invoked!
ReportMediaModel: ( SD card Details)
  Size            = 14 [MB]
  mwCylinders       = 450
  mwHeadCount       = 2
  mwSectorsPerTrack = 32

When the ioctl is invoked through the "sfdisk -lV /dev/tfa0"

TIFM INFO | <tifm_ioctl> invoked! 
TIFM INFO | dev no. [ 0 ] sock no. [ 0 ]
TIFM INFO | <GetGeometry_ioctl> geo.cylinders = 450
TIFM INFO | <GetGeometry_ioctl> geo.heads = 2
TIFM INFO | <GetGeometry_ioctl> geo.sectors = 32
TIFM INFO | <GetGeometry_ioctl> geo.start = 0

This means that I am giving the proper details to the user program but
the sfdisk is printing it wrong (probably manipulation).

And when I try to mount ......

mount /dev/tfa0 /mnt
FAT: bogus number of reserved sectors
Mount: you must specify the filesystem type 

mount -tvfat /dev/tfa0 /mnt
FAT: bogus number of reserved sectors
Mount: wrong fs type, bad option, bas superblock on /dev/tfa0,
	 or too many mounted file systems

I have gone through the mount.c code in order to understand where I am
exactly failing. 
mount is failing in guess_fstype_and_mount() in do_mount_syscall after
issuing the mount sys call.
I am attaching the source code of mount functionality which may be on
some help to u in u8ndertaing why exactly its failing.

Regards,
Mukund Jampala




>-----Original Message-----
>From: linux-os (Dick Johnson) [mailto:linux-os@analogic.com]
>Sent: Friday, July 29, 2005 11:39 PM
>To: Mukund JB.
>Cc: Lennart Sorensen; Srinivas G.; linux-kernel-Mailing-list
>Subject: RE: Unable to mount the SD card formatted using the DIGITAL
CAMREA
>on Linux box
>
>
>On Fri, 29 Jul 2005, linux-os (Dick Johnson) wrote:
>
>>
>>
>> camera formatted info
>> ----------------------
>> Disk /dev/tfa0: 448 cylinders, 2 heads, 32 sectors/track
>> Units = cylinders of 32768 bytes, blocks of 1024 bytes, counting from
0
>>
>>    Device Boot Start     End   #cyls    #blocks   Id  System
>> /dev/tfa0p1   *      0+    449     450-     14371+   1  FAT12
>> /dev/tfa0p2          0       -       0          0    0  Empty
>> /dev/tfa0p3          0       -       0          0    0  Empty
>> /dev/tfa0p4          0       -       0          0    0  Empty
>> Warning: partition 1 extends past end of disk
>>
>> If it's 488 cylinders, then it should start at 0 and end at 447,
>> not 449.
>>
>
>Sorry typo, 487, not 447.
>
>
>> It looks like some kind of driver error to begin with. The
>> fact that it sometimes works should be overlooked until the
>> driver returns the correct number of cylinders (the same
>> number that the formatting utility gets). Check to see if
>> your driver could return a different disk size under different
>> conditions.
>>
>> On Fri, 29 Jul 2005, Mukund JB. wrote:
>>
>>>
>>> Dear Lennart, Dick Johnson, Erik Mouw & All,
>>>
>>> Thanks for all ur precious support.
>>>
>>> The cannon camera (other devices too) formatted SD is indeed a
partition
>>> FAT12. When I said
>>> sfdisk -l, it showed the fs ID as 1. 1 is indeed the FAT12 fs ID.
>>>
>>> Attached are the logs for win and camera device sfdisk -Vl
/dev/tfa0.
>>>
>>> The SD card formatted in camera is partitioned FAT12 disk.
>>> Also, the SD card formatted in windows is partitioned FAT12 disk.
>>> (see the attachment)
>>>
>>> on ur suggestion I verified whether camera partition device has a
valid
>>> FS ID. I verified. It is FAT12. It is the same for windows
>>> formatted device. The FS ID of both the formats is 1. i.e. FAT12.
>>>
>>> I has notion that my driver is not supporting partition devices.
This
>>> makes this clean that my driver is supporting the partition devices
>>> (windows formatted SD). If both are partitioned where is the
difference?
>>>
>>>
>>> So, can someone please help me telling what else could be missing
that
>>> is creating this problem?
>>>
>>> Regards,
>>> Mukund Jampala
>>>
>>>
>>>> -----Original Message-----
>>>> From: linux-kernel-owner@vger.kernel.org [mailto:linux-kernel-
>>>> owner@vger.kernel.org] On Behalf Of Lennart Sorensen
>>>> Sent: Friday, July 29, 2005 7:08 PM
>>>> To: linux-os (Dick Johnson)
>>>> Cc: Srinivas G.; linux-kernel-Mailing-list
>>>> Subject: Re: Unable to mount the SD card formatted using the
DIGITAL
>>> CAMREA
>>>> on Linux box
>>>>
>>>> On Fri, Jul 29, 2005 at 08:02:14AM -0400, linux-os (Dick Johnson)
>>> wrote:
>>>>> Execute linux `fdisk` on the device. You may find that the
>>>>> ID byte is wrong.
>>>>>
>>>>> Also, why do you need a special block device driver? The SanDisk
>>>>> and CompacFlash devices should look like IDE drives.
>>>>
>>>> SD usually is secure digital (MMC compatible somewhat I believe).
It
>>>> does not provide IDE unlike CompactFlash.  SD uses a serial
interface
>>> if
>>>> I remember correctly.
>>>>
>>>> Len Sorensen
>>>> -
>>>> To unsubscribe from this list: send the line "unsubscribe
linux-kernel"
>>> in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>> Please read the FAQ at  http://www.tux.org/lkml/
>>>
>>
>> Cheers,
>> Dick Johnson
>> Penguin : Linux version 2.6.12 on an i686 machine (5537.79 BogoMips).
>> Warning : 98.36% of all statistics are fiction.
>> .
>> I apologize for the following. I tried to kill it with the above dot
:
>>
>> ****************************************************************
>> The information transmitted in this message is confidential and may
be
>privileged.  Any review, retransmission, dissemination, or other use of
>this information by persons or entities other than the intended
recipient
>is prohibited.  If you are not the intended recipient, please notify
>Analogic Corporation immediately - by replying to this message or by
>sending an email to DeliveryErrors@analogic.com - and destroy all
copies of
>this information, including any attachments, without reading or
disclosing
>them.
>>
>> Thank you.
>> -
>> To unsubscribe from this list: send the line "unsubscribe
linux-kernel"
>in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/
>>
>
>Cheers,
>Dick Johnson
>Penguin : Linux version 2.6.12 on an i686 machine (5537.79 BogoMips).
>Warning : 98.36% of all statistics are fiction.
>.
>I apologize for the following. I tried to kill it with the above dot :
>
>****************************************************************
>The information transmitted in this message is confidential and may be
>privileged.  Any review, retransmission, dissemination, or other use of
>this information by persons or entities other than the intended
recipient
>is prohibited.  If you are not the intended recipient, please notify
>Analogic Corporation immediately - by replying to this message or by
>sending an email to DeliveryErrors@analogic.com - and destroy all
copies of
>this information, including any attachments, without reading or
disclosing
>them.
>
>
>Thank you.

[-- Attachment #2: mount_guess_fstype.c --]
[-- Type: application/octet-stream, Size: 16999 bytes --]

/*
 * Thu Jul 14 07:32:40 1994: faith@cs.unc.edu added changes from Adam
 * J. Richter (adam@adam.yggdrasil.com) so that /proc/filesystems is used
 * if no -t option is given.  I modified his patches so that, if
 * /proc/filesystems is not available, the behavior of mount is the same as
 * it was previously.
 *
 * Wed Feb 8 09:23:18 1995: Mike Grupenhoff <kashmir@umiacs.UMD.EDU> added
 * a probe of the superblock for the type before /proc/filesystems is
 * checked.
 *
 * Fri Apr  5 01:13:33 1996: quinlan@bucknell.edu, fixed up iso9660 autodetect
 *
 * Wed Nov  11 11:33:55 1998: K.Garloff@ping.de, try /etc/filesystems before
 * /proc/filesystems
 * [This was mainly in order to specify vfat before fat; these days we often
 *  detect *fat and then assume vfat, so perhaps /etc/filesystems isnt
 *  so useful anymore.]
 *
 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
 * added Native Language Support
 *
 * 2000-12-01 Sepp Wijnands <mrrazz@garbage-coderz.net>
 * added probes for cramfs, hfs, hpfs and adfs.
 *
 * 2001-10-26 Tim Launchbury
 * added sysv magic.
 *
 * aeb - many changes.
 *
 */

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "linux_fs.h"
#include "mount_guess_fstype.h"
#include "sundries.h"		/* for xstrdup */
#include "nls.h"

#define ETC_FILESYSTEMS		"/etc/filesystems"
#define PROC_FILESYSTEMS	"/proc/filesystems"

#define SIZE(a) (sizeof(a)/sizeof(a[0]))

/* Most file system types can be recognized by a `magic' number
   in the superblock.  Note that the order of the tests is
   significant: by coincidence a filesystem can have the
   magic numbers for several file system types simultaneously.
   For example, the romfs magic lives in the 1st sector;
   xiafs does not touch the 1st sector and has its magic in
   the 2nd sector; ext2 does not touch the first two sectors. */

static inline unsigned short
swapped(unsigned short a) {
     return (a>>8) | (a<<8);
}

/*
    char *guess_fstype(const char *device);

    Probes the device and attempts to determine the type of filesystem
    contained within.

    Original routine by <jmorriso@bogomips.ww.ubc.ca>; made into a function
    for mount(8) by Mike Grupenhoff <kashmir@umiacs.umd.edu>.
    Corrected the test for xiafs - aeb
    Read the superblock only once - aeb
    Added a very weak heuristic for vfat - aeb
    Added iso9660, minix-v2, romfs, qnx4, udf, vxfs, swap - aeb
    Added a test for high sierra (iso9660) - quinlan@bucknell.edu
    Added ufs from a patch by jj. But maybe there are several types of ufs?
    Added ntfs from a patch by Richard Russon.
    Added xfs - 2000-03-21 Martin K. Petersen <mkp@linuxcare.com>
    Added cramfs, hfs, hpfs, adfs - Sepp Wijnands <mrrazz@garbage-coderz.net>
    Added ext3 - Andrew Morton
    Added jfs - Christoph Hellwig
    Added sysv - Tim Launchbury
    Added udf - Bryce Nesbitt
*/
static char
*magic_known[] = {
	"adfs", "bfs", "cramfs", "ext", "ext2", "ext3",
	"hfs", "hpfs", "iso9660", "jfs", "minix", "ntfs",
	"qnx4", "reiserfs", "romfs", "swap", "sysv", "udf", "ufs",
	"vxfs", "xfs", "xiafs"
};

static struct tried {
	struct tried *next;
	char *type;
} *tried = NULL;

static int
was_tested(const char *fstype) {
	char **m;
	struct tried *t;

	for (m = magic_known; m - magic_known < SIZE(magic_known); m++)
		if (!strcmp(*m, fstype))
			return 1;
	for (t = tried; t; t = t->next) {
		if (!strcmp(t->type, fstype))
			return 1;
	}
	return 0;
}

static void
set_tested(const char *fstype) {
	struct tried *t = xmalloc(sizeof(struct tried));

	t->next = tried;
	t->type = xstrdup(fstype);
	tried = t;
}

static void
free_tested(void) {
	struct tried *t, *tt;

	t = tried;
	while(t) {
		free(t->type);
		tt = t->next;
		free(t);
		t = tt;
	}
	tried = NULL;
}

/*
 * udf magic - I find that trying to mount garbage as an udf fs
 * causes a very large kernel delay, almost killing the machine.
 * So, we do not try udf unless there is positive evidence that it
 * might work. Strings below taken from ECMA 167.
 */
/*
 * It seems that before udf 2.00 the volume descriptor was not well
 * defined.  For 2.00 you're supposed to keep scanning records until
 * you find one NOT in this list.  (See ECMA 2/8.3.1).
 */
static char
*udf_magic[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02",
		 "NSR03", "TEA01" };


static int
may_be_udf(const char *id) {
    char **m;

    for (m = udf_magic; m - udf_magic < SIZE(udf_magic); m++)
       if (!strncmp(*m, id, 5))
	  return 1;
    return 0;
}

/* we saw "CD001" - may be iso9660 or udf - Bryce Nesbitt */
static int
is_really_udf(int fd) {
	int j, bs;
	struct iso_volume_descriptor isosb;

	/* determine the block size by scanning in 2K increments
	   (block sizes larger than 2K will be null padded) */
	for (bs = 1; bs < 16; bs++) {
		lseek(fd, bs*2048+32768, SEEK_SET);
		if (read(fd, (char *)&isosb, sizeof(isosb)) != sizeof(isosb))
			return 0;
		if (isosb.id[0])
			break;
	}

	/* Scan up to another 64 blocks looking for additional VSD's */
	for (j = 1; j < 64; j++) {
		if (j > 1) {
			lseek(fd, j*bs*2048+32768, SEEK_SET);
			if (read(fd, (char *)&isosb, sizeof(isosb))
			    != sizeof(isosb))
				return 0;
		}
		/* If we find NSR0x then call it udf:
		   NSR01 for UDF 1.00
		   NSR02 for UDF 1.50
		   NSR03 for UDF 2.00 */
		if (!strncmp(isosb.id, "NSR0", 4))
			return 1;
		if (!may_be_udf(isosb.id))
			return 0;
	}

	return 0;
}

static int
may_be_swap(const char *s) {
	return (strncmp(s-10, "SWAP-SPACE", 10) == 0 ||
		strncmp(s-10, "SWAPSPACE2", 10) == 0);
}

/* rather weak necessary condition */
static int
may_be_adfs(const u_char *s) {
	u_char *p;
	int sum;

	p = (u_char *) s + 511;
	sum = 0;
	while(--p != s)
		sum = (sum >> 8) + (sum & 0xff) + *p;

	return (sum == p[511]);
}

static int is_reiserfs_magic_string (struct reiserfs_super_block * rs)
{
    return (!strncmp (rs->s_magic, REISERFS_SUPER_MAGIC_STRING, 
		      strlen ( REISERFS_SUPER_MAGIC_STRING)) ||
	    !strncmp (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING, 
		      strlen ( REISER2FS_SUPER_MAGIC_STRING)));
}

char *
do_guess_fstype(const char *device) {
    int fd;
    char *type = NULL;
    union {
	struct minix_super_block ms;
	struct ext_super_block es;
	struct ext2_super_block e2s;
	struct vxfs_super_block vs;
    } sb;			/* stuff at 1024 */
    union {
	struct xiafs_super_block xiasb;
	char romfs_magic[8];
	char qnx4fs_magic[10];	/* ignore first 4 bytes */
	long bfs_magic;
	struct ntfs_super_block ntfssb;
	struct fat_super_block fatsb;
	struct xfs_super_block xfsb;
	struct cramfs_super_block cramfssb;
    } xsb;
    struct ufs_super_block ufssb;
    union {
	struct iso_volume_descriptor iso;
	struct hs_volume_descriptor hs;
    } isosb;
    struct reiserfs_super_block reiserfssb;	/* block 64 or 8 */
    struct jfs_super_block jfssb;		/* block 32 */
    struct hfs_super_block hfssb;
    struct hpfs_super_block hpfssb;
    struct adfs_super_block adfssb;
    struct sysv_super_block svsb;
    struct stat statbuf;

    /* opening and reading an arbitrary unknown path can have
       undesired side effects - first check that `device' refers
       to a block device or ordinary file */
    if (stat (device, &statbuf) ||
	!(S_ISBLK(statbuf.st_mode) || S_ISREG(statbuf.st_mode)))
      return 0;

    fd = open(device, O_RDONLY);
    if (fd < 0)
      return 0;

    /* do seeks and reads in disk order, otherwise a very short
       partition may cause a failure because of read error */

    if (!type) {
	 /* block 0 */
	 if (lseek(fd, 0, SEEK_SET) != 0
	     || read(fd, (char *) &xsb, sizeof(xsb)) != sizeof(xsb))
	      goto try_iso9660;
	 /* Gyorgy Kovesdi: none of my photocds has a readable block 0 */

	 if (xiafsmagic(xsb.xiasb) == _XIAFS_SUPER_MAGIC)
	      type = "xiafs";
	 else if(!strncmp(xsb.romfs_magic, "-rom1fs-", 8))
	      type = "romfs";
	 else if(!strncmp(xsb.xfsb.s_magic, XFS_SUPER_MAGIC, 4))
	      type = "xfs";
	 else if(!strncmp(xsb.qnx4fs_magic+4, "QNX4FS", 6))
	      type = "qnx4";
	 else if(xsb.bfs_magic == 0x1badface)
	      type = "bfs";
	 else if(!strncmp(xsb.ntfssb.s_magic, NTFS_SUPER_MAGIC,
			  sizeof(xsb.ntfssb.s_magic)))
	      type = "ntfs";
	 else if(cramfsmagic(xsb.cramfssb) == CRAMFS_SUPER_MAGIC ||
		 cramfsmagic(xsb.cramfssb) == CRAMFS_SUPER_MAGIC_BE)
	      type = "cramfs";
	 else if ((!strncmp(xsb.fatsb.s_os, "MSDOS", 5) ||
		   !strncmp(xsb.fatsb.s_os, "MSWIN", 5) ||
		   !strncmp(xsb.fatsb.s_os, "MTOOL", 5) ||
		   !strncmp(xsb.fatsb.s_os, "IBM", 3) ||
		   !strncmp(xsb.fatsb.s_os, "DRDOS", 5) ||
		   !strncmp(xsb.fatsb.s_os, "mkdosfs", 7) ||
		   !strncmp(xsb.fatsb.s_os, "kmkdosfs", 8) ||
		   /* Michal Svec: created by fdformat, old msdos utility for
		      formatting large (1.7) floppy disks. */
		   !strncmp(xsb.fatsb.s_os, "CH-FOR18", 8))
		  && (!strncmp(xsb.fatsb.s_fs, "FAT12   ", 8) ||
		      !strncmp(xsb.fatsb.s_fs, "FAT16   ", 8) ||
		      !strncmp(xsb.fatsb.s_fs2, "FAT32   ", 8)))
	      type = "vfat";	/* only guessing - might as well be fat or umsdos */
    }

    if (!type) {
	    /* sector 1 */
	    if (lseek(fd, 512 , SEEK_SET) != 512
		|| read(fd, (char *) &svsb, sizeof(svsb)) != sizeof(svsb))
		    goto io_error;
	    if (sysvmagic(svsb) == SYSV_SUPER_MAGIC )
		    type = "sysv";
    }

    if (!type) {
	/* block 1 */
	if (lseek(fd, 1024, SEEK_SET) != 1024 ||
	    read(fd, (char *) &sb, sizeof(sb)) != sizeof(sb))
		goto io_error;

	/* ext2 has magic in little-endian on disk, so "swapped" is
	   superfluous; however, there have existed strange byteswapped
	   PPC ext2 systems */
	if (ext2magic(sb.e2s) == EXT2_SUPER_MAGIC ||
	    ext2magic(sb.e2s) == EXT2_PRE_02B_MAGIC ||
	    ext2magic(sb.e2s) == swapped(EXT2_SUPER_MAGIC)) {
		type = "ext2";

	     /* maybe even ext3? */
	     if ((assemble4le(sb.e2s.s_feature_compat)
		  & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
		 assemble4le(sb.e2s.s_journal_inum) != 0)
		     type = "ext3";	/* "ext3,ext2" */
	}

	else if (minixmagic(sb.ms) == MINIX_SUPER_MAGIC ||
		 minixmagic(sb.ms) == MINIX_SUPER_MAGIC2 ||
		 minixmagic(sb.ms) == swapped(MINIX_SUPER_MAGIC2) ||
		 minixmagic(sb.ms) == MINIX2_SUPER_MAGIC ||
		 minixmagic(sb.ms) == MINIX2_SUPER_MAGIC2)
		type = "minix";

	else if (extmagic(sb.es) == EXT_SUPER_MAGIC)
		type = "ext";

	else if (vxfsmagic(sb.vs) == VXFS_SUPER_MAGIC)
		type = "vxfs";
    }

    if (!type) {
	/* block 1 */
        if (lseek(fd, 0x400, SEEK_SET) != 0x400
            || read(fd, (char *) &hfssb, sizeof(hfssb)) != sizeof(hfssb))
             goto io_error;

        /* also check if block size is equal to 512 bytes,
	   or a multiple. (I see 1536 here.) */
        if (hfsmagic(hfssb) == HFS_SUPER_MAGIC &&	/* always BE */
	    hfsblksize(hfssb) != 0 &&
	    (hfsblksize(hfssb) & 0x1ff) == 0)
             type = "hfs";
    }

    if (!type) {
	/* block 3 */
        if (lseek(fd, 0xc00, SEEK_SET) != 0xc00
            || read(fd, (char *) &adfssb, sizeof(adfssb)) != sizeof(adfssb))
             goto io_error;

	/* only a weak test */
        if (may_be_adfs((u_char *) &adfssb)
            && (adfsblksize(adfssb) >= 8 &&
                adfsblksize(adfssb) <= 10))
             type = "adfs";
    }

    if (!type) {
	 int mag;

	 /* block 8 */
	 if (lseek(fd, 8192, SEEK_SET) != 8192
	     || read(fd, (char *) &ufssb, sizeof(ufssb)) != sizeof(ufssb))
	      goto io_error;

	 mag = ufsmagic(ufssb);
	 if (mag == UFS_SUPER_MAGIC_LE || mag == UFS_SUPER_MAGIC_BE)
	      type = "ufs";
    }

    if (!type) {
	/* block 8 */
	if (lseek(fd, REISERFS_OLD_DISK_OFFSET_IN_BYTES, SEEK_SET) !=
				REISERFS_OLD_DISK_OFFSET_IN_BYTES
	    || read(fd, (char *) &reiserfssb, sizeof(reiserfssb)) !=
		sizeof(reiserfssb))
	    goto io_error;
	if (is_reiserfs_magic_string(&reiserfssb))
	    type = "reiserfs";
    }

    if (!type) {
	/* block 8 */
        if (lseek(fd, 0x2000, SEEK_SET) != 0x2000
            || read(fd, (char *) &hpfssb, sizeof(hpfssb)) != sizeof(hpfssb))
             goto io_error;

        if (hpfsmagic(hpfssb) == HPFS_SUPER_MAGIC)
             type = "hpfs";
    }

    if (!type) {
	 /* block 32 */
	 if (lseek(fd, JFS_SUPER1_OFF, SEEK_SET) != JFS_SUPER1_OFF
	     || read(fd, (char *) &jfssb, sizeof(jfssb)) != sizeof(jfssb))
	      goto io_error;
	 if (!strncmp(jfssb.s_magic, JFS_MAGIC, 4))
	      type = "jfs";
    }

    if (!type) {
	 /* block 32 */
    try_iso9660:
	 if (lseek(fd, 0x8000, SEEK_SET) != 0x8000
	     || read(fd, (char *) &isosb, sizeof(isosb)) != sizeof(isosb))
	      goto io_error;

	 if (strncmp(isosb.hs.id, HS_STANDARD_ID, sizeof(isosb.hs.id)) == 0) {
		 /* "CDROM" */
		 type = "iso9660";
	 } else if (strncmp(isosb.iso.id, ISO_STANDARD_ID,
			  sizeof(isosb.iso.id)) == 0) {
		 /* CD001 */
		 type = "iso9660";
		 if (is_really_udf(fd))
			 type = "udf";
	 } else if (may_be_udf(isosb.iso.id))
		 type = "udf";
    }

    if (!type) {
	/* block 64 */
	if (lseek(fd, REISERFS_DISK_OFFSET_IN_BYTES, SEEK_SET) !=
		REISERFS_DISK_OFFSET_IN_BYTES
	    || read(fd, (char *) &reiserfssb, sizeof(reiserfssb)) !=
		sizeof(reiserfssb))
	    goto io_error;
	if (is_reiserfs_magic_string(&reiserfssb))
	    type = "reiserfs";
    }

    if (!type) {
	    /* perhaps the user tries to mount the swap space
	       on a new disk; warn her before she does mke2fs on it */
	    int pagesize = getpagesize();
	    int rd;
	    char buf[32768];

	    rd = pagesize;
	    if (rd < 8192)
		    rd = 8192;
	    if (rd > sizeof(buf))
		    rd = sizeof(buf);
	    if (lseek(fd, 0, SEEK_SET) != 0
		|| read(fd, buf, rd) != rd)
		    goto io_error;
	    if (may_be_swap(buf+pagesize) ||
		may_be_swap(buf+4096) || may_be_swap(buf+8192))
		    type = "swap";
    }

    close (fd);
    return(type);

io_error:
    if (errno)
	 perror(device);
    else
	 fprintf(stderr, _("mount: error while guessing filesystem type\n"));
    close(fd);
    return 0;
}

char *
guess_fstype(const char *spec) {
	char *type = do_guess_fstype(spec);
	if (verbose) {
	    printf (_("mount: you didn't specify a filesystem type for %s\n"),
		    spec);
	    if (!type)
	      printf (_("       I will try all types mentioned in %s or %s\n"),
		      ETC_FILESYSTEMS, PROC_FILESYSTEMS);
	    else if (!strcmp(type, "swap"))
	      printf (_("       and it looks like this is swapspace\n"));
	    else
	      printf (_("       I will try type %s\n"), type);
	}
	return type;
}

static char *
procfsnext(FILE *procfs) {
   char line[100];
   char fsname[100];

   while (fgets(line, sizeof(line), procfs)) {
      if (sscanf (line, "nodev %[^\n]\n", fsname) == 1) continue;
      if (sscanf (line, " %[^ \n]\n", fsname) != 1) continue;
      return strdup(fsname);
   }
   return 0;
}

/* Only use /proc/filesystems here, this is meant to test what
   the kernel knows about, so /etc/filesystems is irrelevant.
   Return: 1: yes, 0: no, -1: cannot open procfs */
int
is_in_procfs(const char *type) {
    FILE *procfs;
    char *fsname;
    int ret = -1;

    procfs = fopen(PROC_FILESYSTEMS, "r");
    if (procfs) {
	ret = 0;
	while ((fsname = procfsnext(procfs)) != NULL)
	    if (!strcmp(fsname, type)) {
		ret = 1;
		break;
	    }
	fclose(procfs);
	procfs = NULL;
    }
    return ret;
}

/* Try all types in FILESYSTEMS, except those in *types,
   in case *types starts with "no" */
/* return: 0: OK, -1: error in errno, 1: type not found */
/* when 0 or -1 is returned, *types contains the type used */
/* when 1 is returned, *types is NULL */
int
procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args,
	   char **types) {
	char *files[2] = { ETC_FILESYSTEMS, PROC_FILESYSTEMS };
	FILE *procfs;
	char *fsname;
	char *notypes = NULL;
	int no = 0;
	int ret = 1;
	int errsv = 0;
	int i;

	if (*types && !strncmp(*types, "no", 2)) {
		no = 1;
		notypes = (*types) + 2;
	}
	*types = NULL;

	/* Use PROC_FILESYSTEMS only when ETC_FILESYSTEMS does not exist.
	   In some cases trying a filesystem that the kernel knows about
	   on the wrong data will crash the kernel; in such cases
	   ETC_FILESYSTEMS can be used to list the filesystems that we
	   are allowed to try, and in the order they should be tried.
	   End ETC_FILESYSTEMS with a line containing a single '*' only,
	   if PROC_FILESYSTEMS should be tried afterwards. */

	for (i=0; i<2; i++) {
		procfs = fopen(files[i], "r");
		if (!procfs)
			continue;
		while ((fsname = procfsnext(procfs)) != NULL) {
			if (!strcmp(fsname, "*")) {
				fclose(procfs);
				goto nexti;
			}
			if (was_tested (fsname))
				continue;
			if (no && matching_type(fsname, notypes))
				continue;
			set_tested (fsname);
			args->type = fsname;
			if (verbose) {
				printf(_("Trying %s\n"), fsname);
				fflush(stdout);
			}
			if ((*mount_fn) (args) == 0) {
				*types = fsname;
				ret = 0;
				break;
			} else if (errno != EINVAL &&
				   is_in_procfs(fsname) == 1) {
				*types = "guess";
				ret = -1;
				errsv = errno;
				break;
			}
		}
		free_tested();
		fclose(procfs);
		errno = errsv;
		return ret;
	nexti:;
	}
	return 1;
}

[-- Attachment #3: mount.c --]
[-- Type: application/octet-stream, Size: 46693 bytes --]

/*
 * A mount(8) for Linux 0.99.
 * mount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
 *
 * Wed Sep 14 22:43:00 1994: Mitchum DSouza
 * (mitch@mrc-applied-psychology.cambridge.ac.uk) added support for mounting
 * the "loop" device.
 *
 * Wed Sep 14 22:55:10 1994: Sander van Malssen (svm@kozmix.hacktic.nl)
 * added support for remounting readonly file systems readonly.
 *
 * Wed Feb  8 12:27:00 1995: Andries.Brouwer@cwi.nl fixed up error messages.
 * Sat Jun  3 20:44:38 1995: Patches from Andries.Brouwer@cwi.nl applied.
 * Tue Sep 26 22:38:20 1995: aeb@cwi.nl, many changes
 * Fri Feb 23 13:47:00 1996: aeb@cwi.nl, loop device related changes
 *
 * Since then, many changes - aeb.
 *
 * Wed Oct  1 23:55:28 1997: Dick Streefland <dick_streefland@tasking.com>
 * Implemented the "bg", "fg" and "retry" mount options for NFS.
 *
 * Tue Aug  4 15:54:31 1998: aeb@cwi.nl:
 * Open fd 0,1,2 so that printf's do not clobber /etc/mtab or so.
 * Mangle filenames with embedded spaces. Add ufsmagic. Add locking.
 * Avoid unnecessary error messages about /proc.
 * Improve support for noncanonical names in /etc/fstab.
 * Add support for volume labels and UUIDs.
 *
 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
 * - added Native Language Support
 * 1999-03-21 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
 * - fixed strerr(errno) in gettext calls
 * 1999-07-05 Hirokazu Takahashi <h-takaha@sss.abk.nec.co.jp>
 * - fixed use of nouser option
 * 1999-09-09 Michael K. Johnson <johnsonm@redhat.com>
 * - added `owner' mount option
 * 2000-05-11 Mark A. Peloquin <peloquin@us.ibm.com>
 * - check_special_mountprog now returns correct status
 * 2000-11-08 aeb: accept nonnumeric uid=, gid= options
 * 2001-07-13 Michael K. Johnson <johnsonm@redhat.com>
 * - implemented -a -O
 */

#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <stdio.h>

#include <pwd.h>
#include <grp.h>

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/mount.h>

#include "mount_constants.h"
#include "sundries.h"
#include "mntent.h"
#include "fstab.h"
#include "lomount.h"
#include "loop.h"
#include "linux_fs.h"		/* for BLKGETSIZE */
#include "mount_guess_rootdev.h"
#include "mount_guess_fstype.h"
#include "mount_by_label.h"
#include "getusername.h"
#include "env.h"
#include "nls.h"

#define DO_PS_FIDDLING

#ifdef DO_PS_FIDDLING
#include "setproctitle.h"
#endif

/* True for fake mount (-f).  */
static int fake = 0;

/* True if we are allowed to call /sbin/mount.${FSTYPE} */
static int external_allowed = 1;

/* Don't write a entry in /etc/mtab (-n).  */
static int nomtab = 0;

/* True for explicit readonly (-r).  */
static int readonly = 0;

/* Nonzero for chatty (-v).  */
int verbose = 0;

/* Do we hash the password or not */
int hash_password = 1;

/* Nonzero for sloppy (-s).  */
int sloppy = 0;

/* True for explicit read/write (-w).  */
static int readwrite = 0;

/* True for all mount (-a).  */
int mount_all = 0;

/* True for fork() during all mount (-F).  */
static int optfork = 0;

/* Add volumelabel in a listing of mounted devices (-l). */
static int list_with_volumelabel = 0;

/* Nonzero for mount {--bind|--replace|--before|--after|--over|--move} */
static int mounttype = 0;

/* True if ruid != euid.  */
static int suid = 0;

/* Contains the fd to read the passphrase from, if any. */
static int pfd = -1;

/* Contains the preferred keysize in bits we want to use */
static int keysz = 0;

/* Map from -o and fstab option strings to the flag argument to mount(2).  */
struct opt_map {
  const char *opt;		/* option name */
  int  skip;			/* skip in mtab option string */
  int  inv;			/* true if flag value should be inverted */
  int  mask;			/* flag mask value */
};

/* Custom mount options for our own purposes.  */
/* Maybe these should now be freed for kernel use again */
#define MS_NOAUTO	0x80000000
#define MS_USERS	0x40000000
#define MS_USER		0x20000000
#define MS_OWNER	0x10000000
#define MS_NETDEV	0x00020000
#define MS_LOOP		0x00010000

/* Options that we keep the mount system call from seeing.  */
#define MS_NOSYS	(MS_NOAUTO|MS_USERS|MS_USER|MS_NETDEV|MS_LOOP)

/* Options that we keep from appearing in the options field in the mtab.  */
#define MS_NOMTAB	(MS_REMOUNT|MS_NOAUTO|MS_USERS|MS_USER)

/* Options that we make ordinary users have by default.  */
#define MS_SECURE	(MS_NOEXEC|MS_NOSUID|MS_NODEV)

/* Options that we make owner-mounted devices have by default */
#define MS_OWNERSECURE	(MS_NOSUID|MS_NODEV)

static const struct opt_map opt_map[] = {
  { "defaults",	0, 0, 0		},	/* default options */
  { "ro",	1, 0, MS_RDONLY	},	/* read-only */
  { "rw",	1, 1, MS_RDONLY	},	/* read-write */
  { "exec",	0, 1, MS_NOEXEC	},	/* permit execution of binaries */
  { "noexec",	0, 0, MS_NOEXEC	},	/* don't execute binaries */
  { "suid",	0, 1, MS_NOSUID	},	/* honor suid executables */
  { "nosuid",	0, 0, MS_NOSUID	},	/* don't honor suid executables */
  { "dev",	0, 1, MS_NODEV	},	/* interpret device files  */
  { "nodev",	0, 0, MS_NODEV	},	/* don't interpret devices */
  { "sync",	0, 0, MS_SYNCHRONOUS},	/* synchronous I/O */
  { "async",	0, 1, MS_SYNCHRONOUS},	/* asynchronous I/O */
  { "dirsync",	0, 0, MS_DIRSYNC},	/* synchronous directory modifications */
  { "remount",  0, 0, MS_REMOUNT},      /* Alter flags of mounted FS */
  { "bind",	0, 0, MS_BIND   },	/* Remount part of tree elsewhere */
  { "auto",	0, 1, MS_NOAUTO	},	/* Can be mounted using -a */
  { "noauto",	0, 0, MS_NOAUTO	},	/* Can  only be mounted explicitly */
  { "users",	0, 0, MS_USERS	},	/* Allow ordinary user to mount */
  { "nousers",	0, 1, MS_USERS	},	/* Forbid ordinary user to mount */
  { "user",	0, 0, MS_USER	},	/* Allow ordinary user to mount */
  { "nouser",	0, 1, MS_USER	},	/* Forbid ordinary user to mount */
  { "owner",	0, 0, MS_OWNER  },	/* Let the owner of the device mount */
  { "noowner",	0, 1, MS_OWNER  },	/* Device owner has no special privs */
  { "_netdev",	0, 0, MS_NETDEV },	/* Device accessible only via network */
  /* add new options here */
#ifdef MS_NOSUB
  { "sub",	0, 1, MS_NOSUB	},	/* allow submounts */
  { "nosub",	0, 0, MS_NOSUB	},	/* don't allow submounts */
#endif
#ifdef MS_SILENT
  { "quiet",	0, 0, MS_SILENT    },	/* be quiet  */
  { "loud",	0, 1, MS_SILENT    },	/* print out messages. */
#endif
#ifdef MS_MANDLOCK
  { "mand",	0, 0, MS_MANDLOCK },	/* Allow mandatory locks on this FS */
  { "nomand",	0, 1, MS_MANDLOCK },	/* Forbid mandatory locks on this FS */
#endif
  { "loop",	1, 0, MS_LOOP	},	/* use a loop device */
#ifdef MS_NOATIME
  { "atime",	0, 1, MS_NOATIME },	/* Update access time */
  { "noatime",	0, 0, MS_NOATIME },	/* Do not update access time */
#endif
#ifdef MS_NODIRATIME
  { "diratime",	0, 1, MS_NODIRATIME },	/* Update dir access times */
  { "nodiratime", 0, 0, MS_NODIRATIME },/* Do not update dir access times */
#endif
  { NULL,	0, 0, 0		}
};

static char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption,
  *opt_keybits, *opt_nohashpass, *opt_speed;

static struct string_opt_map {
  char *tag;
  int skip;
  char **valptr;
} string_opt_map[] = {
  { "loop=",	0, &opt_loopdev },
  { "vfs=",	1, &opt_vfstype },
  { "offset=",	0, &opt_offset },
  { "encryption=", 0, &opt_encryption },
  { "keybits=", 0, &opt_keybits },
  { "nohashpass", 0, &opt_nohashpass },
  { "speed=", 0, &opt_speed },
  { NULL, 0, NULL }
};

static void
clear_string_opts(void) {
	struct string_opt_map *m;

	for (m = &string_opt_map[0]; m->tag; m++)
		*(m->valptr) = NULL;
}

static int
parse_string_opt(char *s) {
	struct string_opt_map *m;
	int lth;

	for (m = &string_opt_map[0]; m->tag; m++) {
		lth = strlen(m->tag);
		if (!strncmp(s, m->tag, lth)) {
			*(m->valptr) = xstrdup(s + lth);
			return 1;
		}
	}
	return 0;
}

int mount_quiet=0;

/* Report on a single mount.  */
static void
print_one (const struct mntent *me) {
     if (mount_quiet)
	  return;
     printf ("%s on %s", me->mnt_fsname, me->mnt_dir);
     if (me->mnt_type != NULL && *(me->mnt_type) != '\0')
	  printf (" type %s", me->mnt_type);
     if (me->mnt_opts != NULL)
	  printf (" (%s)", me->mnt_opts);
     if (list_with_volumelabel) {
	     const char *label;
	     label = get_volume_label_by_spec(me->mnt_fsname);
	     if (label)
		     printf (" [%s]", label);
     }
     printf ("\n");
}

/* Report on everything in mtab (of the specified types if any).  */
static int
print_all (char *types) {
     struct mntentchn *mc, *mc0;

     mc0 = mtab_head();
     for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) {
	  if (matching_type (mc->m.mnt_type, types))
	       print_one (&(mc->m));
     }
     exit (0);
}


/*
 * Look for OPT in opt_map table and return mask value.
 * If OPT isn't found, tack it onto extra_opts (which is non-NULL).
 * For the options uid= and gid= replace user or group name by its value.
 */
static inline void
parse_opt (const char *opt, int *mask, char *extra_opts) {
	const struct opt_map *om;

	for (om = opt_map; om->opt != NULL; om++)
		if (streq (opt, om->opt)) {
			if (om->inv)
				*mask &= ~om->mask;
			else
				*mask |= om->mask;
			if ((om->mask == MS_USER || om->mask == MS_USERS)
			    && !om->inv)
				*mask |= MS_SECURE;
			if ((om->mask == MS_OWNER) && !om->inv)
				*mask |= MS_OWNERSECURE;
#ifdef MS_SILENT
			if (om->mask == MS_SILENT && om->inv)  {
				mount_quiet = 1;
				verbose = 0;
			}
#endif
			return;
		}

	if (*extra_opts)
		strcat(extra_opts, ",");

	/* convert nonnumeric ids to numeric */
	if (!strncmp(opt, "uid=", 4) && !isdigit(opt[4])) {
		struct passwd *pw = getpwnam(opt+4);
		char uidbuf[20];

		if (pw) {
			sprintf(uidbuf, "uid=%d", pw->pw_uid);
			strcat(extra_opts, uidbuf);
			return;
		}
	}
	if (!strncmp(opt, "gid=", 4) && !isdigit(opt[4])) {
		struct group *gr = getgrnam(opt+4);
		char gidbuf[20];

		if (gr) {
			sprintf(gidbuf, "gid=%d", gr->gr_gid);
			strcat(extra_opts, gidbuf);
			return;
		}
	}

	strcat(extra_opts, opt);
}
  
/* Take -o options list and compute 4th and 5th args to mount(2).  flags
   gets the standard options (indicated by bits) and extra_opts all the rest */
static void
parse_opts (char *opts, int *flags, char **extra_opts) {
	char *opt;

	*flags = 0;
	*extra_opts = NULL;

	clear_string_opts();

	if (opts != NULL) {
		*extra_opts = xmalloc (strlen (opts) + 1); 
		**extra_opts = '\0';

		for (opt = strtok (opts, ","); opt; opt = strtok (NULL, ","))
			if (!parse_string_opt (opt))
				parse_opt (opt, flags, *extra_opts);
	}

	if (readonly)
		*flags |= MS_RDONLY;
	if (readwrite)
		*flags &= ~MS_RDONLY;
	*flags |= mounttype;
}

/* Try to build a canonical options string.  */
static char *
fix_opts_string (int flags, const char *extra_opts, const char *user) {
	const struct opt_map *om;
	const struct string_opt_map *m;
	char *new_opts;

	new_opts = (flags & MS_RDONLY) ? "ro" : "rw";
	for (om = opt_map; om->opt != NULL; om++) {
		if (om->skip)
			continue;
		if (om->inv || !om->mask || (flags & om->mask) != om->mask)
			continue;
		new_opts = xstrconcat3(new_opts, ",", om->opt);
		flags &= ~om->mask;
	}
	for (m = &string_opt_map[0]; m->tag; m++) {
		if (!m->skip && *(m->valptr))
			new_opts = xstrconcat4(new_opts, ",",
					       m->tag, *(m->valptr));
	}
	if (extra_opts && *extra_opts) {
		new_opts = xstrconcat3(new_opts, ",", extra_opts);
	}
	if (user) {
		new_opts = xstrconcat3(new_opts, ",user=", user);
	}
	return new_opts;
}

static int
already (const char *spec, const char *node) {
    struct mntentchn *mc;
    int ret = 1;

    if ((mc = getmntfile(node)) != NULL)
        error (_("mount: according to mtab, %s is already mounted on %s"),
	       mc->m.mnt_fsname, node);
    else if (spec && strcmp (spec, "none") &&
	     (mc = getmntfile(spec)) != NULL)
        error (_("mount: according to mtab, %s is mounted on %s"),
	       spec, mc->m.mnt_dir);
    else
        ret = 0;
    return ret;
}

/* Create mtab with a root entry.  */
static void
create_mtab (void) {
  struct mntentchn *fstab;
  struct mntent mnt;
  int flags;
  char *extra_opts;
  mntFILE *mfp;

  lock_mtab();

  mfp = my_setmntent (MOUNTED, "a+");
  if (mfp == NULL || mfp->mntent_fp == NULL) {
    int errsv = errno;
    die (EX_FILEIO, _("mount: can't open %s for writing: %s"),
	 MOUNTED, strerror (errsv));
  }

  /* Find the root entry by looking it up in fstab */
  if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) {
      parse_opts (xstrdup (fstab->m.mnt_opts), &flags, &extra_opts);
      mnt.mnt_dir = "/";
      mnt.mnt_fsname = canonicalize (fstab->m.mnt_fsname);
      mnt.mnt_type = fstab->m.mnt_type;
      mnt.mnt_opts = fix_opts_string (flags, extra_opts, NULL);
      mnt.mnt_freq = mnt.mnt_passno = 0;

      if (my_addmntent (mfp, &mnt) == 1) {
        int errsv = errno;
	die (EX_FILEIO, _("mount: error writing %s: %s"),
	     MOUNTED, strerror (errsv));
      }
  }
  if (fchmod (fileno (mfp->mntent_fp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0)
    if (errno != EROFS) {
      int errsv = errno;
      die (EX_FILEIO, _("mount: error changing mode of %s: %s"),
	   MOUNTED, strerror (errsv));
    }
  my_endmntent (mfp);

  unlock_mtab();
}

/* count successful mount system calls */
static int mountcount = 0;

/*
 * do_mount_syscall()
 *	Mount a single file system. Keep track of successes.
 * returns: 0: OK, -1: error in errno
 */
static int
do_mount_syscall (struct mountargs *args) {
	int flags = args->flags;
	int ret;

	if ((flags & MS_MGC_MSK) == 0)
		flags |= MS_MGC_VAL;

	ret = mount (args->spec, args->node, args->type, flags, args->data);
	if (ret == 0)
		mountcount++;
	return ret;
}

/*
 * guess_fstype_and_mount()
 *	Mount a single file system. Guess the type when unknown.
 * returns: 0: OK, -1: error in errno, 1: other error
 *	don't exit on non-fatal errors.
 *	on return types is filled with the type used.
 */
static int
guess_fstype_and_mount (char *spec, char *node, char **types,
			int flags, char *mount_opts) {
   struct mountargs args = { spec, node, NULL, flags & ~MS_NOSYS, mount_opts };
   
   if (*types && strcasecmp (*types, "auto") == 0)
      *types = NULL;

   if (!*types && (flags & (MS_BIND | MS_MOVE)))
      *types = "none";		/* random, but not "bind" */

   if (!*types && !(flags & MS_REMOUNT)) {
      *types = guess_fstype(spec);
      if (*types && !strcmp(*types, "swap")) {
	  error(_("%s looks like swapspace - not mounted"), spec);
	  *types = NULL;
	  return 1;
      }
   }

   /* Accept a comma-separated list of types, and try them one by one */
   /* A list like "nonfs,.." indicates types not to use */
   if (*types && strncmp(*types, "no", 2) && index(*types,',')) {
      char *t = strdup(*types);
      char *p;

      while((p = index(t,',')) != NULL) {
	 *p = 0;
	 args.type = *types = t;
	 if(do_mount_syscall (&args) == 0)
	    return 0;
	 t = p+1;
      }
      /* do last type below */
      *types = t;
   }

   if (*types || (flags & MS_REMOUNT)) {
      args.type = *types;
      return do_mount_syscall (&args);
   }

   return procfsloop(do_mount_syscall, &args, types);
}

/*
 * suid_check()
 *	Die if the user is not allowed to do this.
 */
static void
suid_check(char *spec, char *node, int *flags, char **user) {
  if (suid) {
      /* RedHat patch: allow owners to mount when fstab contains
	 the owner option.  Note that this should never be used
         in a high security environment, but may be useful to give
         people at the console the possibility of mounting a floppy. */
      if (*flags & MS_OWNER) {
	  if (!strncmp(spec, "/dev/", 5)) {
	      struct stat sb;

	      if (!stat(spec, &sb)) {
		  if (getuid() == sb.st_uid)
		      *flags |= MS_USER;
	      }
	  }
      }
      /* James Kehl <mkehl@gil.com.au> came with a similar patch:
	 allow an arbitrary user to mount when he is the owner of
	 the mount-point and has write-access to the device.
         This is even less secure. Let me skip it for the time being;
         there should be an explicit fstab line allowing such things. */

      if (!(*flags & (MS_USER | MS_USERS))) {
          if (already (spec, node))
	    die (EX_USAGE, _("mount failed"));
	  else
            die (EX_USAGE, _("mount: only root can mount %s on %s"), spec, node);
      }
      if (*flags & MS_USER)
	  *user = getusername();
  }

  if (*flags & MS_OWNER)
      *flags &= ~MS_OWNER;
}

static int
loop_check(char **spec, char **type, int *flags,
	   int *loop, char **loopdev, char **loopfile) {
  int looptype, offset;

  /*
   * In the case of a loop mount, either type is of the form lo@/dev/loop5
   * or the option "-o loop=/dev/loop5" or just "-o loop" is given, or
   * mount just has to figure things out for itself from the fact that
   * spec is not a block device. We do not test for a block device
   * immediately: maybe later other types of mountable objects will occur.
   */

  *loopdev = opt_loopdev;

  looptype = (*type && strncmp("lo@", *type, 3) == 0);
  if (looptype) {
    if (*loopdev)
      error(_("mount: loop device specified twice"));
    *loopdev = *type + 3;
    *type = opt_vfstype;
  } else if (opt_vfstype) {
    if (*type)
      error(_("mount: type specified twice"));
    else
      *type = opt_vfstype;
  }

  *loop = ((*flags & MS_LOOP) || *loopdev || opt_offset || opt_encryption ||
	   opt_keybits);
  *loopfile = *spec;

  if (*loop) {
    *flags |= MS_LOOP;
    if (fake) {
      if (verbose)
	printf(_("mount: skipping the setup of a loop device\n"));
    } else {
      int loopro = (*flags & MS_RDONLY);

      if (!*loopdev || !**loopdev)
	*loopdev = find_unused_loop_device();
      if (!*loopdev)
	return EX_SYSERR;	/* no more loop devices */
      if (verbose)
	printf(_("mount: going to use the loop device %s\n"), *loopdev);
      offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0;
      if (!keysz && opt_keybits)
	keysz  = strtoul(opt_keybits, NULL, 0);
      if (opt_nohashpass)
	hash_password=0;
      if (set_loop (*loopdev, *loopfile, offset, opt_encryption, pfd, 
		    keysz, &loopro, hash_password)) {
	if (verbose)
	  printf(_("mount: failed setting up loop device\n"));
	return EX_FAIL;
      }
      if (verbose > 1)
	printf(_("mount: setup loop device successfully\n"));
      *spec = *loopdev;
      if (loopro)
	*flags |= MS_RDONLY;
    }
  }

  return 0;
}

static void
update_mtab_entry(char *spec, char *node, char *type, char *opts,
		  int flags, int freq, int pass) {
    struct mntent mnt;

    mnt.mnt_fsname = canonicalize (spec);
    mnt.mnt_dir = canonicalize (node);
    mnt.mnt_type = type;
    mnt.mnt_opts = opts;
    mnt.mnt_freq = freq;
    mnt.mnt_passno = pass;
      
    /* We get chatty now rather than after the update to mtab since the
       mount succeeded, even if the write to /etc/mtab should fail.  */
    if (verbose)
	    print_one (&mnt);

    if (!nomtab && mtab_is_writable()) {
	if (flags & MS_REMOUNT)
	    update_mtab (mnt.mnt_dir, &mnt);
	else {
	    mntFILE *mfp;

	    lock_mtab();
	    mfp = my_setmntent(MOUNTED, "a+");
	    if (mfp == NULL || mfp->mntent_fp == NULL) {
	       	int errsv = errno;
		error(_("mount: can't open %s: %s"), MOUNTED,
		      strerror (errsv));
	    } else {
		if ((my_addmntent (mfp, &mnt)) == 1) {
			int errsv = errno;
			error(_("mount: error writing %s: %s"), MOUNTED,
			      strerror (errsv));
		}
		my_endmntent(mfp);
	    }
	    unlock_mtab();
	}
    }
}

static void
set_pfd(char *s) {
	if (!isdigit(*s))
		die(EX_USAGE,
		    _("mount: argument to -p or --pass-fd must be a number"));
	pfd = atoi(optarg);
}

static void
cdrom_setspeed(char *spec) {
#define CDROM_SELECT_SPEED      0x5322  /* Set the CD-ROM speed */
    if (opt_speed) {
	int cdrom;
	int speed = atoi(opt_speed);

	if ((cdrom = open(spec, O_RDONLY | O_NONBLOCK)) < 0)
	    die(EX_FAIL, _("mount: cannot open %s for setting speed"),
		spec);
	if (ioctl(cdrom, CDROM_SELECT_SPEED, speed) < 0)
	    die(EX_FAIL, _("mount: cannot set speed: %s"),
		strerror(errno));
	close(cdrom);
    }
}

/*
 * check_special_mountprog()
 *	If there is a special mount program for this type, exec it.
 * returns: 0: no exec was done, 1: exec was done, status has result
 */

static int
check_special_mountprog(char *spec, char *node, char *type, int flags,
			char *extra_opts, int *status) {
  char mountprog[120];
  struct stat statbuf;
  int res;

  if (!external_allowed)
      return 0;

  if (type && strlen(type) < 100) {
       sprintf(mountprog, "/sbin/mount.%s", type);
       if (stat(mountprog, &statbuf) == 0) {
	    res = fork();
	    if (res == 0) {
		 char *oo, *mountargs[10];
		 int i = 0;

		 setuid(getuid());
		 setgid(getgid());
		 oo = fix_opts_string (flags, extra_opts, NULL);
		 mountargs[i++] = mountprog;
		 mountargs[i++] = spec;
		 mountargs[i++] = node;
		 if (nomtab)
		      mountargs[i++] = "-n";
		 if (verbose)
		      mountargs[i++] = "-v";
		 if (oo && *oo) {
		      mountargs[i++] = "-o";
		      mountargs[i++] = oo;
		 }
		 mountargs[i] = NULL;
		 execv(mountprog, mountargs);
		 exit(1);	/* exec failed */
	    } else if (res != -1) {
		 int st;
		 wait(&st);
		 *status = (WIFEXITED(st) ? WEXITSTATUS(st) : EX_SYSERR);
		 return 1;
	    } else {
	    	 int errsv = errno;
		 error(_("mount: cannot fork: %s"), strerror(errsv));
	    }
       }
  }
  return 0;
}

/*
 * try_mount_one()
 *	Try to mount one file system. When "bg" is 1, this is a retry
 *	in the background. One additional exit code EX_BG is used here.
 *	It is used to instruct the caller to retry the mount in the
 *	background.
 * returns: 0: OK, EX_SYSERR, EX_FAIL, return code from nfsmount,
 *      return status from wait
 */
static int
try_mount_one (const char *spec0, const char *node0, char *types0,
	       const char *opts0, int freq, int pass, int bg, int ro) {
  int res, status;
  int mnt5_res = 0;		/* only for gcc */
  int mnt_err;
  int flags;
  char *extra_opts;		/* written in mtab */
  char *mount_opts;		/* actually used on system call */
  const char *opts;
  char *spec, *node, *types;
  char *user = 0;
  int loop = 0;
  char *loopdev = 0, *loopfile = 0;
  struct stat statbuf;
  int nfs_mount_version = 0;	/* any version */

  spec = xstrdup(spec0);
  node = xstrdup(node0);
  types = xstrdup(types0);
  opts = xstrdup(opts0);

  parse_opts (xstrdup (opts), &flags, &extra_opts);

  /* quietly succeed for fstab entries that don't get mounted automatically */
  if (mount_all && (flags & MS_NOAUTO))
    return 0;

  suid_check(spec, node, &flags, &user);

  mount_opts = extra_opts;

  if (opt_speed)
      cdrom_setspeed(spec);

  if (!(flags & MS_REMOUNT)) {
      /*
       * Don't set up a (new) loop device if we only remount - this left
       * stale assignments of files to loop devices. Nasty when used for
       * encryption.
       */
      res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile);
      if (res)
	  return res;
  }

  /*
   * Call mount.TYPE for types that require a separate mount program.
   * For the moment these types are ncpfs and smbfs. Maybe also vxfs.
   * All such special things must occur isolated in the types string.
   */
  if (check_special_mountprog (spec, node, types, flags, extra_opts, &status))
      return status;

  /*
   * Also nfs requires a separate program, but it is built in.
   */
  if (!fake && types && streq (types, "nfs")) {
#ifdef HAVE_NFS
retry_nfs:
    mnt_err = nfsmount (spec, node, &flags, &extra_opts, &mount_opts,
			&nfs_mount_version, bg);
    if (mnt_err)
      return mnt_err;
#else
    die (EX_SOFTWARE, _("mount: this version was compiled "
	              "without support for the type `nfs'"));
#endif
  }

  block_signals (SIG_BLOCK);

  if (!fake)
    mnt5_res = guess_fstype_and_mount (spec, node, &types, flags & ~MS_NOSYS,
				       mount_opts);

  if (fake || mnt5_res == 0) {
      /* Mount succeeded, report this (if verbose) and write mtab entry.  */
      if (loop)
	  opt_loopdev = loopdev;

      update_mtab_entry(loop ? loopfile : spec,
			node,
			types ? types : "unknown",
			fix_opts_string (flags & ~MS_NOMTAB, extra_opts, user),
			flags,
			freq,
			pass);

      block_signals (SIG_UNBLOCK);
      return 0;
  }

  mnt_err = errno;

  if (loop)
	del_loop(spec);

  block_signals (SIG_UNBLOCK);

#ifdef HAVE_NFS
  if (mnt_err && types && streq (types, "nfs")) {
      if (nfs_mount_version == 4) {
	  if (verbose)
	    printf(_("mount: failed with nfs mount version 4, trying 3..\n"));
	  nfs_mount_version = 3;
	  goto retry_nfs;
      }
  }
#endif

  /* Mount failed, complain, but don't die.  */

  if (types == 0) {
    if (suid)
      error (_("mount: I could not determine the filesystem type, "
	       "and none was specified"));
    else
      error (_("mount: you must specify the filesystem type"));
  } else if (mnt5_res != -1) {
      /* should not happen */
      error (_("mount: mount failed"));
  } else {
   switch (mnt_err) {
    case EPERM:
      if (geteuid() == 0) {
	   if (stat (node, &statbuf) || !S_ISDIR(statbuf.st_mode))
		error (_("mount: mount point %s is not a directory"), node);
	   else
		error (_("mount: permission denied"));
      } else
	error (_("mount: must be superuser to use mount"));
      break;
    case EBUSY:
      if (flags & MS_REMOUNT) {
	error (_("mount: %s is busy"), node);
      } else if (!strcmp(types, "proc") && !strcmp(node, "/proc")) {
	/* heuristic: if /proc/version exists, then probably proc is mounted */
	if (stat ("/proc/version", &statbuf))   /* proc mounted? */
	   error (_("mount: %s is busy"), node);   /* no */
	else if (!mount_all || verbose)            /* yes, don't mention it */
	   error (_("mount: proc already mounted"));
      } else {
	error (_("mount: %s already mounted or %s busy"), spec, node);
	already (spec, node);
      }
      break;
    case ENOENT:
      if (lstat (node, &statbuf))
	   error (_("mount: mount point %s does not exist"), node);
      else if (stat (node, &statbuf))
	   error (_("mount: mount point %s is a symbolic link to nowhere"),
		  node);
      else if (stat (spec, &statbuf))
	   error (_("mount: special device %s does not exist"), spec);
      else {
           errno = mnt_err;
           perror("mount");
      }
      break;
    case ENOTDIR:
      if (stat (node, &statbuf) || ! S_ISDIR(statbuf.st_mode))
           error (_("mount: mount point %s is not a directory"), node);
      else if (stat (spec, &statbuf) && errno == ENOTDIR)
	   error (_("mount: special device %s does not exist\n"
		    "       (a path prefix is not a directory)\n"), spec);
      else {
	   errno = mnt_err;
	   perror("mount");
      }
      break;
    case EINVAL:
    { int fd;
      long size;
      int warned=0;

      if (flags & MS_REMOUNT) {
	error (_("mount: %s not mounted already, or bad option"), node);
      } else {
	error (_("mount: wrong fs type, bad option, bad superblock on %s,\n"
	       "       or too many mounted file systems"),
	       spec);

	if (stat (spec, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)
	   && (fd = open(spec, O_RDONLY | O_NONBLOCK)) >= 0) {
	  if(ioctl(fd, BLKGETSIZE, &size) == 0) {
	    if (size == 0) {
	      warned++;
	  error ("       (could this be the IDE device where you in fact use\n"
		 "       ide-scsi so that sr0 or sda or so is needed?)");
	    }
	    if (size && size <= 2) {
	      warned++;
	  error ("       (aren't you trying to mount an extended partition,\n"
		 "       instead of some logical partition inside?)");
	    }
	  close(fd);
	  }
#if 0
	  /* 0xf for SCSI, 0x3f for IDE. One might check /proc/partitions
	     to see whether this thing really is partitioned.
	     Do not suggest partitions for /dev/fd0. */
	  if (!warned && (statbuf.st_rdev & 0xf) == 0) {
	    warned++;
	    error ("       (could this be the whole disk device\n"
		   "       where you need a partition?)");
	  }
#endif
	}
      }
      break;
    }
    case EMFILE:
      error (_("mount table full")); break;
    case EIO:
      error (_("mount: %s: can't read superblock"), spec); break;
    case ENODEV:
    { int pfs;
      if ((pfs = is_in_procfs(types)) == 1 || !strcmp(types, "guess"))
        error(_("mount: %s: unknown device"), spec);
      else if (pfs == 0) {
	char *lowtype, *p;
	int u;

	error (_("mount: fs type %s not supported by kernel"), types);

	/* maybe this loser asked for FAT or ISO9660 or isofs */
	lowtype = xstrdup(types);
	u = 0;
	for(p=lowtype; *p; p++) {
	  if(tolower(*p) != *p) {
	    *p = tolower(*p);
	    u++;
	  }
	}
	if (u && is_in_procfs(lowtype) == 1)
	  error (_("mount: probably you meant %s"), lowtype);
	else if (!strncmp(lowtype, "iso", 3) && is_in_procfs("iso9660") == 1)
	  error (_("mount: maybe you meant iso9660 ?"));
	free(lowtype);
      } else
	error (_("mount: %s has wrong device number or fs type %s not supported"),
	       spec, types);
      break;
    }
    case ENOTBLK:
      if (stat (spec, &statbuf)) /* strange ... */
	error (_("mount: %s is not a block device, and stat fails?"), spec);
      else if (S_ISBLK(statbuf.st_mode))
        error (_("mount: the kernel does not recognize %s as a block device\n"
	       "       (maybe `insmod driver'?)"), spec);
      else if (S_ISREG(statbuf.st_mode))
	error (_("mount: %s is not a block device (maybe try `-o loop'?)"),
		 spec);
      else
	error (_("mount: %s is not a block device"), spec);
      break;
    case ENXIO:
      error (_("mount: %s is not a valid block device"), spec); break;
    case EACCES:  /* pre-linux 1.1.38, 1.1.41 and later */
    case EROFS:   /* linux 1.1.38 and later */
    { char *bd = (loop ? "" : _("block device "));
      if (ro || (flags & MS_RDONLY)) {
          error (_("mount: cannot mount %s%s read-only"),
		 bd, spec);
          break;
      } else if (readwrite) {
	  error (_("mount: %s%s is write-protected but explicit `-w' flag given"),
		 bd, spec);
	  break;
      } else {
	 if (loop) {
	     opts = opts0;
	     types = types0;
	 }
         if (opts) {
	     char *opts1 = realloc(xstrdup(opts), strlen(opts)+4);
             strcat(opts1, ",ro");
	     opts = opts1;
         } else
             opts = "ro";
	 if (types && !strcmp(types, "guess"))
	     types = 0;
         error (_("mount: %s%s is write-protected, mounting read-only"),
		bd, spec0);
	 return try_mount_one (spec0, node0, types, opts, freq, pass, bg, 1);
      }
      break;
    }
    default:
      error ("mount: %s", strerror (mnt_err)); break;
    }
  }
  return EX_FAIL;
}

/*
 * set_proc_name()
 *	Update the argument vector, so that this process may be easily
 *	identified in a "ps" listing.
 */
static void
set_proc_name (const char *spec)
{
#ifdef DO_PS_FIDDLING
	setproctitle ("mount", spec);
#endif
}

static char *
subst_string(const char *s, const char *sub, int sublen, const char *repl) {
	char *n;

	n = (char *) xmalloc(strlen(s)-sublen+strlen(repl)+1);
	strncpy (n, s, sub-s);
	strcpy (n + (sub-s), repl);
	strcat (n, sub+sublen);
	return n;
}

static const char *
usersubst(const char *opts) {
	char *s, *w;
	char id[40];

	s = "uid=useruid";
	if (opts && (w = strstr(opts, s)) != NULL) {
		sprintf(id, "uid=%d", getuid());
		opts = subst_string(opts, w, strlen(s), id);
	}
	s = "gid=usergid";
	if (opts && (w = strstr(opts, s)) != NULL) {
		sprintf(id, "gid=%d", getgid());
		opts = subst_string(opts, w, strlen(s), id);
	}
	return opts;
}
		

/*
 * Return 0 for success (either mounted sth or -a and NOAUTO was given)
 */
static int
mount_one (const char *spec, const char *node, char *types, const char *opts,
	   char *cmdlineopts, int freq, int pass) {
  int status;
  int status2;
  int specset = 0;
  char *nspec;

  /* Substitute values in opts, if required */
  opts = usersubst(opts);

  /* Merge the fstab and command line options.  */
  if (opts == NULL)
       opts = cmdlineopts;
  else if (cmdlineopts != NULL)
       opts = xstrconcat3(opts, ",", cmdlineopts);

  if (!strncmp(spec, "UUID=", 5)) {
      specset = 1;
      nspec = get_spec_by_uuid(spec+5);
  } else if (!strncmp(spec, "LABEL=", 6)) {
      const char *nspec2 = NULL;
      specset = 2;
      nspec = get_spec_by_volume_label(spec+6);
      if (nspec)
	      nspec2 = second_occurrence_of_vol_label(spec+6);
      if (nspec2) {
	      if (verbose)
		      printf(_("mount: the label %s occurs on "
			       "both %s and %s\n"),
			     spec+6, nspec, nspec2);
	      die (EX_FAIL,
		   _("mount: %s duplicate - not mounted"),
		   spec, _PATH_FSTAB);
      }
  } else
      nspec = 0;		/* just for gcc */

  if (specset) {
      if (nspec) {
	  spec = nspec;
	  if (verbose > 1)
		  printf(_("mount: going to mount %s by %s\n"), spec,
			 (specset==1) ? _("UUID") : _("label"));
      } else if(!mount_all)
          die (EX_USAGE, _("mount: no such partition found"));
      /* if -a then we may be rescued by a noauto option */
  }

  if (types == NULL && !mounttype) {
      if (strchr (spec, ':') != NULL) {
	types = "nfs";
	if (verbose)
	  printf(_("mount: no type was given - "
		 "I'll assume nfs because of the colon\n"));
      } else if(!strncmp(spec, "//", 2)) {
	types = "smbfs";
	if (verbose)
	  printf(_("mount: no type was given - "
		   "I'll assume smbfs because of the // prefix\n"));
      }
  }

  /*
   * Try to mount the file system. When the exit status is EX_BG,
   * we will retry in the background. Otherwise, we're done.
   */
  status = try_mount_one (spec, node, types, opts, freq, pass, 0, 0);
  if (status != EX_BG)
    return status;

  /*
   * Retry in the background.
   */
  printf (_("mount: backgrounding \"%s\"\n"), spec);
  fflush( stdout );		/* prevent duplicate output */
  if (fork() > 0)
    return 0;			/* parent returns "success" */
  spec = xstrdup(spec);		/* arguments will be destroyed */
  node = xstrdup(node);		/* by set_proc_name()          */
  types = xstrdup(types);
  opts = xstrdup(opts);
  set_proc_name (spec);		/* make a nice "ps" listing */
  status2 = try_mount_one (spec, node, types, opts, freq, pass, 1, 0);
  if (verbose && status2)
    printf (_("mount: giving up \"%s\"\n"), spec);
  exit (0);			/* child stops here */
}

/* Check if an fsname/dir pair was already in the old mtab.  */
static int
mounted (char *spec, char *node) {
     struct mntentchn *mc, *mc0;
     char *nspec = NULL;

     if (!strncmp(spec, "UUID=", 5))
	  nspec = get_spec_by_uuid(spec+5);
     else if (!strncmp(spec, "LABEL=", 6))
	  nspec = get_spec_by_volume_label(spec+6);

     if (nspec)
	  spec = nspec;

     spec = canonicalize (spec);
     node = canonicalize (node);

     mc0 = mtab_head();
     for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
	  if (streq (spec, mc->m.mnt_fsname) && streq (node, mc->m.mnt_dir))
	       return 1;
     return 0;
}

/* avoid using stat() on things we are not going to mount anyway.. */
static int
has_noauto (char *opts) {
	char *s;

	if (!opts)
		return 0;
	s = strstr(opts, "noauto");
	if (!s)
		return 0;
	return (s == opts || s[-1] == ',') && (s[6] == 0 || s[6] == ',');
}

/* Mount all filesystems of the specified types except swap and root.  */
/* With the --fork option: fork and let different incarnations of
   mount handle different filesystems.  However, try to avoid several
   simultaneous mounts on the same physical disk, since that is very slow. */
#define DISKMAJOR(m)	(((int) m) & ~0xf)

static int
do_mount_all (char *types, char *options, char *test_opts) {
	struct mntentchn *mc, *mc0, *mtmp;
	int status = 0;
	struct stat statbuf;
	struct child {
		pid_t pid;
		char *group;
		struct mntentchn *mec;
		struct mntentchn *meclast;
		struct child *nxt;
	} childhead, *childtail, *cp;
	char major[22];
	char *g, *colon;

	/* build a chain of what we have to do, or maybe
	   several chains, one for each major or NFS host */
	childhead.nxt = 0;
	childtail = &childhead;
	mc0 = fstab_head();
	for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) {
		if (has_noauto (mc->m.mnt_opts))
			continue;
		if (matching_type (mc->m.mnt_type, types)
		    && matching_opts (mc->m.mnt_opts, test_opts)
		    && !streq (mc->m.mnt_dir, "/")
		    && !streq (mc->m.mnt_dir, "root")) {

			if (mounted (mc->m.mnt_fsname, mc->m.mnt_dir)) {
				if (verbose)
					printf(_("mount: %s already mounted "
						 "on %s\n"),
					       mc->m.mnt_fsname,
					       mc->m.mnt_dir);
				continue;
			}

			mtmp = (struct mntentchn *) xmalloc(sizeof(*mtmp));
			*mtmp = *mc;
			mtmp->nxt = 0;
			g = NULL;
			if (optfork) {
				if (stat(mc->m.mnt_fsname, &statbuf) == 0 &&
				    S_ISBLK(statbuf.st_mode)) {
					sprintf(major, "#%x",
						DISKMAJOR(statbuf.st_rdev));
					g = major;
				}
#ifdef HAVE_NFS
				if (strcmp(mc->m.mnt_type, "nfs") == 0) {
					g = xstrdup(mc->m.mnt_fsname);
					colon = strchr(g, ':');
					if (colon)
						*colon = '\0';
				}
#endif
			}
			if (g) {
				for (cp = childhead.nxt; cp; cp = cp->nxt)
					if (cp->group &&
					    strcmp(cp->group, g) == 0) {
						cp->meclast->nxt = mtmp;
						cp->meclast = mtmp;
						goto fnd;
					}
			}
			cp = (struct child *) xmalloc(sizeof *cp);
			cp->nxt = 0;
			cp->mec = cp->meclast = mtmp;
			cp->group = xstrdup(g);
			cp->pid = 0;
			childtail->nxt = cp;
			childtail = cp;
		fnd:;

		}
	}
			      
	/* now do everything */
	for (cp = childhead.nxt; cp; cp = cp->nxt) {
		pid_t p = -1;
		if (optfork) {
			p = fork();
			if (p == -1) {
				int errsv = errno;
				error(_("mount: cannot fork: %s"),
				      strerror (errsv));
			}
			else if (p != 0)
				cp->pid = p;
		}

		/* if child, or not forked, do the mounting */
		if (p == 0 || p == -1) {
			for (mc = cp->mec; mc; mc = mc->nxt) {
				status |= mount_one (mc->m.mnt_fsname,
						     mc->m.mnt_dir,
						     mc->m.mnt_type,
						     mc->m.mnt_opts,
						     options, 0, 0);
			}
			if (mountcount)
				status |= EX_SOMEOK;
			if (p == 0)
				exit(status);
		}
	}

	/* wait for children, if any */
	while ((cp = childhead.nxt) != NULL) {
		childhead.nxt = cp->nxt;
		if (cp->pid) {
			int ret;
		keep_waiting:
			if(waitpid(cp->pid, &ret, 0) == -1) {
				if (errno == EINTR)
					goto keep_waiting;
				perror("waitpid");
			} else if (WIFEXITED(ret))
				status |= WEXITSTATUS(ret);
			else
				status |= EX_SYSERR;
		}
	}
	if (mountcount)
		status |= EX_SOMEOK;
	return status;
}

extern char version[];
static struct option longopts[] = {
	{ "all", 0, 0, 'a' },
	{ "fake", 0, 0, 'f' },
	{ "fork", 0, 0, 'F' },
	{ "help", 0, 0, 'h' },
	{ "no-mtab", 0, 0, 'n' },
	{ "read-only", 0, 0, 'r' },
	{ "ro", 0, 0, 'r' },
	{ "verbose", 0, 0, 'v' },
	{ "version", 0, 0, 'V' },
	{ "read-write", 0, 0, 'w' },
	{ "rw", 0, 0, 'w' },
	{ "options", 1, 0, 'o' },
	{ "test-opts", 1, 0, 'O' },
	{ "pass-fd", 1, 0, 'p' },
	{ "keybits", 1, 0, 'k' },
	{ "types", 1, 0, 't' },
	{ "bind", 0, 0, 128 },
	{ "replace", 0, 0, 129 },
	{ "after", 0, 0, 130 },
	{ "before", 0, 0, 131 },
	{ "over", 0, 0, 132 },
	{ "move", 0, 0, 133 },
	{ "guess-fstype", 1, 0, 134 },
	{ "rbind", 0, 0, 135 },
	{ "internal-only", 0, 0, 'i' },
	{ NULL, 0, 0, 0 }
};

/* Keep the usage message at max 22 lines, each at most 70 chars long.
   The user should not need a pager to read it. */
static void
usage (FILE *fp, int n) {
	fprintf(fp, _(
	  "Usage: mount -V                 : print version\n"
	  "       mount -h                 : print this help\n"
	  "       mount                    : list mounted filesystems\n"
	  "       mount -l                 : idem, including volume labels\n"
	  "So far the informational part. Next the mounting.\n"
	  "The command is `mount [-t fstype] something somewhere'.\n"
	  "Details found in /etc/fstab may be omitted.\n"
	  "       mount -a [-t|-O] ...     : mount all stuff from /etc/fstab\n"
	  "       mount device             : mount device at the known place\n"
	  "       mount directory          : mount known device here\n"
	  "       mount -t type dev dir    : ordinary mount command\n"
	  "Note that one does not really mount a device, one mounts\n"
	  "a filesystem (of the given type) found on the device.\n"
	  "One can also mount an already visible directory tree elsewhere:\n"
	  "       mount --bind olddir newdir\n"
	  "or move a subtree:\n"
	  "       mount --move olddir newdir\n"
	  "A device can be given by name, say /dev/hda1 or /dev/cdrom,\n"
	  "or by label, using  -L label  or by uuid, using  -U uuid .\n"
	  "Other options: [-nfFrsvw] [-o options] [-p passwdfd].\n"
	  "For many more details, say  man 8 mount .\n"
	));
/*
	  "Union or stack mounts are specified using one of\n"
	  "       --replace, --after, --before, --over\n"
*/
	unlock_mtab();
	exit (n);
}

int
main (int argc, char *argv[]) {
	int c, result = 0, specseen;
	char *options = NULL, *test_opts = NULL, *spec, *node;
	char *volumelabel = NULL;
	char *passfd = NULL;
	char *keysize = NULL;
	char *uuid = NULL;
	char *types = NULL;
	struct mntentchn *mc;
	int fd;

	sanitize_env();
	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

	umask(033);

	/* People report that a mount called from init without console
	   writes error messages to /etc/mtab
	   Let us try to avoid getting fd's 0,1,2 */
	while((fd = open("/dev/null", O_RDWR)) == 0 || fd == 1 || fd == 2) ;
	if (fd > 2)
		close(fd);

#ifdef DO_PS_FIDDLING
	initproctitle(argc, argv);
#endif

	while ((c = getopt_long (argc, argv, "afFhilL:k:no:O:p:rsU:vVwt:",
				 longopts, NULL)) != -1) {
		switch (c) {
		case 'a':	       /* mount everything in fstab */
			++mount_all;
			break;
		case 'f':	       /* fake: don't actually call mount(2) */
			++fake;
			break;
		case 'F':
			++optfork;
			break;
		case 'h':		/* help */
			usage (stdout, 0);
			break;
		case 'i':
			external_allowed = 0;
			break;
		case 'l':
			list_with_volumelabel = 1;
			break;
		case 'L':
			volumelabel = optarg;
			break;
		case 'k':
			keysize = optarg;
			break;
		case 'n':		/* do not write /etc/mtab */
			++nomtab;
			break;
		case 'o':		/* specify mount options */
			if (options)
				options = xstrconcat3(options, ",", optarg);
			else
				options = xstrdup(optarg);
			break;
		case 'O':		/* with -t: mount only if (not) opt */
			if (test_opts)
				test_opts = xstrconcat3(test_opts, ",", optarg);
			else
				test_opts = xstrdup(optarg);
			break;
		case 'p':		/* fd on which to read passwd */
			set_pfd(optarg);
			break;
		case 'r':		/* mount readonly */
			readonly = 1;
			readwrite = 0;
			break;
		case 's':		/* allow sloppy mount options */
			sloppy = 1;
			break;
		case 't':		/* specify file system types */
			types = optarg;
			break;
		case 'U':
			uuid = optarg;
			break;
		case 'v':		/* be chatty - more so if repeated */
			++verbose;
			break;
		case 'V':		/* version */
			printf ("mount: %s\n", version);
			exit (0);
		case 'w':		/* mount read/write */
			readwrite = 1;
			readonly = 0;
			break;
		case 0:
			break;

		case 128: /* bind */
			mounttype = MS_BIND;
			break;
		case 129: /* replace */
			mounttype = MS_REPLACE;
			break;
		case 130: /* after */
			mounttype = MS_AFTER;
			break;
		case 131: /* before */
			mounttype = MS_BEFORE;
			break;
		case 132: /* over */
			mounttype = MS_OVER;
			break;
		case 133: /* move */
			mounttype = MS_MOVE;
			break;
		case 134:
			/* undocumented, may go away again:
			   call: mount --guess-fstype device
			   use only for testing purposes -
			   the guessing is not reliable at all */
		    {
			char *fstype;
			fstype = do_guess_fstype(optarg);
			printf("%s\n", fstype ? fstype : "unknown");
			exit(fstype ? 0 : EX_FAIL);
		    }
		case 135:
			mounttype = (MS_BIND | MS_REC);
			break;
		case '?':
		default:
			usage (stderr, EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

	specseen = (uuid || volumelabel) ? 1 : 0; 	/* yes, .. i know */

	if (argc+specseen == 0 && !mount_all) {
		if (options || mounttype)
			usage (stderr, EX_USAGE);
		return print_all (types);
	}

	if (getuid () != geteuid ()) {
		suid = 1;
		if (types || options || readwrite || nomtab || mount_all ||
		    fake || mounttype || (argc + specseen) != 1)
			die (EX_USAGE, _("mount: only root can do that"));
	}

	if (!nomtab && mtab_does_not_exist()) {
		if (verbose > 1)
			printf(_("mount: no %s found - creating it..\n"),
			       MOUNTED);
		create_mtab ();
	}

	if (specseen) {
		if (uuid)
			spec = get_spec_by_uuid(uuid);
		else {
			const char *spec2;
			spec = get_spec_by_volume_label(volumelabel);
			spec2 = second_occurrence_of_vol_label(volumelabel);
			if (spec2)
				die (EX_FAIL,
				     _("mount: the label %s occurs on "
				       "both %s and %s - not mounted\n"),
				     volumelabel, spec, spec2);
		}
		if (!spec)
			die (EX_USAGE, _("mount: no such partition found"));
		if (verbose)
			printf(_("mount: mounting %s\n"), spec);
	} else
		spec = NULL;		/* just for gcc */

	if (passfd && sscanf(passfd,"%d",&pfd) != 1)
	        die (EX_USAGE, _("mount: argument to --pass-fd or -p must be a number"));
	if (keysize && sscanf(keysize,"%d",&keysz) != 1)
	        die (EX_USAGE, _("mount: argument to --keybits or -k must be a number"));

	switch (argc+specseen) {
	case 0:
		/* mount -a */
		result = do_mount_all (types, options, test_opts);
		if (result == 0 && verbose)
			error(_("nothing was mounted"));
		break;

	case 1:
		/* mount [-nfrvw] [-o options] special | node */
		if (types != NULL)
			usage (stderr, EX_USAGE);
		if (specseen) {
			/* We know the device. Where shall we mount it? */
			mc = (uuid ? getfsuuidspec (uuid)
			           : getfsvolspec (volumelabel));
			if (mc == NULL)
				mc = getfsspec (spec);
			if (mc == NULL)
				die (EX_USAGE,
				     _("mount: cannot find %s in %s"),
				     spec, _PATH_FSTAB);
			mc->m.mnt_fsname = spec;
		} else {
			/* Try to find the other pathname in fstab.  */
			spec = canonicalize (*argv);
			if ((mc = getfsspec (spec)) == NULL &&
			    (mc = getfsfile (spec)) == NULL &&
			    /* Try noncanonical name in fstab
			       perhaps /dev/cdrom or /dos is a symlink */
			    (mc = getfsspec (*argv)) == NULL &&
			    (mc = getfsfile (*argv)) == NULL &&
			    /* Try mtab - maybe this was a remount */
			    (mc = getmntfile (spec)) == NULL)
				die (EX_USAGE,
				     _("mount: can't find %s in %s or %s"),
				     spec, _PATH_FSTAB, MOUNTED);
			/* Earlier mtab was tried first, but this would
			   sometimes try the wrong mount in case mtab had
			   the root device entry wrong. */
		}

		result = mount_one (xstrdup (mc->m.mnt_fsname),
				    xstrdup (mc->m.mnt_dir),
				    xstrdup (mc->m.mnt_type),
				    mc->m.mnt_opts, options, 0, 0);
		break;

	case 2:
		/* mount [-nfrvw] [-t vfstype] [-o options] special node */
		if (specseen) {
			/* we have spec already */
			node = argv[0];
		} else {
			spec = argv[0];
			node = argv[1];
		}
		result = mount_one (spec, node, types, NULL, options, 0, 0);
		break;
      
	default:
		usage (stderr, EX_USAGE);
	}

	if (result == EX_SOMEOK)
		result = 0;
	exit (result);
}

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
  2005-08-01 11:31 Mukund JB.
@ 2005-08-01 12:08 ` linux-os (Dick Johnson)
  2005-08-02 13:42 ` Lennart Sorensen
  1 sibling, 0 replies; 15+ messages in thread
From: linux-os (Dick Johnson) @ 2005-08-01 12:08 UTC (permalink / raw)
  To: Mukund JB.; +Cc: Lennart Sorensen, Srinivas G., linux-kernel-Mailing-list



So where is the driver? There is obviously something wrong there,
yet you send copies of mount source. Mount works, it's your driver
that doesn't. You need to fix your driver. There are some very
common errors. For instance sectors start at 1, not 0, while
cylinders and heads start at 0. You need to look at your source-
code, first for the most common errors, then for others.

As a debugging aid, you can make a file-system on a file. Then
you can write the whole thing to the hardware using `cp` or `dd`.
If the resulting file-system mounts and works properly, it
may help find the problem.

On Mon, 1 Aug 2005, Mukund JB. wrote:

> Dear all,
>
> Below are my driver messages logged at initialization time & sfdisk call
> time.
>
> when module is initialized................
>
> TIFM INFO | TI init Routine Invoked!
> ReportMediaModel: ( SD card Details)
>  Size            = 14 [MB]
>  mwCylinders       = 450
>  mwHeadCount       = 2
>  mwSectorsPerTrack = 32
>
> When the ioctl is invoked through the "sfdisk -lV /dev/tfa0"
>
> TIFM INFO | <tifm_ioctl> invoked!
> TIFM INFO | dev no. [ 0 ] sock no. [ 0 ]
> TIFM INFO | <GetGeometry_ioctl> geo.cylinders = 450
> TIFM INFO | <GetGeometry_ioctl> geo.heads = 2
> TIFM INFO | <GetGeometry_ioctl> geo.sectors = 32
> TIFM INFO | <GetGeometry_ioctl> geo.start = 0
>
> This means that I am giving the proper details to the user program but
> the sfdisk is printing it wrong (probably manipulation).
>
> And when I try to mount ......
>
> mount /dev/tfa0 /mnt
> FAT: bogus number of reserved sectors
> Mount: you must specify the filesystem type
>
> mount -tvfat /dev/tfa0 /mnt
> FAT: bogus number of reserved sectors
> Mount: wrong fs type, bad option, bas superblock on /dev/tfa0,
> 	 or too many mounted file systems
>
> I have gone through the mount.c code in order to understand where I am
> exactly failing.
> mount is failing in guess_fstype_and_mount() in do_mount_syscall after
> issuing the mount sys call.
> I am attaching the source code of mount functionality which may be on
> some help to u in u8ndertaing why exactly its failing.
>
> Regards,
> Mukund Jampala
>
>
>
>
>> -----Original Message-----
>> From: linux-os (Dick Johnson) [mailto:linux-os@analogic.com]
>> Sent: Friday, July 29, 2005 11:39 PM
>> To: Mukund JB.
>> Cc: Lennart Sorensen; Srinivas G.; linux-kernel-Mailing-list
>> Subject: RE: Unable to mount the SD card formatted using the DIGITAL
> CAMREA
>> on Linux box
>>
>>
>> On Fri, 29 Jul 2005, linux-os (Dick Johnson) wrote:
>>
>>>
>>>
>>> camera formatted info
>>> ----------------------
>>> Disk /dev/tfa0: 448 cylinders, 2 heads, 32 sectors/track
>>> Units = cylinders of 32768 bytes, blocks of 1024 bytes, counting from
> 0
>>>
>>>    Device Boot Start     End   #cyls    #blocks   Id  System
>>> /dev/tfa0p1   *      0+    449     450-     14371+   1  FAT12
>>> /dev/tfa0p2          0       -       0          0    0  Empty
>>> /dev/tfa0p3          0       -       0          0    0  Empty
>>> /dev/tfa0p4          0       -       0          0    0  Empty
>>> Warning: partition 1 extends past end of disk
>>>
>>> If it's 488 cylinders, then it should start at 0 and end at 447,
>>> not 449.
>>>
>>
>> Sorry typo, 487, not 447.
>>
>>
>>> It looks like some kind of driver error to begin with. The
>>> fact that it sometimes works should be overlooked until the
>>> driver returns the correct number of cylinders (the same
>>> number that the formatting utility gets). Check to see if
>>> your driver could return a different disk size under different
>>> conditions.
>>>
>>> On Fri, 29 Jul 2005, Mukund JB. wrote:
>>>
>>>>
>>>> Dear Lennart, Dick Johnson, Erik Mouw & All,
>>>>
>>>> Thanks for all ur precious support.
>>>>
>>>> The cannon camera (other devices too) formatted SD is indeed a
> partition
>>>> FAT12. When I said
>>>> sfdisk -l, it showed the fs ID as 1. 1 is indeed the FAT12 fs ID.
>>>>
>>>> Attached are the logs for win and camera device sfdisk -Vl
> /dev/tfa0.
>>>>
>>>> The SD card formatted in camera is partitioned FAT12 disk.
>>>> Also, the SD card formatted in windows is partitioned FAT12 disk.
>>>> (see the attachment)
>>>>
>>>> on ur suggestion I verified whether camera partition device has a
> valid
>>>> FS ID. I verified. It is FAT12. It is the same for windows
>>>> formatted device. The FS ID of both the formats is 1. i.e. FAT12.
>>>>
>>>> I has notion that my driver is not supporting partition devices.
> This
>>>> makes this clean that my driver is supporting the partition devices
>>>> (windows formatted SD). If both are partitioned where is the
> difference?
>>>>
>>>>
>>>> So, can someone please help me telling what else could be missing
> that
>>>> is creating this problem?
>>>>
>>>> Regards,
>>>> Mukund Jampala
>>>>
>>>>
>>>>> -----Original Message-----
>>>>> From: linux-kernel-owner@vger.kernel.org [mailto:linux-kernel-
>>>>> owner@vger.kernel.org] On Behalf Of Lennart Sorensen
>>>>> Sent: Friday, July 29, 2005 7:08 PM
>>>>> To: linux-os (Dick Johnson)
>>>>> Cc: Srinivas G.; linux-kernel-Mailing-list
>>>>> Subject: Re: Unable to mount the SD card formatted using the
> DIGITAL
>>>> CAMREA
>>>>> on Linux box
>>>>>
>>>>> On Fri, Jul 29, 2005 at 08:02:14AM -0400, linux-os (Dick Johnson)
>>>> wrote:
>>>>>> Execute linux `fdisk` on the device. You may find that the
>>>>>> ID byte is wrong.
>>>>>>
>>>>>> Also, why do you need a special block device driver? The SanDisk
>>>>>> and CompacFlash devices should look like IDE drives.
>>>>>
>>>>> SD usually is secure digital (MMC compatible somewhat I believe).
> It
>>>>> does not provide IDE unlike CompactFlash.  SD uses a serial
> interface
>>>> if
>>>>> I remember correctly.
>>>>>
>>>>> Len Sorensen
>>>>> -
>>>>> To unsubscribe from this list: send the line "unsubscribe
> linux-kernel"
>>>> in
>>>>> the body of a message to majordomo@vger.kernel.org
>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>> Please read the FAQ at  http://www.tux.org/lkml/
>>>>
>>>
>>> Cheers,
>>> Dick Johnson
>>> Penguin : Linux version 2.6.12 on an i686 machine (5537.79 BogoMips).
>>> Warning : 98.36% of all statistics are fiction.
>>> .
>>> I apologize for the following. I tried to kill it with the above dot
> :
>>>
>>> ****************************************************************
>>> The information transmitted in this message is confidential and may
> be
>> privileged.  Any review, retransmission, dissemination, or other use of
>> this information by persons or entities other than the intended
> recipient
>> is prohibited.  If you are not the intended recipient, please notify
>> Analogic Corporation immediately - by replying to this message or by
>> sending an email to DeliveryErrors@analogic.com - and destroy all
> copies of
>> this information, including any attachments, without reading or
> disclosing
>> them.
>>>
>>> Thank you.
>>> -
>>> To unsubscribe from this list: send the line "unsubscribe
> linux-kernel"
>> in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>> Please read the FAQ at  http://www.tux.org/lkml/
>>>
>>
>> Cheers,
>> Dick Johnson
>> Penguin : Linux version 2.6.12 on an i686 machine (5537.79 BogoMips).
>> Warning : 98.36% of all statistics are fiction.
>> .
>> I apologize for the following. I tried to kill it with the above dot :
>>
>> ****************************************************************
>> The information transmitted in this message is confidential and may be
>> privileged.  Any review, retransmission, dissemination, or other use of
>> this information by persons or entities other than the intended
> recipient
>> is prohibited.  If you are not the intended recipient, please notify
>> Analogic Corporation immediately - by replying to this message or by
>> sending an email to DeliveryErrors@analogic.com - and destroy all
> copies of
>> this information, including any attachments, without reading or
> disclosing
>> them.
>>
>>
>> Thank you.
>

Cheers,
Dick Johnson
Penguin : Linux version 2.6.12 on an i686 machine (5537.79 BogoMips).
Warning : 98.36% of all statistics are fiction.
.
I apologize for the following. I tried to kill it with the above dot :

****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
  2005-08-01 11:31 Mukund JB.
  2005-08-01 12:08 ` linux-os (Dick Johnson)
@ 2005-08-02 13:42 ` Lennart Sorensen
  1 sibling, 0 replies; 15+ messages in thread
From: Lennart Sorensen @ 2005-08-02 13:42 UTC (permalink / raw)
  To: Mukund JB.
  Cc: linux-os (Dick Johnson), Srinivas G., linux-kernel-Mailing-list

On Mon, Aug 01, 2005 at 05:01:00PM +0530, Mukund JB. wrote:
> Dear all,
> 
> Below are my driver messages logged at initialization time & sfdisk call
> time. 
> 
> when module is initialized................
> 
> TIFM INFO | TI init Routine Invoked!
> ReportMediaModel: ( SD card Details)
>   Size            = 14 [MB]
>   mwCylinders       = 450
>   mwHeadCount       = 2
>   mwSectorsPerTrack = 32

Well the 450 cylinders there is right, so why is the driver passing info
down to user space saying the device has 448 cylinders?  Somehow you are
loosing 2 cylinders in your driver somewhere.

> When the ioctl is invoked through the "sfdisk -lV /dev/tfa0"
> 
> TIFM INFO | <tifm_ioctl> invoked! 
> TIFM INFO | dev no. [ 0 ] sock no. [ 0 ]
> TIFM INFO | <GetGeometry_ioctl> geo.cylinders = 450
> TIFM INFO | <GetGeometry_ioctl> geo.heads = 2
> TIFM INFO | <GetGeometry_ioctl> geo.sectors = 32
> TIFM INFO | <GetGeometry_ioctl> geo.start = 0
> 
> This means that I am giving the proper details to the user program but
> the sfdisk is printing it wrong (probably manipulation).
> 
> And when I try to mount ......
> 
> mount /dev/tfa0 /mnt
> FAT: bogus number of reserved sectors
> Mount: you must specify the filesystem type 

Well if the partition table/fs size is larger than the device currently
claims to be, the FS will fail and mount will fail.  Nothing wrong in
mount, just broken device driver.

> mount -tvfat /dev/tfa0 /mnt
> FAT: bogus number of reserved sectors
> Mount: wrong fs type, bad option, bas superblock on /dev/tfa0,
> 	 or too many mounted file systems
> 
> I have gone through the mount.c code in order to understand where I am
> exactly failing. 
> mount is failing in guess_fstype_and_mount() in do_mount_syscall after
> issuing the mount sys call.
> I am attaching the source code of mount functionality which may be on
> some help to u in u8ndertaing why exactly its failing.

Perhaps adding more debuging to your driver wherever user space calls in
to get the size of the device, to make sure you have the right
information passed along.  Heads and sectors looks fine, but the
cylinder count needs fixing since it is currently reporting 2 less than
it really is.  This has to be 100% a problem in the device driver.

Len Sorensen

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
       [not found] <C349E772C72290419567CFD84C26E017042219@mail.esn.co.in>
@ 2005-08-02 22:18 ` chuck gelm
  0 siblings, 0 replies; 15+ messages in thread
From: chuck gelm @ 2005-08-02 22:18 UTC (permalink / raw)
  To: Mukund JB.; +Cc: linux-newbie

Mukund JB. wrote:
> Dear all,
> 
> I have problem in mounting my SD device.
> I have a commotion in resolving an issue with sfdisk info.
> The sfdisk displays my device partition and cylinder info as follows.
> 
> #sfdisk -lV /dev/tfa0
> 
> Disk /dev/tfa0: 448 cylinders, 2 heads, 32 sectors/track
> Units = cylinders of 32768 bytes, blocks of 1024 bytes, counting from 0
> 
>    Device Boot Start     End   #cyls    #blocks   Id  System
> /dev/tfa0p1   *      0+    449     450-     14371+   1  FAT12
> /dev/tfa0p2          0       -       0          0    0  Empty
> /dev/tfa0p3          0       -       0          0    0  Empty
> /dev/tfa0p4          0       -       0          0    0  Empty
> Warning: partition 1 extends past end of disk
> 
> The SD card driver is returning the following info to the HDIO_GETGEO
> ioctl called from sfdisk.
> ------------- driver messages ---------------------------
> TIFM INFO | <tifm_ioctl> invoked! 
> TIFM INFO | <GetGeometry_ioctl> geo.cylinders = 450
> TIFM INFO | <GetGeometry_ioctl> geo.heads = 2
> TIFM INFO | <GetGeometry_ioctl> geo.sectors = 32
> TIFM INFO | <GetGeometry_ioctl> geo.start = 0
> 
> When we have a close look at the cylinder info returned by driver &
> sfdisk, they differ. 
> When I refer to the SD card manufacture spec, it reveals the n/o
> cylinders are 450. So, driver is returning the exact/proper cylinder
> value.
> 
> Why is sfdisk giving improper cylinder info?
> Can some one explain me how this mismatch info between the driver and
> application can effect my mounting of my device?
> I assume HDIO_GETGEO is the only way sfdisk communicates with the
> driver.
> 
> Regards,
> Mukund Jampala
SFDISK(8)           Linux Programmer's Manual           SFDISK(8)

NAME
        sfdisk - Partition table manipulator for Linux

SYNOPSIS
        sfdisk [options] device
        sfdisk -s [partition]

DESCRIPTION
        sfdisk has four (main) uses:
         list the size of a partition,
         list the partitions on a device,
         check the partitions on a        device, and
         - very dangerous - repartition a device.

Uh, let me repeat that last line:
  - very dangerous - repartition a device.

I suggest using fdisk to partition the device or let your
camera (re)format the media.

HTH, Chuck



-
To unsubscribe from this list: send the line "unsubscribe linux-newbie" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.linux-learn.org/faqs

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
@ 2005-08-05  9:46 Mukund JB.
  0 siblings, 0 replies; 15+ messages in thread
From: Mukund JB. @ 2005-08-05  9:46 UTC (permalink / raw)
  To: Erik Mouw; +Cc: linux-fsdevel


Dear Erik,

Sorry for the delay in response. 
I was required to fix the partition problem first.

I have an update in gathering some partition info about in SD cards
formatted in windows and Camera.

I tried printing data from the ox1be offset of 0th sector on windows
formatted SD card and Camera formatted SD card.

Please see the details below.

Windows SD_0_Sector details at 0x1be offset
------------------------------------------

bootable 		= 111 	  ( 0x01BE)
beg-chs.heads 	= 116			.
beg-chs.sect 	= 104			.
beg-chs.cylin 	= 101			.
sys-type 		= 114			.
end-chs.heads 	= 32			.
end-chs.sect 	= 109			.
end-chs.cylin 	= 101			.
start sect  	= 778135908		.
n/o sec in part = 1141509631		.


Camera SD_0_Sector details at 0x1be offset
------------------------------------------

bootable 		= 128
beg-chs.heads 	= 1
beg-chs.sect 	= 26
beg-chs.cylin 	= 0
sys-type 		= 1
end-chs.heads 	= 1
end-chs.sect 	= 96
end-chs.cylin 	= 193
start sect  	= 57
n/o sec in part = 28743

To the surprise of me, the windows partition table data looks corrupted
and the camera created partition table looks tome meaningfull.
But, windows SD card mounts and camera SD card fails to mount.

I am planning to get the FAT12 details from the first partition of
camera starting at sector 57 as you can see in the 'start sect'
variable.

Please help me finding a way to fix this.

Thanks & Regards,
Mukund Jampala


>-----Original Message-----
>From: Erik Mouw [mailto:J.A.K.Mouw@its.tudelft.nl]
>Sent: Friday, July 29, 2005 5:56 PM
>To: Srinivas G.
>Cc: kernelnewbies@nl.linux.org
>Subject: Re: Unable to mount the SD card formatted using the DIGITAL
CAMREA
>on Linux box
>
>(don't write to me personally, I do read the list)
>
>On Fri, Jul 29, 2005 at 04:56:43PM +0530, Srinivas G. wrote:
>> We have developed a Block Device Driver to handle the flash media
>> devices in Linux 2.6.x kernel. It is working fine. We are able to
mount
>> the SD cards that are formatted on Windows systems, but we unable
mount
>> the cards that are formatted using the DIGITAL CAMERA.
>>
>> We have found one thing that the Windows and Digital Camera both are
>> formatting the SD cards in FAT12 only. But why we are not able to
mount
>> the SD cards on Linux Box that are formatted using the Digital
Camera.
>
>Probably because the camera and linux disagree about the geometry in
>CHS (cylinder, head, sector) of the flash device.
>
>Each partition table entry contains the start and end CHS of that
>partition. However, since a flash device (and also modern hard drives)
>doesn't have a meaningful geometry value, the same information is also
>encoded in logical sectors (start and size of the partition).
>
>If the logical information is zero, the kernel falls back onto the CHS
>information in the partition table and has to assume a certain
>geometry. If that assumption differs from the assumption of the camera,
>the partition boundaries will be wrong and you will not be able to
>mount the partition directly. However, you can figure out the start of
>the partition by hand, and use a loop device to get at the correct
>offset.
>
>
>Erik
>
>--
>Erik Mouw
>J.A.K.Mouw@its.tudelft.nl  mouw@nl.linux.org

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
@ 2005-08-08  8:56 Mukund JB.
  0 siblings, 0 replies; 15+ messages in thread
From: Mukund JB. @ 2005-08-08  8:56 UTC (permalink / raw)
  To: Erik Mouw; +Cc: linux-fsdevel, linux-kernel


Dear Erik & all,

Sorry for the delay in my latest updates. 
I was required to fix the partition problem first.

I have an update in gathering some partition info about in SD cards
formatted in windows and Camera.

I tried printing data from the ox1BE offset of 0th sector on windows
formatted SD card and Camera formatted SD card.

Please see the details below.

Windows SD_0_Sector details at 0x1BE offset
------------------------------------------

bootable 		= 111 	  ( 0x01BE)
beg-chs.heads 	= 116			.
beg-chs.sect 	= 104			.
beg-chs.cylin 	= 101			.
sys-type 		= 114			.
end-chs.heads 	= 32			.
end-chs.sect 	= 109			.
end-chs.cylin 	= 101			.
start sect  	= 778135908		.
n/o sec in part = 1141509631		.


Camera SD_0_Sector details at 0x1BE offset
------------------------------------------

bootable 		= 128
beg-chs.heads 	= 1
beg-chs.sect 	= 26
beg-chs.cylin 	= 0
sys-type 		= 1
end-chs.heads 	= 1
end-chs.sect 	= 96
end-chs.cylin 	= 193
start sect  	= 57
n/o sec in part = 28743

To the surprise of me, the windows partition table data looks corrupted
and the camera created partition table looks tome meaningful. But,
windows SD card mounts and camera SD card fails to mount.

I am planning to get the FAT12 details from the first partition of
camera starting at sector 57 as you can see in the 'start sect'
variable.

Please help me finding a way to fix this.

Thanks & Regards,
Mukund Jampala


>-----Original Message-----
>From: Erik Mouw [mailto:J.A.K.Mouw@its.tudelft.nl]
>Sent: Friday, July 29, 2005 5:56 PM
>To: Srinivas G.
>Cc: kernelnewbies@nl.linux.org
>Subject: Re: Unable to mount the SD card formatted using the DIGITAL 
>CAMREA on Linux box
>
>(don't write to me personally, I do read the list)
>
>On Fri, Jul 29, 2005 at 04:56:43PM +0530, Srinivas G. wrote:
>> We have developed a Block Device Driver to handle the flash media 
>> devices in Linux 2.6.x kernel. It is working fine. We are able to 
>> mount the SD cards that are formatted on Windows systems, but we 
>> unable mount the cards that are formatted using the DIGITAL CAMERA.
>>
>> We have found one thing that the Windows and Digital Camera both are 
>> formatting the SD cards in FAT12 only. But why we are not able to 
>> mount the SD cards on Linux Box that are formatted using the Digital 
>> Camera.
>
>Probably because the camera and linux disagree about the geometry in 
>CHS (cylinder, head, sector) of the flash device.
>
>Each partition table entry contains the start and end CHS of that 
>partition. However, since a flash device (and also modern hard drives) 
>doesn't have a meaningful geometry value, the same information is also 
>encoded in logical sectors (start and size of the partition).
>
>If the logical information is zero, the kernel falls back onto the CHS 
>information in the partition table and has to assume a certain 
>geometry. If that assumption differs from the assumption of the camera,

>the partition boundaries will be wrong and you will not be able to 
>mount the partition directly. However, you can figure out the start of 
>the partition by hand, and use a loop device to get at the correct 
>offset.
>
>
>Erik
>
>--
>Erik Mouw
>J.A.K.Mouw@its.tudelft.nl  mouw@nl.linux.org

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box
@ 2005-08-09 12:11 Mukund JB.
  0 siblings, 0 replies; 15+ messages in thread
From: Mukund JB. @ 2005-08-09 12:11 UTC (permalink / raw)
  To: Lennart Sorensen, linux-os (Dick Johnson)
  Cc: Srinivas G., linux-kernel-Mailing-list

Dear all,

No, the TI PCI 7x21 provides IDE like interface.
However, that is NOT the point here?

I just want to know what could be the problem in mounting a SD card
Formatted in the camera while it is mounting on windows (same HW).

Regards,
Mukund Jampala

>> Execute linux `fdisk` on the device. You may find that the
>> ID byte is wrong.
>>
>> Also, why do you need a special block device driver? The SanDisk
>> and CompacFlash devices should look like IDE drives.
>
>SD usually is secure digital (MMC compatible somewhat I believe).  It
>does not provide IDE unlike CompactFlash.  SD uses a serial interface
if
>I remember correctly.
>
>Len Sorensen



>-
>To unsubscribe from this list: send the line "unsubscribe linux-kernel"
in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2005-08-09 12:11 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <C349E772C72290419567CFD84C26E017042219@mail.esn.co.in>
2005-08-02 22:18 ` Unable to mount the SD card formatted using the DIGITAL CAMREA on Linux box chuck gelm
2005-08-09 12:11 Mukund JB.
  -- strict thread matches above, loose matches on Subject: below --
2005-08-08  8:56 Mukund JB.
2005-08-05  9:46 Mukund JB.
2005-08-01 11:31 Mukund JB.
2005-08-01 12:08 ` linux-os (Dick Johnson)
2005-08-02 13:42 ` Lennart Sorensen
2005-07-29 17:35 Mukund JB.
2005-07-29 17:43 ` Lennart Sorensen
2005-07-29 18:05 ` linux-os (Dick Johnson)
2005-07-29 18:09   ` linux-os (Dick Johnson)
2005-07-29 11:23 Srinivas G.
2005-07-29 12:02 ` linux-os (Dick Johnson)
2005-07-29 13:37   ` Lennart Sorensen
2005-07-29 13:11 ` Norbert van Nobelen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.