diff options
| -rw-r--r-- | arch/alpha/kernel/osf_sys.c | 19 | ||||
| -rw-r--r-- | arch/parisc/hpux/fs.c | 30 | ||||
| -rw-r--r-- | fs/9p/vfs_dir.c | 1 | ||||
| -rw-r--r-- | fs/adfs/dir.c | 1 | ||||
| -rw-r--r-- | fs/affs/dir.c | 1 | ||||
| -rw-r--r-- | fs/autofs4/root.c | 2 | ||||
| -rw-r--r-- | fs/befs/linuxvfs.c | 1 | ||||
| -rw-r--r-- | fs/compat.c | 8 | ||||
| -rw-r--r-- | fs/dcache.c | 2 | ||||
| -rw-r--r-- | fs/efs/namei.c | 3 | ||||
| -rw-r--r-- | fs/ntfs/namei.c | 89 | ||||
| -rw-r--r-- | fs/proc/generic.c | 1 | ||||
| -rw-r--r-- | fs/readdir.c | 8 | ||||
| -rw-r--r-- | fs/seq_file.c | 11 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 1 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 2 | ||||
| -rw-r--r-- | include/linux/dcache.h | 2 |
17 files changed, 66 insertions, 116 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 6e943135f0e0..8509dad31204 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
| @@ -121,24 +121,29 @@ osf_filldir(void *__buf, const char *name, int namlen, loff_t offset, | |||
| 121 | if (reclen > buf->count) | 121 | if (reclen > buf->count) |
| 122 | return -EINVAL; | 122 | return -EINVAL; |
| 123 | d_ino = ino; | 123 | d_ino = ino; |
| 124 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | 124 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { |
| 125 | buf->error = -EOVERFLOW; | ||
| 125 | return -EOVERFLOW; | 126 | return -EOVERFLOW; |
| 127 | } | ||
| 126 | if (buf->basep) { | 128 | if (buf->basep) { |
| 127 | if (put_user(offset, buf->basep)) | 129 | if (put_user(offset, buf->basep)) |
| 128 | return -EFAULT; | 130 | goto Efault; |
| 129 | buf->basep = NULL; | 131 | buf->basep = NULL; |
| 130 | } | 132 | } |
| 131 | dirent = buf->dirent; | 133 | dirent = buf->dirent; |
| 132 | put_user(d_ino, &dirent->d_ino); | 134 | if (put_user(d_ino, &dirent->d_ino) || |
| 133 | put_user(namlen, &dirent->d_namlen); | 135 | put_user(namlen, &dirent->d_namlen) || |
| 134 | put_user(reclen, &dirent->d_reclen); | 136 | put_user(reclen, &dirent->d_reclen) || |
| 135 | if (copy_to_user(dirent->d_name, name, namlen) || | 137 | copy_to_user(dirent->d_name, name, namlen) || |
| 136 | put_user(0, dirent->d_name + namlen)) | 138 | put_user(0, dirent->d_name + namlen)) |
| 137 | return -EFAULT; | 139 | goto Efault; |
| 138 | dirent = (void __user *)dirent + reclen; | 140 | dirent = (void __user *)dirent + reclen; |
| 139 | buf->dirent = dirent; | 141 | buf->dirent = dirent; |
| 140 | buf->count -= reclen; | 142 | buf->count -= reclen; |
| 141 | return 0; | 143 | return 0; |
| 144 | Efault: | ||
| 145 | buf->error = -EFAULT; | ||
| 146 | return -EFAULT; | ||
| 142 | } | 147 | } |
| 143 | 148 | ||
| 144 | asmlinkage int | 149 | asmlinkage int |
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c index 1263f00dc35d..69ff671498e5 100644 --- a/arch/parisc/hpux/fs.c +++ b/arch/parisc/hpux/fs.c | |||
| @@ -84,22 +84,28 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset, | |||
| 84 | if (reclen > buf->count) | 84 | if (reclen > buf->count) |
| 85 | return -EINVAL; | 85 | return -EINVAL; |
| 86 | d_ino = ino; | 86 | d_ino = ino; |
| 87 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | 87 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { |
| 88 | buf->error = -EOVERFLOW; | ||
| 88 | return -EOVERFLOW; | 89 | return -EOVERFLOW; |
| 90 | } | ||
| 89 | dirent = buf->previous; | 91 | dirent = buf->previous; |
| 90 | if (dirent) | 92 | if (dirent) |
| 91 | put_user(offset, &dirent->d_off); | 93 | if (put_user(offset, &dirent->d_off)) |
| 94 | goto Efault; | ||
| 92 | dirent = buf->current_dir; | 95 | dirent = buf->current_dir; |
| 96 | if (put_user(d_ino, &dirent->d_ino) || | ||
| 97 | put_user(reclen, &dirent->d_reclen) || | ||
| 98 | put_user(namlen, &dirent->d_namlen) || | ||
| 99 | copy_to_user(dirent->d_name, name, namlen) || | ||
| 100 | put_user(0, dirent->d_name + namlen)) | ||
| 101 | goto Efault; | ||
| 93 | buf->previous = dirent; | 102 | buf->previous = dirent; |
| 94 | put_user(d_ino, &dirent->d_ino); | 103 | buf->current_dir = (void __user *)dirent + reclen; |
| 95 | put_user(reclen, &dirent->d_reclen); | ||
| 96 | put_user(namlen, &dirent->d_namlen); | ||
| 97 | copy_to_user(dirent->d_name, name, namlen); | ||
| 98 | put_user(0, dirent->d_name + namlen); | ||
| 99 | dirent = (void __user *)dirent + reclen; | ||
| 100 | buf->current_dir = dirent; | ||
| 101 | buf->count -= reclen; | 104 | buf->count -= reclen; |
| 102 | return 0; | 105 | return 0; |
| 106 | Efault: | ||
| 107 | buffer->error = -EFAULT; | ||
| 108 | return -EFAULT; | ||
| 103 | } | 109 | } |
| 104 | 110 | ||
| 105 | #undef NAME_OFFSET | 111 | #undef NAME_OFFSET |
| @@ -126,8 +132,10 @@ int hpux_getdents(unsigned int fd, struct hpux_dirent __user *dirent, unsigned i | |||
| 126 | error = buf.error; | 132 | error = buf.error; |
| 127 | lastdirent = buf.previous; | 133 | lastdirent = buf.previous; |
| 128 | if (lastdirent) { | 134 | if (lastdirent) { |
| 129 | put_user(file->f_pos, &lastdirent->d_off); | 135 | if (put_user(file->f_pos, &lastdirent->d_off)) |
| 130 | error = count - buf.count; | 136 | error = -EFAULT; |
| 137 | else | ||
| 138 | error = count - buf.count; | ||
| 131 | } | 139 | } |
| 132 | 140 | ||
| 133 | out_putf: | 141 | out_putf: |
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 88e3787c6ea9..e298fe194093 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
| @@ -119,6 +119,7 @@ int v9fs_dir_release(struct inode *inode, struct file *filp) | |||
| 119 | 119 | ||
| 120 | const struct file_operations v9fs_dir_operations = { | 120 | const struct file_operations v9fs_dir_operations = { |
| 121 | .read = generic_read_dir, | 121 | .read = generic_read_dir, |
| 122 | .llseek = generic_file_llseek, | ||
| 122 | .readdir = v9fs_dir_readdir, | 123 | .readdir = v9fs_dir_readdir, |
| 123 | .open = v9fs_file_open, | 124 | .open = v9fs_file_open, |
| 124 | .release = v9fs_dir_release, | 125 | .release = v9fs_dir_release, |
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c index fc1a8dc64d78..85a30e929800 100644 --- a/fs/adfs/dir.c +++ b/fs/adfs/dir.c | |||
| @@ -197,6 +197,7 @@ out: | |||
| 197 | 197 | ||
| 198 | const struct file_operations adfs_dir_operations = { | 198 | const struct file_operations adfs_dir_operations = { |
| 199 | .read = generic_read_dir, | 199 | .read = generic_read_dir, |
| 200 | .llseek = generic_file_llseek, | ||
| 200 | .readdir = adfs_readdir, | 201 | .readdir = adfs_readdir, |
| 201 | .fsync = file_fsync, | 202 | .fsync = file_fsync, |
| 202 | }; | 203 | }; |
diff --git a/fs/affs/dir.c b/fs/affs/dir.c index 6e3f282424b0..7b36904dbeac 100644 --- a/fs/affs/dir.c +++ b/fs/affs/dir.c | |||
| @@ -19,6 +19,7 @@ static int affs_readdir(struct file *, void *, filldir_t); | |||
| 19 | 19 | ||
| 20 | const struct file_operations affs_dir_operations = { | 20 | const struct file_operations affs_dir_operations = { |
| 21 | .read = generic_read_dir, | 21 | .read = generic_read_dir, |
| 22 | .llseek = generic_file_llseek, | ||
| 22 | .readdir = affs_readdir, | 23 | .readdir = affs_readdir, |
| 23 | .fsync = file_fsync, | 24 | .fsync = file_fsync, |
| 24 | }; | 25 | }; |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index bcfb2dc0a61b..2a41c2a7fc52 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
| @@ -36,6 +36,7 @@ const struct file_operations autofs4_root_operations = { | |||
| 36 | .release = dcache_dir_close, | 36 | .release = dcache_dir_close, |
| 37 | .read = generic_read_dir, | 37 | .read = generic_read_dir, |
| 38 | .readdir = dcache_readdir, | 38 | .readdir = dcache_readdir, |
| 39 | .llseek = dcache_dir_lseek, | ||
| 39 | .ioctl = autofs4_root_ioctl, | 40 | .ioctl = autofs4_root_ioctl, |
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| @@ -44,6 +45,7 @@ const struct file_operations autofs4_dir_operations = { | |||
| 44 | .release = dcache_dir_close, | 45 | .release = dcache_dir_close, |
| 45 | .read = generic_read_dir, | 46 | .read = generic_read_dir, |
| 46 | .readdir = dcache_readdir, | 47 | .readdir = dcache_readdir, |
| 48 | .llseek = dcache_dir_lseek, | ||
| 47 | }; | 49 | }; |
| 48 | 50 | ||
| 49 | const struct inode_operations autofs4_indirect_root_inode_operations = { | 51 | const struct inode_operations autofs4_indirect_root_inode_operations = { |
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 02c6e62b72f8..740f53672a8a 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
| @@ -66,6 +66,7 @@ static struct kmem_cache *befs_inode_cachep; | |||
| 66 | static const struct file_operations befs_dir_operations = { | 66 | static const struct file_operations befs_dir_operations = { |
| 67 | .read = generic_read_dir, | 67 | .read = generic_read_dir, |
| 68 | .readdir = befs_readdir, | 68 | .readdir = befs_readdir, |
| 69 | .llseek = generic_file_llseek, | ||
| 69 | }; | 70 | }; |
| 70 | 71 | ||
| 71 | static const struct inode_operations befs_dir_inode_operations = { | 72 | static const struct inode_operations befs_dir_inode_operations = { |
diff --git a/fs/compat.c b/fs/compat.c index c9d1472e65c5..075d0509970d 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
| @@ -792,8 +792,10 @@ static int compat_fillonedir(void *__buf, const char *name, int namlen, | |||
| 792 | if (buf->result) | 792 | if (buf->result) |
| 793 | return -EINVAL; | 793 | return -EINVAL; |
| 794 | d_ino = ino; | 794 | d_ino = ino; |
| 795 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | 795 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { |
| 796 | buf->result = -EOVERFLOW; | ||
| 796 | return -EOVERFLOW; | 797 | return -EOVERFLOW; |
| 798 | } | ||
| 797 | buf->result++; | 799 | buf->result++; |
| 798 | dirent = buf->dirent; | 800 | dirent = buf->dirent; |
| 799 | if (!access_ok(VERIFY_WRITE, dirent, | 801 | if (!access_ok(VERIFY_WRITE, dirent, |
| @@ -862,8 +864,10 @@ static int compat_filldir(void *__buf, const char *name, int namlen, | |||
| 862 | if (reclen > buf->count) | 864 | if (reclen > buf->count) |
| 863 | return -EINVAL; | 865 | return -EINVAL; |
| 864 | d_ino = ino; | 866 | d_ino = ino; |
| 865 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | 867 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { |
| 868 | buf->error = -EOVERFLOW; | ||
| 866 | return -EOVERFLOW; | 869 | return -EOVERFLOW; |
| 870 | } | ||
| 867 | dirent = buf->previous; | 871 | dirent = buf->previous; |
| 868 | if (dirent) { | 872 | if (dirent) { |
| 869 | if (__put_user(offset, &dirent->d_off)) | 873 | if (__put_user(offset, &dirent->d_off)) |
diff --git a/fs/dcache.c b/fs/dcache.c index 101663d15e9f..80e93956aced 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
| @@ -1236,7 +1236,7 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) | |||
| 1236 | * If no entry exists with the exact case name, allocate new dentry with | 1236 | * If no entry exists with the exact case name, allocate new dentry with |
| 1237 | * the exact case, and return the spliced entry. | 1237 | * the exact case, and return the spliced entry. |
| 1238 | */ | 1238 | */ |
| 1239 | struct dentry *d_add_ci(struct inode *inode, struct dentry *dentry, | 1239 | struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, |
| 1240 | struct qstr *name) | 1240 | struct qstr *name) |
| 1241 | { | 1241 | { |
| 1242 | int error; | 1242 | int error; |
diff --git a/fs/efs/namei.c b/fs/efs/namei.c index 3a404e7fad53..291abb11e20e 100644 --- a/fs/efs/namei.c +++ b/fs/efs/namei.c | |||
| @@ -74,8 +74,7 @@ struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct namei | |||
| 74 | } | 74 | } |
| 75 | unlock_kernel(); | 75 | unlock_kernel(); |
| 76 | 76 | ||
| 77 | d_add(dentry, inode); | 77 | return d_splice_alias(inode, dentry); |
| 78 | return NULL; | ||
| 79 | } | 78 | } |
| 80 | 79 | ||
| 81 | static struct inode *efs_nfs_get_inode(struct super_block *sb, u64 ino, | 80 | static struct inode *efs_nfs_get_inode(struct super_block *sb, u64 ino, |
diff --git a/fs/ntfs/namei.c b/fs/ntfs/namei.c index e1781c8b1650..9e8a95be7a1e 100644 --- a/fs/ntfs/namei.c +++ b/fs/ntfs/namei.c | |||
| @@ -174,7 +174,6 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent, | |||
| 174 | // TODO: Consider moving this lot to a separate function! (AIA) | 174 | // TODO: Consider moving this lot to a separate function! (AIA) |
| 175 | handle_name: | 175 | handle_name: |
| 176 | { | 176 | { |
| 177 | struct dentry *real_dent, *new_dent; | ||
| 178 | MFT_RECORD *m; | 177 | MFT_RECORD *m; |
| 179 | ntfs_attr_search_ctx *ctx; | 178 | ntfs_attr_search_ctx *ctx; |
| 180 | ntfs_inode *ni = NTFS_I(dent_inode); | 179 | ntfs_inode *ni = NTFS_I(dent_inode); |
| @@ -255,93 +254,9 @@ handle_name: | |||
| 255 | } | 254 | } |
| 256 | nls_name.hash = full_name_hash(nls_name.name, nls_name.len); | 255 | nls_name.hash = full_name_hash(nls_name.name, nls_name.len); |
| 257 | 256 | ||
| 258 | /* | 257 | dent = d_add_ci(dent, dent_inode, &nls_name); |
| 259 | * Note: No need for dent->d_lock lock as i_mutex is held on the | ||
| 260 | * parent inode. | ||
| 261 | */ | ||
| 262 | |||
| 263 | /* Does a dentry matching the nls_name exist already? */ | ||
| 264 | real_dent = d_lookup(dent->d_parent, &nls_name); | ||
| 265 | /* If not, create it now. */ | ||
| 266 | if (!real_dent) { | ||
| 267 | real_dent = d_alloc(dent->d_parent, &nls_name); | ||
| 268 | kfree(nls_name.name); | ||
| 269 | if (!real_dent) { | ||
| 270 | err = -ENOMEM; | ||
| 271 | goto err_out; | ||
| 272 | } | ||
| 273 | new_dent = d_splice_alias(dent_inode, real_dent); | ||
| 274 | if (new_dent) | ||
| 275 | dput(real_dent); | ||
| 276 | else | ||
| 277 | new_dent = real_dent; | ||
| 278 | ntfs_debug("Done. (Created new dentry.)"); | ||
| 279 | return new_dent; | ||
| 280 | } | ||
| 281 | kfree(nls_name.name); | 258 | kfree(nls_name.name); |
| 282 | /* Matching dentry exists, check if it is negative. */ | 259 | return dent; |
| 283 | if (real_dent->d_inode) { | ||
| 284 | if (unlikely(real_dent->d_inode != dent_inode)) { | ||
| 285 | /* This can happen because bad inodes are unhashed. */ | ||
| 286 | BUG_ON(!is_bad_inode(dent_inode)); | ||
| 287 | BUG_ON(!is_bad_inode(real_dent->d_inode)); | ||
| 288 | } | ||
| 289 | /* | ||
| 290 | * Already have the inode and the dentry attached, decrement | ||
| 291 | * the reference count to balance the ntfs_iget() we did | ||
| 292 | * earlier on. We found the dentry using d_lookup() so it | ||
| 293 | * cannot be disconnected and thus we do not need to worry | ||
| 294 | * about any NFS/disconnectedness issues here. | ||
| 295 | */ | ||
| 296 | iput(dent_inode); | ||
| 297 | ntfs_debug("Done. (Already had inode and dentry.)"); | ||
| 298 | return real_dent; | ||
| 299 | } | ||
| 300 | /* | ||
| 301 | * Negative dentry: instantiate it unless the inode is a directory and | ||
| 302 | * has a 'disconnected' dentry (i.e. IS_ROOT and DCACHE_DISCONNECTED), | ||
| 303 | * in which case d_move() that in place of the found dentry. | ||
| 304 | */ | ||
| 305 | if (!S_ISDIR(dent_inode->i_mode)) { | ||
| 306 | /* Not a directory; everything is easy. */ | ||
| 307 | d_instantiate(real_dent, dent_inode); | ||
| 308 | ntfs_debug("Done. (Already had negative file dentry.)"); | ||
| 309 | return real_dent; | ||
| 310 | } | ||
| 311 | spin_lock(&dcache_lock); | ||
| 312 | if (list_empty(&dent_inode->i_dentry)) { | ||
| 313 | /* | ||
| 314 | * Directory without a 'disconnected' dentry; we need to do | ||
| 315 | * d_instantiate() by hand because it takes dcache_lock which | ||
| 316 | * we already hold. | ||
| 317 | */ | ||
| 318 | list_add(&real_dent->d_alias, &dent_inode->i_dentry); | ||
| 319 | real_dent->d_inode = dent_inode; | ||
| 320 | spin_unlock(&dcache_lock); | ||
| 321 | security_d_instantiate(real_dent, dent_inode); | ||
| 322 | ntfs_debug("Done. (Already had negative directory dentry.)"); | ||
| 323 | return real_dent; | ||
| 324 | } | ||
| 325 | /* | ||
| 326 | * Directory with a 'disconnected' dentry; get a reference to the | ||
| 327 | * 'disconnected' dentry. | ||
| 328 | */ | ||
| 329 | new_dent = list_entry(dent_inode->i_dentry.next, struct dentry, | ||
| 330 | d_alias); | ||
| 331 | dget_locked(new_dent); | ||
| 332 | spin_unlock(&dcache_lock); | ||
| 333 | /* Do security vodoo. */ | ||
| 334 | security_d_instantiate(real_dent, dent_inode); | ||
| 335 | /* Move new_dent in place of real_dent. */ | ||
| 336 | d_move(new_dent, real_dent); | ||
| 337 | /* Balance the ntfs_iget() we did above. */ | ||
| 338 | iput(dent_inode); | ||
| 339 | /* Throw away real_dent. */ | ||
| 340 | dput(real_dent); | ||
| 341 | /* Use new_dent as the actual dentry. */ | ||
| 342 | ntfs_debug("Done. (Already had negative, disconnected directory " | ||
| 343 | "dentry.)"); | ||
| 344 | return new_dent; | ||
| 345 | 260 | ||
| 346 | eio_err_out: | 261 | eio_err_out: |
| 347 | ntfs_error(vol->sb, "Illegal file name attribute. Run chkdsk."); | 262 | ntfs_error(vol->sb, "Illegal file name attribute. Run chkdsk."); |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 4fb81e9c94e3..bca0f81eb687 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
| @@ -330,6 +330,7 @@ retry: | |||
| 330 | spin_lock(&proc_inum_lock); | 330 | spin_lock(&proc_inum_lock); |
| 331 | ida_remove(&proc_inum_ida, i); | 331 | ida_remove(&proc_inum_ida, i); |
| 332 | spin_unlock(&proc_inum_lock); | 332 | spin_unlock(&proc_inum_lock); |
| 333 | return 0; | ||
| 333 | } | 334 | } |
| 334 | return PROC_DYNAMIC_FIRST + i; | 335 | return PROC_DYNAMIC_FIRST + i; |
| 335 | } | 336 | } |
diff --git a/fs/readdir.c b/fs/readdir.c index 4e026e5407fb..93a7559bbfd8 100644 --- a/fs/readdir.c +++ b/fs/readdir.c | |||
| @@ -80,8 +80,10 @@ static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset | |||
| 80 | if (buf->result) | 80 | if (buf->result) |
| 81 | return -EINVAL; | 81 | return -EINVAL; |
| 82 | d_ino = ino; | 82 | d_ino = ino; |
| 83 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | 83 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { |
| 84 | buf->result = -EOVERFLOW; | ||
| 84 | return -EOVERFLOW; | 85 | return -EOVERFLOW; |
| 86 | } | ||
| 85 | buf->result++; | 87 | buf->result++; |
| 86 | dirent = buf->dirent; | 88 | dirent = buf->dirent; |
| 87 | if (!access_ok(VERIFY_WRITE, dirent, | 89 | if (!access_ok(VERIFY_WRITE, dirent, |
| @@ -155,8 +157,10 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset, | |||
| 155 | if (reclen > buf->count) | 157 | if (reclen > buf->count) |
| 156 | return -EINVAL; | 158 | return -EINVAL; |
| 157 | d_ino = ino; | 159 | d_ino = ino; |
| 158 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | 160 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) { |
| 161 | buf->error = -EOVERFLOW; | ||
| 159 | return -EOVERFLOW; | 162 | return -EOVERFLOW; |
| 163 | } | ||
| 160 | dirent = buf->previous; | 164 | dirent = buf->previous; |
| 161 | if (dirent) { | 165 | if (dirent) { |
| 162 | if (__put_user(offset, &dirent->d_off)) | 166 | if (__put_user(offset, &dirent->d_off)) |
diff --git a/fs/seq_file.c b/fs/seq_file.c index 5d54205e486b..bd20f7f5a933 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
| @@ -108,9 +108,9 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) | |||
| 108 | goto Done; | 108 | goto Done; |
| 109 | } | 109 | } |
| 110 | /* we need at least one record in buffer */ | 110 | /* we need at least one record in buffer */ |
| 111 | pos = m->index; | ||
| 112 | p = m->op->start(m, &pos); | ||
| 111 | while (1) { | 113 | while (1) { |
| 112 | pos = m->index; | ||
| 113 | p = m->op->start(m, &pos); | ||
| 114 | err = PTR_ERR(p); | 114 | err = PTR_ERR(p); |
| 115 | if (!p || IS_ERR(p)) | 115 | if (!p || IS_ERR(p)) |
| 116 | break; | 116 | break; |
| @@ -119,6 +119,11 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) | |||
| 119 | break; | 119 | break; |
| 120 | if (unlikely(err)) | 120 | if (unlikely(err)) |
| 121 | m->count = 0; | 121 | m->count = 0; |
| 122 | if (unlikely(!m->count)) { | ||
| 123 | p = m->op->next(m, p, &pos); | ||
| 124 | m->index = pos; | ||
| 125 | continue; | ||
| 126 | } | ||
| 122 | if (m->count < m->size) | 127 | if (m->count < m->size) |
| 123 | goto Fill; | 128 | goto Fill; |
| 124 | m->op->stop(m, p); | 129 | m->op->stop(m, p); |
| @@ -128,6 +133,8 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) | |||
| 128 | goto Enomem; | 133 | goto Enomem; |
| 129 | m->count = 0; | 134 | m->count = 0; |
| 130 | m->version = 0; | 135 | m->version = 0; |
| 136 | pos = m->index; | ||
| 137 | p = m->op->start(m, &pos); | ||
| 131 | } | 138 | } |
| 132 | m->op->stop(m, p); | 139 | m->op->stop(m, p); |
| 133 | m->count = 0; | 140 | m->count = 0; |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 5f60363b9343..5311c1acdd40 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
| @@ -475,6 +475,7 @@ const struct file_operations xfs_invis_file_operations = { | |||
| 475 | const struct file_operations xfs_dir_file_operations = { | 475 | const struct file_operations xfs_dir_file_operations = { |
| 476 | .read = generic_read_dir, | 476 | .read = generic_read_dir, |
| 477 | .readdir = xfs_file_readdir, | 477 | .readdir = xfs_file_readdir, |
| 478 | .llseek = generic_file_llseek, | ||
| 478 | .unlocked_ioctl = xfs_file_ioctl, | 479 | .unlocked_ioctl = xfs_file_ioctl, |
| 479 | #ifdef CONFIG_COMPAT | 480 | #ifdef CONFIG_COMPAT |
| 480 | .compat_ioctl = xfs_file_compat_ioctl, | 481 | .compat_ioctl = xfs_file_compat_ioctl, |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 91bcd979242c..095d271f3434 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
| @@ -355,7 +355,7 @@ xfs_vn_ci_lookup( | |||
| 355 | /* else case-insensitive match... */ | 355 | /* else case-insensitive match... */ |
| 356 | dname.name = ci_name.name; | 356 | dname.name = ci_name.name; |
| 357 | dname.len = ci_name.len; | 357 | dname.len = ci_name.len; |
| 358 | dentry = d_add_ci(VFS_I(ip), dentry, &dname); | 358 | dentry = d_add_ci(dentry, VFS_I(ip), &dname); |
| 359 | kmem_free(ci_name.name); | 359 | kmem_free(ci_name.name); |
| 360 | return dentry; | 360 | return dentry; |
| 361 | } | 361 | } |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 07aa198f19ed..efba1de629ac 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
| @@ -230,7 +230,7 @@ extern void d_delete(struct dentry *); | |||
| 230 | extern struct dentry * d_alloc(struct dentry *, const struct qstr *); | 230 | extern struct dentry * d_alloc(struct dentry *, const struct qstr *); |
| 231 | extern struct dentry * d_alloc_anon(struct inode *); | 231 | extern struct dentry * d_alloc_anon(struct inode *); |
| 232 | extern struct dentry * d_splice_alias(struct inode *, struct dentry *); | 232 | extern struct dentry * d_splice_alias(struct inode *, struct dentry *); |
| 233 | extern struct dentry * d_add_ci(struct inode *, struct dentry *, struct qstr *); | 233 | extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *); |
| 234 | extern void shrink_dcache_sb(struct super_block *); | 234 | extern void shrink_dcache_sb(struct super_block *); |
| 235 | extern void shrink_dcache_parent(struct dentry *); | 235 | extern void shrink_dcache_parent(struct dentry *); |
| 236 | extern void shrink_dcache_for_umount(struct super_block *); | 236 | extern void shrink_dcache_for_umount(struct super_block *); |
