2005-09-20 01:11:29

by Steven Procter

[permalink] [raw]
Subject: Minor problem in nfsv3 write


There is a minor bug in the way writes are handled in nfs3. If the
client requests a write for more than 32k of data the server will only
write 32k but report that it wrote the whole amount.

This happens when nfs3svc_decode_writeargs caps the amount that can be
written to NFSSVC_MAXBLKSIZE (which is 32k), by limiting the amount that
it copies into the args object (fs/nfsd/nfs3xdr.c:375). The amount that
is reported to the client is copied from the request packet, which is
the amount the client requested (fs/nfsd/nfs3proc.c:209) not the amount
which was written.

I think the right thing to do is adjust the amount in the request object
to the amount that will be written in the decoder.

Following is an modified version of nfs3svc_decode_writeargs and diffs
against a 2.6.13 kernel which does this.

--Steven

int
nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
struct nfsd3_writeargs *args)
{
unsigned int len, v, hdr;

if (!(p = decode_fh(p, &args->fh))
|| !(p = xdr_decode_hyper(p, &args->offset)))
return 0;

args->count = ntohl(*p++);
args->stable = ntohl(*p++);
len = args->len = ntohl(*p++);

hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
if (rqstp->rq_arg.len < len + hdr)
return 0;

args->vec[0].iov_base = (void*)p;
args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;

if (len > NFSSVC_MAXBLKSIZE) {
len = NFSSVC_MAXBLKSIZE;
/* adjust count to match the amount that will be written */
args->count = len;
}
v= 0;
while (len > args->vec[v].iov_len) {
len -= args->vec[v].iov_len;
v++;
args->vec[v].iov_base = page_address(rqstp->rq_argpages[v]);
args->vec[v].iov_len = PAGE_SIZE;
}
args->vec[v].iov_len = len;
args->vlen = v+1;

/* args->count may be less than args->len since it is capped */
return args->count <= args->len && args->vec[0].iov_len > 0;
}

*** fs/nfsd/nfs3xdr.c.orig Fri Sep 16 18:02:12 2005
--- fs/nfsd/nfs3xdr.c Mon Sep 19 17:35:22 2005
***************
*** 372,379 ****
args->vec[0].iov_base = (void*)p;
args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;

! if (len > NFSSVC_MAXBLKSIZE)
len = NFSSVC_MAXBLKSIZE;
v= 0;
while (len > args->vec[v].iov_len) {
len -= args->vec[v].iov_len;
--- 372,382 ----
args->vec[0].iov_base = (void*)p;
args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;

! if (len > NFSSVC_MAXBLKSIZE) {
len = NFSSVC_MAXBLKSIZE;
+ /* adjust count to match the amount that will be written */
+ args->count = len;
+ }
v= 0;
while (len > args->vec[v].iov_len) {
len -= args->vec[v].iov_len;
***************
*** 384,390 ****
args->vec[v].iov_len = len;
args->vlen = v+1;

! return args->count == args->len && args->vec[0].iov_len > 0;
}

int
--- 387,394 ----
args->vec[v].iov_len = len;
args->vlen = v+1;

! /* args->count may be less than args->len since it is capped */
! return args->count <= args->len && args->vec[0].iov_len > 0;
}

int


-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server.
Download it for free - -and be entered to win a 42" plasma tv or your very
own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs


2005-09-20 01:25:30

by J. Bruce Fields

[permalink] [raw]
Subject: Re: Minor problem in nfsv3 write

On Mon, Sep 19, 2005 at 06:10:46PM -0700, Steven wrote:
>
> There is a minor bug in the way writes are handled in nfs3. If the
> client requests a write for more than 32k of data the server will only
> write 32k but report that it wrote the whole amount.

Our server also reports 32k as the maximum write size. So the bug is on
the client side here, isn't it?

--b.


-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server.
Download it for free - -and be entered to win a 42" plasma tv or your very
own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2005-09-20 06:34:00

by Sumeet Gupta

[permalink] [raw]
Subject: Re: Minor problem in nfsv3 write

Still the following message is coming in /var/log/messages

