]> git.pld-linux.org Git - packages/kernel.git/commitdiff
- NFS patch fron trond:
authorJan Rękorajski <baggins@pld-linux.org>
Thu, 6 Mar 2003 15:54:45 +0000 (15:54 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
  A patch that papers over a glibc bug. In glibc-2.2 and above, they use
  the new getdents64() syscall even for the 32-bit readdir. As a result, they
  have problems coping with the unsigned 64-bit d_off values that may get
  returned by some NFSv3 servers.
  NOTE: You might still have to set the '32bitclients' export option on
  some IRIX servers.

Changed files:
    linux-2.4.20-irixnfs.patch -> 1.1

linux-2.4.20-irixnfs.patch [new file with mode: 0644]

diff --git a/linux-2.4.20-irixnfs.patch b/linux-2.4.20-irixnfs.patch
new file mode 100644 (file)
index 0000000..81e9397
--- /dev/null
@@ -0,0 +1,110 @@
+diff -urNp linux-1080/fs/nfs/dir.c linux-1090/fs/nfs/dir.c
+--- linux-1080/fs/nfs/dir.c    
++++ linux-1090/fs/nfs/dir.c    
+@@ -34,6 +34,7 @@
+ #define NFS_PARANOIA 1
+ /* #define NFS_DEBUG_VERBOSE 1 */
++static loff_t nfs_dir_llseek(struct file *, loff_t, int);
+ static int nfs_readdir(struct file *, void *, filldir_t);
+ static struct dentry *nfs_lookup(struct inode *, struct dentry *);
+ static int nfs_create(struct inode *, struct dentry *, int);
+@@ -48,6 +49,7 @@ static int nfs_rename(struct inode *, st
+ static int nfs_fsync_dir(struct file *, struct dentry *, int);
+ struct file_operations nfs_dir_operations = {
++      llseek:         nfs_dir_llseek,
+       read:           generic_read_dir,
+       readdir:        nfs_readdir,
+       open:           nfs_open,
+@@ -70,6 +72,25 @@ struct inode_operations nfs_dir_inode_op
+       setattr:        nfs_notify_change,
+ };
++static loff_t nfs_dir_llseek(struct file *file, loff_t offset, int origin)
++{
++      switch (origin) {
++              case 1:
++                      if (offset == 0) {
++                              offset = file->f_pos;
++                              break;
++                      }
++              case 2:
++                      return -EINVAL;
++      }
++      if (offset != file->f_pos) {
++              file->f_pos = offset;
++              file->f_reada = 0;
++              file->f_version = ++event;
++      }
++      return (offset <= 0) ? 0 : offset;
++}
++
+ typedef u32 * (*decode_dirent_t)(u32 *, struct nfs_entry *, int);
+ typedef struct {
+       struct file     *file;
+diff -urNp linux-1080/fs/nfs/nfs2xdr.c linux-1090/fs/nfs/nfs2xdr.c
+--- linux-1080/fs/nfs/nfs2xdr.c        
++++ linux-1090/fs/nfs/nfs2xdr.c        
+@@ -369,7 +369,7 @@ nfs_xdr_readdirargs(struct rpc_rqst *req
+               count = count >> 2;
+       p = xdr_encode_fhandle(p, args->fh);
+-      *p++ = htonl(args->cookie);
++      *p++ = htonl(args->cookie & 0xFFFFFFFF);
+       *p++ = htonl(count); /* see above */
+       req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
+@@ -466,7 +466,7 @@ nfs_decode_dirent(u32 *p, struct nfs_ent
+       entry->name       = (const char *) p;
+       p                += XDR_QUADLEN(entry->len);
+       entry->prev_cookie        = entry->cookie;
+-      entry->cookie     = ntohl(*p++);
++      entry->cookie     = (s64)((off_t)ntohl(*p++));
+       entry->eof        = !p[0] && p[1];
+       return p;
+diff -urNp linux-1080/fs/nfs/nfs3xdr.c linux-1090/fs/nfs/nfs3xdr.c
+--- linux-1080/fs/nfs/nfs3xdr.c        
++++ linux-1090/fs/nfs/nfs3xdr.c        
+@@ -465,6 +465,13 @@ nfs3_xdr_linkargs(struct rpc_rqst *req, 
+       return 0;
+ }
++/* Hack to sign-extending 32-bit cookies */
++static inline
++u64 nfs_transform_cookie64(u64 cookie)
++{
++      return (cookie & 0x80000000) ? (cookie ^ 0xFFFFFFFF00000000) : cookie;
++}
++
+ /*
+  * Encode arguments to readdir call
+  */
+@@ -476,7 +483,7 @@ nfs3_xdr_readdirargs(struct rpc_rqst *re
+       u32 count = args->count;
+       p = xdr_encode_fhandle(p, args->fh);
+-      p = xdr_encode_hyper(p, args->cookie);
++      p = xdr_encode_hyper(p, nfs_transform_cookie64(args->cookie));
+       *p++ = args->verf[0];
+       *p++ = args->verf[1];
+       if (args->plus) {
+@@ -600,6 +607,7 @@ u32 *
+ nfs3_decode_dirent(u32 *p, struct nfs_entry *entry, int plus)
+ {
+       struct nfs_entry old = *entry;
++      u64 cookie;
+       if (!*p++) {
+               if (!*p)
+@@ -613,7 +621,8 @@ nfs3_decode_dirent(u32 *p, struct nfs_en
+       entry->name = (const char *) p;
+       p += XDR_QUADLEN(entry->len);
+       entry->prev_cookie = entry->cookie;
+-      p = xdr_decode_hyper(p, &entry->cookie);
++      p = xdr_decode_hyper(p, &cookie);
++      entry->cookie = nfs_transform_cookie64(cookie);
+       if (plus) {
+               p = xdr_decode_post_op_attr(p, &entry->fattr);
This page took 0.075751 seconds and 4 git commands to generate.