# This is a BitKeeper generated diff -Nru style patch. # # drivers/scsi/scsi_merge.c # 2004/08/16 15:24:30-03:00 pbadari@us.ibm.com +3 -3 # scsi PHYS_4G merging doesn't work # # ChangeSet # 2004/08/16 14:51:05-03:00 neilb@cse.unsw.edu.au # [PATCH] Use llseek instead of f_pos= for directory seeking. # # nfsd currently just sets f_pos when seeking in a directory. # This bypasses any checking and other handling that a filesystem # might want to do. # # So instead, we use 'llseek' copied out of fs/read_write.c # use that, both to seek at the start, and the find the new position at # the end. # # If it were not too intrusive, would could export llseek as vfs_llseek as was # done in 2.6.... # # Thanks to # "Derrick Schommer" # "Trond Myklebust" # # # Signed-off-by: Neil Brown # # ### Diffstat output # ./fs/nfsd/vfs.c | 35 ++++++++++++++++++++++++++++------- # 1 files changed, 28 insertions(+), 7 deletions(-) # TAG: MailDone # # fs/nfsd/vfs.c # 2004/08/15 20:54:28-03:00 neilb@cse.unsw.edu.au +28 -7 # Use llseek instead of f_pos= for directory seeking. # # ChangeSet # 2004/08/16 14:50:04-03:00 neilb@cse.unsw.edu.au # [PATCH] Fixed possibly xdr parsing error if write size exceed 2^31 # # xdr_argsize_check needs to cope with the possibility that the # pointer has wrapped and could be below buf->base. # # Signed-off-by: Neil Brown # # ### Diffstat output # ./fs/nfsd/nfs3xdr.c | 2 +- # ./include/linux/nfsd/xdr3.h | 2 +- # 2 files changed, 2 insertions(+), 2 deletions(-) # # include/linux/nfsd/xdr3.h # 2004/08/15 20:48:43-03:00 neilb@cse.unsw.edu.au +1 -1 # Fixed possibly xdr parsing error if write size exceed 2^31 # # fs/nfsd/nfs3xdr.c # 2004/08/14 00:23:06-03:00 neilb@cse.unsw.edu.au +1 -1 # Fixed possibly xdr parsing error if write size exceed 2^31 # # ChangeSet # 2004/08/16 14:47:13-03:00 neilb@cse.unsw.edu.au # [PATCH] Allow larger NFSd MAXBLKSIZE on architectures with larger PAGE_SIZE # # This patch makes NFSSVC_MAXBLKSIZE depend on PAGE_SIZE so that machines # with large page sizes can take advantage of that feature to serve NFS # with larger blocksizes, increasing performance and avoiding a fallback # to synchronous traffic between machines with page sizes greater than 8K. # Also, documents the actual constraints on NFSSVC_MAXBLKSIZE. # # From: Greg Banks # Signed-off-by: Neil Brown # # ### Diffstat output # ./include/linux/nfsd/const.h | 12 ++++++++++-- # 1 files changed, 10 insertions(+), 2 deletions(-) # # include/linux/nfsd/const.h # 2004/08/15 20:53:48-03:00 neilb@cse.unsw.edu.au +10 -2 # Allow larger NFSd MAXBLKSIZE on architectures with larger PAGE_SIZE # # ChangeSet # 2004/08/16 14:45:44-03:00 pbadari@us.ibm.com # [PATCH] scsi PHYS_4G merging doesn't work # # We recently found that, BH_PHYS_4G() handling in scsi-merge # code is broken. Instead of creating new segment when the IO # crosses 4G boundary, its forcing to create a new request. # So we end up not merging IOs and start doing small IOs. # # Only requirement is, driver can't handle crossing 4G boundary # in a single segment - but we can have multiple segments doing # IOs all over the place. # # Here is the patch to fix it (suggested by Jens Axboe). # # ChangeSet # 2004/08/15 21:30:53-03:00 linville@tuxdriver.com # [PATCH] Add IOI Media Bay to SCSI quirk list # TAG: MailDone # # drivers/scsi/scsi_scan.c # 2004/08/12 19:33:36-03:00 linville@tuxdriver.com +1 -0 # 2.4 -- add IOI Media Bay to SCSI quirk list # diff -Nru a/drivers/scsi/scsi_merge.c b/drivers/scsi/scsi_merge.c --- a/drivers/scsi/scsi_merge.c 2004-08-16 13:02:01 -07:00 +++ b/drivers/scsi/scsi_merge.c 2004-08-16 13:02:01 -07:00 @@ -418,7 +418,7 @@ return 0; if (!BH_PHYS_4G(req->bhtail, bh)) - return 0; + goto new_end_segment; if (use_clustering) { /* @@ -477,7 +477,7 @@ return 0; if (!BH_PHYS_4G(bh, req->bh)) - return 0; + goto new_start_segment; if (use_clustering) { /* @@ -640,7 +640,7 @@ return 0; if (!BH_PHYS_4G(req->bhtail, next->bh)) - return 0; + goto dont_combine; /* * The main question is whether the two segments at the boundaries diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c --- a/drivers/scsi/scsi_scan.c 2004-08-16 13:02:01 -07:00 +++ b/drivers/scsi/scsi_scan.c 2004-08-16 13:02:01 -07:00 @@ -190,6 +190,7 @@ {"HITACHI", "DF500", "*", BLIST_SPARSELUN}, {"HITACHI", "DF600", "*", BLIST_SPARSELUN}, {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"IOI", "Media Bay", "*", BLIST_FORCELUN}, {"HITACHI", "OPEN-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, /* HITACHI XP Arrays */ {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, /* HITACHI 9960 */ {"WINSYS","FLASHDISK G6", "*", BLIST_SPARSELUN}, diff -Nru a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c --- a/fs/nfsd/nfs3xdr.c 2004-08-16 13:02:01 -07:00 +++ b/fs/nfsd/nfs3xdr.c 2004-08-16 13:02:01 -07:00 @@ -273,7 +273,7 @@ { struct svc_buf *buf = &rqstp->rq_argbuf; - return p - buf->base <= buf->buflen; + return p >= buf->base && p <= buf->base + buf->buflen ; } static inline int diff -Nru a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c --- a/fs/nfsd/vfs.c 2004-08-16 13:02:01 -07:00 +++ b/fs/nfsd/vfs.c 2004-08-16 13:02:01 -07:00 @@ -586,6 +586,22 @@ return ra; } +/* copied from fs/read_write.c */ +static inline loff_t llseek(struct file *file, loff_t offset, int origin) +{ + loff_t (*fn)(struct file *, loff_t, int); + loff_t retval; + + fn = default_llseek; + if (file->f_op && file->f_op->llseek) + fn = file->f_op->llseek; + lock_kernel(); + retval = fn(file, offset, origin); + unlock_kernel(); + return retval; +} + + /* * Read data from a file. count must contain the requested read count * on entry. On return, *count contains the number of bytes actually read. @@ -621,7 +637,7 @@ file.f_ralen = ra->p_ralen; file.f_rawin = ra->p_rawin; } - file.f_pos = offset; + llseek(&file, offset, 0); oldfs = get_fs(); set_fs(KERNEL_DS); err = file.f_op->read(&file, buf, *count, &file.f_pos); @@ -706,7 +722,8 @@ if (stable && !EX_WGATHER(exp)) file.f_flags |= O_SYNC; - file.f_pos = offset; /* set write offset */ + + llseek(&file, offset, 0); /* Write the data. */ oldfs = get_fs(); set_fs(KERNEL_DS); @@ -1398,10 +1415,12 @@ err = nfsd_open(rqstp, fhp, S_IFDIR, MAY_READ, &file); if (err) goto out; - if (offset > ~(u32) 0) - goto out_close; - file.f_pos = offset; + offset = llseek(&file, offset, 0); + if (offset < 0) { + err = nfserrno((int)offset); + goto out_close; + } /* Set up the readdir context */ memset(&cd, 0, sizeof(cd)); @@ -1429,11 +1448,13 @@ /* If we didn't fill the buffer completely, we're at EOF */ eof = !cd.eob; + + offset = llseek(&file, 0LL, 1); if (cd.offset) { if (rqstp->rq_vers == 3) - (void)xdr_encode_hyper(cd.offset, file.f_pos); + (void)xdr_encode_hyper(cd.offset, offset); else - *cd.offset = htonl(file.f_pos); + *cd.offset = htonl(offset); } p = cd.buffer; diff -Nru a/include/linux/nfsd/const.h b/include/linux/nfsd/const.h --- a/include/linux/nfsd/const.h 2004-08-16 13:02:01 -07:00 +++ b/include/linux/nfsd/const.h 2004-08-16 13:02:01 -07:00 @@ -12,6 +12,7 @@ #include #include #include +#include /* * Maximum protocol version supported by knfsd @@ -19,9 +20,16 @@ #define NFSSVC_MAXVERS 3 /* - * Maximum blocksize supported by daemon currently at 8K + * Maximum blocksize supported by daemon. We want the largest + * value which 1) fits in a UDP datagram less some headers + * 2) is a multiple of page size 3) can be successfully kmalloc()ed + * by each nfsd. */ -#define NFSSVC_MAXBLKSIZE (8*1024) +#if PAGE_SIZE > (16*1024) +#define NFSSVC_MAXBLKSIZE (32*1024) +#else +#define NFSSVC_MAXBLKSIZE (2*PAGE_SIZE) +#endif #ifdef __KERNEL__ diff -Nru a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h --- a/include/linux/nfsd/xdr3.h 2004-08-16 13:02:01 -07:00 +++ b/include/linux/nfsd/xdr3.h 2004-08-16 13:02:01 -07:00 @@ -41,7 +41,7 @@ __u32 count; int stable; __u8 * data; - int len; + __u32 len; }; struct nfsd3_createargs {