Sep 20 13:56:46 rncpet31 nfs: Starting NFS services: succeeded
Sep 20 13:56:46 rncpet31 nfs: rpc.rquotad startup succeeded
Sep 20 13:56:46 rncpet31 nfsd[2256]: nfssvc: No such device
Sep 20 13:56:46 rncpet31 nfs: rpc.nfsd startup failed
Sep 20 13:56:46 rncpet31 nfs: rpc.mountd startup succeeded



steps I followed while upgrading my kernel from 2.4 to 2.6.9

STEP 1:
This has some useful hints on some of the changes needed.
STEP 2:
Download the latest version of module-init-tools

"module-init-tools-3.0.tar.gz" and
"modutils-2.4.21-23.src.rpm"

http://www.kernel.org/pub/linux/kernel/people/rusty/modules/module-init-tools-3.0.tar.gz
http://www.kernel.org/pub/linux/kernel/people/rusty/modules/modutils-2.4.21-23.src.rpm

STEP 3:
Install module-init-tools. This will replace depmod
[/sbin/depmod] and other tools.

tar -zxvf module-init-tools-3.0.tar.gz
cd module-init-tools-3.0
./configure --prefix=/sbin
make
make install
./generate-modprobe.conf /etc/modprobe.conf
STEP 4:
Install modutils-2.4.21-23.src.rpm. You may get warnings
about user rusty and group rusty not existing. Also, yes,
you'll have to force the install. If you don't do these steps
for both Redhat 9 and Redhat 8, you'll have problems with the
make modules_install.

rpm -i modutils-2.4.21-23.src.rpm
rpmbuild -bb /usr/src/redhat/SPECS/modutils.spec
rpm -Fi /usr/src/redhat/RPMS/i386/modutils-2.4.21-23.i386.rpm
STEP 5:
Install and configure the kernel. Do NOT use the /usr/src/linux
area! Reference the README. I put my files in /home/src/kernel/

gunzip linux-2.6.9.tar.gz tar -xvf linux-2.6.3.tar cd
linux-2.6.9
STEP 6:
Copy the appropriate /usr/src/linux-2.4/configs
[kernel-2.4.20-i686.config, kernel-2.4.20-i686-smp.config]
to .config in whatever directory you are installing. In my
case it's /home/src/kernel/linux-2.6.9

cp /usr/src/linux-2.4/configs/kernel-2.4.20-i686.config \
/home/src/kernel/linux-2.6.3/.config

STEP 7:
Assuming you copied the appropriate kernel-2.4 config to
.config, run the following which will run through necessary
questions for the 2.6 kernel. Or, you might want to use the
config2.6-chirico...this has already been run through make
oldconfig on my system, and I've answered the necessary questions
for a general system.
make oldconfig
STEP 8:
This is very important. Make sure you're .config has the
following in it CONFIG_EXT3_FS=y You'll run into the following
error if you leave this =m instead of =y:

pivotroot: pivot_root(/sysroot,/sysroot/initrd) failed

This is because Redhat 9.0 and 8.0 use the ext3 filesystem
for /boot ...

STEP 9:
Edit the Makefile and add changes to the Extraversion as desired.
Patches will update these values as well.

VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 3
EXTRAVERSION = -skim-ch6
STEP 10:
make bzImage
STEP 11:
make modules
STEP 12:
make modules_install
STEP 13:
make install
If you come across errors here, what version of "depmod" is
being picked up in your path?

Also, if you get a module not found, say the following:
No module aic7xxx found for kernel 2.6.x
Then, in /lib/modules/2.6.x/kernel/drivers/scsi/aic7xxx/
cp aic7xxx.ko aic7xxx.o

insmod should look for aic7xxx.ko ;but , it looks for aic7xxx.o

If you still have trouble, make the following change in the
.config

CONFIG_BLK_DEV_SD=y
and go back to STEP 10.

You also may want to ref
kernel-2.6.3-i686-smp-chirico-aic7xxx.config
in
http://prdownloads.sourceforge.net/souptonuts/configs-0.3.tar.gz?download

