]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/nfsd/vfs.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild...
[linux-2.6-omap-h63xx.git] / fs / nfsd / vfs.c
index 93b22f661d9da05c658cf064d1e12ea8cfb38785..4433c8f001635862419edb603ecf5725462f3222 100644 (file)
@@ -410,6 +410,7 @@ out_nfserr:
 static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf)
 {
        ssize_t buflen;
+       ssize_t ret;
 
        buflen = vfs_getxattr(dentry, key, NULL, 0);
        if (buflen <= 0)
@@ -419,7 +420,10 @@ static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf)
        if (!*buf)
                return -ENOMEM;
 
-       return vfs_getxattr(dentry, key, *buf, buflen);
+       ret = vfs_getxattr(dentry, key, *buf, buflen);
+       if (ret < 0)
+               kfree(*buf);
+       return ret;
 }
 #endif
 
@@ -1831,6 +1835,7 @@ struct buffered_dirent {
 struct readdir_data {
        char            *dirent;
        size_t          used;
+       int             full;
 };
 
 static int nfsd_buffered_filldir(void *__buf, const char *name, int namlen,
@@ -1841,8 +1846,10 @@ static int nfsd_buffered_filldir(void *__buf, const char *name, int namlen,
        unsigned int reclen;
 
        reclen = ALIGN(sizeof(struct buffered_dirent) + namlen, sizeof(u64));
-       if (buf->used + reclen > PAGE_SIZE)
+       if (buf->used + reclen > PAGE_SIZE) {
+               buf->full = 1;
                return -EINVAL;
+       }
 
        de->namlen = namlen;
        de->offset = offset;
@@ -1868,15 +1875,19 @@ static int nfsd_buffered_readdir(struct file *file, filldir_t func,
                return -ENOMEM;
 
        offset = *offsetp;
-       cdp->err = nfserr_eof; /* will be cleared on successful read */
 
        while (1) {
                unsigned int reclen;
 
+               cdp->err = nfserr_eof; /* will be cleared on successful read */
                buf.used = 0;
+               buf.full = 0;
 
                host_err = vfs_readdir(file, nfsd_buffered_filldir, &buf);
-               if (host_err)
+               if (buf.full)
+                       host_err = 0;
+
+               if (host_err < 0)
                        break;
 
                size = buf.used;
@@ -1884,7 +1895,6 @@ static int nfsd_buffered_readdir(struct file *file, filldir_t func,
                if (!size)
                        break;
 
-
                de = (struct buffered_dirent *)buf.dirent;
                while (size > 0) {
                        offset = de->offset;
@@ -1901,7 +1911,7 @@ static int nfsd_buffered_readdir(struct file *file, filldir_t func,
                        size -= reclen;
                        de = (struct buffered_dirent *)((char *)de + reclen);
                }
-               offset = vfs_llseek(file, 0, 1);
+               offset = vfs_llseek(file, 0, SEEK_CUR);
        }
 
  done: