Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
[PATCH] deal with the first call of ->show() generating no output
[PATCH] fix ->llseek() for a bunch of directories
[PATCH] fix regular readdir() and friends
[PATCH] fix hpux_getdents()
[PATCH] fix osf_getdirents()
[PATCH] ntfs: use d_add_ci
[PATCH] change d_add_ci argument ordering
[PATCH] fix efs_lookup()
[PATCH] proc: inode number fixlet

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