STEP 14:
mkdir /sys
STEP 15:
/etc/rc.sysinit needs to be modified. Look for the following
line:

action $"Mounting proc filesystem: " mount -n -t proc /proc /proc

and after this line enter the following:

action $"Mounting sysfs filesystem: " mount -t sysfs none /sys

Here's my /etc/rc.sysinit for reference:

http://prdownloads.sourceforge.net/souptonuts/rc.sysinit.txt?download

Be very careful at this step. Backup the /etc/rc.sysinit file.

Thomer [http://thomer.com/linux/migrate-to-2.6.html ] also added
changes to /etc/fstab. I only had to do STEP 16 below.

STEP 16:
Add the following to /etc/fstab for usb support.
/proc/bus/usb /proc/bus/usb usbdevfs defaults 0 0
STEP 17 (CHECKING EVERYTHING):

Check the following:

a. The new image file should be installed on boot and there
should be sym link to it. My latest kernel is 2.6.3-skim-ch6,
and I got the "-skim-ch6" from the values I put in the Makefile,
so I see the following:

/boot
vmlinuz -> vmlinuz-2.6.3-skim-ch6
System.map -> System.map-2.6.3-skim-ch6

/boot/grub/grub.conf Should have been automatically
updated from make.

In /boot/grub/grub.conf change "default=0" to boot
with the new kernel. Here's an example of my
grub.conf:

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to
# root (hd0,2)
# kernel /vmlinuz-version ro root=/dev/hda6
# initrd /initrd-version.img
#boot=/dev/hda
default=0
timeout=10
splashimage=(hd0,2)/grub/splash.xpm.gz
title Red Hat Linux (2.6.3-skim-ch6)
root (hd0,2)
kernel /vmlinuz-2.6.3-skim-ch6 ro root=LABEL=/
initrd /initrd-2.6.3-skim-ch6.img
b. The directory /sys exists

c. You added the mount command for sys in /etc/rc.sysinit

d. CONFIG_EXT3_FS=y was used in the .config

e. Run /sbin/lsmod or cat /proc/modules to make
sure a 2.4 kernel module wasn't forgotten. Also
look at "$cat /proc/iomem"


Did I missed out something ??

do some other rpms also needs to be downloaded ??

the following command show give the results as

[root@rncpet31 root]# rpm -q mount kernel
mount-2.11y-9
kernel-2.4.20-8

what does this means ??? why rpm -q kernel command showing kernel-2.4.20-8 ??


Regards
Sumeet Gupta




Steven <[email protected]>
Sent by: [email protected]
09/20/2005 06:40 AM


To: [email protected]
cc:
Subject: [NFS] Minor problem in nfsv3 write



There is a minor bug in the way writes are handled in nfs3. If the
client requests a write for more than 32k of data the server will only
write 32k but report that it wrote the whole amount.

This happens when nfs3svc_decode_writeargs caps the amount that can be
written to NFSSVC_MAXBLKSIZE (which is 32k), by limiting the amount that
it copies into the args object (fs/nfsd/nfs3xdr.c:375). The amount that
is reported to the client is copied from the request packet, which is
the amount the client requested (fs/nfsd/nfs3proc.c:209) not the amount
which was written.

I think the right thing to do is adjust the amount in the request object
to the amount that will be written in the decoder.

Following is an modified version of nfs3svc_decode_writeargs and diffs
against a 2.6.13 kernel which does this.

--Steven

int
nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
struct nfsd3_writeargs *args)
{
unsigned int len, v, hdr;

if (!(p = decode_fh(p, &args->fh))
|| !(p = xdr_decode_hyper(p, &args->offset)))
return 0;

args->count = ntohl(*p++);
args->stable = ntohl(*p++);
len = args->len = ntohl(*p++);

hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
if (rqstp->rq_arg.len < len + hdr)
return 0;

args->vec[0].iov_base = (void*)p;
args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;

if (len > NFSSVC_MAXBLKSIZE) {
len = NFSSVC_MAXBLKSIZE;
/* adjust count to match the amount that will be written
*/
args->count = len;
}
v= 0;
while (len > args->vec[v].iov_len) {
len -= args->vec[v].iov_len;
v++;
args->vec[v].iov_base =
page_address(rqstp->rq_argpages[v]);
args->vec[v].iov_len = PAGE_SIZE;
}
args->vec[v].iov_len = len;
args->vlen = v+1;

/* args->count may be less than args->len since it is capped */
return args->count <= args->len && args->vec[0].iov_len > 0;
}

