write(2) to /dev/ad4 = EINVAL

Lukasz Jaroszewski lvj at nietykalni.org
Mon Jan 26 05:04:29 PST 2009


2009/1/26 Christoph Mallon <christoph.mallon at gmx.de>:
> Lukasz Jaroszewski schrieb:
>>
>> 2009/1/26 Hans Petter Selasky <hselasky at c2i.net>:
>>>
>>> On Monday 26 January 2009, Lukasz Jaroszewski wrote:
>>>>
>>>> Hi,
>>>> after opening /dev/ad4 with success for O_RDWR, I am getting [EINVAL]
>>>> from write(2), which according to man 2 write, means
>>>>  ``     [EINVAL]           The pointer associated with d was
>>>> negative.'', as you can see below it is not true, I have tried
>>>> different block sizes, with same result.
>>>>
>>>> How can I write one byte to /dev/adN ?
>>>
>>> Hi,
>>>
>>> You cannot write one byte to /dev/adN, I think. Harddisks are block
>>> based.
>>> Please see:
>>>
>>> diskinfo -v ad4
>>>
>>> And especially the "sector size". When you seek and transfer data the
>>> offset
>>> and length must be a factor of the "sector size" or "block size". See
>>> also
>>> LBA, logical block address.
>>
>>
>> Yes, I have tried with bs=512 and multiplies, no luck.
>>
>> root@~(0)   diskinfo -v ad4
>> ad4
>>        512             # sectorsize
>>        2029805568      # mediasize in bytes (1.9G)
>>        3964464         # mediasize in sectors
>>        3933            # Cylinders according to firmware.
>>        16              # Heads according to firmware.
>>        63              # Sectors according to firmware.
>>        ad:CFx20CARDx200000190C # Disk ident.
>
> It would be helpful, if you showed the actual code, instead of letting us
> guess what you are doing.

Ok, I solved that, I were trying to dd with bs correctly set, tho
if=./s wasn't big enough plus I had code like below, where I didn't
check write for errors, just called perror, which gave me wrong errno.

So to change one byte, I need to read it, change it, and write it in
512 chunks? or play with kernel and add smth like ``write_byte'' to
ata?

I am sorry for bothering with my silly errors.


<includes>
#define S  0x200

int
main(int argc, char **argv){
  int fd,i=0;
  char *s;
  s = malloc(S);
  for(i=0;i<S;i++)
    s[i] = 'B';
  if((fd = open("/dev/ad4",
O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH))==-1)
    perror("open(2)");
  lseek(fd, 0, SEEK_SET);
  write(fd, s,S);
  perror("write");
  close(fd);
  return 0;
}

Best Regards
Lukasz
>


More information about the freebsd-hackers mailing list