diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/aio.c | 24 | ||||
-rw-r--r-- | fs/binfmt_aout.c | 14 | ||||
-rw-r--r-- | fs/binfmt_elf.c | 2 | ||||
-rw-r--r-- | fs/btrfs/backref.c | 8 | ||||
-rw-r--r-- | fs/btrfs/reada.c | 2 | ||||
-rw-r--r-- | fs/cifs/dir.c | 20 | ||||
-rw-r--r-- | fs/cifs/inode.c | 28 | ||||
-rw-r--r-- | fs/dcache.c | 33 | ||||
-rw-r--r-- | fs/ecryptfs/miscdev.c | 2 | ||||
-rw-r--r-- | fs/exec.c | 18 | ||||
-rw-r--r-- | fs/gfs2/glock.c | 14 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 5 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 5 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 13 | ||||
-rw-r--r-- | fs/namei.c | 66 |
15 files changed, 164 insertions, 90 deletions
@@ -228,12 +228,6 @@ static void __put_ioctx(struct kioctx *ctx) | |||
228 | call_rcu(&ctx->rcu_head, ctx_rcu_free); | 228 | call_rcu(&ctx->rcu_head, ctx_rcu_free); |
229 | } | 229 | } |
230 | 230 | ||
231 | static inline void get_ioctx(struct kioctx *kioctx) | ||
232 | { | ||
233 | BUG_ON(atomic_read(&kioctx->users) <= 0); | ||
234 | atomic_inc(&kioctx->users); | ||
235 | } | ||
236 | |||
237 | static inline int try_get_ioctx(struct kioctx *kioctx) | 231 | static inline int try_get_ioctx(struct kioctx *kioctx) |
238 | { | 232 | { |
239 | return atomic_inc_not_zero(&kioctx->users); | 233 | return atomic_inc_not_zero(&kioctx->users); |
@@ -273,7 +267,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) | |||
273 | mm = ctx->mm = current->mm; | 267 | mm = ctx->mm = current->mm; |
274 | atomic_inc(&mm->mm_count); | 268 | atomic_inc(&mm->mm_count); |
275 | 269 | ||
276 | atomic_set(&ctx->users, 1); | 270 | atomic_set(&ctx->users, 2); |
277 | spin_lock_init(&ctx->ctx_lock); | 271 | spin_lock_init(&ctx->ctx_lock); |
278 | spin_lock_init(&ctx->ring_info.ring_lock); | 272 | spin_lock_init(&ctx->ring_info.ring_lock); |
279 | init_waitqueue_head(&ctx->wait); | 273 | init_waitqueue_head(&ctx->wait); |
@@ -490,6 +484,8 @@ static void kiocb_batch_free(struct kioctx *ctx, struct kiocb_batch *batch) | |||
490 | kmem_cache_free(kiocb_cachep, req); | 484 | kmem_cache_free(kiocb_cachep, req); |
491 | ctx->reqs_active--; | 485 | ctx->reqs_active--; |
492 | } | 486 | } |
487 | if (unlikely(!ctx->reqs_active && ctx->dead)) | ||
488 | wake_up_all(&ctx->wait); | ||
493 | spin_unlock_irq(&ctx->ctx_lock); | 489 | spin_unlock_irq(&ctx->ctx_lock); |
494 | } | 490 | } |
495 | 491 | ||
@@ -607,11 +603,16 @@ static void aio_fput_routine(struct work_struct *data) | |||
607 | fput(req->ki_filp); | 603 | fput(req->ki_filp); |
608 | 604 | ||
609 | /* Link the iocb into the context's free list */ | 605 | /* Link the iocb into the context's free list */ |
606 | rcu_read_lock(); | ||
610 | spin_lock_irq(&ctx->ctx_lock); | 607 | spin_lock_irq(&ctx->ctx_lock); |
611 | really_put_req(ctx, req); | 608 | really_put_req(ctx, req); |
609 | /* | ||
610 | * at that point ctx might've been killed, but actual | ||
611 | * freeing is RCU'd | ||
612 | */ | ||
612 | spin_unlock_irq(&ctx->ctx_lock); | 613 | spin_unlock_irq(&ctx->ctx_lock); |
614 | rcu_read_unlock(); | ||
613 | 615 | ||
614 | put_ioctx(ctx); | ||
615 | spin_lock_irq(&fput_lock); | 616 | spin_lock_irq(&fput_lock); |
616 | } | 617 | } |
617 | spin_unlock_irq(&fput_lock); | 618 | spin_unlock_irq(&fput_lock); |
@@ -642,7 +643,6 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) | |||
642 | * this function will be executed w/out any aio kthread wakeup. | 643 | * this function will be executed w/out any aio kthread wakeup. |
643 | */ | 644 | */ |
644 | if (unlikely(!fput_atomic(req->ki_filp))) { | 645 | if (unlikely(!fput_atomic(req->ki_filp))) { |
645 | get_ioctx(ctx); | ||
646 | spin_lock(&fput_lock); | 646 | spin_lock(&fput_lock); |
647 | list_add(&req->ki_list, &fput_head); | 647 | list_add(&req->ki_list, &fput_head); |
648 | spin_unlock(&fput_lock); | 648 | spin_unlock(&fput_lock); |
@@ -1336,10 +1336,10 @@ SYSCALL_DEFINE2(io_setup, unsigned, nr_events, aio_context_t __user *, ctxp) | |||
1336 | ret = PTR_ERR(ioctx); | 1336 | ret = PTR_ERR(ioctx); |
1337 | if (!IS_ERR(ioctx)) { | 1337 | if (!IS_ERR(ioctx)) { |
1338 | ret = put_user(ioctx->user_id, ctxp); | 1338 | ret = put_user(ioctx->user_id, ctxp); |
1339 | if (!ret) | 1339 | if (!ret) { |
1340 | put_ioctx(ioctx); | ||
1340 | return 0; | 1341 | return 0; |
1341 | 1342 | } | |
1342 | get_ioctx(ioctx); /* io_destroy() expects us to hold a ref */ | ||
1343 | io_destroy(ioctx); | 1343 | io_destroy(ioctx); |
1344 | } | 1344 | } |
1345 | 1345 | ||
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index a6395bdb26ae..1ff94054d35a 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -259,6 +259,13 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
259 | current->mm->free_area_cache = current->mm->mmap_base; | 259 | current->mm->free_area_cache = current->mm->mmap_base; |
260 | current->mm->cached_hole_size = 0; | 260 | current->mm->cached_hole_size = 0; |
261 | 261 | ||
262 | retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); | ||
263 | if (retval < 0) { | ||
264 | /* Someone check-me: is this error path enough? */ | ||
265 | send_sig(SIGKILL, current, 0); | ||
266 | return retval; | ||
267 | } | ||
268 | |||
262 | install_exec_creds(bprm); | 269 | install_exec_creds(bprm); |
263 | current->flags &= ~PF_FORKNOEXEC; | 270 | current->flags &= ~PF_FORKNOEXEC; |
264 | 271 | ||
@@ -352,13 +359,6 @@ beyond_if: | |||
352 | return retval; | 359 | return retval; |
353 | } | 360 | } |
354 | 361 | ||
355 | retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); | ||
356 | if (retval < 0) { | ||
357 | /* Someone check-me: is this error path enough? */ | ||
358 | send_sig(SIGKILL, current, 0); | ||
359 | return retval; | ||
360 | } | ||
361 | |||
362 | current->mm->start_stack = | 362 | current->mm->start_stack = |
363 | (unsigned long) create_aout_tables((char __user *) bprm->p, bprm); | 363 | (unsigned long) create_aout_tables((char __user *) bprm->p, bprm); |
364 | #ifdef __alpha__ | 364 | #ifdef __alpha__ |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index bcb884e2d613..07d096c49920 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -1421,7 +1421,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, | |||
1421 | for (i = 1; i < view->n; ++i) { | 1421 | for (i = 1; i < view->n; ++i) { |
1422 | const struct user_regset *regset = &view->regsets[i]; | 1422 | const struct user_regset *regset = &view->regsets[i]; |
1423 | do_thread_regset_writeback(t->task, regset); | 1423 | do_thread_regset_writeback(t->task, regset); |
1424 | if (regset->core_note_type && | 1424 | if (regset->core_note_type && regset->get && |
1425 | (!regset->active || regset->active(t->task, regset))) { | 1425 | (!regset->active || regset->active(t->task, regset))) { |
1426 | int ret; | 1426 | int ret; |
1427 | size_t size = regset->n * regset->size; | 1427 | size_t size = regset->n * regset->size; |
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 98f6bf10bbd4..0436c12da8c2 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -583,7 +583,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, | |||
583 | struct btrfs_path *path; | 583 | struct btrfs_path *path; |
584 | struct btrfs_key info_key = { 0 }; | 584 | struct btrfs_key info_key = { 0 }; |
585 | struct btrfs_delayed_ref_root *delayed_refs = NULL; | 585 | struct btrfs_delayed_ref_root *delayed_refs = NULL; |
586 | struct btrfs_delayed_ref_head *head = NULL; | 586 | struct btrfs_delayed_ref_head *head; |
587 | int info_level = 0; | 587 | int info_level = 0; |
588 | int ret; | 588 | int ret; |
589 | struct list_head prefs_delayed; | 589 | struct list_head prefs_delayed; |
@@ -607,6 +607,8 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, | |||
607 | * at a specified point in time | 607 | * at a specified point in time |
608 | */ | 608 | */ |
609 | again: | 609 | again: |
610 | head = NULL; | ||
611 | |||
610 | ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0); | 612 | ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0); |
611 | if (ret < 0) | 613 | if (ret < 0) |
612 | goto out; | 614 | goto out; |
@@ -635,8 +637,10 @@ again: | |||
635 | goto again; | 637 | goto again; |
636 | } | 638 | } |
637 | ret = __add_delayed_refs(head, seq, &info_key, &prefs_delayed); | 639 | ret = __add_delayed_refs(head, seq, &info_key, &prefs_delayed); |
638 | if (ret) | 640 | if (ret) { |
641 | spin_unlock(&delayed_refs->lock); | ||
639 | goto out; | 642 | goto out; |
643 | } | ||
640 | } | 644 | } |
641 | spin_unlock(&delayed_refs->lock); | 645 | spin_unlock(&delayed_refs->lock); |
642 | 646 | ||
diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c index 2373b39a132b..22db04550f6a 100644 --- a/fs/btrfs/reada.c +++ b/fs/btrfs/reada.c | |||
@@ -305,7 +305,7 @@ again: | |||
305 | 305 | ||
306 | spin_lock(&fs_info->reada_lock); | 306 | spin_lock(&fs_info->reada_lock); |
307 | ret = radix_tree_insert(&dev->reada_zones, | 307 | ret = radix_tree_insert(&dev->reada_zones, |
308 | (unsigned long)zone->end >> PAGE_CACHE_SHIFT, | 308 | (unsigned long)(zone->end >> PAGE_CACHE_SHIFT), |
309 | zone); | 309 | zone); |
310 | spin_unlock(&fs_info->reada_lock); | 310 | spin_unlock(&fs_info->reada_lock); |
311 | 311 | ||
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 63a196b97d50..bc7e24420ac0 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -584,10 +584,26 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
584 | * If either that or op not supported returned, follow | 584 | * If either that or op not supported returned, follow |
585 | * the normal lookup. | 585 | * the normal lookup. |
586 | */ | 586 | */ |
587 | if ((rc == 0) || (rc == -ENOENT)) | 587 | switch (rc) { |
588 | case 0: | ||
589 | /* | ||
590 | * The server may allow us to open things like | ||
591 | * FIFOs, but the client isn't set up to deal | ||
592 | * with that. If it's not a regular file, just | ||
593 | * close it and proceed as if it were a normal | ||
594 | * lookup. | ||
595 | */ | ||
596 | if (newInode && !S_ISREG(newInode->i_mode)) { | ||
597 | CIFSSMBClose(xid, pTcon, fileHandle); | ||
598 | break; | ||
599 | } | ||
600 | case -ENOENT: | ||
588 | posix_open = true; | 601 | posix_open = true; |
589 | else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP)) | 602 | case -EOPNOTSUPP: |
603 | break; | ||
604 | default: | ||
590 | pTcon->broken_posix_open = true; | 605 | pTcon->broken_posix_open = true; |
606 | } | ||
591 | } | 607 | } |
592 | if (!posix_open) | 608 | if (!posix_open) |
593 | rc = cifs_get_inode_info_unix(&newInode, full_path, | 609 | rc = cifs_get_inode_info_unix(&newInode, full_path, |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index a5f54b7d9822..745da3d0653e 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -534,6 +534,11 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, | |||
534 | if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { | 534 | if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { |
535 | fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode; | 535 | fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode; |
536 | fattr->cf_dtype = DT_DIR; | 536 | fattr->cf_dtype = DT_DIR; |
537 | /* | ||
538 | * Server can return wrong NumberOfLinks value for directories | ||
539 | * when Unix extensions are disabled - fake it. | ||
540 | */ | ||
541 | fattr->cf_nlink = 2; | ||
537 | } else { | 542 | } else { |
538 | fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode; | 543 | fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode; |
539 | fattr->cf_dtype = DT_REG; | 544 | fattr->cf_dtype = DT_REG; |
@@ -541,9 +546,9 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, | |||
541 | /* clear write bits if ATTR_READONLY is set */ | 546 | /* clear write bits if ATTR_READONLY is set */ |
542 | if (fattr->cf_cifsattrs & ATTR_READONLY) | 547 | if (fattr->cf_cifsattrs & ATTR_READONLY) |
543 | fattr->cf_mode &= ~(S_IWUGO); | 548 | fattr->cf_mode &= ~(S_IWUGO); |
544 | } | ||
545 | 549 | ||
546 | fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks); | 550 | fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks); |
551 | } | ||
547 | 552 | ||
548 | fattr->cf_uid = cifs_sb->mnt_uid; | 553 | fattr->cf_uid = cifs_sb->mnt_uid; |
549 | fattr->cf_gid = cifs_sb->mnt_gid; | 554 | fattr->cf_gid = cifs_sb->mnt_gid; |
@@ -1322,7 +1327,6 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) | |||
1322 | } | 1327 | } |
1323 | /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need | 1328 | /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need |
1324 | to set uid/gid */ | 1329 | to set uid/gid */ |
1325 | inc_nlink(inode); | ||
1326 | 1330 | ||
1327 | cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb); | 1331 | cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb); |
1328 | cifs_fill_uniqueid(inode->i_sb, &fattr); | 1332 | cifs_fill_uniqueid(inode->i_sb, &fattr); |
@@ -1355,7 +1359,6 @@ mkdir_retry_old: | |||
1355 | d_drop(direntry); | 1359 | d_drop(direntry); |
1356 | } else { | 1360 | } else { |
1357 | mkdir_get_info: | 1361 | mkdir_get_info: |
1358 | inc_nlink(inode); | ||
1359 | if (pTcon->unix_ext) | 1362 | if (pTcon->unix_ext) |
1360 | rc = cifs_get_inode_info_unix(&newinode, full_path, | 1363 | rc = cifs_get_inode_info_unix(&newinode, full_path, |
1361 | inode->i_sb, xid); | 1364 | inode->i_sb, xid); |
@@ -1436,6 +1439,11 @@ mkdir_get_info: | |||
1436 | } | 1439 | } |
1437 | } | 1440 | } |
1438 | mkdir_out: | 1441 | mkdir_out: |
1442 | /* | ||
1443 | * Force revalidate to get parent dir info when needed since cached | ||
1444 | * attributes are invalid now. | ||
1445 | */ | ||
1446 | CIFS_I(inode)->time = 0; | ||
1439 | kfree(full_path); | 1447 | kfree(full_path); |
1440 | FreeXid(xid); | 1448 | FreeXid(xid); |
1441 | cifs_put_tlink(tlink); | 1449 | cifs_put_tlink(tlink); |
@@ -1475,7 +1483,6 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
1475 | cifs_put_tlink(tlink); | 1483 | cifs_put_tlink(tlink); |
1476 | 1484 | ||
1477 | if (!rc) { | 1485 | if (!rc) { |
1478 | drop_nlink(inode); | ||
1479 | spin_lock(&direntry->d_inode->i_lock); | 1486 | spin_lock(&direntry->d_inode->i_lock); |
1480 | i_size_write(direntry->d_inode, 0); | 1487 | i_size_write(direntry->d_inode, 0); |
1481 | clear_nlink(direntry->d_inode); | 1488 | clear_nlink(direntry->d_inode); |
@@ -1483,12 +1490,15 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
1483 | } | 1490 | } |
1484 | 1491 | ||
1485 | cifsInode = CIFS_I(direntry->d_inode); | 1492 | cifsInode = CIFS_I(direntry->d_inode); |
1486 | cifsInode->time = 0; /* force revalidate to go get info when | 1493 | /* force revalidate to go get info when needed */ |
1487 | needed */ | 1494 | cifsInode->time = 0; |
1488 | 1495 | ||
1489 | cifsInode = CIFS_I(inode); | 1496 | cifsInode = CIFS_I(inode); |
1490 | cifsInode->time = 0; /* force revalidate to get parent dir info | 1497 | /* |
1491 | since cached search results now invalid */ | 1498 | * Force revalidate to get parent dir info when needed since cached |
1499 | * attributes are invalid now. | ||
1500 | */ | ||
1501 | cifsInode->time = 0; | ||
1492 | 1502 | ||
1493 | direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = | 1503 | direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = |
1494 | current_fs_time(inode->i_sb); | 1504 | current_fs_time(inode->i_sb); |
diff --git a/fs/dcache.c b/fs/dcache.c index fe19ac13f75f..bcbdb33fcc20 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -104,7 +104,7 @@ static unsigned int d_hash_shift __read_mostly; | |||
104 | 104 | ||
105 | static struct hlist_bl_head *dentry_hashtable __read_mostly; | 105 | static struct hlist_bl_head *dentry_hashtable __read_mostly; |
106 | 106 | ||
107 | static inline struct hlist_bl_head *d_hash(struct dentry *parent, | 107 | static inline struct hlist_bl_head *d_hash(const struct dentry *parent, |
108 | unsigned long hash) | 108 | unsigned long hash) |
109 | { | 109 | { |
110 | hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES; | 110 | hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES; |
@@ -137,6 +137,26 @@ int proc_nr_dentry(ctl_table *table, int write, void __user *buffer, | |||
137 | } | 137 | } |
138 | #endif | 138 | #endif |
139 | 139 | ||
140 | /* | ||
141 | * Compare 2 name strings, return 0 if they match, otherwise non-zero. | ||
142 | * The strings are both count bytes long, and count is non-zero. | ||
143 | */ | ||
144 | static inline int dentry_cmp(const unsigned char *cs, size_t scount, | ||
145 | const unsigned char *ct, size_t tcount) | ||
146 | { | ||
147 | if (scount != tcount) | ||
148 | return 1; | ||
149 | |||
150 | do { | ||
151 | if (*cs != *ct) | ||
152 | return 1; | ||
153 | cs++; | ||
154 | ct++; | ||
155 | tcount--; | ||
156 | } while (tcount); | ||
157 | return 0; | ||
158 | } | ||
159 | |||
140 | static void __d_free(struct rcu_head *head) | 160 | static void __d_free(struct rcu_head *head) |
141 | { | 161 | { |
142 | struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); | 162 | struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); |
@@ -1717,8 +1737,9 @@ EXPORT_SYMBOL(d_add_ci); | |||
1717 | * child is looked up. Thus, an interlocking stepping of sequence lock checks | 1737 | * child is looked up. Thus, an interlocking stepping of sequence lock checks |
1718 | * is formed, giving integrity down the path walk. | 1738 | * is formed, giving integrity down the path walk. |
1719 | */ | 1739 | */ |
1720 | struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, | 1740 | struct dentry *__d_lookup_rcu(const struct dentry *parent, |
1721 | unsigned *seq, struct inode **inode) | 1741 | const struct qstr *name, |
1742 | unsigned *seqp, struct inode **inode) | ||
1722 | { | 1743 | { |
1723 | unsigned int len = name->len; | 1744 | unsigned int len = name->len; |
1724 | unsigned int hash = name->hash; | 1745 | unsigned int hash = name->hash; |
@@ -1748,6 +1769,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, | |||
1748 | * See Documentation/filesystems/path-lookup.txt for more details. | 1769 | * See Documentation/filesystems/path-lookup.txt for more details. |
1749 | */ | 1770 | */ |
1750 | hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) { | 1771 | hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) { |
1772 | unsigned seq; | ||
1751 | struct inode *i; | 1773 | struct inode *i; |
1752 | const char *tname; | 1774 | const char *tname; |
1753 | int tlen; | 1775 | int tlen; |
@@ -1756,7 +1778,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, | |||
1756 | continue; | 1778 | continue; |
1757 | 1779 | ||
1758 | seqretry: | 1780 | seqretry: |
1759 | *seq = read_seqcount_begin(&dentry->d_seq); | 1781 | seq = read_seqcount_begin(&dentry->d_seq); |
1760 | if (dentry->d_parent != parent) | 1782 | if (dentry->d_parent != parent) |
1761 | continue; | 1783 | continue; |
1762 | if (d_unhashed(dentry)) | 1784 | if (d_unhashed(dentry)) |
@@ -1771,7 +1793,7 @@ seqretry: | |||
1771 | * edge of memory when walking. If we could load this | 1793 | * edge of memory when walking. If we could load this |
1772 | * atomically some other way, we could drop this check. | 1794 | * atomically some other way, we could drop this check. |
1773 | */ | 1795 | */ |
1774 | if (read_seqcount_retry(&dentry->d_seq, *seq)) | 1796 | if (read_seqcount_retry(&dentry->d_seq, seq)) |
1775 | goto seqretry; | 1797 | goto seqretry; |
1776 | if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) { | 1798 | if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) { |
1777 | if (parent->d_op->d_compare(parent, *inode, | 1799 | if (parent->d_op->d_compare(parent, *inode, |
@@ -1788,6 +1810,7 @@ seqretry: | |||
1788 | * order to do anything useful with the returned dentry | 1810 | * order to do anything useful with the returned dentry |
1789 | * anyway. | 1811 | * anyway. |
1790 | */ | 1812 | */ |
1813 | *seqp = seq; | ||
1791 | *inode = i; | 1814 | *inode = i; |
1792 | return dentry; | 1815 | return dentry; |
1793 | } | 1816 | } |
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index 349209dc6a91..3a06f4043df4 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c | |||
@@ -429,7 +429,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, | |||
429 | goto memdup; | 429 | goto memdup; |
430 | } else if (count < MIN_MSG_PKT_SIZE || count > MAX_MSG_PKT_SIZE) { | 430 | } else if (count < MIN_MSG_PKT_SIZE || count > MAX_MSG_PKT_SIZE) { |
431 | printk(KERN_WARNING "%s: Acceptable packet size range is " | 431 | printk(KERN_WARNING "%s: Acceptable packet size range is " |
432 | "[%d-%lu], but amount of data written is [%zu].", | 432 | "[%d-%zu], but amount of data written is [%zu].", |
433 | __func__, MIN_MSG_PKT_SIZE, MAX_MSG_PKT_SIZE, count); | 433 | __func__, MIN_MSG_PKT_SIZE, MAX_MSG_PKT_SIZE, count); |
434 | return -EINVAL; | 434 | return -EINVAL; |
435 | } | 435 | } |
@@ -1918,7 +1918,6 @@ static int coredump_wait(int exit_code, struct core_state *core_state) | |||
1918 | { | 1918 | { |
1919 | struct task_struct *tsk = current; | 1919 | struct task_struct *tsk = current; |
1920 | struct mm_struct *mm = tsk->mm; | 1920 | struct mm_struct *mm = tsk->mm; |
1921 | struct completion *vfork_done; | ||
1922 | int core_waiters = -EBUSY; | 1921 | int core_waiters = -EBUSY; |
1923 | 1922 | ||
1924 | init_completion(&core_state->startup); | 1923 | init_completion(&core_state->startup); |
@@ -1930,22 +1929,9 @@ static int coredump_wait(int exit_code, struct core_state *core_state) | |||
1930 | core_waiters = zap_threads(tsk, mm, core_state, exit_code); | 1929 | core_waiters = zap_threads(tsk, mm, core_state, exit_code); |
1931 | up_write(&mm->mmap_sem); | 1930 | up_write(&mm->mmap_sem); |
1932 | 1931 | ||
1933 | if (unlikely(core_waiters < 0)) | 1932 | if (core_waiters > 0) |
1934 | goto fail; | ||
1935 | |||
1936 | /* | ||
1937 | * Make sure nobody is waiting for us to release the VM, | ||
1938 | * otherwise we can deadlock when we wait on each other | ||
1939 | */ | ||
1940 | vfork_done = tsk->vfork_done; | ||
1941 | if (vfork_done) { | ||
1942 | tsk->vfork_done = NULL; | ||
1943 | complete(vfork_done); | ||
1944 | } | ||
1945 | |||
1946 | if (core_waiters) | ||
1947 | wait_for_completion(&core_state->startup); | 1933 | wait_for_completion(&core_state->startup); |
1948 | fail: | 1934 | |
1949 | return core_waiters; | 1935 | return core_waiters; |
1950 | } | 1936 | } |
1951 | 1937 | ||
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 376816fcd040..351a3e797789 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -167,14 +167,19 @@ void gfs2_glock_add_to_lru(struct gfs2_glock *gl) | |||
167 | spin_unlock(&lru_lock); | 167 | spin_unlock(&lru_lock); |
168 | } | 168 | } |
169 | 169 | ||
170 | static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl) | 170 | static void __gfs2_glock_remove_from_lru(struct gfs2_glock *gl) |
171 | { | 171 | { |
172 | spin_lock(&lru_lock); | ||
173 | if (!list_empty(&gl->gl_lru)) { | 172 | if (!list_empty(&gl->gl_lru)) { |
174 | list_del_init(&gl->gl_lru); | 173 | list_del_init(&gl->gl_lru); |
175 | atomic_dec(&lru_count); | 174 | atomic_dec(&lru_count); |
176 | clear_bit(GLF_LRU, &gl->gl_flags); | 175 | clear_bit(GLF_LRU, &gl->gl_flags); |
177 | } | 176 | } |
177 | } | ||
178 | |||
179 | static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl) | ||
180 | { | ||
181 | spin_lock(&lru_lock); | ||
182 | __gfs2_glock_remove_from_lru(gl); | ||
178 | spin_unlock(&lru_lock); | 183 | spin_unlock(&lru_lock); |
179 | } | 184 | } |
180 | 185 | ||
@@ -217,11 +222,12 @@ void gfs2_glock_put(struct gfs2_glock *gl) | |||
217 | struct gfs2_sbd *sdp = gl->gl_sbd; | 222 | struct gfs2_sbd *sdp = gl->gl_sbd; |
218 | struct address_space *mapping = gfs2_glock2aspace(gl); | 223 | struct address_space *mapping = gfs2_glock2aspace(gl); |
219 | 224 | ||
220 | if (atomic_dec_and_test(&gl->gl_ref)) { | 225 | if (atomic_dec_and_lock(&gl->gl_ref, &lru_lock)) { |
226 | __gfs2_glock_remove_from_lru(gl); | ||
227 | spin_unlock(&lru_lock); | ||
221 | spin_lock_bucket(gl->gl_hash); | 228 | spin_lock_bucket(gl->gl_hash); |
222 | hlist_bl_del_rcu(&gl->gl_list); | 229 | hlist_bl_del_rcu(&gl->gl_list); |
223 | spin_unlock_bucket(gl->gl_hash); | 230 | spin_unlock_bucket(gl->gl_hash); |
224 | gfs2_glock_remove_from_lru(gl); | ||
225 | GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders)); | 231 | GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders)); |
226 | GLOCK_BUG_ON(gl, mapping && mapping->nrpages); | 232 | GLOCK_BUG_ON(gl, mapping && mapping->nrpages); |
227 | trace_gfs2_glock_put(gl); | 233 | trace_gfs2_glock_put(gl); |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index a7d611b93f0f..56987460cdae 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -391,10 +391,6 @@ static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation) | |||
391 | int error; | 391 | int error; |
392 | int dblocks = 1; | 392 | int dblocks = 1; |
393 | 393 | ||
394 | error = gfs2_rindex_update(sdp); | ||
395 | if (error) | ||
396 | fs_warn(sdp, "rindex update returns %d\n", error); | ||
397 | |||
398 | error = gfs2_inplace_reserve(dip, RES_DINODE); | 394 | error = gfs2_inplace_reserve(dip, RES_DINODE); |
399 | if (error) | 395 | if (error) |
400 | goto out; | 396 | goto out; |
@@ -1043,6 +1039,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry) | |||
1043 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); | 1039 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); |
1044 | if (!rgd) | 1040 | if (!rgd) |
1045 | goto out_inodes; | 1041 | goto out_inodes; |
1042 | |||
1046 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); | 1043 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); |
1047 | 1044 | ||
1048 | 1045 | ||
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 6aacf3f230a2..24f609c9ef91 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -800,6 +800,11 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo) | |||
800 | fs_err(sdp, "can't get quota file inode: %d\n", error); | 800 | fs_err(sdp, "can't get quota file inode: %d\n", error); |
801 | goto fail_rindex; | 801 | goto fail_rindex; |
802 | } | 802 | } |
803 | |||
804 | error = gfs2_rindex_update(sdp); | ||
805 | if (error) | ||
806 | goto fail_qinode; | ||
807 | |||
803 | return 0; | 808 | return 0; |
804 | 809 | ||
805 | fail_qinode: | 810 | fail_qinode: |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 981bfa32121a..49ada95209d0 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -683,16 +683,21 @@ int gfs2_rindex_update(struct gfs2_sbd *sdp) | |||
683 | struct gfs2_glock *gl = ip->i_gl; | 683 | struct gfs2_glock *gl = ip->i_gl; |
684 | struct gfs2_holder ri_gh; | 684 | struct gfs2_holder ri_gh; |
685 | int error = 0; | 685 | int error = 0; |
686 | int unlock_required = 0; | ||
686 | 687 | ||
687 | /* Read new copy from disk if we don't have the latest */ | 688 | /* Read new copy from disk if we don't have the latest */ |
688 | if (!sdp->sd_rindex_uptodate) { | 689 | if (!sdp->sd_rindex_uptodate) { |
689 | mutex_lock(&sdp->sd_rindex_mutex); | 690 | mutex_lock(&sdp->sd_rindex_mutex); |
690 | error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, &ri_gh); | 691 | if (!gfs2_glock_is_locked_by_me(gl)) { |
691 | if (error) | 692 | error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, &ri_gh); |
692 | return error; | 693 | if (error) |
694 | return error; | ||
695 | unlock_required = 1; | ||
696 | } | ||
693 | if (!sdp->sd_rindex_uptodate) | 697 | if (!sdp->sd_rindex_uptodate) |
694 | error = gfs2_ri_update(ip); | 698 | error = gfs2_ri_update(ip); |
695 | gfs2_glock_dq_uninit(&ri_gh); | 699 | if (unlock_required) |
700 | gfs2_glock_dq_uninit(&ri_gh); | ||
696 | mutex_unlock(&sdp->sd_rindex_mutex); | 701 | mutex_unlock(&sdp->sd_rindex_mutex); |
697 | } | 702 | } |
698 | 703 | ||
diff --git a/fs/namei.c b/fs/namei.c index a780ea515c47..e2ba62820a0f 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1374,6 +1374,34 @@ static inline int can_lookup(struct inode *inode) | |||
1374 | return 1; | 1374 | return 1; |
1375 | } | 1375 | } |
1376 | 1376 | ||
1377 | unsigned int full_name_hash(const unsigned char *name, unsigned int len) | ||
1378 | { | ||
1379 | unsigned long hash = init_name_hash(); | ||
1380 | while (len--) | ||
1381 | hash = partial_name_hash(*name++, hash); | ||
1382 | return end_name_hash(hash); | ||
1383 | } | ||
1384 | EXPORT_SYMBOL(full_name_hash); | ||
1385 | |||
1386 | /* | ||
1387 | * We know there's a real path component here of at least | ||
1388 | * one character. | ||
1389 | */ | ||
1390 | static inline unsigned long hash_name(const char *name, unsigned int *hashp) | ||
1391 | { | ||
1392 | unsigned long hash = init_name_hash(); | ||
1393 | unsigned long len = 0, c; | ||
1394 | |||
1395 | c = (unsigned char)*name; | ||
1396 | do { | ||
1397 | len++; | ||
1398 | hash = partial_name_hash(c, hash); | ||
1399 | c = (unsigned char)name[len]; | ||
1400 | } while (c && c != '/'); | ||
1401 | *hashp = end_name_hash(hash); | ||
1402 | return len; | ||
1403 | } | ||
1404 | |||
1377 | /* | 1405 | /* |
1378 | * Name resolution. | 1406 | * Name resolution. |
1379 | * This is the basic name resolution function, turning a pathname into | 1407 | * This is the basic name resolution function, turning a pathname into |
@@ -1394,31 +1422,22 @@ static int link_path_walk(const char *name, struct nameidata *nd) | |||
1394 | 1422 | ||
1395 | /* At this point we know we have a real path component. */ | 1423 | /* At this point we know we have a real path component. */ |
1396 | for(;;) { | 1424 | for(;;) { |
1397 | unsigned long hash; | ||
1398 | struct qstr this; | 1425 | struct qstr this; |
1399 | unsigned int c; | 1426 | long len; |
1400 | int type; | 1427 | int type; |
1401 | 1428 | ||
1402 | err = may_lookup(nd); | 1429 | err = may_lookup(nd); |
1403 | if (err) | 1430 | if (err) |
1404 | break; | 1431 | break; |
1405 | 1432 | ||
1433 | len = hash_name(name, &this.hash); | ||
1406 | this.name = name; | 1434 | this.name = name; |
1407 | c = *(const unsigned char *)name; | 1435 | this.len = len; |
1408 | |||
1409 | hash = init_name_hash(); | ||
1410 | do { | ||
1411 | name++; | ||
1412 | hash = partial_name_hash(c, hash); | ||
1413 | c = *(const unsigned char *)name; | ||
1414 | } while (c && (c != '/')); | ||
1415 | this.len = name - (const char *) this.name; | ||
1416 | this.hash = end_name_hash(hash); | ||
1417 | 1436 | ||
1418 | type = LAST_NORM; | 1437 | type = LAST_NORM; |
1419 | if (this.name[0] == '.') switch (this.len) { | 1438 | if (name[0] == '.') switch (len) { |
1420 | case 2: | 1439 | case 2: |
1421 | if (this.name[1] == '.') { | 1440 | if (name[1] == '.') { |
1422 | type = LAST_DOTDOT; | 1441 | type = LAST_DOTDOT; |
1423 | nd->flags |= LOOKUP_JUMPED; | 1442 | nd->flags |= LOOKUP_JUMPED; |
1424 | } | 1443 | } |
@@ -1437,12 +1456,18 @@ static int link_path_walk(const char *name, struct nameidata *nd) | |||
1437 | } | 1456 | } |
1438 | } | 1457 | } |
1439 | 1458 | ||
1440 | /* remove trailing slashes? */ | 1459 | if (!name[len]) |
1441 | if (!c) | ||
1442 | goto last_component; | 1460 | goto last_component; |
1443 | while (*++name == '/'); | 1461 | /* |
1444 | if (!*name) | 1462 | * If it wasn't NUL, we know it was '/'. Skip that |
1463 | * slash, and continue until no more slashes. | ||
1464 | */ | ||
1465 | do { | ||
1466 | len++; | ||
1467 | } while (unlikely(name[len] == '/')); | ||
1468 | if (!name[len]) | ||
1445 | goto last_component; | 1469 | goto last_component; |
1470 | name += len; | ||
1446 | 1471 | ||
1447 | err = walk_component(nd, &next, &this, type, LOOKUP_FOLLOW); | 1472 | err = walk_component(nd, &next, &this, type, LOOKUP_FOLLOW); |
1448 | if (err < 0) | 1473 | if (err < 0) |
@@ -1775,24 +1800,21 @@ static struct dentry *lookup_hash(struct nameidata *nd) | |||
1775 | struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) | 1800 | struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) |
1776 | { | 1801 | { |
1777 | struct qstr this; | 1802 | struct qstr this; |
1778 | unsigned long hash; | ||
1779 | unsigned int c; | 1803 | unsigned int c; |
1780 | 1804 | ||
1781 | WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex)); | 1805 | WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex)); |
1782 | 1806 | ||
1783 | this.name = name; | 1807 | this.name = name; |
1784 | this.len = len; | 1808 | this.len = len; |
1809 | this.hash = full_name_hash(name, len); | ||
1785 | if (!len) | 1810 | if (!len) |
1786 | return ERR_PTR(-EACCES); | 1811 | return ERR_PTR(-EACCES); |
1787 | 1812 | ||
1788 | hash = init_name_hash(); | ||
1789 | while (len--) { | 1813 | while (len--) { |
1790 | c = *(const unsigned char *)name++; | 1814 | c = *(const unsigned char *)name++; |
1791 | if (c == '/' || c == '\0') | 1815 | if (c == '/' || c == '\0') |
1792 | return ERR_PTR(-EACCES); | 1816 | return ERR_PTR(-EACCES); |
1793 | hash = partial_name_hash(c, hash); | ||
1794 | } | 1817 | } |
1795 | this.hash = end_name_hash(hash); | ||
1796 | /* | 1818 | /* |
1797 | * See if the low-level filesystem might want | 1819 | * See if the low-level filesystem might want |
1798 | * to use its own hash.. | 1820 | * to use its own hash.. |