*** fs/nfsd/nfs3xdr.c.orig Fri Sep 16 18:02:12 2005
--- fs/nfsd/nfs3xdr.c Mon Sep 19 17:35:22 2005
***************
*** 372,379 ****
args->vec[0].iov_base = (void*)p;
args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len -
hdr;

! if (len > NFSSVC_MAXBLKSIZE)
len = NFSSVC_MAXBLKSIZE;
v= 0;
while (len > args->vec[v].iov_len) {
len -= args->vec[v].iov_len;
--- 372,382 ----
args->vec[0].iov_base = (void*)p;
args->vec[0].iov_len = rqstp->rq_arg.head[0].iov_len -
hdr;

! if (len > NFSSVC_MAXBLKSIZE) {
len = NFSSVC_MAXBLKSIZE;
+ /* adjust count to match the amount that
will be written */
+ args->count = len;
+ }
v= 0;
while (len > args->vec[v].iov_len) {
len -= args->vec[v].iov_len;
***************
*** 384,390 ****
args->vec[v].iov_len = len;
args->vlen = v+1;

! return args->count == args->len && args->vec[0].iov_len >
0;
}

int
--- 387,394 ----
args->vec[v].iov_len = len;
args->vlen = v+1;

! /* args->count may be less than args->len since it is
capped */
! return args->count <= args->len && args->vec[0].iov_len >
0;
}

int


-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server.
Download it for free - -and be entered to win a 42" plasma tv or your very
own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs


2005-09-20 12:32:56

by Peter Staubach

[permalink] [raw]
Subject: Re: Minor problem in nfsv3 write

J. Bruce Fields wrote:

>On Mon, Sep 19, 2005 at 06:10:46PM -0700, Steven wrote:
>
>
>>There is a minor bug in the way writes are handled in nfs3. If the
>>client requests a write for more than 32k of data the server will only
>>write 32k but report that it wrote the whole amount.
>>
>>
>
>Our server also reports 32k as the maximum write size. So the bug is on
>the client side here, isn't it?
>

This would be a bug in the client, but if the server is going to attempt
to write some of the data anyway, then it should correctly report the
number of bytes written. Otherwise, the server should reject the entire
request.

Thanx...

ps


-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server.
Download it for free - -and be entered to win a 42" plasma tv or your very
own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2005-09-20 18:31:47

by Steven Procter

[permalink] [raw]
Subject: Re: Minor problem in nfsv3 write

> This would be a bug in the client, but if the server is going to attempt
> to write some of the data anyway, then it should correctly report the
> number of bytes written. Otherwise, the server should reject the entire
> request.

I agree. I don't think it is a good policy to tell the client that all
of the data was written when some was not.

For what it's worth, the RFC says that if the write size exceeds wtmax
then the server may write only wtmax bytes of the request.

--Steven


-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server.
Download it for free - -and be entered to win a 42" plasma tv or your very
own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs

2005-09-20 19:26:54

by J. Bruce Fields

[permalink] [raw]
Subject: Re: Minor problem in nfsv3 write

On Tue, Sep 20, 2005 at 11:30:54AM -0700, Steven wrote:
> I agree. I don't think it is a good policy to tell the client that all
> of the data was written when some was not.
>
> For what it's worth, the RFC says that if the write size exceeds wtmax
> then the server may write only wtmax bytes of the request.

OK. Could you regenerate that patch with diff -up? (See
Documentation/SubmittingPatches.) Don't bother sending the modified
function, it's the patch that people want.

--b.


-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server.
Download it for free - -and be entered to win a 42" plasma tv or your very
own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs