diff options
Diffstat (limited to 'fs')
172 files changed, 2361 insertions, 1924 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index d7312825592b..c509123bea49 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
| @@ -1744,10 +1744,10 @@ config ROOT_NFS | |||
| 1744 | If you want your Linux box to mount its whole root file system (the | 1744 | If you want your Linux box to mount its whole root file system (the |
| 1745 | one containing the directory /) from some other computer over the | 1745 | one containing the directory /) from some other computer over the |
| 1746 | net via NFS (presumably because your box doesn't have a hard disk), | 1746 | net via NFS (presumably because your box doesn't have a hard disk), |
| 1747 | say Y. Read <file:Documentation/nfsroot.txt> for details. It is | 1747 | say Y. Read <file:Documentation/filesystems/nfsroot.txt> for |
| 1748 | likely that in this case, you also want to say Y to "Kernel level IP | 1748 | details. It is likely that in this case, you also want to say Y to |
| 1749 | autoconfiguration" so that your box can discover its network address | 1749 | "Kernel level IP autoconfiguration" so that your box can discover |
| 1750 | at boot time. | 1750 | its network address at boot time. |
| 1751 | 1751 | ||
| 1752 | Most people say N here. | 1752 | Most people say N here. |
| 1753 | 1753 | ||
diff --git a/fs/afs/cell.c b/fs/afs/cell.c index 970d38f30565..584bb0f9c36a 100644 --- a/fs/afs/cell.c +++ b/fs/afs/cell.c | |||
| @@ -127,14 +127,21 @@ struct afs_cell *afs_cell_create(const char *name, char *vllist) | |||
| 127 | 127 | ||
| 128 | _enter("%s,%s", name, vllist); | 128 | _enter("%s,%s", name, vllist); |
| 129 | 129 | ||
| 130 | down_write(&afs_cells_sem); | ||
| 131 | read_lock(&afs_cells_lock); | ||
| 132 | list_for_each_entry(cell, &afs_cells, link) { | ||
| 133 | if (strcasecmp(cell->name, name) == 0) | ||
| 134 | goto duplicate_name; | ||
| 135 | } | ||
| 136 | read_unlock(&afs_cells_lock); | ||
| 137 | |||
| 130 | cell = afs_cell_alloc(name, vllist); | 138 | cell = afs_cell_alloc(name, vllist); |
| 131 | if (IS_ERR(cell)) { | 139 | if (IS_ERR(cell)) { |
| 132 | _leave(" = %ld", PTR_ERR(cell)); | 140 | _leave(" = %ld", PTR_ERR(cell)); |
| 141 | up_write(&afs_cells_sem); | ||
| 133 | return cell; | 142 | return cell; |
| 134 | } | 143 | } |
| 135 | 144 | ||
| 136 | down_write(&afs_cells_sem); | ||
| 137 | |||
| 138 | /* add a proc directory for this cell */ | 145 | /* add a proc directory for this cell */ |
| 139 | ret = afs_proc_cell_setup(cell); | 146 | ret = afs_proc_cell_setup(cell); |
| 140 | if (ret < 0) | 147 | if (ret < 0) |
| @@ -167,6 +174,11 @@ error: | |||
| 167 | kfree(cell); | 174 | kfree(cell); |
| 168 | _leave(" = %d", ret); | 175 | _leave(" = %d", ret); |
| 169 | return ERR_PTR(ret); | 176 | return ERR_PTR(ret); |
| 177 | |||
| 178 | duplicate_name: | ||
| 179 | read_unlock(&afs_cells_lock); | ||
| 180 | up_write(&afs_cells_sem); | ||
| 181 | return ERR_PTR(-EEXIST); | ||
| 170 | } | 182 | } |
| 171 | 183 | ||
| 172 | /* | 184 | /* |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 5ca3625cd39e..eec41c76de72 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
| @@ -573,7 +573,6 @@ extern const struct file_operations afs_mntpt_file_operations; | |||
| 573 | 573 | ||
| 574 | extern int afs_mntpt_check_symlink(struct afs_vnode *, struct key *); | 574 | extern int afs_mntpt_check_symlink(struct afs_vnode *, struct key *); |
| 575 | extern void afs_mntpt_kill_timer(void); | 575 | extern void afs_mntpt_kill_timer(void); |
| 576 | extern void afs_umount_begin(struct vfsmount *, int); | ||
| 577 | 576 | ||
| 578 | /* | 577 | /* |
| 579 | * proc.c | 578 | * proc.c |
| @@ -750,7 +749,7 @@ extern int afs_fsync(struct file *, struct dentry *, int); | |||
| 750 | extern unsigned afs_debug; | 749 | extern unsigned afs_debug; |
| 751 | 750 | ||
| 752 | #define dbgprintk(FMT,...) \ | 751 | #define dbgprintk(FMT,...) \ |
| 753 | printk("[%x%-6.6s] "FMT"\n", smp_processor_id(), current->comm ,##__VA_ARGS__) | 752 | printk("[%-6.6s] "FMT"\n", current->comm ,##__VA_ARGS__) |
| 754 | 753 | ||
| 755 | /* make sure we maintain the format strings, even when debugging is disabled */ | 754 | /* make sure we maintain the format strings, even when debugging is disabled */ |
| 756 | static inline __attribute__((format(printf,1,2))) | 755 | static inline __attribute__((format(printf,1,2))) |
diff --git a/fs/afs/main.c b/fs/afs/main.c index 0f60f6b35769..2d3e5d4fb9f7 100644 --- a/fs/afs/main.c +++ b/fs/afs/main.c | |||
| @@ -22,7 +22,7 @@ MODULE_LICENSE("GPL"); | |||
| 22 | 22 | ||
| 23 | unsigned afs_debug; | 23 | unsigned afs_debug; |
| 24 | module_param_named(debug, afs_debug, uint, S_IWUSR | S_IRUGO); | 24 | module_param_named(debug, afs_debug, uint, S_IWUSR | S_IRUGO); |
| 25 | MODULE_PARM_DESC(afs_debug, "AFS debugging mask"); | 25 | MODULE_PARM_DESC(debug, "AFS debugging mask"); |
| 26 | 26 | ||
| 27 | static char *rootcell; | 27 | static char *rootcell; |
| 28 | 28 | ||
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index a3510b8ba3e7..2f5503902c37 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c | |||
| @@ -283,11 +283,3 @@ void afs_mntpt_kill_timer(void) | |||
| 283 | cancel_delayed_work(&afs_mntpt_expiry_timer); | 283 | cancel_delayed_work(&afs_mntpt_expiry_timer); |
| 284 | flush_scheduled_work(); | 284 | flush_scheduled_work(); |
| 285 | } | 285 | } |
| 286 | |||
| 287 | /* | ||
| 288 | * begin unmount by attempting to remove all automounted mountpoints we added | ||
| 289 | */ | ||
| 290 | void afs_umount_begin(struct vfsmount *vfsmnt, int flags) | ||
| 291 | { | ||
| 292 | shrink_submounts(vfsmnt, &afs_vfsmounts); | ||
| 293 | } | ||
diff --git a/fs/afs/super.c b/fs/afs/super.c index 36bbce45f44b..4b572b801d8d 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
| @@ -50,7 +50,6 @@ static const struct super_operations afs_super_ops = { | |||
| 50 | .write_inode = afs_write_inode, | 50 | .write_inode = afs_write_inode, |
| 51 | .destroy_inode = afs_destroy_inode, | 51 | .destroy_inode = afs_destroy_inode, |
| 52 | .clear_inode = afs_clear_inode, | 52 | .clear_inode = afs_clear_inode, |
| 53 | .umount_begin = afs_umount_begin, | ||
| 54 | .put_super = afs_put_super, | 53 | .put_super = afs_put_super, |
| 55 | .show_options = generic_show_options, | 54 | .show_options = generic_show_options, |
| 56 | }; | 55 | }; |
| @@ -936,14 +936,6 @@ int aio_complete(struct kiocb *iocb, long res, long res2) | |||
| 936 | return 1; | 936 | return 1; |
| 937 | } | 937 | } |
| 938 | 938 | ||
| 939 | /* | ||
| 940 | * Check if the user asked us to deliver the result through an | ||
| 941 | * eventfd. The eventfd_signal() function is safe to be called | ||
| 942 | * from IRQ context. | ||
| 943 | */ | ||
| 944 | if (!IS_ERR(iocb->ki_eventfd)) | ||
| 945 | eventfd_signal(iocb->ki_eventfd, 1); | ||
| 946 | |||
| 947 | info = &ctx->ring_info; | 939 | info = &ctx->ring_info; |
| 948 | 940 | ||
| 949 | /* add a completion event to the ring buffer. | 941 | /* add a completion event to the ring buffer. |
| @@ -992,10 +984,27 @@ int aio_complete(struct kiocb *iocb, long res, long res2) | |||
| 992 | kunmap_atomic(ring, KM_IRQ1); | 984 | kunmap_atomic(ring, KM_IRQ1); |
| 993 | 985 | ||
| 994 | pr_debug("added to ring %p at [%lu]\n", iocb, tail); | 986 | pr_debug("added to ring %p at [%lu]\n", iocb, tail); |
| 987 | |||
| 988 | /* | ||
| 989 | * Check if the user asked us to deliver the result through an | ||
| 990 | * eventfd. The eventfd_signal() function is safe to be called | ||
| 991 | * from IRQ context. | ||
| 992 | */ | ||
| 993 | if (!IS_ERR(iocb->ki_eventfd)) | ||
| 994 | eventfd_signal(iocb->ki_eventfd, 1); | ||
| 995 | |||
| 995 | put_rq: | 996 | put_rq: |
| 996 | /* everything turned out well, dispose of the aiocb. */ | 997 | /* everything turned out well, dispose of the aiocb. */ |
| 997 | ret = __aio_put_req(ctx, iocb); | 998 | ret = __aio_put_req(ctx, iocb); |
| 998 | 999 | ||
| 1000 | /* | ||
| 1001 | * We have to order our ring_info tail store above and test | ||
| 1002 | * of the wait list below outside the wait lock. This is | ||
| 1003 | * like in wake_up_bit() where clearing a bit has to be | ||
| 1004 | * ordered with the unlocked test. | ||
| 1005 | */ | ||
| 1006 | smp_mb(); | ||
| 1007 | |||
| 999 | if (waitqueue_active(&ctx->wait)) | 1008 | if (waitqueue_active(&ctx->wait)) |
| 1000 | wake_up(&ctx->wait); | 1009 | wake_up(&ctx->wait); |
| 1001 | 1010 | ||
| @@ -1782,6 +1791,7 @@ asmlinkage long sys_io_getevents(aio_context_t ctx_id, | |||
| 1782 | put_ioctx(ioctx); | 1791 | put_ioctx(ioctx); |
| 1783 | } | 1792 | } |
| 1784 | 1793 | ||
| 1794 | asmlinkage_protect(5, ret, ctx_id, min_nr, nr, events, timeout); | ||
| 1785 | return ret; | 1795 | return ret; |
| 1786 | } | 1796 | } |
| 1787 | 1797 | ||
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 23321889d9b0..f42be069e085 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c | |||
| @@ -81,13 +81,10 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, | |||
| 81 | 81 | ||
| 82 | if (IS_ERR(anon_inode_inode)) | 82 | if (IS_ERR(anon_inode_inode)) |
| 83 | return -ENODEV; | 83 | return -ENODEV; |
| 84 | file = get_empty_filp(); | ||
| 85 | if (!file) | ||
| 86 | return -ENFILE; | ||
| 87 | 84 | ||
| 88 | error = get_unused_fd(); | 85 | error = get_unused_fd(); |
| 89 | if (error < 0) | 86 | if (error < 0) |
| 90 | goto err_put_filp; | 87 | return error; |
| 91 | fd = error; | 88 | fd = error; |
| 92 | 89 | ||
| 93 | /* | 90 | /* |
| @@ -114,14 +111,15 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, | |||
| 114 | dentry->d_flags &= ~DCACHE_UNHASHED; | 111 | dentry->d_flags &= ~DCACHE_UNHASHED; |
| 115 | d_instantiate(dentry, anon_inode_inode); | 112 | d_instantiate(dentry, anon_inode_inode); |
| 116 | 113 | ||
| 117 | file->f_path.mnt = mntget(anon_inode_mnt); | 114 | error = -ENFILE; |
| 118 | file->f_path.dentry = dentry; | 115 | file = alloc_file(anon_inode_mnt, dentry, |
| 116 | FMODE_READ | FMODE_WRITE, fops); | ||
| 117 | if (!file) | ||
| 118 | goto err_dput; | ||
| 119 | file->f_mapping = anon_inode_inode->i_mapping; | 119 | file->f_mapping = anon_inode_inode->i_mapping; |
| 120 | 120 | ||
| 121 | file->f_pos = 0; | 121 | file->f_pos = 0; |
| 122 | file->f_flags = O_RDWR; | 122 | file->f_flags = O_RDWR; |
| 123 | file->f_op = fops; | ||
| 124 | file->f_mode = FMODE_READ | FMODE_WRITE; | ||
| 125 | file->f_version = 0; | 123 | file->f_version = 0; |
| 126 | file->private_data = priv; | 124 | file->private_data = priv; |
| 127 | 125 | ||
| @@ -132,10 +130,10 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile, | |||
| 132 | *pfile = file; | 130 | *pfile = file; |
| 133 | return 0; | 131 | return 0; |
| 134 | 132 | ||
| 133 | err_dput: | ||
| 134 | dput(dentry); | ||
| 135 | err_put_unused_fd: | 135 | err_put_unused_fd: |
| 136 | put_unused_fd(fd); | 136 | put_unused_fd(fd); |
| 137 | err_put_filp: | ||
| 138 | put_filp(file); | ||
| 139 | return error; | 137 | return error; |
| 140 | } | 138 | } |
| 141 | EXPORT_SYMBOL_GPL(anon_inode_getfd); | 139 | EXPORT_SYMBOL_GPL(anon_inode_getfd); |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 41a958a7585e..5e1a4fb5cacb 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
| @@ -1424,6 +1424,18 @@ struct elf_note_info { | |||
| 1424 | int thread_notes; | 1424 | int thread_notes; |
| 1425 | }; | 1425 | }; |
| 1426 | 1426 | ||
| 1427 | /* | ||
| 1428 | * When a regset has a writeback hook, we call it on each thread before | ||
| 1429 | * dumping user memory. On register window machines, this makes sure the | ||
| 1430 | * user memory backing the register data is up to date before we read it. | ||
| 1431 | */ | ||
| 1432 | static void do_thread_regset_writeback(struct task_struct *task, | ||
| 1433 | const struct user_regset *regset) | ||
| 1434 | { | ||
| 1435 | if (regset->writeback) | ||
| 1436 | regset->writeback(task, regset, 1); | ||
| 1437 | } | ||
| 1438 | |||
| 1427 | static int fill_thread_core_info(struct elf_thread_core_info *t, | 1439 | static int fill_thread_core_info(struct elf_thread_core_info *t, |
| 1428 | const struct user_regset_view *view, | 1440 | const struct user_regset_view *view, |
| 1429 | long signr, size_t *total) | 1441 | long signr, size_t *total) |
| @@ -1445,6 +1457,8 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, | |||
| 1445 | sizeof(t->prstatus), &t->prstatus); | 1457 | sizeof(t->prstatus), &t->prstatus); |
| 1446 | *total += notesize(&t->notes[0]); | 1458 | *total += notesize(&t->notes[0]); |
| 1447 | 1459 | ||
| 1460 | do_thread_regset_writeback(t->task, &view->regsets[0]); | ||
| 1461 | |||
| 1448 | /* | 1462 | /* |
| 1449 | * Each other regset might generate a note too. For each regset | 1463 | * Each other regset might generate a note too. For each regset |
| 1450 | * that has no core_note_type or is inactive, we leave t->notes[i] | 1464 | * that has no core_note_type or is inactive, we leave t->notes[i] |
| @@ -1452,6 +1466,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, | |||
| 1452 | */ | 1466 | */ |
| 1453 | for (i = 1; i < view->n; ++i) { | 1467 | for (i = 1; i < view->n; ++i) { |
| 1454 | const struct user_regset *regset = &view->regsets[i]; | 1468 | const struct user_regset *regset = &view->regsets[i]; |
| 1469 | do_thread_regset_writeback(t->task, regset); | ||
| 1455 | if (regset->core_note_type && | 1470 | if (regset->core_note_type && |
| 1456 | (!regset->active || regset->active(t->task, regset))) { | 1471 | (!regset->active || regset->active(t->task, regset))) { |
| 1457 | int ret; | 1472 | int ret; |
| @@ -1194,6 +1194,8 @@ EXPORT_SYMBOL(bio_hw_segments); | |||
| 1194 | EXPORT_SYMBOL(bio_add_page); | 1194 | EXPORT_SYMBOL(bio_add_page); |
| 1195 | EXPORT_SYMBOL(bio_add_pc_page); | 1195 | EXPORT_SYMBOL(bio_add_pc_page); |
| 1196 | EXPORT_SYMBOL(bio_get_nr_vecs); | 1196 | EXPORT_SYMBOL(bio_get_nr_vecs); |
| 1197 | EXPORT_SYMBOL(bio_map_user); | ||
| 1198 | EXPORT_SYMBOL(bio_unmap_user); | ||
| 1197 | EXPORT_SYMBOL(bio_map_kern); | 1199 | EXPORT_SYMBOL(bio_map_kern); |
| 1198 | EXPORT_SYMBOL(bio_pair_release); | 1200 | EXPORT_SYMBOL(bio_pair_release); |
| 1199 | EXPORT_SYMBOL(bio_split); | 1201 | EXPORT_SYMBOL(bio_split); |
diff --git a/fs/buffer.c b/fs/buffer.c index 3ebccf4aa7e3..39ff14403d13 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
| @@ -627,8 +627,7 @@ repeat: | |||
| 627 | } | 627 | } |
| 628 | 628 | ||
| 629 | /** | 629 | /** |
| 630 | * sync_mapping_buffers - write out and wait upon a mapping's "associated" | 630 | * sync_mapping_buffers - write out & wait upon a mapping's "associated" buffers |
| 631 | * buffers | ||
| 632 | * @mapping: the mapping which wants those buffers written | 631 | * @mapping: the mapping which wants those buffers written |
| 633 | * | 632 | * |
| 634 | * Starts I/O against the buffers at mapping->private_list, and waits upon | 633 | * Starts I/O against the buffers at mapping->private_list, and waits upon |
| @@ -836,7 +835,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list) | |||
| 836 | smp_mb(); | 835 | smp_mb(); |
| 837 | if (buffer_dirty(bh)) { | 836 | if (buffer_dirty(bh)) { |
| 838 | list_add(&bh->b_assoc_buffers, | 837 | list_add(&bh->b_assoc_buffers, |
| 839 | &bh->b_assoc_map->private_list); | 838 | &mapping->private_list); |
| 840 | bh->b_assoc_map = mapping; | 839 | bh->b_assoc_map = mapping; |
| 841 | } | 840 | } |
| 842 | spin_unlock(lock); | 841 | spin_unlock(lock); |
| @@ -1182,7 +1181,20 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size) | |||
| 1182 | void mark_buffer_dirty(struct buffer_head *bh) | 1181 | void mark_buffer_dirty(struct buffer_head *bh) |
| 1183 | { | 1182 | { |
| 1184 | WARN_ON_ONCE(!buffer_uptodate(bh)); | 1183 | WARN_ON_ONCE(!buffer_uptodate(bh)); |
| 1185 | if (!buffer_dirty(bh) && !test_set_buffer_dirty(bh)) | 1184 | |
| 1185 | /* | ||
| 1186 | * Very *carefully* optimize the it-is-already-dirty case. | ||
| 1187 | * | ||
| 1188 | * Don't let the final "is it dirty" escape to before we | ||
| 1189 | * perhaps modified the buffer. | ||
| 1190 | */ | ||
| 1191 | if (buffer_dirty(bh)) { | ||
| 1192 | smp_mb(); | ||
| 1193 | if (buffer_dirty(bh)) | ||
| 1194 | return; | ||
| 1195 | } | ||
| 1196 | |||
| 1197 | if (!test_set_buffer_dirty(bh)) | ||
| 1186 | __set_page_dirty(bh->b_page, page_mapping(bh->b_page), 0); | 1198 | __set_page_dirty(bh->b_page, page_mapping(bh->b_page), 0); |
| 1187 | } | 1199 | } |
| 1188 | 1200 | ||
| @@ -2565,14 +2577,13 @@ int nobh_write_end(struct file *file, struct address_space *mapping, | |||
| 2565 | struct inode *inode = page->mapping->host; | 2577 | struct inode *inode = page->mapping->host; |
| 2566 | struct buffer_head *head = fsdata; | 2578 | struct buffer_head *head = fsdata; |
| 2567 | struct buffer_head *bh; | 2579 | struct buffer_head *bh; |
| 2580 | BUG_ON(fsdata != NULL && page_has_buffers(page)); | ||
| 2568 | 2581 | ||
| 2569 | if (!PageMappedToDisk(page)) { | 2582 | if (unlikely(copied < len) && !page_has_buffers(page)) |
| 2570 | if (unlikely(copied < len) && !page_has_buffers(page)) | 2583 | attach_nobh_buffers(page, head); |
| 2571 | attach_nobh_buffers(page, head); | 2584 | if (page_has_buffers(page)) |
| 2572 | if (page_has_buffers(page)) | 2585 | return generic_write_end(file, mapping, pos, len, |
| 2573 | return generic_write_end(file, mapping, pos, len, | 2586 | copied, page, fsdata); |
| 2574 | copied, page, fsdata); | ||
| 2575 | } | ||
| 2576 | 2587 | ||
| 2577 | SetPageUptodate(page); | 2588 | SetPageUptodate(page); |
| 2578 | set_page_dirty(page); | 2589 | set_page_dirty(page); |
| @@ -3214,7 +3225,7 @@ static int buffer_cpu_notify(struct notifier_block *self, | |||
| 3214 | } | 3225 | } |
| 3215 | 3226 | ||
| 3216 | /** | 3227 | /** |
| 3217 | * bh_uptodate_or_lock: Test whether the buffer is uptodate | 3228 | * bh_uptodate_or_lock - Test whether the buffer is uptodate |
| 3218 | * @bh: struct buffer_head | 3229 | * @bh: struct buffer_head |
| 3219 | * | 3230 | * |
| 3220 | * Return true if the buffer is up-to-date and false, | 3231 | * Return true if the buffer is up-to-date and false, |
| @@ -3233,7 +3244,7 @@ int bh_uptodate_or_lock(struct buffer_head *bh) | |||
| 3233 | EXPORT_SYMBOL(bh_uptodate_or_lock); | 3244 | EXPORT_SYMBOL(bh_uptodate_or_lock); |
| 3234 | 3245 | ||
| 3235 | /** | 3246 | /** |
| 3236 | * bh_submit_read: Submit a locked buffer for reading | 3247 | * bh_submit_read - Submit a locked buffer for reading |
| 3237 | * @bh: struct buffer_head | 3248 | * @bh: struct buffer_head |
| 3238 | * | 3249 | * |
| 3239 | * Returns zero on success and -EIO on error. | 3250 | * Returns zero on success and -EIO on error. |
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index edd248367b36..dbd91461853c 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
| @@ -6,7 +6,9 @@ and sync so that events like out of disk space get reported properly on | |||
| 6 | cached files. Fix setxattr failure to certain Samba versions. Fix mount | 6 | cached files. Fix setxattr failure to certain Samba versions. Fix mount |
| 7 | of second share to disconnected server session (autoreconnect on this). | 7 | of second share to disconnected server session (autoreconnect on this). |
| 8 | Add ability to modify cifs acls for handling chmod (when mounted with | 8 | Add ability to modify cifs acls for handling chmod (when mounted with |
| 9 | cifsacl flag). | 9 | cifsacl flag). Fix prefixpath path separator so we can handle mounts |
| 10 | with prefixpaths longer than one directory (one path component) when | ||
| 11 | mounted to Windows servers. | ||
| 10 | 12 | ||
| 11 | Version 1.51 | 13 | Version 1.51 |
| 12 | ------------ | 14 | ------------ |
diff --git a/fs/cifs/README b/fs/cifs/README index c623e2f9c5db..50306229b0f9 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
| @@ -461,7 +461,7 @@ A partial list of the supported mount options follows: | |||
| 461 | cifsacl Report mode bits (e.g. on stat) based on the Windows ACL for | 461 | cifsacl Report mode bits (e.g. on stat) based on the Windows ACL for |
| 462 | the file. (EXPERIMENTAL) | 462 | the file. (EXPERIMENTAL) |
| 463 | servern Specify the server 's netbios name (RFC1001 name) to use | 463 | servern Specify the server 's netbios name (RFC1001 name) to use |
| 464 | when attempting to setup a session to the server. This is | 464 | when attempting to setup a session to the server. |
| 465 | This is needed for mounting to some older servers (such | 465 | This is needed for mounting to some older servers (such |
| 466 | as OS/2 or Windows 98 and Windows ME) since they do not | 466 | as OS/2 or Windows 98 and Windows ME) since they do not |
| 467 | support a default server name. A server name can be up | 467 | support a default server name. A server name can be up |
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 73c4c419663c..0228ed06069e 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c | |||
| @@ -98,8 +98,7 @@ void cifs_dump_mids(struct TCP_Server_Info *server) | |||
| 98 | if (mid_entry->resp_buf) { | 98 | if (mid_entry->resp_buf) { |
| 99 | cifs_dump_detail(mid_entry->resp_buf); | 99 | cifs_dump_detail(mid_entry->resp_buf); |
| 100 | cifs_dump_mem("existing buf: ", | 100 | cifs_dump_mem("existing buf: ", |
| 101 | mid_entry->resp_buf, | 101 | mid_entry->resp_buf, 62); |
| 102 | 62 /* fixme */); | ||
| 103 | } | 102 | } |
| 104 | } | 103 | } |
| 105 | } | 104 | } |
| @@ -439,7 +438,7 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset, | |||
| 439 | 438 | ||
| 440 | return length; | 439 | return length; |
| 441 | } | 440 | } |
| 442 | #endif | 441 | #endif /* STATS */ |
| 443 | 442 | ||
| 444 | static struct proc_dir_entry *proc_fs_cifs; | 443 | static struct proc_dir_entry *proc_fs_cifs; |
| 445 | read_proc_t cifs_txanchor_read; | 444 | read_proc_t cifs_txanchor_read; |
| @@ -482,7 +481,7 @@ cifs_proc_init(void) | |||
| 482 | cifs_stats_read, NULL); | 481 | cifs_stats_read, NULL); |
| 483 | if (pde) | 482 | if (pde) |
| 484 | pde->write_proc = cifs_stats_write; | 483 | pde->write_proc = cifs_stats_write; |
| 485 | #endif | 484 | #endif /* STATS */ |
| 486 | pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs, | 485 | pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs, |
| 487 | cifsFYI_read, NULL); | 486 | cifsFYI_read, NULL); |
| 488 | if (pde) | 487 | if (pde) |
| @@ -918,4 +917,12 @@ security_flags_write(struct file *file, const char __user *buffer, | |||
| 918 | /* BB should we turn on MAY flags for other MUST options? */ | 917 | /* BB should we turn on MAY flags for other MUST options? */ |
| 919 | return count; | 918 | return count; |
| 920 | } | 919 | } |
| 921 | #endif | 920 | #else |
| 921 | inline void cifs_proc_init(void) | ||
| 922 | { | ||
| 923 | } | ||
| 924 | |||
| 925 | inline void cifs_proc_clean(void) | ||
| 926 | { | ||
| 927 | } | ||
| 928 | #endif /* PROC_FS */ | ||
diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h index c26cd0d2c6d5..5eb3b83bbfa7 100644 --- a/fs/cifs/cifs_debug.h +++ b/fs/cifs/cifs_debug.h | |||
| @@ -25,8 +25,11 @@ | |||
| 25 | 25 | ||
| 26 | void cifs_dump_mem(char *label, void *data, int length); | 26 | void cifs_dump_mem(char *label, void *data, int length); |
| 27 | #ifdef CONFIG_CIFS_DEBUG2 | 27 | #ifdef CONFIG_CIFS_DEBUG2 |
| 28 | #define DBG2 2 | ||
| 28 | void cifs_dump_detail(struct smb_hdr *); | 29 | void cifs_dump_detail(struct smb_hdr *); |
| 29 | void cifs_dump_mids(struct TCP_Server_Info *); | 30 | void cifs_dump_mids(struct TCP_Server_Info *); |
| 31 | #else | ||
| 32 | #define DBG2 0 | ||
| 30 | #endif | 33 | #endif |
| 31 | extern int traceSMB; /* flag which enables the function below */ | 34 | extern int traceSMB; /* flag which enables the function below */ |
| 32 | void dump_smb(struct smb_hdr *, int); | 35 | void dump_smb(struct smb_hdr *, int); |
| @@ -64,10 +67,10 @@ extern int cifsERROR; | |||
| 64 | * --------- | 67 | * --------- |
| 65 | */ | 68 | */ |
| 66 | #else /* _CIFS_DEBUG */ | 69 | #else /* _CIFS_DEBUG */ |
| 67 | #define cERROR(button,prspec) | 70 | #define cERROR(button, prspec) |
| 68 | #define cEVENT(format,arg...) | 71 | #define cEVENT(format, arg...) |
| 69 | #define cFYI(button, prspec) | 72 | #define cFYI(button, prspec) |
| 70 | #define cifserror(format,arg...) | 73 | #define cifserror(format, arg...) |
| 71 | #endif /* _CIFS_DEBUG */ | 74 | #endif /* _CIFS_DEBUG */ |
| 72 | 75 | ||
| 73 | #endif /* _H_CIFS_DEBUG */ | 76 | #endif /* _H_CIFS_DEBUG */ |
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index 6ad447529961..56c924033b78 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c | |||
| @@ -33,7 +33,6 @@ void dfs_shrink_umount_helper(struct vfsmount *vfsmnt) | |||
| 33 | { | 33 | { |
| 34 | mark_mounts_for_expiry(&cifs_dfs_automount_list); | 34 | mark_mounts_for_expiry(&cifs_dfs_automount_list); |
| 35 | mark_mounts_for_expiry(&cifs_dfs_automount_list); | 35 | mark_mounts_for_expiry(&cifs_dfs_automount_list); |
| 36 | shrink_submounts(vfsmnt, &cifs_dfs_automount_list); | ||
| 37 | } | 36 | } |
| 38 | 37 | ||
| 39 | /** | 38 | /** |
| @@ -74,7 +73,7 @@ static char *cifs_get_share_name(const char *node_name) | |||
| 74 | pSep = memchr(UNC+2, '\\', len-2); | 73 | pSep = memchr(UNC+2, '\\', len-2); |
| 75 | if (!pSep) { | 74 | if (!pSep) { |
| 76 | cERROR(1, ("%s: no server name end in node name: %s", | 75 | cERROR(1, ("%s: no server name end in node name: %s", |
| 77 | __FUNCTION__, node_name)); | 76 | __func__, node_name)); |
| 78 | kfree(UNC); | 77 | kfree(UNC); |
| 79 | return NULL; | 78 | return NULL; |
| 80 | } | 79 | } |
| @@ -84,7 +83,7 @@ static char *cifs_get_share_name(const char *node_name) | |||
| 84 | pSep = memchr(UNC+(pSep-UNC), '\\', len-(pSep-UNC)); | 83 | pSep = memchr(UNC+(pSep-UNC), '\\', len-(pSep-UNC)); |
| 85 | if (!pSep) { | 84 | if (!pSep) { |
| 86 | cERROR(1, ("%s:2 cant find share name in node name: %s", | 85 | cERROR(1, ("%s:2 cant find share name in node name: %s", |
| 87 | __FUNCTION__, node_name)); | 86 | __func__, node_name)); |
| 88 | kfree(UNC); | 87 | kfree(UNC); |
| 89 | return NULL; | 88 | return NULL; |
| 90 | } | 89 | } |
| @@ -127,7 +126,7 @@ static char *compose_mount_options(const char *sb_mountdata, | |||
| 127 | rc = dns_resolve_server_name_to_ip(*devname, &srvIP); | 126 | rc = dns_resolve_server_name_to_ip(*devname, &srvIP); |
| 128 | if (rc != 0) { | 127 | if (rc != 0) { |
| 129 | cERROR(1, ("%s: Failed to resolve server part of %s to IP", | 128 | cERROR(1, ("%s: Failed to resolve server part of %s to IP", |
| 130 | __FUNCTION__, *devname)); | 129 | __func__, *devname)); |
| 131 | mountdata = ERR_PTR(rc); | 130 | mountdata = ERR_PTR(rc); |
| 132 | goto compose_mount_options_out; | 131 | goto compose_mount_options_out; |
| 133 | } | 132 | } |
| @@ -181,8 +180,8 @@ static char *compose_mount_options(const char *sb_mountdata, | |||
| 181 | } | 180 | } |
| 182 | } | 181 | } |
| 183 | 182 | ||
| 184 | /*cFYI(1,("%s: parent mountdata: %s", __FUNCTION__,sb_mountdata));*/ | 183 | /*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/ |
| 185 | /*cFYI(1, ("%s: submount mountdata: %s", __FUNCTION__, mountdata ));*/ | 184 | /*cFYI(1, ("%s: submount mountdata: %s", __func__, mountdata ));*/ |
| 186 | 185 | ||
| 187 | compose_mount_options_out: | 186 | compose_mount_options_out: |
| 188 | kfree(srvIP); | 187 | kfree(srvIP); |
| @@ -286,7 +285,7 @@ static void dump_referral(const struct dfs_info3_param *ref) | |||
| 286 | cFYI(1, ("DFS: node path: %s", ref->node_name)); | 285 | cFYI(1, ("DFS: node path: %s", ref->node_name)); |
| 287 | cFYI(1, ("DFS: fl: %hd, srv_type: %hd", ref->flags, ref->server_type)); | 286 | cFYI(1, ("DFS: fl: %hd, srv_type: %hd", ref->flags, ref->server_type)); |
| 288 | cFYI(1, ("DFS: ref_flags: %hd, path_consumed: %hd", ref->ref_flag, | 287 | cFYI(1, ("DFS: ref_flags: %hd, path_consumed: %hd", ref->ref_flag, |
| 289 | ref->PathConsumed)); | 288 | ref->path_consumed)); |
| 290 | } | 289 | } |
| 291 | 290 | ||
| 292 | 291 | ||
| @@ -302,7 +301,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) | |||
| 302 | int rc = 0; | 301 | int rc = 0; |
| 303 | struct vfsmount *mnt = ERR_PTR(-ENOENT); | 302 | struct vfsmount *mnt = ERR_PTR(-ENOENT); |
| 304 | 303 | ||
| 305 | cFYI(1, ("in %s", __FUNCTION__)); | 304 | cFYI(1, ("in %s", __func__)); |
| 306 | BUG_ON(IS_ROOT(dentry)); | 305 | BUG_ON(IS_ROOT(dentry)); |
| 307 | 306 | ||
| 308 | xid = GetXid(); | 307 | xid = GetXid(); |
| @@ -336,7 +335,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) | |||
| 336 | len = strlen(referrals[i].node_name); | 335 | len = strlen(referrals[i].node_name); |
| 337 | if (len < 2) { | 336 | if (len < 2) { |
| 338 | cERROR(1, ("%s: Net Address path too short: %s", | 337 | cERROR(1, ("%s: Net Address path too short: %s", |
| 339 | __FUNCTION__, referrals[i].node_name)); | 338 | __func__, referrals[i].node_name)); |
| 340 | rc = -EINVAL; | 339 | rc = -EINVAL; |
| 341 | goto out_err; | 340 | goto out_err; |
| 342 | } | 341 | } |
| @@ -344,7 +343,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) | |||
| 344 | nd->path.dentry, | 343 | nd->path.dentry, |
| 345 | referrals[i].node_name); | 344 | referrals[i].node_name); |
| 346 | cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p", | 345 | cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p", |
| 347 | __FUNCTION__, | 346 | __func__, |
| 348 | referrals[i].node_name, mnt)); | 347 | referrals[i].node_name, mnt)); |
| 349 | 348 | ||
| 350 | /* complete mount procedure if we accured submount */ | 349 | /* complete mount procedure if we accured submount */ |
| @@ -365,7 +364,7 @@ out: | |||
| 365 | FreeXid(xid); | 364 | FreeXid(xid); |
| 366 | free_dfs_info_array(referrals, num_referrals); | 365 | free_dfs_info_array(referrals, num_referrals); |
| 367 | kfree(full_path); | 366 | kfree(full_path); |
| 368 | cFYI(1, ("leaving %s" , __FUNCTION__)); | 367 | cFYI(1, ("leaving %s" , __func__)); |
| 369 | return ERR_PTR(rc); | 368 | return ERR_PTR(rc); |
| 370 | out_err: | 369 | out_err: |
| 371 | path_put(&nd->path); | 370 | path_put(&nd->path); |
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c index d543accc10dd..6653e29637a7 100644 --- a/fs/cifs/cifs_spnego.c +++ b/fs/cifs/cifs_spnego.c | |||
| @@ -125,7 +125,7 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo) | |||
| 125 | #ifdef CONFIG_CIFS_DEBUG2 | 125 | #ifdef CONFIG_CIFS_DEBUG2 |
| 126 | if (cifsFYI && !IS_ERR(spnego_key)) { | 126 | if (cifsFYI && !IS_ERR(spnego_key)) { |
| 127 | struct cifs_spnego_msg *msg = spnego_key->payload.data; | 127 | struct cifs_spnego_msg *msg = spnego_key->payload.data; |
| 128 | cifs_dump_mem("SPNEGO reply blob:", msg->data, min(1024, | 128 | cifs_dump_mem("SPNEGO reply blob:", msg->data, min(1024U, |
| 129 | msg->secblob_len + msg->sesskey_len)); | 129 | msg->secblob_len + msg->sesskey_len)); |
| 130 | } | 130 | } |
| 131 | #endif /* CONFIG_CIFS_DEBUG2 */ | 131 | #endif /* CONFIG_CIFS_DEBUG2 */ |
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index b5903b89250d..7d75272a6b3f 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | * | 32 | * |
| 33 | */ | 33 | */ |
| 34 | int | 34 | int |
| 35 | cifs_strfromUCS_le(char *to, const __le16 * from, | 35 | cifs_strfromUCS_le(char *to, const __le16 *from, |
| 36 | int len, const struct nls_table *codepage) | 36 | int len, const struct nls_table *codepage) |
| 37 | { | 37 | { |
| 38 | int i; | 38 | int i; |
| @@ -61,7 +61,7 @@ cifs_strfromUCS_le(char *to, const __le16 * from, | |||
| 61 | * | 61 | * |
| 62 | */ | 62 | */ |
| 63 | int | 63 | int |
| 64 | cifs_strtoUCS(__le16 * to, const char *from, int len, | 64 | cifs_strtoUCS(__le16 *to, const char *from, int len, |
| 65 | const struct nls_table *codepage) | 65 | const struct nls_table *codepage) |
| 66 | { | 66 | { |
| 67 | int charlen; | 67 | int charlen; |
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h index 614c11fcdcb6..14eb9a2395d3 100644 --- a/fs/cifs/cifs_unicode.h +++ b/fs/cifs/cifs_unicode.h | |||
| @@ -254,7 +254,8 @@ UniStrstr(const wchar_t *ucs1, const wchar_t *ucs2) | |||
| 254 | const wchar_t *anchor2 = ucs2; | 254 | const wchar_t *anchor2 = ucs2; |
| 255 | 255 | ||
| 256 | while (*ucs1) { | 256 | while (*ucs1) { |
| 257 | if (*ucs1 == *ucs2) { /* Partial match found */ | 257 | if (*ucs1 == *ucs2) { |
| 258 | /* Partial match found */ | ||
| 258 | ucs1++; | 259 | ucs1++; |
| 259 | ucs2++; | 260 | ucs2++; |
| 260 | } else { | 261 | } else { |
| @@ -279,7 +280,8 @@ UniToupper(register wchar_t uc) | |||
| 279 | { | 280 | { |
| 280 | register const struct UniCaseRange *rp; | 281 | register const struct UniCaseRange *rp; |
| 281 | 282 | ||
| 282 | if (uc < sizeof (CifsUniUpperTable)) { /* Latin characters */ | 283 | if (uc < sizeof(CifsUniUpperTable)) { |
| 284 | /* Latin characters */ | ||
| 283 | return uc + CifsUniUpperTable[uc]; /* Use base tables */ | 285 | return uc + CifsUniUpperTable[uc]; /* Use base tables */ |
| 284 | } else { | 286 | } else { |
| 285 | rp = CifsUniUpperRange; /* Use range tables */ | 287 | rp = CifsUniUpperRange; /* Use range tables */ |
| @@ -320,7 +322,8 @@ UniTolower(wchar_t uc) | |||
| 320 | { | 322 | { |
| 321 | register struct UniCaseRange *rp; | 323 | register struct UniCaseRange *rp; |
| 322 | 324 | ||
| 323 | if (uc < sizeof (UniLowerTable)) { /* Latin characters */ | 325 | if (uc < sizeof(UniLowerTable)) { |
| 326 | /* Latin characters */ | ||
| 324 | return uc + UniLowerTable[uc]; /* Use base tables */ | 327 | return uc + UniLowerTable[uc]; /* Use base tables */ |
| 325 | } else { | 328 | } else { |
| 326 | rp = UniLowerRange; /* Use range tables */ | 329 | rp = UniLowerRange; /* Use range tables */ |
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index a7035bd18e4e..1cb5b0a9f2ac 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * fs/cifs/cifsacl.c | 2 | * fs/cifs/cifsacl.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) International Business Machines Corp., 2007 | 4 | * Copyright (C) International Business Machines Corp., 2007,2008 |
| 5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
| 6 | * | 6 | * |
| 7 | * Contains the routines for mapping CIFS/NTFS ACLs | 7 | * Contains the routines for mapping CIFS/NTFS ACLs |
| @@ -46,8 +46,7 @@ static struct cifs_wksid wksidarr[NUM_WK_SIDS] = { | |||
| 46 | static const struct cifs_sid sid_everyone = { | 46 | static const struct cifs_sid sid_everyone = { |
| 47 | 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; | 47 | 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; |
| 48 | /* group users */ | 48 | /* group users */ |
| 49 | static const struct cifs_sid sid_user = | 49 | static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; |
| 50 | {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; | ||
| 51 | 50 | ||
| 52 | 51 | ||
| 53 | int match_sid(struct cifs_sid *ctsid) | 52 | int match_sid(struct cifs_sid *ctsid) |
| @@ -195,9 +194,9 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode, | |||
| 195 | /* For deny ACEs we change the mask so that subsequent allow access | 194 | /* For deny ACEs we change the mask so that subsequent allow access |
| 196 | control entries do not turn on the bits we are denying */ | 195 | control entries do not turn on the bits we are denying */ |
| 197 | if (type == ACCESS_DENIED) { | 196 | if (type == ACCESS_DENIED) { |
| 198 | if (flags & GENERIC_ALL) { | 197 | if (flags & GENERIC_ALL) |
| 199 | *pbits_to_set &= ~S_IRWXUGO; | 198 | *pbits_to_set &= ~S_IRWXUGO; |
| 200 | } | 199 | |
| 201 | if ((flags & GENERIC_WRITE) || | 200 | if ((flags & GENERIC_WRITE) || |
| 202 | ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) | 201 | ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) |
| 203 | *pbits_to_set &= ~S_IWUGO; | 202 | *pbits_to_set &= ~S_IWUGO; |
| @@ -216,9 +215,7 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode, | |||
| 216 | 215 | ||
| 217 | if (flags & GENERIC_ALL) { | 216 | if (flags & GENERIC_ALL) { |
| 218 | *pmode |= (S_IRWXUGO & (*pbits_to_set)); | 217 | *pmode |= (S_IRWXUGO & (*pbits_to_set)); |
| 219 | #ifdef CONFIG_CIFS_DEBUG2 | 218 | cFYI(DBG2, ("all perms")); |
| 220 | cFYI(1, ("all perms")); | ||
| 221 | #endif | ||
| 222 | return; | 219 | return; |
| 223 | } | 220 | } |
| 224 | if ((flags & GENERIC_WRITE) || | 221 | if ((flags & GENERIC_WRITE) || |
| @@ -231,9 +228,7 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode, | |||
| 231 | ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) | 228 | ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) |
| 232 | *pmode |= (S_IXUGO & (*pbits_to_set)); | 229 | *pmode |= (S_IXUGO & (*pbits_to_set)); |
| 233 | 230 | ||
| 234 | #ifdef CONFIG_CIFS_DEBUG2 | 231 | cFYI(DBG2, ("access flags 0x%x mode now 0x%x", flags, *pmode)); |
| 235 | cFYI(1, ("access flags 0x%x mode now 0x%x", flags, *pmode)); | ||
| 236 | #endif | ||
| 237 | return; | 232 | return; |
| 238 | } | 233 | } |
| 239 | 234 | ||
| @@ -262,13 +257,11 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use, | |||
| 262 | if (mode & S_IXUGO) | 257 | if (mode & S_IXUGO) |
| 263 | *pace_flags |= SET_FILE_EXEC_RIGHTS; | 258 | *pace_flags |= SET_FILE_EXEC_RIGHTS; |
| 264 | 259 | ||
| 265 | #ifdef CONFIG_CIFS_DEBUG2 | 260 | cFYI(DBG2, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags)); |
| 266 | cFYI(1, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags)); | ||
| 267 | #endif | ||
| 268 | return; | 261 | return; |
| 269 | } | 262 | } |
| 270 | 263 | ||
| 271 | static __le16 fill_ace_for_sid(struct cifs_ace *pntace, | 264 | static __u16 fill_ace_for_sid(struct cifs_ace *pntace, |
| 272 | const struct cifs_sid *psid, __u64 nmode, umode_t bits) | 265 | const struct cifs_sid *psid, __u64 nmode, umode_t bits) |
| 273 | { | 266 | { |
| 274 | int i; | 267 | int i; |
| @@ -358,11 +351,9 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, | |||
| 358 | return; | 351 | return; |
| 359 | } | 352 | } |
| 360 | 353 | ||
| 361 | #ifdef CONFIG_CIFS_DEBUG2 | 354 | cFYI(DBG2, ("DACL revision %d size %d num aces %d", |
| 362 | cFYI(1, ("DACL revision %d size %d num aces %d", | ||
| 363 | le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size), | 355 | le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size), |
| 364 | le32_to_cpu(pdacl->num_aces))); | 356 | le32_to_cpu(pdacl->num_aces))); |
| 365 | #endif | ||
| 366 | 357 | ||
| 367 | /* reset rwx permissions for user/group/other. | 358 | /* reset rwx permissions for user/group/other. |
| 368 | Also, if num_aces is 0 i.e. DACL has no ACEs, | 359 | Also, if num_aces is 0 i.e. DACL has no ACEs, |
| @@ -381,10 +372,6 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, | |||
| 381 | ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), | 372 | ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), |
| 382 | GFP_KERNEL); | 373 | GFP_KERNEL); |
| 383 | 374 | ||
| 384 | /* cifscred->cecount = pdacl->num_aces; | ||
| 385 | cifscred->aces = kmalloc(num_aces * | ||
| 386 | sizeof(struct cifs_ace *), GFP_KERNEL);*/ | ||
| 387 | |||
| 388 | for (i = 0; i < num_aces; ++i) { | 375 | for (i = 0; i < num_aces; ++i) { |
| 389 | ppace[i] = (struct cifs_ace *) (acl_base + acl_size); | 376 | ppace[i] = (struct cifs_ace *) (acl_base + acl_size); |
| 390 | #ifdef CONFIG_CIFS_DEBUG2 | 377 | #ifdef CONFIG_CIFS_DEBUG2 |
| @@ -424,7 +411,7 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, | |||
| 424 | static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, | 411 | static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, |
| 425 | struct cifs_sid *pgrpsid, __u64 nmode) | 412 | struct cifs_sid *pgrpsid, __u64 nmode) |
| 426 | { | 413 | { |
| 427 | __le16 size = 0; | 414 | u16 size = 0; |
| 428 | struct cifs_acl *pnndacl; | 415 | struct cifs_acl *pnndacl; |
| 429 | 416 | ||
| 430 | pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl)); | 417 | pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl)); |
| @@ -437,7 +424,7 @@ static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, | |||
| 437 | &sid_everyone, nmode, S_IRWXO); | 424 | &sid_everyone, nmode, S_IRWXO); |
| 438 | 425 | ||
| 439 | pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl)); | 426 | pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl)); |
| 440 | pndacl->num_aces = 3; | 427 | pndacl->num_aces = cpu_to_le32(3); |
| 441 | 428 | ||
| 442 | return (0); | 429 | return (0); |
| 443 | } | 430 | } |
| @@ -495,13 +482,11 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, | |||
| 495 | le32_to_cpu(pntsd->gsidoffset)); | 482 | le32_to_cpu(pntsd->gsidoffset)); |
| 496 | dacloffset = le32_to_cpu(pntsd->dacloffset); | 483 | dacloffset = le32_to_cpu(pntsd->dacloffset); |
| 497 | dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); | 484 | dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); |
| 498 | #ifdef CONFIG_CIFS_DEBUG2 | 485 | cFYI(DBG2, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x " |
| 499 | cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x " | ||
| 500 | "sacloffset 0x%x dacloffset 0x%x", | 486 | "sacloffset 0x%x dacloffset 0x%x", |
| 501 | pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), | 487 | pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), |
| 502 | le32_to_cpu(pntsd->gsidoffset), | 488 | le32_to_cpu(pntsd->gsidoffset), |
| 503 | le32_to_cpu(pntsd->sacloffset), dacloffset)); | 489 | le32_to_cpu(pntsd->sacloffset), dacloffset)); |
| 504 | #endif | ||
| 505 | /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */ | 490 | /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */ |
| 506 | rc = parse_sid(owner_sid_ptr, end_of_acl); | 491 | rc = parse_sid(owner_sid_ptr, end_of_acl); |
| 507 | if (rc) | 492 | if (rc) |
| @@ -571,9 +556,9 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | |||
| 571 | 556 | ||
| 572 | /* Retrieve an ACL from the server */ | 557 | /* Retrieve an ACL from the server */ |
| 573 | static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | 558 | static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, |
| 574 | const char *path) | 559 | const char *path, const __u16 *pfid) |
| 575 | { | 560 | { |
| 576 | struct cifsFileInfo *open_file; | 561 | struct cifsFileInfo *open_file = NULL; |
| 577 | int unlock_file = FALSE; | 562 | int unlock_file = FALSE; |
| 578 | int xid; | 563 | int xid; |
| 579 | int rc = -EIO; | 564 | int rc = -EIO; |
| @@ -588,7 +573,11 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | |||
| 588 | return NULL; | 573 | return NULL; |
| 589 | 574 | ||
| 590 | xid = GetXid(); | 575 | xid = GetXid(); |
| 591 | open_file = find_readable_file(CIFS_I(inode)); | 576 | if (pfid == NULL) |
| 577 | open_file = find_readable_file(CIFS_I(inode)); | ||
| 578 | else | ||
| 579 | fid = *pfid; | ||
| 580 | |||
| 592 | sb = inode->i_sb; | 581 | sb = inode->i_sb; |
| 593 | if (sb == NULL) { | 582 | if (sb == NULL) { |
| 594 | FreeXid(xid); | 583 | FreeXid(xid); |
| @@ -599,7 +588,7 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | |||
| 599 | if (open_file) { | 588 | if (open_file) { |
| 600 | unlock_file = TRUE; | 589 | unlock_file = TRUE; |
| 601 | fid = open_file->netfid; | 590 | fid = open_file->netfid; |
| 602 | } else { | 591 | } else if (pfid == NULL) { |
| 603 | int oplock = FALSE; | 592 | int oplock = FALSE; |
| 604 | /* open file */ | 593 | /* open file */ |
| 605 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, | 594 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, |
| @@ -615,10 +604,11 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | |||
| 615 | 604 | ||
| 616 | rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); | 605 | rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); |
| 617 | cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); | 606 | cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); |
| 618 | if (unlock_file == TRUE) | 607 | if (unlock_file == TRUE) /* find_readable_file increments ref count */ |
| 619 | atomic_dec(&open_file->wrtPending); | 608 | atomic_dec(&open_file->wrtPending); |
| 620 | else | 609 | else if (pfid == NULL) /* if opened above we have to close the handle */ |
| 621 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | 610 | CIFSSMBClose(xid, cifs_sb->tcon, fid); |
| 611 | /* else handle was passed in by caller */ | ||
| 622 | 612 | ||
| 623 | FreeXid(xid); | 613 | FreeXid(xid); |
| 624 | return pntsd; | 614 | return pntsd; |
| @@ -636,9 +626,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | |||
| 636 | struct super_block *sb; | 626 | struct super_block *sb; |
| 637 | struct cifs_sb_info *cifs_sb; | 627 | struct cifs_sb_info *cifs_sb; |
| 638 | 628 | ||
| 639 | #ifdef CONFIG_CIFS_DEBUG2 | 629 | cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); |
| 640 | cFYI(1, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); | ||
| 641 | #endif | ||
| 642 | 630 | ||
| 643 | if (!inode) | 631 | if (!inode) |
| 644 | return (rc); | 632 | return (rc); |
| @@ -669,9 +657,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | |||
| 669 | } | 657 | } |
| 670 | 658 | ||
| 671 | rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); | 659 | rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); |
| 672 | #ifdef CONFIG_CIFS_DEBUG2 | 660 | cFYI(DBG2, ("SetCIFSACL rc = %d", rc)); |
| 673 | cFYI(1, ("SetCIFSACL rc = %d", rc)); | ||
| 674 | #endif | ||
| 675 | if (unlock_file == TRUE) | 661 | if (unlock_file == TRUE) |
| 676 | atomic_dec(&open_file->wrtPending); | 662 | atomic_dec(&open_file->wrtPending); |
| 677 | else | 663 | else |
| @@ -683,16 +669,14 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | |||
| 683 | } | 669 | } |
| 684 | 670 | ||
| 685 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ | 671 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ |
| 686 | void acl_to_uid_mode(struct inode *inode, const char *path) | 672 | void acl_to_uid_mode(struct inode *inode, const char *path, const __u16 *pfid) |
| 687 | { | 673 | { |
| 688 | struct cifs_ntsd *pntsd = NULL; | 674 | struct cifs_ntsd *pntsd = NULL; |
| 689 | u32 acllen = 0; | 675 | u32 acllen = 0; |
| 690 | int rc = 0; | 676 | int rc = 0; |
| 691 | 677 | ||
| 692 | #ifdef CONFIG_CIFS_DEBUG2 | 678 | cFYI(DBG2, ("converting ACL to mode for %s", path)); |
| 693 | cFYI(1, ("converting ACL to mode for %s", path)); | 679 | pntsd = get_cifs_acl(&acllen, inode, path, pfid); |
| 694 | #endif | ||
| 695 | pntsd = get_cifs_acl(&acllen, inode, path); | ||
| 696 | 680 | ||
| 697 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ | 681 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ |
| 698 | if (pntsd) | 682 | if (pntsd) |
| @@ -712,12 +696,10 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) | |||
| 712 | struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ | 696 | struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ |
| 713 | struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ | 697 | struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ |
| 714 | 698 | ||
| 715 | #ifdef CONFIG_CIFS_DEBUG2 | 699 | cFYI(DBG2, ("set ACL from mode for %s", path)); |
| 716 | cFYI(1, ("set ACL from mode for %s", path)); | ||
| 717 | #endif | ||
| 718 | 700 | ||
| 719 | /* Get the security descriptor */ | 701 | /* Get the security descriptor */ |
| 720 | pntsd = get_cifs_acl(&acllen, inode, path); | 702 | pntsd = get_cifs_acl(&acllen, inode, path, NULL); |
| 721 | 703 | ||
| 722 | /* Add three ACEs for owner, group, everyone getting rid of | 704 | /* Add three ACEs for owner, group, everyone getting rid of |
| 723 | other ACEs as chmod disables ACEs and set the security descriptor */ | 705 | other ACEs as chmod disables ACEs and set the security descriptor */ |
| @@ -736,16 +718,12 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) | |||
| 736 | 718 | ||
| 737 | rc = build_sec_desc(pntsd, pnntsd, acllen, inode, nmode); | 719 | rc = build_sec_desc(pntsd, pnntsd, acllen, inode, nmode); |
| 738 | 720 | ||
| 739 | #ifdef CONFIG_CIFS_DEBUG2 | 721 | cFYI(DBG2, ("build_sec_desc rc: %d", rc)); |
| 740 | cFYI(1, ("build_sec_desc rc: %d", rc)); | ||
| 741 | #endif | ||
| 742 | 722 | ||
| 743 | if (!rc) { | 723 | if (!rc) { |
| 744 | /* Set the security descriptor */ | 724 | /* Set the security descriptor */ |
| 745 | rc = set_cifs_acl(pnntsd, acllen, inode, path); | 725 | rc = set_cifs_acl(pnntsd, acllen, inode, path); |
| 746 | #ifdef CONFIG_CIFS_DEBUG2 | 726 | cFYI(DBG2, ("set_cifs_acl rc: %d", rc)); |
| 747 | cFYI(1, ("set_cifs_acl rc: %d", rc)); | ||
| 748 | #endif | ||
| 749 | } | 727 | } |
| 750 | 728 | ||
| 751 | kfree(pnntsd); | 729 | kfree(pnntsd); |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index fcc434227691..a04b17e5a9d0 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -204,9 +204,8 @@ cifs_put_super(struct super_block *sb) | |||
| 204 | return; | 204 | return; |
| 205 | } | 205 | } |
| 206 | rc = cifs_umount(sb, cifs_sb); | 206 | rc = cifs_umount(sb, cifs_sb); |
| 207 | if (rc) { | 207 | if (rc) |
| 208 | cERROR(1, ("cifs_umount failed with return code %d", rc)); | 208 | cERROR(1, ("cifs_umount failed with return code %d", rc)); |
| 209 | } | ||
| 210 | #ifdef CONFIG_CIFS_DFS_UPCALL | 209 | #ifdef CONFIG_CIFS_DFS_UPCALL |
| 211 | if (cifs_sb->mountdata) { | 210 | if (cifs_sb->mountdata) { |
| 212 | kfree(cifs_sb->mountdata); | 211 | kfree(cifs_sb->mountdata); |
| @@ -461,7 +460,7 @@ int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats) | |||
| 461 | 460 | ||
| 462 | static struct quotactl_ops cifs_quotactl_ops = { | 461 | static struct quotactl_ops cifs_quotactl_ops = { |
| 463 | .set_xquota = cifs_xquota_set, | 462 | .set_xquota = cifs_xquota_set, |
| 464 | .get_xquota = cifs_xquota_set, | 463 | .get_xquota = cifs_xquota_get, |
| 465 | .set_xstate = cifs_xstate_set, | 464 | .set_xstate = cifs_xstate_set, |
| 466 | .get_xstate = cifs_xstate_get, | 465 | .get_xstate = cifs_xstate_get, |
| 467 | }; | 466 | }; |
| @@ -472,9 +471,7 @@ static void cifs_umount_begin(struct vfsmount *vfsmnt, int flags) | |||
| 472 | struct cifs_sb_info *cifs_sb; | 471 | struct cifs_sb_info *cifs_sb; |
| 473 | struct cifsTconInfo *tcon; | 472 | struct cifsTconInfo *tcon; |
| 474 | 473 | ||
| 475 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
| 476 | dfs_shrink_umount_helper(vfsmnt); | 474 | dfs_shrink_umount_helper(vfsmnt); |
| 477 | #endif /* CONFIG CIFS_DFS_UPCALL */ | ||
| 478 | 475 | ||
| 479 | if (!(flags & MNT_FORCE)) | 476 | if (!(flags & MNT_FORCE)) |
| 480 | return; | 477 | return; |
| @@ -992,9 +989,7 @@ static int __init | |||
| 992 | init_cifs(void) | 989 | init_cifs(void) |
| 993 | { | 990 | { |
| 994 | int rc = 0; | 991 | int rc = 0; |
| 995 | #ifdef CONFIG_PROC_FS | ||
| 996 | cifs_proc_init(); | 992 | cifs_proc_init(); |
| 997 | #endif | ||
| 998 | /* INIT_LIST_HEAD(&GlobalServerList);*/ /* BB not implemented yet */ | 993 | /* INIT_LIST_HEAD(&GlobalServerList);*/ /* BB not implemented yet */ |
| 999 | INIT_LIST_HEAD(&GlobalSMBSessionList); | 994 | INIT_LIST_HEAD(&GlobalSMBSessionList); |
| 1000 | INIT_LIST_HEAD(&GlobalTreeConnectionList); | 995 | INIT_LIST_HEAD(&GlobalTreeConnectionList); |
| @@ -1095,19 +1090,15 @@ init_cifs(void) | |||
| 1095 | out_destroy_inodecache: | 1090 | out_destroy_inodecache: |
| 1096 | cifs_destroy_inodecache(); | 1091 | cifs_destroy_inodecache(); |
| 1097 | out_clean_proc: | 1092 | out_clean_proc: |
| 1098 | #ifdef CONFIG_PROC_FS | ||
| 1099 | cifs_proc_clean(); | 1093 | cifs_proc_clean(); |
| 1100 | #endif | ||
| 1101 | return rc; | 1094 | return rc; |
| 1102 | } | 1095 | } |
| 1103 | 1096 | ||
| 1104 | static void __exit | 1097 | static void __exit |
| 1105 | exit_cifs(void) | 1098 | exit_cifs(void) |
| 1106 | { | 1099 | { |
| 1107 | cFYI(0, ("exit_cifs")); | 1100 | cFYI(DBG2, ("exit_cifs")); |
| 1108 | #ifdef CONFIG_PROC_FS | ||
| 1109 | cifs_proc_clean(); | 1101 | cifs_proc_clean(); |
| 1110 | #endif | ||
| 1111 | #ifdef CONFIG_CIFS_DFS_UPCALL | 1102 | #ifdef CONFIG_CIFS_DFS_UPCALL |
| 1112 | unregister_key_type(&key_type_dns_resolver); | 1103 | unregister_key_type(&key_type_dns_resolver); |
| 1113 | #endif | 1104 | #endif |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 5d32d8ddc82e..69a2e1942542 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -454,7 +454,7 @@ struct dir_notify_req { | |||
| 454 | 454 | ||
| 455 | struct dfs_info3_param { | 455 | struct dfs_info3_param { |
| 456 | int flags; /* DFSREF_REFERRAL_SERVER, DFSREF_STORAGE_SERVER*/ | 456 | int flags; /* DFSREF_REFERRAL_SERVER, DFSREF_STORAGE_SERVER*/ |
| 457 | int PathConsumed; | 457 | int path_consumed; |
| 458 | int server_type; | 458 | int server_type; |
| 459 | int ref_flag; | 459 | int ref_flag; |
| 460 | char *path_name; | 460 | char *path_name; |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 2f09f565a3d9..7e5e0e78cd72 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -39,8 +39,8 @@ extern int smb_send(struct socket *, struct smb_hdr *, | |||
| 39 | unsigned int /* length */ , struct sockaddr *); | 39 | unsigned int /* length */ , struct sockaddr *); |
| 40 | extern unsigned int _GetXid(void); | 40 | extern unsigned int _GetXid(void); |
| 41 | extern void _FreeXid(unsigned int); | 41 | extern void _FreeXid(unsigned int); |
| 42 | #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__FUNCTION__, xid,current->fsuid)); | 42 | #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current->fsuid)); |
| 43 | #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__FUNCTION__,curr_xid,(int)rc));} | 43 | #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));} |
| 44 | extern char *build_path_from_dentry(struct dentry *); | 44 | extern char *build_path_from_dentry(struct dentry *); |
| 45 | extern char *build_wildcard_path_from_dentry(struct dentry *direntry); | 45 | extern char *build_wildcard_path_from_dentry(struct dentry *direntry); |
| 46 | /* extern void renew_parental_timestamps(struct dentry *direntry);*/ | 46 | /* extern void renew_parental_timestamps(struct dentry *direntry);*/ |
| @@ -53,11 +53,11 @@ extern int SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, | |||
| 53 | extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, | 53 | extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, |
| 54 | struct kvec *, int /* nvec to send */, | 54 | struct kvec *, int /* nvec to send */, |
| 55 | int * /* type of buf returned */ , const int flags); | 55 | int * /* type of buf returned */ , const int flags); |
| 56 | extern int SendReceiveBlockingLock(const unsigned int /* xid */ , | 56 | extern int SendReceiveBlockingLock(const unsigned int xid, |
| 57 | struct cifsTconInfo *, | 57 | struct cifsTconInfo *ptcon, |
| 58 | struct smb_hdr * /* input */ , | 58 | struct smb_hdr *in_buf , |
| 59 | struct smb_hdr * /* out */ , | 59 | struct smb_hdr *out_buf, |
| 60 | int * /* bytes returned */); | 60 | int *bytes_returned); |
| 61 | extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length); | 61 | extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length); |
| 62 | extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); | 62 | extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); |
| 63 | extern int is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); | 63 | extern int is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); |
| @@ -84,7 +84,7 @@ extern __u16 GetNextMid(struct TCP_Server_Info *server); | |||
| 84 | extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, | 84 | extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, |
| 85 | struct cifsTconInfo *); | 85 | struct cifsTconInfo *); |
| 86 | extern void DeleteOplockQEntry(struct oplock_q_entry *); | 86 | extern void DeleteOplockQEntry(struct oplock_q_entry *); |
| 87 | extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); | 87 | extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601); |
| 88 | extern u64 cifs_UnixTimeToNT(struct timespec); | 88 | extern u64 cifs_UnixTimeToNT(struct timespec); |
| 89 | extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); | 89 | extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); |
| 90 | extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); | 90 | extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); |
| @@ -92,11 +92,12 @@ extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); | |||
| 92 | extern int cifs_get_inode_info(struct inode **pinode, | 92 | extern int cifs_get_inode_info(struct inode **pinode, |
| 93 | const unsigned char *search_path, | 93 | const unsigned char *search_path, |
| 94 | FILE_ALL_INFO * pfile_info, | 94 | FILE_ALL_INFO * pfile_info, |
| 95 | struct super_block *sb, int xid); | 95 | struct super_block *sb, int xid, const __u16 *pfid); |
| 96 | extern int cifs_get_inode_info_unix(struct inode **pinode, | 96 | extern int cifs_get_inode_info_unix(struct inode **pinode, |
| 97 | const unsigned char *search_path, | 97 | const unsigned char *search_path, |
| 98 | struct super_block *sb, int xid); | 98 | struct super_block *sb, int xid); |
| 99 | extern void acl_to_uid_mode(struct inode *inode, const char *search_path); | 99 | extern void acl_to_uid_mode(struct inode *inode, const char *path, |
| 100 | const __u16 *pfid); | ||
| 100 | extern int mode_to_acl(struct inode *inode, const char *path, __u64); | 101 | extern int mode_to_acl(struct inode *inode, const char *path, __u64); |
| 101 | 102 | ||
| 102 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, | 103 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, |
| @@ -104,7 +105,11 @@ extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, | |||
| 104 | extern int cifs_umount(struct super_block *, struct cifs_sb_info *); | 105 | extern int cifs_umount(struct super_block *, struct cifs_sb_info *); |
| 105 | #ifdef CONFIG_CIFS_DFS_UPCALL | 106 | #ifdef CONFIG_CIFS_DFS_UPCALL |
| 106 | extern void dfs_shrink_umount_helper(struct vfsmount *vfsmnt); | 107 | extern void dfs_shrink_umount_helper(struct vfsmount *vfsmnt); |
| 107 | #endif | 108 | #else |
| 109 | static inline void dfs_shrink_umount_helper(struct vfsmount *vfsmnt) | ||
| 110 | { | ||
| 111 | } | ||
| 112 | #endif /* DFS_UPCALL */ | ||
| 108 | void cifs_proc_init(void); | 113 | void cifs_proc_init(void); |
| 109 | void cifs_proc_clean(void); | 114 | void cifs_proc_clean(void); |
| 110 | 115 | ||
| @@ -175,11 +180,11 @@ extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, | |||
| 175 | struct kstatfs *FSData); | 180 | struct kstatfs *FSData); |
| 176 | 181 | ||
| 177 | extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, | 182 | extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, |
| 178 | const char *fileName, const FILE_BASIC_INFO * data, | 183 | const char *fileName, const FILE_BASIC_INFO *data, |
| 179 | const struct nls_table *nls_codepage, | 184 | const struct nls_table *nls_codepage, |
| 180 | int remap_special_chars); | 185 | int remap_special_chars); |
| 181 | extern int CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, | 186 | extern int CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, |
| 182 | const FILE_BASIC_INFO * data, __u16 fid); | 187 | const FILE_BASIC_INFO *data, __u16 fid); |
| 183 | #if 0 | 188 | #if 0 |
| 184 | extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, | 189 | extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, |
| 185 | char *fileName, __u16 dos_attributes, | 190 | char *fileName, __u16 dos_attributes, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 9409524e4bf8..30bbe448e260 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * fs/cifs/cifssmb.c | 2 | * fs/cifs/cifssmb.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) International Business Machines Corp., 2002,2007 | 4 | * Copyright (C) International Business Machines Corp., 2002,2008 |
| 5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
| 6 | * | 6 | * |
| 7 | * Contains the routines for constructing the SMB PDUs themselves | 7 | * Contains the routines for constructing the SMB PDUs themselves |
| @@ -102,10 +102,12 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon) | |||
| 102 | to this tcon */ | 102 | to this tcon */ |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | /* If the return code is zero, this function must fill in request_buf pointer */ | 105 | /* Allocate and return pointer to an SMB request buffer, and set basic |
| 106 | SMB information in the SMB header. If the return code is zero, this | ||
| 107 | function must have filled in request_buf pointer */ | ||
| 106 | static int | 108 | static int |
| 107 | small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | 109 | small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, |
| 108 | void **request_buf /* returned */) | 110 | void **request_buf) |
| 109 | { | 111 | { |
| 110 | int rc = 0; | 112 | int rc = 0; |
| 111 | 113 | ||
| @@ -363,7 +365,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, | |||
| 363 | *response_buf = *request_buf; | 365 | *response_buf = *request_buf; |
| 364 | 366 | ||
| 365 | header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, | 367 | header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, |
| 366 | wct /*wct */ ); | 368 | wct); |
| 367 | 369 | ||
| 368 | if (tcon != NULL) | 370 | if (tcon != NULL) |
| 369 | cifs_stats_inc(&tcon->num_smbs_sent); | 371 | cifs_stats_inc(&tcon->num_smbs_sent); |
| @@ -523,7 +525,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
| 523 | if (remain >= (MIN_TZ_ADJ / 2)) | 525 | if (remain >= (MIN_TZ_ADJ / 2)) |
| 524 | result += MIN_TZ_ADJ; | 526 | result += MIN_TZ_ADJ; |
| 525 | if (val < 0) | 527 | if (val < 0) |
| 526 | result = - result; | 528 | result = -result; |
| 527 | server->timeAdj = result; | 529 | server->timeAdj = result; |
| 528 | } else { | 530 | } else { |
| 529 | server->timeAdj = (int)tmp; | 531 | server->timeAdj = (int)tmp; |
| @@ -600,7 +602,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
| 600 | server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize), | 602 | server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize), |
| 601 | (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); | 603 | (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); |
| 602 | server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); | 604 | server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); |
| 603 | cFYI(0, ("Max buf = %d", ses->server->maxBuf)); | 605 | cFYI(DBG2, ("Max buf = %d", ses->server->maxBuf)); |
| 604 | GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); | 606 | GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); |
| 605 | server->capabilities = le32_to_cpu(pSMBr->Capabilities); | 607 | server->capabilities = le32_to_cpu(pSMBr->Capabilities); |
| 606 | server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); | 608 | server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); |
| @@ -868,9 +870,8 @@ PsxDelete: | |||
| 868 | pSMB->ByteCount = cpu_to_le16(byte_count); | 870 | pSMB->ByteCount = cpu_to_le16(byte_count); |
| 869 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 871 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 870 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 872 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 871 | if (rc) { | 873 | if (rc) |
| 872 | cFYI(1, ("Posix delete returned %d", rc)); | 874 | cFYI(1, ("Posix delete returned %d", rc)); |
| 873 | } | ||
| 874 | cifs_buf_release(pSMB); | 875 | cifs_buf_release(pSMB); |
| 875 | 876 | ||
| 876 | cifs_stats_inc(&tcon->num_deletes); | 877 | cifs_stats_inc(&tcon->num_deletes); |
| @@ -916,9 +917,8 @@ DelFileRetry: | |||
| 916 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 917 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 917 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 918 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 918 | cifs_stats_inc(&tcon->num_deletes); | 919 | cifs_stats_inc(&tcon->num_deletes); |
| 919 | if (rc) { | 920 | if (rc) |
| 920 | cFYI(1, ("Error in RMFile = %d", rc)); | 921 | cFYI(1, ("Error in RMFile = %d", rc)); |
| 921 | } | ||
| 922 | 922 | ||
| 923 | cifs_buf_release(pSMB); | 923 | cifs_buf_release(pSMB); |
| 924 | if (rc == -EAGAIN) | 924 | if (rc == -EAGAIN) |
| @@ -961,9 +961,8 @@ RmDirRetry: | |||
| 961 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 961 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 962 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 962 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 963 | cifs_stats_inc(&tcon->num_rmdirs); | 963 | cifs_stats_inc(&tcon->num_rmdirs); |
| 964 | if (rc) { | 964 | if (rc) |
| 965 | cFYI(1, ("Error in RMDir = %d", rc)); | 965 | cFYI(1, ("Error in RMDir = %d", rc)); |
| 966 | } | ||
| 967 | 966 | ||
| 968 | cifs_buf_release(pSMB); | 967 | cifs_buf_release(pSMB); |
| 969 | if (rc == -EAGAIN) | 968 | if (rc == -EAGAIN) |
| @@ -1005,9 +1004,8 @@ MkDirRetry: | |||
| 1005 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 1004 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 1006 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 1005 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 1007 | cifs_stats_inc(&tcon->num_mkdirs); | 1006 | cifs_stats_inc(&tcon->num_mkdirs); |
| 1008 | if (rc) { | 1007 | if (rc) |
| 1009 | cFYI(1, ("Error in Mkdir = %d", rc)); | 1008 | cFYI(1, ("Error in Mkdir = %d", rc)); |
| 1010 | } | ||
| 1011 | 1009 | ||
| 1012 | cifs_buf_release(pSMB); | 1010 | cifs_buf_release(pSMB); |
| 1013 | if (rc == -EAGAIN) | 1011 | if (rc == -EAGAIN) |
| @@ -1017,7 +1015,7 @@ MkDirRetry: | |||
| 1017 | 1015 | ||
| 1018 | int | 1016 | int |
| 1019 | CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags, | 1017 | CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags, |
| 1020 | __u64 mode, __u16 * netfid, FILE_UNIX_BASIC_INFO *pRetData, | 1018 | __u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData, |
| 1021 | __u32 *pOplock, const char *name, | 1019 | __u32 *pOplock, const char *name, |
| 1022 | const struct nls_table *nls_codepage, int remap) | 1020 | const struct nls_table *nls_codepage, int remap) |
| 1023 | { | 1021 | { |
| @@ -1027,8 +1025,8 @@ CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags, | |||
| 1027 | int rc = 0; | 1025 | int rc = 0; |
| 1028 | int bytes_returned = 0; | 1026 | int bytes_returned = 0; |
| 1029 | __u16 params, param_offset, offset, byte_count, count; | 1027 | __u16 params, param_offset, offset, byte_count, count; |
| 1030 | OPEN_PSX_REQ * pdata; | 1028 | OPEN_PSX_REQ *pdata; |
| 1031 | OPEN_PSX_RSP * psx_rsp; | 1029 | OPEN_PSX_RSP *psx_rsp; |
| 1032 | 1030 | ||
| 1033 | cFYI(1, ("In POSIX Create")); | 1031 | cFYI(1, ("In POSIX Create")); |
| 1034 | PsxCreat: | 1032 | PsxCreat: |
| @@ -1110,9 +1108,7 @@ PsxCreat: | |||
| 1110 | /* check to make sure response data is there */ | 1108 | /* check to make sure response data is there */ |
| 1111 | if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) { | 1109 | if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) { |
| 1112 | pRetData->Type = cpu_to_le32(-1); /* unknown */ | 1110 | pRetData->Type = cpu_to_le32(-1); /* unknown */ |
| 1113 | #ifdef CONFIG_CIFS_DEBUG2 | 1111 | cFYI(DBG2, ("unknown type")); |
| 1114 | cFYI(1, ("unknown type")); | ||
| 1115 | #endif | ||
| 1116 | } else { | 1112 | } else { |
| 1117 | if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP) | 1113 | if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP) |
| 1118 | + sizeof(FILE_UNIX_BASIC_INFO)) { | 1114 | + sizeof(FILE_UNIX_BASIC_INFO)) { |
| @@ -1169,8 +1165,8 @@ static __u16 convert_disposition(int disposition) | |||
| 1169 | int | 1165 | int |
| 1170 | SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, | 1166 | SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, |
| 1171 | const char *fileName, const int openDisposition, | 1167 | const char *fileName, const int openDisposition, |
| 1172 | const int access_flags, const int create_options, __u16 * netfid, | 1168 | const int access_flags, const int create_options, __u16 *netfid, |
| 1173 | int *pOplock, FILE_ALL_INFO * pfile_info, | 1169 | int *pOplock, FILE_ALL_INFO *pfile_info, |
| 1174 | const struct nls_table *nls_codepage, int remap) | 1170 | const struct nls_table *nls_codepage, int remap) |
| 1175 | { | 1171 | { |
| 1176 | int rc = -EACCES; | 1172 | int rc = -EACCES; |
| @@ -1221,8 +1217,8 @@ OldOpenRetry: | |||
| 1221 | 1217 | ||
| 1222 | if (create_options & CREATE_OPTION_SPECIAL) | 1218 | if (create_options & CREATE_OPTION_SPECIAL) |
| 1223 | pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM); | 1219 | pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM); |
| 1224 | else | 1220 | else /* BB FIXME BB */ |
| 1225 | pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); /* BB FIXME */ | 1221 | pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); |
| 1226 | 1222 | ||
| 1227 | /* if ((omode & S_IWUGO) == 0) | 1223 | /* if ((omode & S_IWUGO) == 0) |
| 1228 | pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/ | 1224 | pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/ |
| @@ -1284,8 +1280,8 @@ OldOpenRetry: | |||
| 1284 | int | 1280 | int |
| 1285 | CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, | 1281 | CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, |
| 1286 | const char *fileName, const int openDisposition, | 1282 | const char *fileName, const int openDisposition, |
| 1287 | const int access_flags, const int create_options, __u16 * netfid, | 1283 | const int access_flags, const int create_options, __u16 *netfid, |
| 1288 | int *pOplock, FILE_ALL_INFO * pfile_info, | 1284 | int *pOplock, FILE_ALL_INFO *pfile_info, |
| 1289 | const struct nls_table *nls_codepage, int remap) | 1285 | const struct nls_table *nls_codepage, int remap) |
| 1290 | { | 1286 | { |
| 1291 | int rc = -EACCES; | 1287 | int rc = -EACCES; |
| @@ -1556,9 +1552,9 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, | |||
| 1556 | } /* else setting file size with write of zero bytes */ | 1552 | } /* else setting file size with write of zero bytes */ |
| 1557 | if (wct == 14) | 1553 | if (wct == 14) |
| 1558 | byte_count = bytes_sent + 1; /* pad */ | 1554 | byte_count = bytes_sent + 1; /* pad */ |
| 1559 | else /* wct == 12 */ { | 1555 | else /* wct == 12 */ |
| 1560 | byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */ | 1556 | byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */ |
| 1561 | } | 1557 | |
| 1562 | pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); | 1558 | pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); |
| 1563 | pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); | 1559 | pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); |
| 1564 | pSMB->hdr.smb_buf_length += byte_count; | 1560 | pSMB->hdr.smb_buf_length += byte_count; |
| @@ -1663,7 +1659,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, | |||
| 1663 | rc = -EIO; | 1659 | rc = -EIO; |
| 1664 | *nbytes = 0; | 1660 | *nbytes = 0; |
| 1665 | } else { | 1661 | } else { |
| 1666 | WRITE_RSP * pSMBr = (WRITE_RSP *)iov[0].iov_base; | 1662 | WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base; |
| 1667 | *nbytes = le16_to_cpu(pSMBr->CountHigh); | 1663 | *nbytes = le16_to_cpu(pSMBr->CountHigh); |
| 1668 | *nbytes = (*nbytes) << 16; | 1664 | *nbytes = (*nbytes) << 16; |
| 1669 | *nbytes += le16_to_cpu(pSMBr->Count); | 1665 | *nbytes += le16_to_cpu(pSMBr->Count); |
| @@ -1744,9 +1740,8 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, | |||
| 1744 | /* SMB buffer freed by function above */ | 1740 | /* SMB buffer freed by function above */ |
| 1745 | } | 1741 | } |
| 1746 | cifs_stats_inc(&tcon->num_locks); | 1742 | cifs_stats_inc(&tcon->num_locks); |
| 1747 | if (rc) { | 1743 | if (rc) |
| 1748 | cFYI(1, ("Send error in Lock = %d", rc)); | 1744 | cFYI(1, ("Send error in Lock = %d", rc)); |
| 1749 | } | ||
| 1750 | 1745 | ||
| 1751 | /* Note: On -EAGAIN error only caller can retry on handle based calls | 1746 | /* Note: On -EAGAIN error only caller can retry on handle based calls |
| 1752 | since file handle passed in no longer valid */ | 1747 | since file handle passed in no longer valid */ |
| @@ -1791,7 +1786,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | |||
| 1791 | 1786 | ||
| 1792 | count = sizeof(struct cifs_posix_lock); | 1787 | count = sizeof(struct cifs_posix_lock); |
| 1793 | pSMB->MaxParameterCount = cpu_to_le16(2); | 1788 | pSMB->MaxParameterCount = cpu_to_le16(2); |
| 1794 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ | 1789 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */ |
| 1795 | pSMB->SetupCount = 1; | 1790 | pSMB->SetupCount = 1; |
| 1796 | pSMB->Reserved3 = 0; | 1791 | pSMB->Reserved3 = 0; |
| 1797 | if (get_flag) | 1792 | if (get_flag) |
| @@ -1972,9 +1967,8 @@ renameRetry: | |||
| 1972 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 1967 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 1973 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 1968 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 1974 | cifs_stats_inc(&tcon->num_renames); | 1969 | cifs_stats_inc(&tcon->num_renames); |
| 1975 | if (rc) { | 1970 | if (rc) |
| 1976 | cFYI(1, ("Send error in rename = %d", rc)); | 1971 | cFYI(1, ("Send error in rename = %d", rc)); |
| 1977 | } | ||
| 1978 | 1972 | ||
| 1979 | cifs_buf_release(pSMB); | 1973 | cifs_buf_release(pSMB); |
| 1980 | 1974 | ||
| @@ -2016,7 +2010,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon, | |||
| 2016 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; | 2010 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; |
| 2017 | rename_info = (struct set_file_rename *) data_offset; | 2011 | rename_info = (struct set_file_rename *) data_offset; |
| 2018 | pSMB->MaxParameterCount = cpu_to_le16(2); | 2012 | pSMB->MaxParameterCount = cpu_to_le16(2); |
| 2019 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ | 2013 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */ |
| 2020 | pSMB->SetupCount = 1; | 2014 | pSMB->SetupCount = 1; |
| 2021 | pSMB->Reserved3 = 0; | 2015 | pSMB->Reserved3 = 0; |
| 2022 | pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); | 2016 | pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); |
| @@ -2052,9 +2046,8 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon, | |||
| 2052 | rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, | 2046 | rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, |
| 2053 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 2047 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 2054 | cifs_stats_inc(&pTcon->num_t2renames); | 2048 | cifs_stats_inc(&pTcon->num_t2renames); |
| 2055 | if (rc) { | 2049 | if (rc) |
| 2056 | cFYI(1, ("Send error in Rename (by file handle) = %d", rc)); | 2050 | cFYI(1, ("Send error in Rename (by file handle) = %d", rc)); |
| 2057 | } | ||
| 2058 | 2051 | ||
| 2059 | cifs_buf_release(pSMB); | 2052 | cifs_buf_release(pSMB); |
| 2060 | 2053 | ||
| @@ -2211,9 +2204,8 @@ createSymLinkRetry: | |||
| 2211 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 2204 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 2212 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 2205 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 2213 | cifs_stats_inc(&tcon->num_symlinks); | 2206 | cifs_stats_inc(&tcon->num_symlinks); |
| 2214 | if (rc) { | 2207 | if (rc) |
| 2215 | cFYI(1, ("Send error in SetPathInfo create symlink = %d", rc)); | 2208 | cFYI(1, ("Send error in SetPathInfo create symlink = %d", rc)); |
| 2216 | } | ||
| 2217 | 2209 | ||
| 2218 | if (pSMB) | 2210 | if (pSMB) |
| 2219 | cifs_buf_release(pSMB); | 2211 | cifs_buf_release(pSMB); |
| @@ -2299,9 +2291,8 @@ createHardLinkRetry: | |||
| 2299 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 2291 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 2300 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 2292 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 2301 | cifs_stats_inc(&tcon->num_hardlinks); | 2293 | cifs_stats_inc(&tcon->num_hardlinks); |
| 2302 | if (rc) { | 2294 | if (rc) |
| 2303 | cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc)); | 2295 | cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc)); |
| 2304 | } | ||
| 2305 | 2296 | ||
| 2306 | cifs_buf_release(pSMB); | 2297 | cifs_buf_release(pSMB); |
| 2307 | if (rc == -EAGAIN) | 2298 | if (rc == -EAGAIN) |
| @@ -2370,9 +2361,9 @@ winCreateHardLinkRetry: | |||
| 2370 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 2361 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 2371 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 2362 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 2372 | cifs_stats_inc(&tcon->num_hardlinks); | 2363 | cifs_stats_inc(&tcon->num_hardlinks); |
| 2373 | if (rc) { | 2364 | if (rc) |
| 2374 | cFYI(1, ("Send error in hard link (NT rename) = %d", rc)); | 2365 | cFYI(1, ("Send error in hard link (NT rename) = %d", rc)); |
| 2375 | } | 2366 | |
| 2376 | cifs_buf_release(pSMB); | 2367 | cifs_buf_release(pSMB); |
| 2377 | if (rc == -EAGAIN) | 2368 | if (rc == -EAGAIN) |
| 2378 | goto winCreateHardLinkRetry; | 2369 | goto winCreateHardLinkRetry; |
| @@ -2968,9 +2959,8 @@ setAclRetry: | |||
| 2968 | pSMB->ByteCount = cpu_to_le16(byte_count); | 2959 | pSMB->ByteCount = cpu_to_le16(byte_count); |
| 2969 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 2960 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 2970 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 2961 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 2971 | if (rc) { | 2962 | if (rc) |
| 2972 | cFYI(1, ("Set POSIX ACL returned %d", rc)); | 2963 | cFYI(1, ("Set POSIX ACL returned %d", rc)); |
| 2973 | } | ||
| 2974 | 2964 | ||
| 2975 | setACLerrorExit: | 2965 | setACLerrorExit: |
| 2976 | cifs_buf_release(pSMB); | 2966 | cifs_buf_release(pSMB); |
| @@ -2982,7 +2972,7 @@ setACLerrorExit: | |||
| 2982 | /* BB fix tabs in this function FIXME BB */ | 2972 | /* BB fix tabs in this function FIXME BB */ |
| 2983 | int | 2973 | int |
| 2984 | CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, | 2974 | CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, |
| 2985 | const int netfid, __u64 * pExtAttrBits, __u64 *pMask) | 2975 | const int netfid, __u64 *pExtAttrBits, __u64 *pMask) |
| 2986 | { | 2976 | { |
| 2987 | int rc = 0; | 2977 | int rc = 0; |
| 2988 | struct smb_t2_qfi_req *pSMB = NULL; | 2978 | struct smb_t2_qfi_req *pSMB = NULL; |
| @@ -3000,7 +2990,7 @@ GetExtAttrRetry: | |||
| 3000 | if (rc) | 2990 | if (rc) |
| 3001 | return rc; | 2991 | return rc; |
| 3002 | 2992 | ||
| 3003 | params = 2 /* level */ +2 /* fid */; | 2993 | params = 2 /* level */ + 2 /* fid */; |
| 3004 | pSMB->t2.TotalDataCount = 0; | 2994 | pSMB->t2.TotalDataCount = 0; |
| 3005 | pSMB->t2.MaxParameterCount = cpu_to_le16(4); | 2995 | pSMB->t2.MaxParameterCount = cpu_to_le16(4); |
| 3006 | /* BB find exact max data count below from sess structure BB */ | 2996 | /* BB find exact max data count below from sess structure BB */ |
| @@ -3071,7 +3061,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | |||
| 3071 | { | 3061 | { |
| 3072 | int rc = 0; | 3062 | int rc = 0; |
| 3073 | int buf_type = 0; | 3063 | int buf_type = 0; |
| 3074 | QUERY_SEC_DESC_REQ * pSMB; | 3064 | QUERY_SEC_DESC_REQ *pSMB; |
| 3075 | struct kvec iov[1]; | 3065 | struct kvec iov[1]; |
| 3076 | 3066 | ||
| 3077 | cFYI(1, ("GetCifsACL")); | 3067 | cFYI(1, ("GetCifsACL")); |
| @@ -3101,7 +3091,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | |||
| 3101 | if (rc) { | 3091 | if (rc) { |
| 3102 | cFYI(1, ("Send error in QuerySecDesc = %d", rc)); | 3092 | cFYI(1, ("Send error in QuerySecDesc = %d", rc)); |
| 3103 | } else { /* decode response */ | 3093 | } else { /* decode response */ |
| 3104 | __le32 * parm; | 3094 | __le32 *parm; |
| 3105 | __u32 parm_len; | 3095 | __u32 parm_len; |
| 3106 | __u32 acl_len; | 3096 | __u32 acl_len; |
| 3107 | struct smb_com_ntransact_rsp *pSMBr; | 3097 | struct smb_com_ntransact_rsp *pSMBr; |
| @@ -3230,8 +3220,8 @@ int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, | |||
| 3230 | FILE_ALL_INFO *pFinfo, | 3220 | FILE_ALL_INFO *pFinfo, |
| 3231 | const struct nls_table *nls_codepage, int remap) | 3221 | const struct nls_table *nls_codepage, int remap) |
| 3232 | { | 3222 | { |
| 3233 | QUERY_INFORMATION_REQ * pSMB; | 3223 | QUERY_INFORMATION_REQ *pSMB; |
| 3234 | QUERY_INFORMATION_RSP * pSMBr; | 3224 | QUERY_INFORMATION_RSP *pSMBr; |
| 3235 | int rc = 0; | 3225 | int rc = 0; |
| 3236 | int bytes_returned; | 3226 | int bytes_returned; |
| 3237 | int name_len; | 3227 | int name_len; |
| @@ -3263,9 +3253,11 @@ QInfRetry: | |||
| 3263 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 3253 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 3264 | if (rc) { | 3254 | if (rc) { |
| 3265 | cFYI(1, ("Send error in QueryInfo = %d", rc)); | 3255 | cFYI(1, ("Send error in QueryInfo = %d", rc)); |
| 3266 | } else if (pFinfo) { /* decode response */ | 3256 | } else if (pFinfo) { |
| 3267 | struct timespec ts; | 3257 | struct timespec ts; |
| 3268 | __u32 time = le32_to_cpu(pSMBr->last_write_time); | 3258 | __u32 time = le32_to_cpu(pSMBr->last_write_time); |
| 3259 | |||
| 3260 | /* decode response */ | ||
| 3269 | /* BB FIXME - add time zone adjustment BB */ | 3261 | /* BB FIXME - add time zone adjustment BB */ |
| 3270 | memset(pFinfo, 0, sizeof(FILE_ALL_INFO)); | 3262 | memset(pFinfo, 0, sizeof(FILE_ALL_INFO)); |
| 3271 | ts.tv_nsec = 0; | 3263 | ts.tv_nsec = 0; |
| @@ -3296,7 +3288,7 @@ QInfRetry: | |||
| 3296 | int | 3288 | int |
| 3297 | CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, | 3289 | CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, |
| 3298 | const unsigned char *searchName, | 3290 | const unsigned char *searchName, |
| 3299 | FILE_ALL_INFO * pFindData, | 3291 | FILE_ALL_INFO *pFindData, |
| 3300 | int legacy /* old style infolevel */, | 3292 | int legacy /* old style infolevel */, |
| 3301 | const struct nls_table *nls_codepage, int remap) | 3293 | const struct nls_table *nls_codepage, int remap) |
| 3302 | { | 3294 | { |
| @@ -3371,10 +3363,12 @@ QPathInfoRetry: | |||
| 3371 | else if (pFindData) { | 3363 | else if (pFindData) { |
| 3372 | int size; | 3364 | int size; |
| 3373 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); | 3365 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); |
| 3374 | if (legacy) /* we do not read the last field, EAsize, | 3366 | |
| 3375 | fortunately since it varies by subdialect | 3367 | /* On legacy responses we do not read the last field, |
| 3376 | and on Set vs. Get, is two bytes or 4 | 3368 | EAsize, fortunately since it varies by subdialect and |
| 3377 | bytes depending but we don't care here */ | 3369 | also note it differs on Set vs. Get, ie two bytes or 4 |
| 3370 | bytes depending but we don't care here */ | ||
| 3371 | if (legacy) | ||
| 3378 | size = sizeof(FILE_INFO_STANDARD); | 3372 | size = sizeof(FILE_INFO_STANDARD); |
| 3379 | else | 3373 | else |
| 3380 | size = sizeof(FILE_ALL_INFO); | 3374 | size = sizeof(FILE_ALL_INFO); |
| @@ -3476,85 +3470,6 @@ UnixQPathInfoRetry: | |||
| 3476 | return rc; | 3470 | return rc; |
| 3477 | } | 3471 | } |
| 3478 | 3472 | ||
| 3479 | #if 0 /* function unused at present */ | ||
| 3480 | int CIFSFindSingle(const int xid, struct cifsTconInfo *tcon, | ||
| 3481 | const char *searchName, FILE_ALL_INFO * findData, | ||
| 3482 | const struct nls_table *nls_codepage) | ||
| 3483 | { | ||
| 3484 | /* level 257 SMB_ */ | ||
| 3485 | TRANSACTION2_FFIRST_REQ *pSMB = NULL; | ||
| 3486 | TRANSACTION2_FFIRST_RSP *pSMBr = NULL; | ||
| 3487 | int rc = 0; | ||
| 3488 | int bytes_returned; | ||
| 3489 | int name_len; | ||
| 3490 | __u16 params, byte_count; | ||
| 3491 | |||
| 3492 | cFYI(1, ("In FindUnique")); | ||
| 3493 | findUniqueRetry: | ||
| 3494 | rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, | ||
| 3495 | (void **) &pSMBr); | ||
| 3496 | if (rc) | ||
| 3497 | return rc; | ||
| 3498 | |||
| 3499 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | ||
| 3500 | name_len = | ||
| 3501 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, | ||
| 3502 | PATH_MAX, nls_codepage); | ||
| 3503 | name_len++; /* trailing null */ | ||
| 3504 | name_len *= 2; | ||
| 3505 | } else { /* BB improve the check for buffer overruns BB */ | ||
| 3506 | name_len = strnlen(searchName, PATH_MAX); | ||
| 3507 | name_len++; /* trailing null */ | ||
| 3508 | strncpy(pSMB->FileName, searchName, name_len); | ||
| 3509 | } | ||
| 3510 | |||
| 3511 | params = 12 + name_len /* includes null */ ; | ||
| 3512 | pSMB->TotalDataCount = 0; /* no EAs */ | ||
| 3513 | pSMB->MaxParameterCount = cpu_to_le16(2); | ||
| 3514 | pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ | ||
| 3515 | pSMB->MaxSetupCount = 0; | ||
| 3516 | pSMB->Reserved = 0; | ||
| 3517 | pSMB->Flags = 0; | ||
| 3518 | pSMB->Timeout = 0; | ||
| 3519 | pSMB->Reserved2 = 0; | ||
| 3520 | pSMB->ParameterOffset = cpu_to_le16( | ||
| 3521 | offsetof(struct smb_com_transaction2_ffirst_req, InformationLevel)-4); | ||
| 3522 | pSMB->DataCount = 0; | ||
| 3523 | pSMB->DataOffset = 0; | ||
| 3524 | pSMB->SetupCount = 1; /* one byte, no need to le convert */ | ||
| 3525 | pSMB->Reserved3 = 0; | ||
| 3526 | pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST); | ||
| 3527 | byte_count = params + 1 /* pad */ ; | ||
| 3528 | pSMB->TotalParameterCount = cpu_to_le16(params); | ||
| 3529 | pSMB->ParameterCount = pSMB->TotalParameterCount; | ||
| 3530 | pSMB->SearchAttributes = | ||
| 3531 | cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | | ||
| 3532 | ATTR_DIRECTORY); | ||
| 3533 | pSMB->SearchCount = cpu_to_le16(16); /* BB increase */ | ||
| 3534 | pSMB->SearchFlags = cpu_to_le16(1); | ||
| 3535 | pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO); | ||
| 3536 | pSMB->SearchStorageType = 0; /* BB what should we set this to? BB */ | ||
| 3537 | pSMB->hdr.smb_buf_length += byte_count; | ||
| 3538 | pSMB->ByteCount = cpu_to_le16(byte_count); | ||
| 3539 | |||
| 3540 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | ||
| 3541 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | ||
| 3542 | |||
| 3543 | if (rc) { | ||
| 3544 | cFYI(1, ("Send error in FindFileDirInfo = %d", rc)); | ||
| 3545 | } else { /* decode response */ | ||
| 3546 | cifs_stats_inc(&tcon->num_ffirst); | ||
| 3547 | /* BB fill in */ | ||
| 3548 | } | ||
| 3549 | |||
| 3550 | cifs_buf_release(pSMB); | ||
| 3551 | if (rc == -EAGAIN) | ||
| 3552 | goto findUniqueRetry; | ||
| 3553 | |||
| 3554 | return rc; | ||
| 3555 | } | ||
| 3556 | #endif /* end unused (temporarily) function */ | ||
| 3557 | |||
| 3558 | /* xid, tcon, searchName and codepage are input parms, rest are returned */ | 3473 | /* xid, tcon, searchName and codepage are input parms, rest are returned */ |
| 3559 | int | 3474 | int |
| 3560 | CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, | 3475 | CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, |
| @@ -3566,7 +3481,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, | |||
| 3566 | /* level 257 SMB_ */ | 3481 | /* level 257 SMB_ */ |
| 3567 | TRANSACTION2_FFIRST_REQ *pSMB = NULL; | 3482 | TRANSACTION2_FFIRST_REQ *pSMB = NULL; |
| 3568 | TRANSACTION2_FFIRST_RSP *pSMBr = NULL; | 3483 | TRANSACTION2_FFIRST_RSP *pSMBr = NULL; |
| 3569 | T2_FFIRST_RSP_PARMS * parms; | 3484 | T2_FFIRST_RSP_PARMS *parms; |
| 3570 | int rc = 0; | 3485 | int rc = 0; |
| 3571 | int bytes_returned = 0; | 3486 | int bytes_returned = 0; |
| 3572 | int name_len; | 3487 | int name_len; |
| @@ -3697,7 +3612,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, | |||
| 3697 | { | 3612 | { |
| 3698 | TRANSACTION2_FNEXT_REQ *pSMB = NULL; | 3613 | TRANSACTION2_FNEXT_REQ *pSMB = NULL; |
| 3699 | TRANSACTION2_FNEXT_RSP *pSMBr = NULL; | 3614 | TRANSACTION2_FNEXT_RSP *pSMBr = NULL; |
| 3700 | T2_FNEXT_RSP_PARMS * parms; | 3615 | T2_FNEXT_RSP_PARMS *parms; |
| 3701 | char *response_data; | 3616 | char *response_data; |
| 3702 | int rc = 0; | 3617 | int rc = 0; |
| 3703 | int bytes_returned, name_len; | 3618 | int bytes_returned, name_len; |
| @@ -3836,9 +3751,9 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, | |||
| 3836 | pSMB->FileID = searchHandle; | 3751 | pSMB->FileID = searchHandle; |
| 3837 | pSMB->ByteCount = 0; | 3752 | pSMB->ByteCount = 0; |
| 3838 | rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); | 3753 | rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); |
| 3839 | if (rc) { | 3754 | if (rc) |
| 3840 | cERROR(1, ("Send error in FindClose = %d", rc)); | 3755 | cERROR(1, ("Send error in FindClose = %d", rc)); |
| 3841 | } | 3756 | |
| 3842 | cifs_stats_inc(&tcon->num_fclose); | 3757 | cifs_stats_inc(&tcon->num_fclose); |
| 3843 | 3758 | ||
| 3844 | /* Since session is dead, search handle closed on server already */ | 3759 | /* Since session is dead, search handle closed on server already */ |
| @@ -3851,7 +3766,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, | |||
| 3851 | int | 3766 | int |
| 3852 | CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, | 3767 | CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, |
| 3853 | const unsigned char *searchName, | 3768 | const unsigned char *searchName, |
| 3854 | __u64 * inode_number, | 3769 | __u64 *inode_number, |
| 3855 | const struct nls_table *nls_codepage, int remap) | 3770 | const struct nls_table *nls_codepage, int remap) |
| 3856 | { | 3771 | { |
| 3857 | int rc = 0; | 3772 | int rc = 0; |
| @@ -4560,9 +4475,8 @@ SETFSUnixRetry: | |||
| 4560 | cERROR(1, ("Send error in SETFSUnixInfo = %d", rc)); | 4475 | cERROR(1, ("Send error in SETFSUnixInfo = %d", rc)); |
| 4561 | } else { /* decode response */ | 4476 | } else { /* decode response */ |
| 4562 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); | 4477 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); |
| 4563 | if (rc) { | 4478 | if (rc) |
| 4564 | rc = -EIO; /* bad smb */ | 4479 | rc = -EIO; /* bad smb */ |
| 4565 | } | ||
| 4566 | } | 4480 | } |
| 4567 | cifs_buf_release(pSMB); | 4481 | cifs_buf_release(pSMB); |
| 4568 | 4482 | ||
| @@ -4744,9 +4658,8 @@ SetEOFRetry: | |||
| 4744 | pSMB->ByteCount = cpu_to_le16(byte_count); | 4658 | pSMB->ByteCount = cpu_to_le16(byte_count); |
| 4745 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 4659 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 4746 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 4660 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 4747 | if (rc) { | 4661 | if (rc) |
| 4748 | cFYI(1, ("SetPathInfo (file size) returned %d", rc)); | 4662 | cFYI(1, ("SetPathInfo (file size) returned %d", rc)); |
| 4749 | } | ||
| 4750 | 4663 | ||
| 4751 | cifs_buf_release(pSMB); | 4664 | cifs_buf_release(pSMB); |
| 4752 | 4665 | ||
| @@ -4897,9 +4810,8 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, | |||
| 4897 | pSMB->ByteCount = cpu_to_le16(byte_count); | 4810 | pSMB->ByteCount = cpu_to_le16(byte_count); |
| 4898 | memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); | 4811 | memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); |
| 4899 | rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); | 4812 | rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); |
| 4900 | if (rc) { | 4813 | if (rc) |
| 4901 | cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc)); | 4814 | cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc)); |
| 4902 | } | ||
| 4903 | 4815 | ||
| 4904 | /* Note: On -EAGAIN error only caller can retry on handle based calls | 4816 | /* Note: On -EAGAIN error only caller can retry on handle based calls |
| 4905 | since file handle passed in no longer valid */ | 4817 | since file handle passed in no longer valid */ |
| @@ -4975,9 +4887,8 @@ SetTimesRetry: | |||
| 4975 | pSMB->ByteCount = cpu_to_le16(byte_count); | 4887 | pSMB->ByteCount = cpu_to_le16(byte_count); |
| 4976 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 4888 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 4977 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 4889 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 4978 | if (rc) { | 4890 | if (rc) |
| 4979 | cFYI(1, ("SetPathInfo (times) returned %d", rc)); | 4891 | cFYI(1, ("SetPathInfo (times) returned %d", rc)); |
| 4980 | } | ||
| 4981 | 4892 | ||
| 4982 | cifs_buf_release(pSMB); | 4893 | cifs_buf_release(pSMB); |
| 4983 | 4894 | ||
| @@ -5027,9 +4938,8 @@ SetAttrLgcyRetry: | |||
| 5027 | pSMB->ByteCount = cpu_to_le16(name_len + 1); | 4938 | pSMB->ByteCount = cpu_to_le16(name_len + 1); |
| 5028 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 4939 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 5029 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 4940 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 5030 | if (rc) { | 4941 | if (rc) |
| 5031 | cFYI(1, ("Error in LegacySetAttr = %d", rc)); | 4942 | cFYI(1, ("Error in LegacySetAttr = %d", rc)); |
| 5032 | } | ||
| 5033 | 4943 | ||
| 5034 | cifs_buf_release(pSMB); | 4944 | cifs_buf_release(pSMB); |
| 5035 | 4945 | ||
| @@ -5138,9 +5048,8 @@ setPermsRetry: | |||
| 5138 | pSMB->ByteCount = cpu_to_le16(byte_count); | 5048 | pSMB->ByteCount = cpu_to_le16(byte_count); |
| 5139 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 5049 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 5140 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 5050 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 5141 | if (rc) { | 5051 | if (rc) |
| 5142 | cFYI(1, ("SetPathInfo (perms) returned %d", rc)); | 5052 | cFYI(1, ("SetPathInfo (perms) returned %d", rc)); |
| 5143 | } | ||
| 5144 | 5053 | ||
| 5145 | if (pSMB) | 5054 | if (pSMB) |
| 5146 | cifs_buf_release(pSMB); | 5055 | cifs_buf_release(pSMB); |
| @@ -5615,9 +5524,8 @@ SetEARetry: | |||
| 5615 | pSMB->ByteCount = cpu_to_le16(byte_count); | 5524 | pSMB->ByteCount = cpu_to_le16(byte_count); |
| 5616 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 5525 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
| 5617 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 5526 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
| 5618 | if (rc) { | 5527 | if (rc) |
| 5619 | cFYI(1, ("SetPathInfo (EA) returned %d", rc)); | 5528 | cFYI(1, ("SetPathInfo (EA) returned %d", rc)); |
| 5620 | } | ||
| 5621 | 5529 | ||
| 5622 | cifs_buf_release(pSMB); | 5530 | cifs_buf_release(pSMB); |
| 5623 | 5531 | ||
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 65d0ba72e78f..8dbfa97cd18c 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -1722,8 +1722,15 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, | |||
| 1722 | originally at mount time */ | 1722 | originally at mount time */ |
| 1723 | if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0) | 1723 | if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0) |
| 1724 | cap &= ~CIFS_UNIX_POSIX_ACL_CAP; | 1724 | cap &= ~CIFS_UNIX_POSIX_ACL_CAP; |
| 1725 | if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) | 1725 | if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) { |
| 1726 | if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) | ||
| 1727 | cERROR(1, ("POSIXPATH support change")); | ||
| 1726 | cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; | 1728 | cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; |
| 1729 | } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) { | ||
| 1730 | cERROR(1, ("possible reconnect error")); | ||
| 1731 | cERROR(1, | ||
| 1732 | ("server disabled POSIX path support")); | ||
| 1733 | } | ||
| 1727 | } | 1734 | } |
| 1728 | 1735 | ||
| 1729 | cap &= CIFS_UNIX_CAP_MASK; | 1736 | cap &= CIFS_UNIX_CAP_MASK; |
| @@ -1753,9 +1760,8 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, | |||
| 1753 | if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) { | 1760 | if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) { |
| 1754 | if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { | 1761 | if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { |
| 1755 | CIFS_SB(sb)->rsize = 127 * 1024; | 1762 | CIFS_SB(sb)->rsize = 127 * 1024; |
| 1756 | #ifdef CONFIG_CIFS_DEBUG2 | 1763 | cFYI(DBG2, |
| 1757 | cFYI(1, ("larger reads not supported by srv")); | 1764 | ("larger reads not supported by srv")); |
| 1758 | #endif | ||
| 1759 | } | 1765 | } |
| 1760 | } | 1766 | } |
| 1761 | 1767 | ||
| @@ -1792,6 +1798,26 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, | |||
| 1792 | } | 1798 | } |
| 1793 | } | 1799 | } |
| 1794 | 1800 | ||
| 1801 | static void | ||
| 1802 | convert_delimiter(char *path, char delim) | ||
| 1803 | { | ||
| 1804 | int i; | ||
| 1805 | char old_delim; | ||
| 1806 | |||
| 1807 | if (path == NULL) | ||
| 1808 | return; | ||
| 1809 | |||
| 1810 | if (delim == '/') | ||
| 1811 | old_delim = '\\'; | ||
| 1812 | else | ||
| 1813 | old_delim = '/'; | ||
| 1814 | |||
| 1815 | for (i = 0; path[i] != '\0'; i++) { | ||
| 1816 | if (path[i] == old_delim) | ||
| 1817 | path[i] = delim; | ||
| 1818 | } | ||
| 1819 | } | ||
| 1820 | |||
| 1795 | int | 1821 | int |
| 1796 | cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | 1822 | cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, |
| 1797 | char *mount_data, const char *devname) | 1823 | char *mount_data, const char *devname) |
| @@ -2057,7 +2083,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 2057 | cifs_sb->prepath = volume_info.prepath; | 2083 | cifs_sb->prepath = volume_info.prepath; |
| 2058 | if (cifs_sb->prepath) { | 2084 | if (cifs_sb->prepath) { |
| 2059 | cifs_sb->prepathlen = strlen(cifs_sb->prepath); | 2085 | cifs_sb->prepathlen = strlen(cifs_sb->prepath); |
| 2060 | cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb); | 2086 | /* we can not convert the / to \ in the path |
| 2087 | separators in the prefixpath yet because we do not | ||
| 2088 | know (until reset_cifs_unix_caps is called later) | ||
| 2089 | whether POSIX PATH CAP is available. We normalize | ||
| 2090 | the / to \ after reset_cifs_unix_caps is called */ | ||
| 2061 | volume_info.prepath = NULL; | 2091 | volume_info.prepath = NULL; |
| 2062 | } else | 2092 | } else |
| 2063 | cifs_sb->prepathlen = 0; | 2093 | cifs_sb->prepathlen = 0; |
| @@ -2225,11 +2255,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 2225 | else | 2255 | else |
| 2226 | tcon->unix_ext = 0; /* server does not support them */ | 2256 | tcon->unix_ext = 0; /* server does not support them */ |
| 2227 | 2257 | ||
| 2258 | /* convert forward to back slashes in prepath here if needed */ | ||
| 2259 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0) | ||
| 2260 | convert_delimiter(cifs_sb->prepath, | ||
| 2261 | CIFS_DIR_SEP(cifs_sb)); | ||
| 2262 | |||
| 2228 | if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) { | 2263 | if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) { |
| 2229 | cifs_sb->rsize = 1024 * 127; | 2264 | cifs_sb->rsize = 1024 * 127; |
| 2230 | #ifdef CONFIG_CIFS_DEBUG2 | 2265 | cFYI(DBG2, |
| 2231 | cFYI(1, ("no very large read support, rsize now 127K")); | 2266 | ("no very large read support, rsize now 127K")); |
| 2232 | #endif | ||
| 2233 | } | 2267 | } |
| 2234 | if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X)) | 2268 | if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X)) |
| 2235 | cifs_sb->wsize = min(cifs_sb->wsize, | 2269 | cifs_sb->wsize = min(cifs_sb->wsize, |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 699ec1198409..0f5c62ba4038 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * vfs operations that deal with dentries | 4 | * vfs operations that deal with dentries |
| 5 | * | 5 | * |
| 6 | * Copyright (C) International Business Machines Corp., 2002,2007 | 6 | * Copyright (C) International Business Machines Corp., 2002,2008 |
| 7 | * Author(s): Steve French (sfrench@us.ibm.com) | 7 | * Author(s): Steve French (sfrench@us.ibm.com) |
| 8 | * | 8 | * |
| 9 | * This library is free software; you can redistribute it and/or modify | 9 | * This library is free software; you can redistribute it and/or modify |
| @@ -111,16 +111,6 @@ cifs_bp_rename_retry: | |||
| 111 | return full_path; | 111 | return full_path; |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | /* char * build_wildcard_path_from_dentry(struct dentry *direntry) | ||
| 115 | { | ||
| 116 | if(full_path == NULL) | ||
| 117 | return full_path; | ||
| 118 | |||
| 119 | full_path[namelen] = '\\'; | ||
| 120 | full_path[namelen+1] = '*'; | ||
| 121 | full_path[namelen+2] = 0; | ||
| 122 | BB remove above eight lines BB */ | ||
| 123 | |||
| 124 | /* Inode operations in similar order to how they appear in Linux file fs.h */ | 114 | /* Inode operations in similar order to how they appear in Linux file fs.h */ |
| 125 | 115 | ||
| 126 | int | 116 | int |
| @@ -171,9 +161,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
| 171 | disposition = FILE_OVERWRITE_IF; | 161 | disposition = FILE_OVERWRITE_IF; |
| 172 | else if ((oflags & O_CREAT) == O_CREAT) | 162 | else if ((oflags & O_CREAT) == O_CREAT) |
| 173 | disposition = FILE_OPEN_IF; | 163 | disposition = FILE_OPEN_IF; |
| 174 | else { | 164 | else |
| 175 | cFYI(1, ("Create flag not set in create function")); | 165 | cFYI(1, ("Create flag not set in create function")); |
| 176 | } | ||
| 177 | } | 166 | } |
| 178 | 167 | ||
| 179 | /* BB add processing to set equivalent of mode - e.g. via CreateX with | 168 | /* BB add processing to set equivalent of mode - e.g. via CreateX with |
| @@ -240,7 +229,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
| 240 | inode->i_sb, xid); | 229 | inode->i_sb, xid); |
| 241 | else { | 230 | else { |
| 242 | rc = cifs_get_inode_info(&newinode, full_path, | 231 | rc = cifs_get_inode_info(&newinode, full_path, |
| 243 | buf, inode->i_sb, xid); | 232 | buf, inode->i_sb, xid, |
| 233 | &fileHandle); | ||
| 244 | if (newinode) { | 234 | if (newinode) { |
| 245 | newinode->i_mode = mode; | 235 | newinode->i_mode = mode; |
| 246 | if ((oplock & CIFS_CREATE_ACTION) && | 236 | if ((oplock & CIFS_CREATE_ACTION) && |
| @@ -367,7 +357,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
| 367 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { | 357 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { |
| 368 | int oplock = 0; | 358 | int oplock = 0; |
| 369 | u16 fileHandle; | 359 | u16 fileHandle; |
| 370 | FILE_ALL_INFO * buf; | 360 | FILE_ALL_INFO *buf; |
| 371 | 361 | ||
| 372 | cFYI(1, ("sfu compat create special file")); | 362 | cFYI(1, ("sfu compat create special file")); |
| 373 | 363 | ||
| @@ -494,7 +484,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
| 494 | parent_dir_inode->i_sb, xid); | 484 | parent_dir_inode->i_sb, xid); |
| 495 | else | 485 | else |
| 496 | rc = cifs_get_inode_info(&newInode, full_path, NULL, | 486 | rc = cifs_get_inode_info(&newInode, full_path, NULL, |
| 497 | parent_dir_inode->i_sb, xid); | 487 | parent_dir_inode->i_sb, xid, NULL); |
| 498 | 488 | ||
| 499 | if ((rc == 0) && (newInode != NULL)) { | 489 | if ((rc == 0) && (newInode != NULL)) { |
| 500 | if (pTcon->nocase) | 490 | if (pTcon->nocase) |
| @@ -534,9 +524,8 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) | |||
| 534 | int isValid = 1; | 524 | int isValid = 1; |
| 535 | 525 | ||
| 536 | if (direntry->d_inode) { | 526 | if (direntry->d_inode) { |
| 537 | if (cifs_revalidate(direntry)) { | 527 | if (cifs_revalidate(direntry)) |
| 538 | return 0; | 528 | return 0; |
| 539 | } | ||
| 540 | } else { | 529 | } else { |
| 541 | cFYI(1, ("neg dentry 0x%p name = %s", | 530 | cFYI(1, ("neg dentry 0x%p name = %s", |
| 542 | direntry, direntry->d_name.name)); | 531 | direntry, direntry->d_name.name)); |
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c index ef7f43824347..7cc86c418182 100644 --- a/fs/cifs/dns_resolve.c +++ b/fs/cifs/dns_resolve.c | |||
| @@ -77,14 +77,14 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) | |||
| 77 | /* search for server name delimiter */ | 77 | /* search for server name delimiter */ |
| 78 | len = strlen(unc); | 78 | len = strlen(unc); |
| 79 | if (len < 3) { | 79 | if (len < 3) { |
| 80 | cFYI(1, ("%s: unc is too short: %s", __FUNCTION__, unc)); | 80 | cFYI(1, ("%s: unc is too short: %s", __func__, unc)); |
| 81 | return -EINVAL; | 81 | return -EINVAL; |
| 82 | } | 82 | } |
| 83 | len -= 2; | 83 | len -= 2; |
| 84 | name = memchr(unc+2, '\\', len); | 84 | name = memchr(unc+2, '\\', len); |
| 85 | if (!name) { | 85 | if (!name) { |
| 86 | cFYI(1, ("%s: probably server name is whole unc: %s", | 86 | cFYI(1, ("%s: probably server name is whole unc: %s", |
| 87 | __FUNCTION__, unc)); | 87 | __func__, unc)); |
| 88 | } else { | 88 | } else { |
| 89 | len = (name - unc) - 2/* leading // */; | 89 | len = (name - unc) - 2/* leading // */; |
| 90 | } | 90 | } |
| @@ -104,7 +104,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) | |||
| 104 | if (*ip_addr) { | 104 | if (*ip_addr) { |
| 105 | memcpy(*ip_addr, rkey->payload.data, len); | 105 | memcpy(*ip_addr, rkey->payload.data, len); |
| 106 | (*ip_addr)[len] = '\0'; | 106 | (*ip_addr)[len] = '\0'; |
| 107 | cFYI(1, ("%s: resolved: %s to %s", __FUNCTION__, | 107 | cFYI(1, ("%s: resolved: %s to %s", __func__, |
| 108 | rkey->description, | 108 | rkey->description, |
| 109 | *ip_addr | 109 | *ip_addr |
| 110 | )); | 110 | )); |
| @@ -114,7 +114,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) | |||
| 114 | } | 114 | } |
| 115 | key_put(rkey); | 115 | key_put(rkey); |
| 116 | } else { | 116 | } else { |
| 117 | cERROR(1, ("%s: unable to resolve: %s", __FUNCTION__, name)); | 117 | cERROR(1, ("%s: unable to resolve: %s", __func__, name)); |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | kfree(name); | 120 | kfree(name); |
diff --git a/fs/cifs/dns_resolve.h b/fs/cifs/dns_resolve.h index 073fdc3db419..966e9288930b 100644 --- a/fs/cifs/dns_resolve.h +++ b/fs/cifs/dns_resolve.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * fs/cifs/dns_resolve.h -- DNS Resolver upcall management for CIFS DFS | 2 | * fs/cifs/dns_resolve.h -- DNS Resolver upcall management for CIFS DFS |
| 3 | * Handles host name to IP address resolution | 3 | * Handles host name to IP address resolution |
| 4 | * | 4 | * |
| 5 | * Copyright (c) International Business Machines Corp., 2008 | 5 | * Copyright (c) International Business Machines Corp., 2008 |
| 6 | * Author(s): Steve French (sfrench@us.ibm.com) | 6 | * Author(s): Steve French (sfrench@us.ibm.com) |
| 7 | * | 7 | * |
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c index 995474c90885..7d1d5aa4c430 100644 --- a/fs/cifs/fcntl.c +++ b/fs/cifs/fcntl.c | |||
| @@ -35,9 +35,8 @@ static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags) | |||
| 35 | 35 | ||
| 36 | /* No way on Linux VFS to ask to monitor xattr | 36 | /* No way on Linux VFS to ask to monitor xattr |
| 37 | changes (and no stream support either */ | 37 | changes (and no stream support either */ |
| 38 | if (fcntl_notify_flags & DN_ACCESS) { | 38 | if (fcntl_notify_flags & DN_ACCESS) |
| 39 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_ACCESS; | 39 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_ACCESS; |
| 40 | } | ||
| 41 | if (fcntl_notify_flags & DN_MODIFY) { | 40 | if (fcntl_notify_flags & DN_MODIFY) { |
| 42 | /* What does this mean on directories? */ | 41 | /* What does this mean on directories? */ |
| 43 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE | | 42 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE | |
| @@ -47,9 +46,8 @@ static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags) | |||
| 47 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_CREATION | | 46 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_CREATION | |
| 48 | FILE_NOTIFY_CHANGE_LAST_WRITE; | 47 | FILE_NOTIFY_CHANGE_LAST_WRITE; |
| 49 | } | 48 | } |
| 50 | if (fcntl_notify_flags & DN_DELETE) { | 49 | if (fcntl_notify_flags & DN_DELETE) |
| 51 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE; | 50 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE; |
| 52 | } | ||
| 53 | if (fcntl_notify_flags & DN_RENAME) { | 51 | if (fcntl_notify_flags & DN_RENAME) { |
| 54 | /* BB review this - checking various server behaviors */ | 52 | /* BB review this - checking various server behaviors */ |
| 55 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_NAME | | 53 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_NAME | |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5f7c374ae89c..40b690073fc1 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -145,7 +145,7 @@ client_can_cache: | |||
| 145 | full_path, inode->i_sb, xid); | 145 | full_path, inode->i_sb, xid); |
| 146 | else | 146 | else |
| 147 | rc = cifs_get_inode_info(&file->f_path.dentry->d_inode, | 147 | rc = cifs_get_inode_info(&file->f_path.dentry->d_inode, |
| 148 | full_path, buf, inode->i_sb, xid); | 148 | full_path, buf, inode->i_sb, xid, NULL); |
| 149 | 149 | ||
| 150 | if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 150 | if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { |
| 151 | pCifsInode->clientCanCacheAll = TRUE; | 151 | pCifsInode->clientCanCacheAll = TRUE; |
| @@ -353,9 +353,9 @@ static int cifs_reopen_file(struct file *file, int can_flush) | |||
| 353 | int disposition = FILE_OPEN; | 353 | int disposition = FILE_OPEN; |
| 354 | __u16 netfid; | 354 | __u16 netfid; |
| 355 | 355 | ||
| 356 | if (file->private_data) { | 356 | if (file->private_data) |
| 357 | pCifsFile = (struct cifsFileInfo *)file->private_data; | 357 | pCifsFile = (struct cifsFileInfo *)file->private_data; |
| 358 | } else | 358 | else |
| 359 | return -EBADF; | 359 | return -EBADF; |
| 360 | 360 | ||
| 361 | xid = GetXid(); | 361 | xid = GetXid(); |
| @@ -440,7 +440,7 @@ reopen_error_exit: | |||
| 440 | else | 440 | else |
| 441 | rc = cifs_get_inode_info(&inode, | 441 | rc = cifs_get_inode_info(&inode, |
| 442 | full_path, NULL, inode->i_sb, | 442 | full_path, NULL, inode->i_sb, |
| 443 | xid); | 443 | xid, NULL); |
| 444 | } /* else we are writing out data to server already | 444 | } /* else we are writing out data to server already |
| 445 | and could deadlock if we tried to flush data, and | 445 | and could deadlock if we tried to flush data, and |
| 446 | since we do not know if we have data that would | 446 | since we do not know if we have data that would |
| @@ -499,9 +499,8 @@ int cifs_close(struct inode *inode, struct file *file) | |||
| 499 | the struct would be in each open file, | 499 | the struct would be in each open file, |
| 500 | but this should give enough time to | 500 | but this should give enough time to |
| 501 | clear the socket */ | 501 | clear the socket */ |
| 502 | #ifdef CONFIG_CIFS_DEBUG2 | 502 | cFYI(DBG2, |
| 503 | cFYI(1, ("close delay, write pending")); | 503 | ("close delay, write pending")); |
| 504 | #endif /* DEBUG2 */ | ||
| 505 | msleep(timeout); | 504 | msleep(timeout); |
| 506 | timeout *= 4; | 505 | timeout *= 4; |
| 507 | } | 506 | } |
| @@ -1423,9 +1422,8 @@ static int cifs_writepage(struct page *page, struct writeback_control *wbc) | |||
| 1423 | xid = GetXid(); | 1422 | xid = GetXid(); |
| 1424 | /* BB add check for wbc flags */ | 1423 | /* BB add check for wbc flags */ |
| 1425 | page_cache_get(page); | 1424 | page_cache_get(page); |
| 1426 | if (!PageUptodate(page)) { | 1425 | if (!PageUptodate(page)) |
| 1427 | cFYI(1, ("ppw - page not up to date")); | 1426 | cFYI(1, ("ppw - page not up to date")); |
| 1428 | } | ||
| 1429 | 1427 | ||
| 1430 | /* | 1428 | /* |
| 1431 | * Set the "writeback" flag, and clear "dirty" in the radix tree. | 1429 | * Set the "writeback" flag, and clear "dirty" in the radix tree. |
| @@ -1460,9 +1458,9 @@ static int cifs_commit_write(struct file *file, struct page *page, | |||
| 1460 | cFYI(1, ("commit write for page %p up to position %lld for %d", | 1458 | cFYI(1, ("commit write for page %p up to position %lld for %d", |
| 1461 | page, position, to)); | 1459 | page, position, to)); |
| 1462 | spin_lock(&inode->i_lock); | 1460 | spin_lock(&inode->i_lock); |
| 1463 | if (position > inode->i_size) { | 1461 | if (position > inode->i_size) |
| 1464 | i_size_write(inode, position); | 1462 | i_size_write(inode, position); |
| 1465 | } | 1463 | |
| 1466 | spin_unlock(&inode->i_lock); | 1464 | spin_unlock(&inode->i_lock); |
| 1467 | if (!PageUptodate(page)) { | 1465 | if (!PageUptodate(page)) { |
| 1468 | position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset; | 1466 | position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset; |
| @@ -1596,9 +1594,9 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
| 1596 | } | 1594 | } |
| 1597 | open_file = (struct cifsFileInfo *)file->private_data; | 1595 | open_file = (struct cifsFileInfo *)file->private_data; |
| 1598 | 1596 | ||
| 1599 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) { | 1597 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) |
| 1600 | cFYI(1, ("attempting read on write only file instance")); | 1598 | cFYI(1, ("attempting read on write only file instance")); |
| 1601 | } | 1599 | |
| 1602 | for (total_read = 0, current_offset = read_data; | 1600 | for (total_read = 0, current_offset = read_data; |
| 1603 | read_size > total_read; | 1601 | read_size > total_read; |
| 1604 | total_read += bytes_read, current_offset += bytes_read) { | 1602 | total_read += bytes_read, current_offset += bytes_read) { |
| @@ -1625,9 +1623,8 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
| 1625 | smb_read_data + | 1623 | smb_read_data + |
| 1626 | 4 /* RFC1001 length field */ + | 1624 | 4 /* RFC1001 length field */ + |
| 1627 | le16_to_cpu(pSMBr->DataOffset), | 1625 | le16_to_cpu(pSMBr->DataOffset), |
| 1628 | bytes_read)) { | 1626 | bytes_read)) |
| 1629 | rc = -EFAULT; | 1627 | rc = -EFAULT; |
| 1630 | } | ||
| 1631 | 1628 | ||
| 1632 | if (buf_type == CIFS_SMALL_BUFFER) | 1629 | if (buf_type == CIFS_SMALL_BUFFER) |
| 1633 | cifs_small_buf_release(smb_read_data); | 1630 | cifs_small_buf_release(smb_read_data); |
| @@ -1814,9 +1811,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
| 1814 | pTcon = cifs_sb->tcon; | 1811 | pTcon = cifs_sb->tcon; |
| 1815 | 1812 | ||
| 1816 | pagevec_init(&lru_pvec, 0); | 1813 | pagevec_init(&lru_pvec, 0); |
| 1817 | #ifdef CONFIG_CIFS_DEBUG2 | 1814 | cFYI(DBG2, ("rpages: num pages %d", num_pages)); |
| 1818 | cFYI(1, ("rpages: num pages %d", num_pages)); | ||
| 1819 | #endif | ||
| 1820 | for (i = 0; i < num_pages; ) { | 1815 | for (i = 0; i < num_pages; ) { |
| 1821 | unsigned contig_pages; | 1816 | unsigned contig_pages; |
| 1822 | struct page *tmp_page; | 1817 | struct page *tmp_page; |
| @@ -1849,10 +1844,8 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
| 1849 | /* Read size needs to be in multiples of one page */ | 1844 | /* Read size needs to be in multiples of one page */ |
| 1850 | read_size = min_t(const unsigned int, read_size, | 1845 | read_size = min_t(const unsigned int, read_size, |
| 1851 | cifs_sb->rsize & PAGE_CACHE_MASK); | 1846 | cifs_sb->rsize & PAGE_CACHE_MASK); |
| 1852 | #ifdef CONFIG_CIFS_DEBUG2 | 1847 | cFYI(DBG2, ("rpages: read size 0x%x contiguous pages %d", |
| 1853 | cFYI(1, ("rpages: read size 0x%x contiguous pages %d", | ||
| 1854 | read_size, contig_pages)); | 1848 | read_size, contig_pages)); |
| 1855 | #endif | ||
| 1856 | rc = -EAGAIN; | 1849 | rc = -EAGAIN; |
| 1857 | while (rc == -EAGAIN) { | 1850 | while (rc == -EAGAIN) { |
| 1858 | if ((open_file->invalidHandle) && | 1851 | if ((open_file->invalidHandle) && |
| @@ -2026,7 +2019,7 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) | |||
| 2026 | struct cifs_sb_info *cifs_sb; | 2019 | struct cifs_sb_info *cifs_sb; |
| 2027 | 2020 | ||
| 2028 | cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb); | 2021 | cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb); |
| 2029 | if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) { | 2022 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { |
| 2030 | /* since no page cache to corrupt on directio | 2023 | /* since no page cache to corrupt on directio |
| 2031 | we can change size safely */ | 2024 | we can change size safely */ |
| 2032 | return 1; | 2025 | return 1; |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index b1a4a65eaa08..bc673c8c1e6b 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -29,6 +29,162 @@ | |||
| 29 | #include "cifs_debug.h" | 29 | #include "cifs_debug.h" |
| 30 | #include "cifs_fs_sb.h" | 30 | #include "cifs_fs_sb.h" |
| 31 | 31 | ||
| 32 | |||
| 33 | static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral) | ||
| 34 | { | ||
| 35 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
| 36 | |||
| 37 | switch (inode->i_mode & S_IFMT) { | ||
| 38 | case S_IFREG: | ||
| 39 | inode->i_op = &cifs_file_inode_ops; | ||
| 40 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { | ||
| 41 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
| 42 | inode->i_fop = &cifs_file_direct_nobrl_ops; | ||
| 43 | else | ||
| 44 | inode->i_fop = &cifs_file_direct_ops; | ||
| 45 | } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
| 46 | inode->i_fop = &cifs_file_nobrl_ops; | ||
| 47 | else { /* not direct, send byte range locks */ | ||
| 48 | inode->i_fop = &cifs_file_ops; | ||
| 49 | } | ||
| 50 | |||
| 51 | |||
| 52 | /* check if server can support readpages */ | ||
| 53 | if (cifs_sb->tcon->ses->server->maxBuf < | ||
| 54 | PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) | ||
| 55 | inode->i_data.a_ops = &cifs_addr_ops_smallbuf; | ||
| 56 | else | ||
| 57 | inode->i_data.a_ops = &cifs_addr_ops; | ||
| 58 | break; | ||
| 59 | case S_IFDIR: | ||
| 60 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
| 61 | if (is_dfs_referral) { | ||
| 62 | inode->i_op = &cifs_dfs_referral_inode_operations; | ||
| 63 | } else { | ||
| 64 | #else /* NO DFS support, treat as a directory */ | ||
| 65 | { | ||
| 66 | #endif | ||
| 67 | inode->i_op = &cifs_dir_inode_ops; | ||
| 68 | inode->i_fop = &cifs_dir_ops; | ||
| 69 | } | ||
| 70 | break; | ||
| 71 | case S_IFLNK: | ||
| 72 | inode->i_op = &cifs_symlink_inode_ops; | ||
| 73 | break; | ||
| 74 | default: | ||
| 75 | init_special_inode(inode, inode->i_mode, inode->i_rdev); | ||
| 76 | break; | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | static void cifs_unix_info_to_inode(struct inode *inode, | ||
| 81 | FILE_UNIX_BASIC_INFO *info, int force_uid_gid) | ||
| 82 | { | ||
| 83 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
| 84 | struct cifsInodeInfo *cifsInfo = CIFS_I(inode); | ||
| 85 | __u64 num_of_bytes = le64_to_cpu(info->NumOfBytes); | ||
| 86 | __u64 end_of_file = le64_to_cpu(info->EndOfFile); | ||
| 87 | |||
| 88 | inode->i_atime = cifs_NTtimeToUnix(le64_to_cpu(info->LastAccessTime)); | ||
| 89 | inode->i_mtime = | ||
| 90 | cifs_NTtimeToUnix(le64_to_cpu(info->LastModificationTime)); | ||
| 91 | inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(info->LastStatusChange)); | ||
| 92 | inode->i_mode = le64_to_cpu(info->Permissions); | ||
| 93 | |||
| 94 | /* | ||
| 95 | * Since we set the inode type below we need to mask off | ||
| 96 | * to avoid strange results if bits set above. | ||
| 97 | */ | ||
| 98 | inode->i_mode &= ~S_IFMT; | ||
| 99 | switch (le32_to_cpu(info->Type)) { | ||
| 100 | case UNIX_FILE: | ||
| 101 | inode->i_mode |= S_IFREG; | ||
| 102 | break; | ||
| 103 | case UNIX_SYMLINK: | ||
| 104 | inode->i_mode |= S_IFLNK; | ||
| 105 | break; | ||
| 106 | case UNIX_DIR: | ||
| 107 | inode->i_mode |= S_IFDIR; | ||
| 108 | break; | ||
| 109 | case UNIX_CHARDEV: | ||
| 110 | inode->i_mode |= S_IFCHR; | ||
| 111 | inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor), | ||
| 112 | le64_to_cpu(info->DevMinor) & MINORMASK); | ||
| 113 | break; | ||
| 114 | case UNIX_BLOCKDEV: | ||
| 115 | inode->i_mode |= S_IFBLK; | ||
| 116 | inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor), | ||
| 117 | le64_to_cpu(info->DevMinor) & MINORMASK); | ||
| 118 | break; | ||
| 119 | case UNIX_FIFO: | ||
| 120 | inode->i_mode |= S_IFIFO; | ||
| 121 | break; | ||
| 122 | case UNIX_SOCKET: | ||
| 123 | inode->i_mode |= S_IFSOCK; | ||
| 124 | break; | ||
| 125 | default: | ||
| 126 | /* safest to call it a file if we do not know */ | ||
| 127 | inode->i_mode |= S_IFREG; | ||
| 128 | cFYI(1, ("unknown type %d", le32_to_cpu(info->Type))); | ||
| 129 | break; | ||
| 130 | } | ||
| 131 | |||
| 132 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) && | ||
| 133 | !force_uid_gid) | ||
| 134 | inode->i_uid = cifs_sb->mnt_uid; | ||
| 135 | else | ||
| 136 | inode->i_uid = le64_to_cpu(info->Uid); | ||
| 137 | |||
| 138 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) && | ||
| 139 | !force_uid_gid) | ||
| 140 | inode->i_gid = cifs_sb->mnt_gid; | ||
| 141 | else | ||
| 142 | inode->i_gid = le64_to_cpu(info->Gid); | ||
| 143 | |||
| 144 | inode->i_nlink = le64_to_cpu(info->Nlinks); | ||
| 145 | |||
| 146 | spin_lock(&inode->i_lock); | ||
| 147 | if (is_size_safe_to_change(cifsInfo, end_of_file)) { | ||
| 148 | /* | ||
| 149 | * We can not safely change the file size here if the client | ||
| 150 | * is writing to it due to potential races. | ||
| 151 | */ | ||
| 152 | i_size_write(inode, end_of_file); | ||
| 153 | |||
| 154 | /* | ||
| 155 | * i_blocks is not related to (i_size / i_blksize), | ||
| 156 | * but instead 512 byte (2**9) size is required for | ||
| 157 | * calculating num blocks. | ||
| 158 | */ | ||
| 159 | inode->i_blocks = (512 - 1 + num_of_bytes) >> 9; | ||
| 160 | } | ||
| 161 | spin_unlock(&inode->i_lock); | ||
| 162 | } | ||
| 163 | |||
| 164 | static const unsigned char *cifs_get_search_path(struct cifsTconInfo *pTcon, | ||
| 165 | const char *search_path) | ||
| 166 | { | ||
| 167 | int tree_len; | ||
| 168 | int path_len; | ||
| 169 | char *tmp_path; | ||
| 170 | |||
| 171 | if (!(pTcon->Flags & SMB_SHARE_IS_IN_DFS)) | ||
| 172 | return search_path; | ||
| 173 | |||
| 174 | /* use full path name for working with DFS */ | ||
| 175 | tree_len = strnlen(pTcon->treeName, MAX_TREE_SIZE + 1); | ||
| 176 | path_len = strnlen(search_path, MAX_PATHCONF); | ||
| 177 | |||
| 178 | tmp_path = kmalloc(tree_len+path_len+1, GFP_KERNEL); | ||
| 179 | if (tmp_path == NULL) | ||
| 180 | return search_path; | ||
| 181 | |||
| 182 | strncpy(tmp_path, pTcon->treeName, tree_len); | ||
| 183 | strncpy(tmp_path+tree_len, search_path, path_len); | ||
| 184 | tmp_path[tree_len+path_len] = 0; | ||
| 185 | return tmp_path; | ||
| 186 | } | ||
| 187 | |||
| 32 | int cifs_get_inode_info_unix(struct inode **pinode, | 188 | int cifs_get_inode_info_unix(struct inode **pinode, |
| 33 | const unsigned char *search_path, struct super_block *sb, int xid) | 189 | const unsigned char *search_path, struct super_block *sb, int xid) |
| 34 | { | 190 | { |
| @@ -37,52 +193,43 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
| 37 | struct cifsTconInfo *pTcon; | 193 | struct cifsTconInfo *pTcon; |
| 38 | struct inode *inode; | 194 | struct inode *inode; |
| 39 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 195 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
| 40 | char *tmp_path; | 196 | const unsigned char *full_path; |
| 197 | bool is_dfs_referral = false; | ||
| 41 | 198 | ||
| 42 | pTcon = cifs_sb->tcon; | 199 | pTcon = cifs_sb->tcon; |
| 43 | cFYI(1, ("Getting info on %s", search_path)); | 200 | cFYI(1, ("Getting info on %s", search_path)); |
| 201 | |||
| 202 | full_path = cifs_get_search_path(pTcon, search_path); | ||
| 203 | |||
| 204 | try_again_CIFSSMBUnixQPathInfo: | ||
| 44 | /* could have done a find first instead but this returns more info */ | 205 | /* could have done a find first instead but this returns more info */ |
| 45 | rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, | 206 | rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &findData, |
| 46 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | 207 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
| 47 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 208 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 48 | /* dump_mem("\nUnixQPathInfo return data", &findData, | 209 | /* dump_mem("\nUnixQPathInfo return data", &findData, |
| 49 | sizeof(findData)); */ | 210 | sizeof(findData)); */ |
| 50 | if (rc) { | 211 | if (rc) { |
| 51 | if (rc == -EREMOTE) { | 212 | if (rc == -EREMOTE && !is_dfs_referral) { |
| 52 | tmp_path = | 213 | is_dfs_referral = true; |
| 53 | kmalloc(strnlen(pTcon->treeName, | 214 | if (full_path != search_path) { |
| 54 | MAX_TREE_SIZE + 1) + | 215 | kfree(full_path); |
| 55 | strnlen(search_path, MAX_PATHCONF) + 1, | 216 | full_path = search_path; |
| 56 | GFP_KERNEL); | 217 | } |
| 57 | if (tmp_path == NULL) | 218 | goto try_again_CIFSSMBUnixQPathInfo; |
| 58 | return -ENOMEM; | ||
| 59 | |||
| 60 | /* have to skip first of the double backslash of | ||
| 61 | UNC name */ | ||
| 62 | strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); | ||
| 63 | strncat(tmp_path, search_path, MAX_PATHCONF); | ||
| 64 | rc = connect_to_dfs_path(xid, pTcon->ses, | ||
| 65 | /* treename + */ tmp_path, | ||
| 66 | cifs_sb->local_nls, | ||
| 67 | cifs_sb->mnt_cifs_flags & | ||
| 68 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 69 | kfree(tmp_path); | ||
| 70 | |||
| 71 | /* BB fix up inode etc. */ | ||
| 72 | } else if (rc) { | ||
| 73 | return rc; | ||
| 74 | } | 219 | } |
| 220 | goto cgiiu_exit; | ||
| 75 | } else { | 221 | } else { |
| 76 | struct cifsInodeInfo *cifsInfo; | 222 | struct cifsInodeInfo *cifsInfo; |
| 77 | __u32 type = le32_to_cpu(findData.Type); | ||
| 78 | __u64 num_of_bytes = le64_to_cpu(findData.NumOfBytes); | 223 | __u64 num_of_bytes = le64_to_cpu(findData.NumOfBytes); |
| 79 | __u64 end_of_file = le64_to_cpu(findData.EndOfFile); | 224 | __u64 end_of_file = le64_to_cpu(findData.EndOfFile); |
| 80 | 225 | ||
| 81 | /* get new inode */ | 226 | /* get new inode */ |
| 82 | if (*pinode == NULL) { | 227 | if (*pinode == NULL) { |
| 83 | *pinode = new_inode(sb); | 228 | *pinode = new_inode(sb); |
| 84 | if (*pinode == NULL) | 229 | if (*pinode == NULL) { |
| 85 | return -ENOMEM; | 230 | rc = -ENOMEM; |
| 231 | goto cgiiu_exit; | ||
| 232 | } | ||
| 86 | /* Is an i_ino of zero legal? */ | 233 | /* Is an i_ino of zero legal? */ |
| 87 | /* Are there sanity checks we can use to ensure that | 234 | /* Are there sanity checks we can use to ensure that |
| 88 | the server is really filling in that field? */ | 235 | the server is really filling in that field? */ |
| @@ -105,113 +252,20 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
| 105 | /* this is ok to set on every inode revalidate */ | 252 | /* this is ok to set on every inode revalidate */ |
| 106 | atomic_set(&cifsInfo->inUse, 1); | 253 | atomic_set(&cifsInfo->inUse, 1); |
| 107 | 254 | ||
| 108 | inode->i_atime = | 255 | cifs_unix_info_to_inode(inode, &findData, 0); |
| 109 | cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime)); | ||
| 110 | inode->i_mtime = | ||
| 111 | cifs_NTtimeToUnix(le64_to_cpu | ||
| 112 | (findData.LastModificationTime)); | ||
| 113 | inode->i_ctime = | ||
| 114 | cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange)); | ||
| 115 | inode->i_mode = le64_to_cpu(findData.Permissions); | ||
| 116 | /* since we set the inode type below we need to mask off | ||
| 117 | to avoid strange results if bits set above */ | ||
| 118 | inode->i_mode &= ~S_IFMT; | ||
| 119 | if (type == UNIX_FILE) { | ||
| 120 | inode->i_mode |= S_IFREG; | ||
| 121 | } else if (type == UNIX_SYMLINK) { | ||
| 122 | inode->i_mode |= S_IFLNK; | ||
| 123 | } else if (type == UNIX_DIR) { | ||
| 124 | inode->i_mode |= S_IFDIR; | ||
| 125 | } else if (type == UNIX_CHARDEV) { | ||
| 126 | inode->i_mode |= S_IFCHR; | ||
| 127 | inode->i_rdev = MKDEV(le64_to_cpu(findData.DevMajor), | ||
| 128 | le64_to_cpu(findData.DevMinor) & MINORMASK); | ||
| 129 | } else if (type == UNIX_BLOCKDEV) { | ||
| 130 | inode->i_mode |= S_IFBLK; | ||
| 131 | inode->i_rdev = MKDEV(le64_to_cpu(findData.DevMajor), | ||
| 132 | le64_to_cpu(findData.DevMinor) & MINORMASK); | ||
| 133 | } else if (type == UNIX_FIFO) { | ||
| 134 | inode->i_mode |= S_IFIFO; | ||
| 135 | } else if (type == UNIX_SOCKET) { | ||
| 136 | inode->i_mode |= S_IFSOCK; | ||
| 137 | } else { | ||
| 138 | /* safest to call it a file if we do not know */ | ||
| 139 | inode->i_mode |= S_IFREG; | ||
| 140 | cFYI(1, ("unknown type %d", type)); | ||
| 141 | } | ||
| 142 | |||
| 143 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) | ||
| 144 | inode->i_uid = cifs_sb->mnt_uid; | ||
| 145 | else | ||
| 146 | inode->i_uid = le64_to_cpu(findData.Uid); | ||
| 147 | |||
| 148 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) | ||
| 149 | inode->i_gid = cifs_sb->mnt_gid; | ||
| 150 | else | ||
| 151 | inode->i_gid = le64_to_cpu(findData.Gid); | ||
| 152 | |||
| 153 | inode->i_nlink = le64_to_cpu(findData.Nlinks); | ||
| 154 | 256 | ||
| 155 | spin_lock(&inode->i_lock); | ||
| 156 | if (is_size_safe_to_change(cifsInfo, end_of_file)) { | ||
| 157 | /* can not safely change the file size here if the | ||
| 158 | client is writing to it due to potential races */ | ||
| 159 | i_size_write(inode, end_of_file); | ||
| 160 | |||
| 161 | /* blksize needs to be multiple of two. So safer to default to | ||
| 162 | blksize and blkbits set in superblock so 2**blkbits and blksize | ||
| 163 | will match rather than setting to: | ||
| 164 | (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ | ||
| 165 | |||
| 166 | /* This seems incredibly stupid but it turns out that i_blocks | ||
| 167 | is not related to (i_size / i_blksize), instead 512 byte size | ||
| 168 | is required for calculating num blocks */ | ||
| 169 | |||
| 170 | /* 512 bytes (2**9) is the fake blocksize that must be used */ | ||
| 171 | /* for this calculation */ | ||
| 172 | inode->i_blocks = (512 - 1 + num_of_bytes) >> 9; | ||
| 173 | } | ||
| 174 | spin_unlock(&inode->i_lock); | ||
| 175 | 257 | ||
| 176 | if (num_of_bytes < end_of_file) | 258 | if (num_of_bytes < end_of_file) |
| 177 | cFYI(1, ("allocation size less than end of file")); | 259 | cFYI(1, ("allocation size less than end of file")); |
| 178 | cFYI(1, ("Size %ld and blocks %llu", | 260 | cFYI(1, ("Size %ld and blocks %llu", |
| 179 | (unsigned long) inode->i_size, | 261 | (unsigned long) inode->i_size, |
| 180 | (unsigned long long)inode->i_blocks)); | 262 | (unsigned long long)inode->i_blocks)); |
| 181 | if (S_ISREG(inode->i_mode)) { | 263 | |
| 182 | cFYI(1, ("File inode")); | 264 | cifs_set_ops(inode, is_dfs_referral); |
| 183 | inode->i_op = &cifs_file_inode_ops; | ||
| 184 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { | ||
| 185 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
| 186 | inode->i_fop = | ||
| 187 | &cifs_file_direct_nobrl_ops; | ||
| 188 | else | ||
| 189 | inode->i_fop = &cifs_file_direct_ops; | ||
| 190 | } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
| 191 | inode->i_fop = &cifs_file_nobrl_ops; | ||
| 192 | else /* not direct, send byte range locks */ | ||
| 193 | inode->i_fop = &cifs_file_ops; | ||
| 194 | |||
| 195 | /* check if server can support readpages */ | ||
| 196 | if (pTcon->ses->server->maxBuf < | ||
| 197 | PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) | ||
| 198 | inode->i_data.a_ops = &cifs_addr_ops_smallbuf; | ||
| 199 | else | ||
| 200 | inode->i_data.a_ops = &cifs_addr_ops; | ||
| 201 | } else if (S_ISDIR(inode->i_mode)) { | ||
| 202 | cFYI(1, ("Directory inode")); | ||
| 203 | inode->i_op = &cifs_dir_inode_ops; | ||
| 204 | inode->i_fop = &cifs_dir_ops; | ||
| 205 | } else if (S_ISLNK(inode->i_mode)) { | ||
| 206 | cFYI(1, ("Symbolic Link inode")); | ||
| 207 | inode->i_op = &cifs_symlink_inode_ops; | ||
| 208 | /* tmp_inode->i_fop = */ /* do not need to set to anything */ | ||
| 209 | } else { | ||
| 210 | cFYI(1, ("Init special inode")); | ||
| 211 | init_special_inode(inode, inode->i_mode, | ||
| 212 | inode->i_rdev); | ||
| 213 | } | ||
| 214 | } | 265 | } |
| 266 | cgiiu_exit: | ||
| 267 | if (full_path != search_path) | ||
| 268 | kfree(full_path); | ||
| 215 | return rc; | 269 | return rc; |
| 216 | } | 270 | } |
| 217 | 271 | ||
| @@ -320,15 +374,16 @@ static int get_sfu_mode(struct inode *inode, | |||
| 320 | 374 | ||
| 321 | int cifs_get_inode_info(struct inode **pinode, | 375 | int cifs_get_inode_info(struct inode **pinode, |
| 322 | const unsigned char *search_path, FILE_ALL_INFO *pfindData, | 376 | const unsigned char *search_path, FILE_ALL_INFO *pfindData, |
| 323 | struct super_block *sb, int xid) | 377 | struct super_block *sb, int xid, const __u16 *pfid) |
| 324 | { | 378 | { |
| 325 | int rc = 0; | 379 | int rc = 0; |
| 326 | struct cifsTconInfo *pTcon; | 380 | struct cifsTconInfo *pTcon; |
| 327 | struct inode *inode; | 381 | struct inode *inode; |
| 328 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 382 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
| 329 | char *tmp_path; | 383 | const unsigned char *full_path = NULL; |
| 330 | char *buf = NULL; | 384 | char *buf = NULL; |
| 331 | int adjustTZ = FALSE; | 385 | int adjustTZ = FALSE; |
| 386 | bool is_dfs_referral = false; | ||
| 332 | 387 | ||
| 333 | pTcon = cifs_sb->tcon; | 388 | pTcon = cifs_sb->tcon; |
| 334 | cFYI(1, ("Getting info on %s", search_path)); | 389 | cFYI(1, ("Getting info on %s", search_path)); |
| @@ -346,8 +401,12 @@ int cifs_get_inode_info(struct inode **pinode, | |||
| 346 | if (buf == NULL) | 401 | if (buf == NULL) |
| 347 | return -ENOMEM; | 402 | return -ENOMEM; |
| 348 | pfindData = (FILE_ALL_INFO *)buf; | 403 | pfindData = (FILE_ALL_INFO *)buf; |
| 404 | |||
| 405 | full_path = cifs_get_search_path(pTcon, search_path); | ||
| 406 | |||
| 407 | try_again_CIFSSMBQPathInfo: | ||
| 349 | /* could do find first instead but this returns more info */ | 408 | /* could do find first instead but this returns more info */ |
| 350 | rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, | 409 | rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData, |
| 351 | 0 /* not legacy */, | 410 | 0 /* not legacy */, |
| 352 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | 411 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
| 353 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 412 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
| @@ -355,7 +414,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
| 355 | when server claims no NT SMB support and the above call | 414 | when server claims no NT SMB support and the above call |
| 356 | failed at least once - set flag in tcon or mount */ | 415 | failed at least once - set flag in tcon or mount */ |
| 357 | if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { | 416 | if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { |
| 358 | rc = SMBQueryInformation(xid, pTcon, search_path, | 417 | rc = SMBQueryInformation(xid, pTcon, full_path, |
| 359 | pfindData, cifs_sb->local_nls, | 418 | pfindData, cifs_sb->local_nls, |
| 360 | cifs_sb->mnt_cifs_flags & | 419 | cifs_sb->mnt_cifs_flags & |
| 361 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 420 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
| @@ -364,31 +423,15 @@ int cifs_get_inode_info(struct inode **pinode, | |||
| 364 | } | 423 | } |
| 365 | /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ | 424 | /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ |
| 366 | if (rc) { | 425 | if (rc) { |
| 367 | if (rc == -EREMOTE) { | 426 | if (rc == -EREMOTE && !is_dfs_referral) { |
| 368 | tmp_path = | 427 | is_dfs_referral = true; |
| 369 | kmalloc(strnlen | 428 | if (full_path != search_path) { |
| 370 | (pTcon->treeName, | 429 | kfree(full_path); |
| 371 | MAX_TREE_SIZE + 1) + | 430 | full_path = search_path; |
| 372 | strnlen(search_path, MAX_PATHCONF) + 1, | ||
| 373 | GFP_KERNEL); | ||
| 374 | if (tmp_path == NULL) { | ||
| 375 | kfree(buf); | ||
| 376 | return -ENOMEM; | ||
| 377 | } | 431 | } |
| 378 | 432 | goto try_again_CIFSSMBQPathInfo; | |
| 379 | strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); | ||
| 380 | strncat(tmp_path, search_path, MAX_PATHCONF); | ||
| 381 | rc = connect_to_dfs_path(xid, pTcon->ses, | ||
| 382 | /* treename + */ tmp_path, | ||
| 383 | cifs_sb->local_nls, | ||
| 384 | cifs_sb->mnt_cifs_flags & | ||
| 385 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 386 | kfree(tmp_path); | ||
| 387 | /* BB fix up inode etc. */ | ||
| 388 | } else if (rc) { | ||
| 389 | kfree(buf); | ||
| 390 | return rc; | ||
| 391 | } | 433 | } |
| 434 | goto cgii_exit; | ||
| 392 | } else { | 435 | } else { |
| 393 | struct cifsInodeInfo *cifsInfo; | 436 | struct cifsInodeInfo *cifsInfo; |
| 394 | __u32 attr = le32_to_cpu(pfindData->Attributes); | 437 | __u32 attr = le32_to_cpu(pfindData->Attributes); |
| @@ -397,8 +440,8 @@ int cifs_get_inode_info(struct inode **pinode, | |||
| 397 | if (*pinode == NULL) { | 440 | if (*pinode == NULL) { |
| 398 | *pinode = new_inode(sb); | 441 | *pinode = new_inode(sb); |
| 399 | if (*pinode == NULL) { | 442 | if (*pinode == NULL) { |
| 400 | kfree(buf); | 443 | rc = -ENOMEM; |
| 401 | return -ENOMEM; | 444 | goto cgii_exit; |
| 402 | } | 445 | } |
| 403 | /* Is an i_ino of zero legal? Can we use that to check | 446 | /* Is an i_ino of zero legal? Can we use that to check |
| 404 | if the server supports returning inode numbers? Are | 447 | if the server supports returning inode numbers? Are |
| @@ -490,9 +533,9 @@ int cifs_get_inode_info(struct inode **pinode, | |||
| 490 | if (decode_sfu_inode(inode, | 533 | if (decode_sfu_inode(inode, |
| 491 | le64_to_cpu(pfindData->EndOfFile), | 534 | le64_to_cpu(pfindData->EndOfFile), |
| 492 | search_path, | 535 | search_path, |
| 493 | cifs_sb, xid)) { | 536 | cifs_sb, xid)) |
| 494 | cFYI(1, ("Unrecognized sfu inode type")); | 537 | cFYI(1, ("Unrecognized sfu inode type")); |
| 495 | } | 538 | |
| 496 | cFYI(1, ("sfu mode 0%o", inode->i_mode)); | 539 | cFYI(1, ("sfu mode 0%o", inode->i_mode)); |
| 497 | } else { | 540 | } else { |
| 498 | inode->i_mode |= S_IFREG; | 541 | inode->i_mode |= S_IFREG; |
| @@ -532,7 +575,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
| 532 | /* fill in 0777 bits from ACL */ | 575 | /* fill in 0777 bits from ACL */ |
| 533 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 576 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
| 534 | cFYI(1, ("Getting mode bits from ACL")); | 577 | cFYI(1, ("Getting mode bits from ACL")); |
| 535 | acl_to_uid_mode(inode, search_path); | 578 | acl_to_uid_mode(inode, search_path, pfid); |
| 536 | } | 579 | } |
| 537 | #endif | 580 | #endif |
| 538 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { | 581 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { |
| @@ -546,37 +589,11 @@ int cifs_get_inode_info(struct inode **pinode, | |||
| 546 | atomic_set(&cifsInfo->inUse, 1); | 589 | atomic_set(&cifsInfo->inUse, 1); |
| 547 | } | 590 | } |
| 548 | 591 | ||
| 549 | if (S_ISREG(inode->i_mode)) { | 592 | cifs_set_ops(inode, is_dfs_referral); |
| 550 | cFYI(1, ("File inode")); | ||
| 551 | inode->i_op = &cifs_file_inode_ops; | ||
| 552 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { | ||
| 553 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
| 554 | inode->i_fop = | ||
| 555 | &cifs_file_direct_nobrl_ops; | ||
| 556 | else | ||
| 557 | inode->i_fop = &cifs_file_direct_ops; | ||
| 558 | } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
| 559 | inode->i_fop = &cifs_file_nobrl_ops; | ||
| 560 | else /* not direct, send byte range locks */ | ||
| 561 | inode->i_fop = &cifs_file_ops; | ||
| 562 | |||
| 563 | if (pTcon->ses->server->maxBuf < | ||
| 564 | PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) | ||
| 565 | inode->i_data.a_ops = &cifs_addr_ops_smallbuf; | ||
| 566 | else | ||
| 567 | inode->i_data.a_ops = &cifs_addr_ops; | ||
| 568 | } else if (S_ISDIR(inode->i_mode)) { | ||
| 569 | cFYI(1, ("Directory inode")); | ||
| 570 | inode->i_op = &cifs_dir_inode_ops; | ||
| 571 | inode->i_fop = &cifs_dir_ops; | ||
| 572 | } else if (S_ISLNK(inode->i_mode)) { | ||
| 573 | cFYI(1, ("Symbolic Link inode")); | ||
| 574 | inode->i_op = &cifs_symlink_inode_ops; | ||
| 575 | } else { | ||
| 576 | init_special_inode(inode, inode->i_mode, | ||
| 577 | inode->i_rdev); | ||
| 578 | } | ||
| 579 | } | 593 | } |
| 594 | cgii_exit: | ||
| 595 | if (full_path != search_path) | ||
| 596 | kfree(full_path); | ||
| 580 | kfree(buf); | 597 | kfree(buf); |
| 581 | return rc; | 598 | return rc; |
| 582 | } | 599 | } |
| @@ -605,7 +622,8 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | |||
| 605 | if (cifs_sb->tcon->unix_ext) | 622 | if (cifs_sb->tcon->unix_ext) |
| 606 | rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); | 623 | rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); |
| 607 | else | 624 | else |
| 608 | rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid); | 625 | rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid, |
| 626 | NULL); | ||
| 609 | if (rc && cifs_sb->tcon->ipc) { | 627 | if (rc && cifs_sb->tcon->ipc) { |
| 610 | cFYI(1, ("ipc connection - fake read inode")); | 628 | cFYI(1, ("ipc connection - fake read inode")); |
| 611 | inode->i_mode |= S_IFDIR; | 629 | inode->i_mode |= S_IFDIR; |
| @@ -792,17 +810,12 @@ psx_del_no_retry: | |||
| 792 | } | 810 | } |
| 793 | 811 | ||
| 794 | static void posix_fill_in_inode(struct inode *tmp_inode, | 812 | static void posix_fill_in_inode(struct inode *tmp_inode, |
| 795 | FILE_UNIX_BASIC_INFO *pData, int *pobject_type, int isNewInode) | 813 | FILE_UNIX_BASIC_INFO *pData, int isNewInode) |
| 796 | { | 814 | { |
| 815 | struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); | ||
| 797 | loff_t local_size; | 816 | loff_t local_size; |
| 798 | struct timespec local_mtime; | 817 | struct timespec local_mtime; |
| 799 | 818 | ||
| 800 | struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); | ||
| 801 | struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb); | ||
| 802 | |||
| 803 | __u32 type = le32_to_cpu(pData->Type); | ||
| 804 | __u64 num_of_bytes = le64_to_cpu(pData->NumOfBytes); | ||
| 805 | __u64 end_of_file = le64_to_cpu(pData->EndOfFile); | ||
| 806 | cifsInfo->time = jiffies; | 819 | cifsInfo->time = jiffies; |
| 807 | atomic_inc(&cifsInfo->inUse); | 820 | atomic_inc(&cifsInfo->inUse); |
| 808 | 821 | ||
| @@ -810,115 +823,27 @@ static void posix_fill_in_inode(struct inode *tmp_inode, | |||
| 810 | local_mtime = tmp_inode->i_mtime; | 823 | local_mtime = tmp_inode->i_mtime; |
| 811 | local_size = tmp_inode->i_size; | 824 | local_size = tmp_inode->i_size; |
| 812 | 825 | ||
| 813 | tmp_inode->i_atime = | 826 | cifs_unix_info_to_inode(tmp_inode, pData, 1); |
| 814 | cifs_NTtimeToUnix(le64_to_cpu(pData->LastAccessTime)); | 827 | cifs_set_ops(tmp_inode, false); |
| 815 | tmp_inode->i_mtime = | ||
| 816 | cifs_NTtimeToUnix(le64_to_cpu(pData->LastModificationTime)); | ||
| 817 | tmp_inode->i_ctime = | ||
| 818 | cifs_NTtimeToUnix(le64_to_cpu(pData->LastStatusChange)); | ||
| 819 | |||
| 820 | tmp_inode->i_mode = le64_to_cpu(pData->Permissions); | ||
| 821 | /* since we set the inode type below we need to mask off type | ||
| 822 | to avoid strange results if bits above were corrupt */ | ||
| 823 | tmp_inode->i_mode &= ~S_IFMT; | ||
| 824 | if (type == UNIX_FILE) { | ||
| 825 | *pobject_type = DT_REG; | ||
| 826 | tmp_inode->i_mode |= S_IFREG; | ||
| 827 | } else if (type == UNIX_SYMLINK) { | ||
| 828 | *pobject_type = DT_LNK; | ||
| 829 | tmp_inode->i_mode |= S_IFLNK; | ||
| 830 | } else if (type == UNIX_DIR) { | ||
| 831 | *pobject_type = DT_DIR; | ||
| 832 | tmp_inode->i_mode |= S_IFDIR; | ||
| 833 | } else if (type == UNIX_CHARDEV) { | ||
| 834 | *pobject_type = DT_CHR; | ||
| 835 | tmp_inode->i_mode |= S_IFCHR; | ||
| 836 | tmp_inode->i_rdev = MKDEV(le64_to_cpu(pData->DevMajor), | ||
| 837 | le64_to_cpu(pData->DevMinor) & MINORMASK); | ||
| 838 | } else if (type == UNIX_BLOCKDEV) { | ||
| 839 | *pobject_type = DT_BLK; | ||
| 840 | tmp_inode->i_mode |= S_IFBLK; | ||
| 841 | tmp_inode->i_rdev = MKDEV(le64_to_cpu(pData->DevMajor), | ||
| 842 | le64_to_cpu(pData->DevMinor) & MINORMASK); | ||
| 843 | } else if (type == UNIX_FIFO) { | ||
| 844 | *pobject_type = DT_FIFO; | ||
| 845 | tmp_inode->i_mode |= S_IFIFO; | ||
| 846 | } else if (type == UNIX_SOCKET) { | ||
| 847 | *pobject_type = DT_SOCK; | ||
| 848 | tmp_inode->i_mode |= S_IFSOCK; | ||
| 849 | } else { | ||
| 850 | /* safest to just call it a file */ | ||
| 851 | *pobject_type = DT_REG; | ||
| 852 | tmp_inode->i_mode |= S_IFREG; | ||
| 853 | cFYI(1, ("unknown inode type %d", type)); | ||
| 854 | } | ||
| 855 | |||
| 856 | #ifdef CONFIG_CIFS_DEBUG2 | ||
| 857 | cFYI(1, ("object type: %d", type)); | ||
| 858 | #endif | ||
| 859 | tmp_inode->i_uid = le64_to_cpu(pData->Uid); | ||
| 860 | tmp_inode->i_gid = le64_to_cpu(pData->Gid); | ||
| 861 | tmp_inode->i_nlink = le64_to_cpu(pData->Nlinks); | ||
| 862 | |||
| 863 | spin_lock(&tmp_inode->i_lock); | ||
| 864 | if (is_size_safe_to_change(cifsInfo, end_of_file)) { | ||
| 865 | /* can not safely change the file size here if the | ||
| 866 | client is writing to it due to potential races */ | ||
| 867 | i_size_write(tmp_inode, end_of_file); | ||
| 868 | |||
| 869 | /* 512 bytes (2**9) is the fake blocksize that must be used */ | ||
| 870 | /* for this calculation, not the real blocksize */ | ||
| 871 | tmp_inode->i_blocks = (512 - 1 + num_of_bytes) >> 9; | ||
| 872 | } | ||
| 873 | spin_unlock(&tmp_inode->i_lock); | ||
| 874 | |||
| 875 | if (S_ISREG(tmp_inode->i_mode)) { | ||
| 876 | cFYI(1, ("File inode")); | ||
| 877 | tmp_inode->i_op = &cifs_file_inode_ops; | ||
| 878 | |||
| 879 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { | ||
| 880 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
| 881 | tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; | ||
| 882 | else | ||
| 883 | tmp_inode->i_fop = &cifs_file_direct_ops; | ||
| 884 | 828 | ||
| 885 | } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | 829 | if (!S_ISREG(tmp_inode->i_mode)) |
| 886 | tmp_inode->i_fop = &cifs_file_nobrl_ops; | 830 | return; |
| 887 | else | ||
| 888 | tmp_inode->i_fop = &cifs_file_ops; | ||
| 889 | 831 | ||
| 890 | if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) && | 832 | /* |
| 891 | (cifs_sb->tcon->ses->server->maxBuf < | 833 | * No sense invalidating pages for new inode |
| 892 | PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) | 834 | * since we we have not started caching |
| 893 | tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; | 835 | * readahead file data yet. |
| 894 | else | 836 | */ |
| 895 | tmp_inode->i_data.a_ops = &cifs_addr_ops; | 837 | if (isNewInode) |
| 896 | 838 | return; | |
| 897 | if (isNewInode) | ||
| 898 | return; /* No sense invalidating pages for new inode | ||
| 899 | since we we have not started caching | ||
| 900 | readahead file data yet */ | ||
| 901 | 839 | ||
| 902 | if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && | 840 | if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && |
| 903 | (local_size == tmp_inode->i_size)) { | 841 | (local_size == tmp_inode->i_size)) { |
| 904 | cFYI(1, ("inode exists but unchanged")); | 842 | cFYI(1, ("inode exists but unchanged")); |
| 905 | } else { | ||
| 906 | /* file may have changed on server */ | ||
| 907 | cFYI(1, ("invalidate inode, readdir detected change")); | ||
| 908 | invalidate_remote_inode(tmp_inode); | ||
| 909 | } | ||
| 910 | } else if (S_ISDIR(tmp_inode->i_mode)) { | ||
| 911 | cFYI(1, ("Directory inode")); | ||
| 912 | tmp_inode->i_op = &cifs_dir_inode_ops; | ||
| 913 | tmp_inode->i_fop = &cifs_dir_ops; | ||
| 914 | } else if (S_ISLNK(tmp_inode->i_mode)) { | ||
| 915 | cFYI(1, ("Symbolic Link inode")); | ||
| 916 | tmp_inode->i_op = &cifs_symlink_inode_ops; | ||
| 917 | /* tmp_inode->i_fop = *//* do not need to set to anything */ | ||
| 918 | } else { | 843 | } else { |
| 919 | cFYI(1, ("Special inode")); | 844 | /* file may have changed on server */ |
| 920 | init_special_inode(tmp_inode, tmp_inode->i_mode, | 845 | cFYI(1, ("invalidate inode, readdir detected change")); |
| 921 | tmp_inode->i_rdev); | 846 | invalidate_remote_inode(tmp_inode); |
| 922 | } | 847 | } |
| 923 | } | 848 | } |
| 924 | 849 | ||
| @@ -968,7 +893,6 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
| 968 | cFYI(1, ("posix mkdir returned 0x%x", rc)); | 893 | cFYI(1, ("posix mkdir returned 0x%x", rc)); |
| 969 | d_drop(direntry); | 894 | d_drop(direntry); |
| 970 | } else { | 895 | } else { |
| 971 | int obj_type; | ||
| 972 | if (pInfo->Type == cpu_to_le32(-1)) { | 896 | if (pInfo->Type == cpu_to_le32(-1)) { |
| 973 | /* no return info, go query for it */ | 897 | /* no return info, go query for it */ |
| 974 | kfree(pInfo); | 898 | kfree(pInfo); |
| @@ -1004,7 +928,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
| 1004 | /* we already checked in POSIXCreate whether | 928 | /* we already checked in POSIXCreate whether |
| 1005 | frame was long enough */ | 929 | frame was long enough */ |
| 1006 | posix_fill_in_inode(direntry->d_inode, | 930 | posix_fill_in_inode(direntry->d_inode, |
| 1007 | pInfo, &obj_type, 1 /* NewInode */); | 931 | pInfo, 1 /* NewInode */); |
| 1008 | #ifdef CONFIG_CIFS_DEBUG2 | 932 | #ifdef CONFIG_CIFS_DEBUG2 |
| 1009 | cFYI(1, ("instantiated dentry %p %s to inode %p", | 933 | cFYI(1, ("instantiated dentry %p %s to inode %p", |
| 1010 | direntry, direntry->d_name.name, newinode)); | 934 | direntry, direntry->d_name.name, newinode)); |
| @@ -1032,7 +956,7 @@ mkdir_get_info: | |||
| 1032 | inode->i_sb, xid); | 956 | inode->i_sb, xid); |
| 1033 | else | 957 | else |
| 1034 | rc = cifs_get_inode_info(&newinode, full_path, NULL, | 958 | rc = cifs_get_inode_info(&newinode, full_path, NULL, |
| 1035 | inode->i_sb, xid); | 959 | inode->i_sb, xid, NULL); |
| 1036 | 960 | ||
| 1037 | if (pTcon->nocase) | 961 | if (pTcon->nocase) |
| 1038 | direntry->d_op = &cifs_ci_dentry_ops; | 962 | direntry->d_op = &cifs_ci_dentry_ops; |
| @@ -1214,9 +1138,8 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, | |||
| 1214 | } /* if we can not get memory just leave rc as EEXIST */ | 1138 | } /* if we can not get memory just leave rc as EEXIST */ |
| 1215 | } | 1139 | } |
| 1216 | 1140 | ||
| 1217 | if (rc) { | 1141 | if (rc) |
| 1218 | cFYI(1, ("rename rc %d", rc)); | 1142 | cFYI(1, ("rename rc %d", rc)); |
| 1219 | } | ||
| 1220 | 1143 | ||
| 1221 | if ((rc == -EIO) || (rc == -EEXIST)) { | 1144 | if ((rc == -EIO) || (rc == -EEXIST)) { |
| 1222 | int oplock = FALSE; | 1145 | int oplock = FALSE; |
| @@ -1315,7 +1238,7 @@ int cifs_revalidate(struct dentry *direntry) | |||
| 1315 | } | 1238 | } |
| 1316 | } else { | 1239 | } else { |
| 1317 | rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL, | 1240 | rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL, |
| 1318 | direntry->d_sb, xid); | 1241 | direntry->d_sb, xid, NULL); |
| 1319 | if (rc) { | 1242 | if (rc) { |
| 1320 | cFYI(1, ("error on getting revalidate info %d", rc)); | 1243 | cFYI(1, ("error on getting revalidate info %d", rc)); |
| 1321 | /* if (rc != -ENOENT) | 1244 | /* if (rc != -ENOENT) |
| @@ -1504,11 +1427,10 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
| 1504 | } | 1427 | } |
| 1505 | cifsInode = CIFS_I(direntry->d_inode); | 1428 | cifsInode = CIFS_I(direntry->d_inode); |
| 1506 | 1429 | ||
| 1507 | /* BB check if we need to refresh inode from server now ? BB */ | 1430 | if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) { |
| 1508 | |||
| 1509 | if (attrs->ia_valid & ATTR_SIZE) { | ||
| 1510 | /* | 1431 | /* |
| 1511 | Flush data before changing file size on server. If the | 1432 | Flush data before changing file size or changing the last |
| 1433 | write time of the file on the server. If the | ||
| 1512 | flush returns error, store it to report later and continue. | 1434 | flush returns error, store it to report later and continue. |
| 1513 | BB: This should be smarter. Why bother flushing pages that | 1435 | BB: This should be smarter. Why bother flushing pages that |
| 1514 | will be truncated anyway? Also, should we error out here if | 1436 | will be truncated anyway? Also, should we error out here if |
| @@ -1519,7 +1441,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
| 1519 | CIFS_I(direntry->d_inode)->write_behind_rc = rc; | 1441 | CIFS_I(direntry->d_inode)->write_behind_rc = rc; |
| 1520 | rc = 0; | 1442 | rc = 0; |
| 1521 | } | 1443 | } |
| 1444 | } | ||
| 1522 | 1445 | ||
| 1446 | if (attrs->ia_valid & ATTR_SIZE) { | ||
| 1523 | /* To avoid spurious oplock breaks from server, in the case of | 1447 | /* To avoid spurious oplock breaks from server, in the case of |
| 1524 | inodes that we already have open, avoid doing path based | 1448 | inodes that we already have open, avoid doing path based |
| 1525 | setting of file size if we can do it by handle. | 1449 | setting of file size if we can do it by handle. |
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index d24fe6880a04..5c792df13d62 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | #define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2) | 31 | #define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2) |
| 32 | 32 | ||
| 33 | int cifs_ioctl (struct inode *inode, struct file *filep, | 33 | int cifs_ioctl(struct inode *inode, struct file *filep, |
| 34 | unsigned int command, unsigned long arg) | 34 | unsigned int command, unsigned long arg) |
| 35 | { | 35 | { |
| 36 | int rc = -ENOTTY; /* strange error - but the precedent */ | 36 | int rc = -ENOTTY; /* strange error - but the precedent */ |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 1d6fb01b8e6d..d4e7ec93285f 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
| @@ -205,7 +205,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) | |||
| 205 | inode->i_sb, xid); | 205 | inode->i_sb, xid); |
| 206 | else | 206 | else |
| 207 | rc = cifs_get_inode_info(&newinode, full_path, NULL, | 207 | rc = cifs_get_inode_info(&newinode, full_path, NULL, |
| 208 | inode->i_sb, xid); | 208 | inode->i_sb, xid, NULL); |
| 209 | 209 | ||
| 210 | if (rc != 0) { | 210 | if (rc != 0) { |
| 211 | cFYI(1, ("Create symlink ok, getinodeinfo fail rc = %d", | 211 | cFYI(1, ("Create symlink ok, getinodeinfo fail rc = %d", |
diff --git a/fs/cifs/md4.c b/fs/cifs/md4.c index a2415c1a14db..a725c2609d67 100644 --- a/fs/cifs/md4.c +++ b/fs/cifs/md4.c | |||
| @@ -56,7 +56,7 @@ lshift(__u32 x, int s) | |||
| 56 | 56 | ||
| 57 | /* this applies md4 to 64 byte chunks */ | 57 | /* this applies md4 to 64 byte chunks */ |
| 58 | static void | 58 | static void |
| 59 | mdfour64(__u32 * M, __u32 * A, __u32 *B, __u32 * C, __u32 *D) | 59 | mdfour64(__u32 *M, __u32 *A, __u32 *B, __u32 *C, __u32 *D) |
| 60 | { | 60 | { |
| 61 | int j; | 61 | int j; |
| 62 | __u32 AA, BB, CC, DD; | 62 | __u32 AA, BB, CC, DD; |
| @@ -137,7 +137,7 @@ mdfour64(__u32 * M, __u32 * A, __u32 *B, __u32 * C, __u32 *D) | |||
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | static void | 139 | static void |
| 140 | copy64(__u32 * M, unsigned char *in) | 140 | copy64(__u32 *M, unsigned char *in) |
| 141 | { | 141 | { |
| 142 | int i; | 142 | int i; |
| 143 | 143 | ||
diff --git a/fs/cifs/md5.c b/fs/cifs/md5.c index f13f96d42fcf..462bbfefd4b6 100644 --- a/fs/cifs/md5.c +++ b/fs/cifs/md5.c | |||
| @@ -161,7 +161,7 @@ MD5Final(unsigned char digest[16], struct MD5Context *ctx) | |||
| 161 | 161 | ||
| 162 | /* This is the central step in the MD5 algorithm. */ | 162 | /* This is the central step in the MD5 algorithm. */ |
| 163 | #define MD5STEP(f, w, x, y, z, data, s) \ | 163 | #define MD5STEP(f, w, x, y, z, data, s) \ |
| 164 | ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) | 164 | (w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x) |
| 165 | 165 | ||
| 166 | /* | 166 | /* |
| 167 | * The core of the MD5 algorithm, this alters an existing MD5 hash to | 167 | * The core of the MD5 algorithm, this alters an existing MD5 hash to |
| @@ -302,9 +302,8 @@ hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, | |||
| 302 | int i; | 302 | int i; |
| 303 | 303 | ||
| 304 | /* if key is longer than 64 bytes truncate it */ | 304 | /* if key is longer than 64 bytes truncate it */ |
| 305 | if (key_len > 64) { | 305 | if (key_len > 64) |
| 306 | key_len = 64; | 306 | key_len = 64; |
| 307 | } | ||
| 308 | 307 | ||
| 309 | /* start out by storing key in pads */ | 308 | /* start out by storing key in pads */ |
| 310 | memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad)); | 309 | memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad)); |
| @@ -359,9 +358,9 @@ hmac_md5(unsigned char key[16], unsigned char *data, int data_len, | |||
| 359 | { | 358 | { |
| 360 | struct HMACMD5Context ctx; | 359 | struct HMACMD5Context ctx; |
| 361 | hmac_md5_init_limK_to_64(key, 16, &ctx); | 360 | hmac_md5_init_limK_to_64(key, 16, &ctx); |
| 362 | if (data_len != 0) { | 361 | if (data_len != 0) |
| 363 | hmac_md5_update(data, data_len, &ctx); | 362 | hmac_md5_update(data, data_len, &ctx); |
| 364 | } | 363 | |
| 365 | hmac_md5_final(digest, &ctx); | 364 | hmac_md5_final(digest, &ctx); |
| 366 | } | 365 | } |
| 367 | #endif | 366 | #endif |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 15546c2354c5..2a42d9fedbb2 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * fs/cifs/misc.c | 2 | * fs/cifs/misc.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) International Business Machines Corp., 2002,2007 | 4 | * Copyright (C) International Business Machines Corp., 2002,2008 |
| 5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
| 6 | * | 6 | * |
| 7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
| @@ -320,9 +320,9 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , | |||
| 320 | if (treeCon->ses) { | 320 | if (treeCon->ses) { |
| 321 | if (treeCon->ses->capabilities & CAP_UNICODE) | 321 | if (treeCon->ses->capabilities & CAP_UNICODE) |
| 322 | buffer->Flags2 |= SMBFLG2_UNICODE; | 322 | buffer->Flags2 |= SMBFLG2_UNICODE; |
| 323 | if (treeCon->ses->capabilities & CAP_STATUS32) { | 323 | if (treeCon->ses->capabilities & CAP_STATUS32) |
| 324 | buffer->Flags2 |= SMBFLG2_ERR_STATUS; | 324 | buffer->Flags2 |= SMBFLG2_ERR_STATUS; |
| 325 | } | 325 | |
| 326 | /* Uid is not converted */ | 326 | /* Uid is not converted */ |
| 327 | buffer->Uid = treeCon->ses->Suid; | 327 | buffer->Uid = treeCon->ses->Suid; |
| 328 | buffer->Mid = GetNextMid(treeCon->ses->server); | 328 | buffer->Mid = GetNextMid(treeCon->ses->server); |
| @@ -610,7 +610,8 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) | |||
| 610 | 610 | ||
| 611 | buffer = (unsigned char *) smb_buf; | 611 | buffer = (unsigned char *) smb_buf; |
| 612 | for (i = 0, j = 0; i < smb_buf_length; i++, j++) { | 612 | for (i = 0, j = 0; i < smb_buf_length; i++, j++) { |
| 613 | if (i % 8 == 0) { /* have reached the beginning of line */ | 613 | if (i % 8 == 0) { |
| 614 | /* have reached the beginning of line */ | ||
| 614 | printk(KERN_DEBUG "| "); | 615 | printk(KERN_DEBUG "| "); |
| 615 | j = 0; | 616 | j = 0; |
| 616 | } | 617 | } |
| @@ -621,7 +622,8 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) | |||
| 621 | else | 622 | else |
| 622 | debug_line[1 + (2 * j)] = '_'; | 623 | debug_line[1 + (2 * j)] = '_'; |
| 623 | 624 | ||
| 624 | if (i % 8 == 7) { /* reached end of line, time to print ascii */ | 625 | if (i % 8 == 7) { |
| 626 | /* reached end of line, time to print ascii */ | ||
| 625 | debug_line[16] = 0; | 627 | debug_line[16] = 0; |
| 626 | printk(" | %s\n", debug_line); | 628 | printk(" | %s\n", debug_line); |
| 627 | } | 629 | } |
| @@ -631,7 +633,7 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) | |||
| 631 | debug_line[2 * j] = ' '; | 633 | debug_line[2 * j] = ' '; |
| 632 | debug_line[1 + (2 * j)] = ' '; | 634 | debug_line[1 + (2 * j)] = ' '; |
| 633 | } | 635 | } |
| 634 | printk( " | %s\n", debug_line); | 636 | printk(" | %s\n", debug_line); |
| 635 | return; | 637 | return; |
| 636 | } | 638 | } |
| 637 | 639 | ||
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 646e1f06941b..3b5a5ce882b6 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * fs/cifs/netmisc.c | 2 | * fs/cifs/netmisc.c |
| 3 | * | 3 | * |
| 4 | * Copyright (c) International Business Machines Corp., 2002 | 4 | * Copyright (c) International Business Machines Corp., 2002,2008 |
| 5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
| 6 | * | 6 | * |
| 7 | * Error mapping routines from Samba libsmb/errormap.c | 7 | * Error mapping routines from Samba libsmb/errormap.c |
| @@ -150,9 +150,7 @@ static int canonicalize_unc(char *cp) | |||
| 150 | if (cp[i] == '\\') | 150 | if (cp[i] == '\\') |
| 151 | break; | 151 | break; |
| 152 | if (cp[i] == '/') { | 152 | if (cp[i] == '/') { |
| 153 | #ifdef CONFIG_CIFS_DEBUG2 | 153 | cFYI(DBG2, ("change slash to \\ in malformed UNC")); |
| 154 | cFYI(1, ("change slash to backslash in malformed UNC")); | ||
| 155 | #endif | ||
| 156 | cp[i] = '\\'; | 154 | cp[i] = '\\'; |
| 157 | return 1; | 155 | return 1; |
| 158 | } | 156 | } |
| @@ -178,9 +176,7 @@ cifs_inet_pton(int address_family, char *cp, void *dst) | |||
| 178 | } else if (address_family == AF_INET6) { | 176 | } else if (address_family == AF_INET6) { |
| 179 | ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); | 177 | ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); |
| 180 | } | 178 | } |
| 181 | #ifdef CONFIG_CIFS_DEBUG2 | 179 | cFYI(DBG2, ("address conversion returned %d for %s", ret, cp)); |
| 182 | cFYI(1, ("address conversion returned %d for %s", ret, cp)); | ||
| 183 | #endif | ||
| 184 | if (ret > 0) | 180 | if (ret > 0) |
| 185 | ret = 1; | 181 | ret = 1; |
| 186 | return ret; | 182 | return ret; |
| @@ -253,7 +249,8 @@ static const struct { | |||
| 253 | ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_MIX}, { | 249 | ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_MIX}, { |
| 254 | ERRHRD, ERRgeneral, NT_STATUS_INVALID_QUOTA_LOWER}, { | 250 | ERRHRD, ERRgeneral, NT_STATUS_INVALID_QUOTA_LOWER}, { |
| 255 | ERRHRD, ERRgeneral, NT_STATUS_DISK_CORRUPT_ERROR}, { | 251 | ERRHRD, ERRgeneral, NT_STATUS_DISK_CORRUPT_ERROR}, { |
| 256 | ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_INVALID}, { /* mapping changed since shell does lookup on * and expects file not found */ | 252 | /* mapping changed since shell does lookup on * expects FileNotFound */ |
| 253 | ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_INVALID}, { | ||
| 257 | ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND}, { | 254 | ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND}, { |
| 258 | ERRDOS, ERRalreadyexists, NT_STATUS_OBJECT_NAME_COLLISION}, { | 255 | ERRDOS, ERRalreadyexists, NT_STATUS_OBJECT_NAME_COLLISION}, { |
| 259 | ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE}, { | 256 | ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE}, { |
| @@ -820,7 +817,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr) | |||
| 820 | /* old style errors */ | 817 | /* old style errors */ |
| 821 | 818 | ||
| 822 | /* DOS class smb error codes - map DOS */ | 819 | /* DOS class smb error codes - map DOS */ |
| 823 | if (smberrclass == ERRDOS) { /* 1 byte field no need to byte reverse */ | 820 | if (smberrclass == ERRDOS) { |
| 821 | /* 1 byte field no need to byte reverse */ | ||
| 824 | for (i = 0; | 822 | for (i = 0; |
| 825 | i < | 823 | i < |
| 826 | sizeof(mapping_table_ERRDOS) / | 824 | sizeof(mapping_table_ERRDOS) / |
| @@ -834,7 +832,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr) | |||
| 834 | } | 832 | } |
| 835 | /* else try next error mapping one to see if match */ | 833 | /* else try next error mapping one to see if match */ |
| 836 | } | 834 | } |
| 837 | } else if (smberrclass == ERRSRV) { /* server class of error codes */ | 835 | } else if (smberrclass == ERRSRV) { |
| 836 | /* server class of error codes */ | ||
| 838 | for (i = 0; | 837 | for (i = 0; |
| 839 | i < | 838 | i < |
| 840 | sizeof(mapping_table_ERRSRV) / | 839 | sizeof(mapping_table_ERRSRV) / |
| @@ -922,8 +921,8 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time) | |||
| 922 | { | 921 | { |
| 923 | struct timespec ts; | 922 | struct timespec ts; |
| 924 | int sec, min, days, month, year; | 923 | int sec, min, days, month, year; |
| 925 | SMB_TIME * st = (SMB_TIME *)&time; | 924 | SMB_TIME *st = (SMB_TIME *)&time; |
| 926 | SMB_DATE * sd = (SMB_DATE *)&date; | 925 | SMB_DATE *sd = (SMB_DATE *)&date; |
| 927 | 926 | ||
| 928 | cFYI(1, ("date %d time %d", date, time)); | 927 | cFYI(1, ("date %d time %d", date, time)); |
| 929 | 928 | ||
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 0f22def4bdff..32b445edc882 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Directory search handling | 4 | * Directory search handling |
| 5 | * | 5 | * |
| 6 | * Copyright (C) International Business Machines Corp., 2004, 2007 | 6 | * Copyright (C) International Business Machines Corp., 2004, 2008 |
| 7 | * Author(s): Steve French (sfrench@us.ibm.com) | 7 | * Author(s): Steve French (sfrench@us.ibm.com) |
| 8 | * | 8 | * |
| 9 | * This library is free software; you can redistribute it and/or modify | 9 | * This library is free software; you can redistribute it and/or modify |
| @@ -42,17 +42,18 @@ static void dump_cifs_file_struct(struct file *file, char *label) | |||
| 42 | cFYI(1, ("empty cifs private file data")); | 42 | cFYI(1, ("empty cifs private file data")); |
| 43 | return; | 43 | return; |
| 44 | } | 44 | } |
| 45 | if (cf->invalidHandle) { | 45 | if (cf->invalidHandle) |
| 46 | cFYI(1, ("invalid handle")); | 46 | cFYI(1, ("invalid handle")); |
| 47 | } | 47 | if (cf->srch_inf.endOfSearch) |
| 48 | if (cf->srch_inf.endOfSearch) { | ||
| 49 | cFYI(1, ("end of search")); | 48 | cFYI(1, ("end of search")); |
| 50 | } | 49 | if (cf->srch_inf.emptyDir) |
| 51 | if (cf->srch_inf.emptyDir) { | ||
| 52 | cFYI(1, ("empty dir")); | 50 | cFYI(1, ("empty dir")); |
| 53 | } | ||
| 54 | } | 51 | } |
| 55 | } | 52 | } |
| 53 | #else | ||
| 54 | static inline void dump_cifs_file_struct(struct file *file, char *label) | ||
| 55 | { | ||
| 56 | } | ||
| 56 | #endif /* DEBUG2 */ | 57 | #endif /* DEBUG2 */ |
| 57 | 58 | ||
| 58 | /* Returns one if new inode created (which therefore needs to be hashed) */ | 59 | /* Returns one if new inode created (which therefore needs to be hashed) */ |
| @@ -150,7 +151,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | |||
| 150 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); | 151 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); |
| 151 | } else { /* legacy, OS2 and DOS style */ | 152 | } else { /* legacy, OS2 and DOS style */ |
| 152 | /* struct timespec ts;*/ | 153 | /* struct timespec ts;*/ |
| 153 | FIND_FILE_STANDARD_INFO * pfindData = | 154 | FIND_FILE_STANDARD_INFO *pfindData = |
| 154 | (FIND_FILE_STANDARD_INFO *)buf; | 155 | (FIND_FILE_STANDARD_INFO *)buf; |
| 155 | 156 | ||
| 156 | tmp_inode->i_mtime = cnvrtDosUnixTm( | 157 | tmp_inode->i_mtime = cnvrtDosUnixTm( |
| @@ -198,9 +199,8 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | |||
| 198 | if (attr & ATTR_DIRECTORY) { | 199 | if (attr & ATTR_DIRECTORY) { |
| 199 | *pobject_type = DT_DIR; | 200 | *pobject_type = DT_DIR; |
| 200 | /* override default perms since we do not lock dirs */ | 201 | /* override default perms since we do not lock dirs */ |
| 201 | if (atomic_read(&cifsInfo->inUse) == 0) { | 202 | if (atomic_read(&cifsInfo->inUse) == 0) |
| 202 | tmp_inode->i_mode = cifs_sb->mnt_dir_mode; | 203 | tmp_inode->i_mode = cifs_sb->mnt_dir_mode; |
| 203 | } | ||
| 204 | tmp_inode->i_mode |= S_IFDIR; | 204 | tmp_inode->i_mode |= S_IFDIR; |
| 205 | } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && | 205 | } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && |
| 206 | (attr & ATTR_SYSTEM)) { | 206 | (attr & ATTR_SYSTEM)) { |
| @@ -231,9 +231,8 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | |||
| 231 | } /* could add code here - to validate if device or weird share type? */ | 231 | } /* could add code here - to validate if device or weird share type? */ |
| 232 | 232 | ||
| 233 | /* can not fill in nlink here as in qpathinfo version and Unx search */ | 233 | /* can not fill in nlink here as in qpathinfo version and Unx search */ |
| 234 | if (atomic_read(&cifsInfo->inUse) == 0) { | 234 | if (atomic_read(&cifsInfo->inUse) == 0) |
| 235 | atomic_set(&cifsInfo->inUse, 1); | 235 | atomic_set(&cifsInfo->inUse, 1); |
| 236 | } | ||
| 237 | 236 | ||
| 238 | spin_lock(&tmp_inode->i_lock); | 237 | spin_lock(&tmp_inode->i_lock); |
| 239 | if (is_size_safe_to_change(cifsInfo, end_of_file)) { | 238 | if (is_size_safe_to_change(cifsInfo, end_of_file)) { |
| @@ -461,9 +460,8 @@ static int initiate_cifs_search(const int xid, struct file *file) | |||
| 461 | 460 | ||
| 462 | full_path = build_path_from_dentry(file->f_path.dentry); | 461 | full_path = build_path_from_dentry(file->f_path.dentry); |
| 463 | 462 | ||
| 464 | if (full_path == NULL) { | 463 | if (full_path == NULL) |
| 465 | return -ENOMEM; | 464 | return -ENOMEM; |
| 466 | } | ||
| 467 | 465 | ||
| 468 | cFYI(1, ("Full path: %s start at: %lld", full_path, file->f_pos)); | 466 | cFYI(1, ("Full path: %s start at: %lld", full_path, file->f_pos)); |
| 469 | 467 | ||
| @@ -471,9 +469,9 @@ ffirst_retry: | |||
| 471 | /* test for Unix extensions */ | 469 | /* test for Unix extensions */ |
| 472 | /* but now check for them on the share/mount not on the SMB session */ | 470 | /* but now check for them on the share/mount not on the SMB session */ |
| 473 | /* if (pTcon->ses->capabilities & CAP_UNIX) { */ | 471 | /* if (pTcon->ses->capabilities & CAP_UNIX) { */ |
| 474 | if (pTcon->unix_ext) { | 472 | if (pTcon->unix_ext) |
| 475 | cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX; | 473 | cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX; |
| 476 | } else if ((pTcon->ses->capabilities & | 474 | else if ((pTcon->ses->capabilities & |
| 477 | (CAP_NT_SMBS | CAP_NT_FIND)) == 0) { | 475 | (CAP_NT_SMBS | CAP_NT_FIND)) == 0) { |
| 478 | cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD; | 476 | cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD; |
| 479 | } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { | 477 | } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { |
| @@ -514,10 +512,10 @@ static int cifs_unicode_bytelen(char *str) | |||
| 514 | static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level) | 512 | static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level) |
| 515 | { | 513 | { |
| 516 | char *new_entry; | 514 | char *new_entry; |
| 517 | FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry; | 515 | FILE_DIRECTORY_INFO *pDirInfo = (FILE_DIRECTORY_INFO *)old_entry; |
| 518 | 516 | ||
| 519 | if (level == SMB_FIND_FILE_INFO_STANDARD) { | 517 | if (level == SMB_FIND_FILE_INFO_STANDARD) { |
| 520 | FIND_FILE_STANDARD_INFO * pfData; | 518 | FIND_FILE_STANDARD_INFO *pfData; |
| 521 | pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo; | 519 | pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo; |
| 522 | 520 | ||
| 523 | new_entry = old_entry + sizeof(FIND_FILE_STANDARD_INFO) + | 521 | new_entry = old_entry + sizeof(FIND_FILE_STANDARD_INFO) + |
| @@ -553,7 +551,7 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile) | |||
| 553 | int len = 0; | 551 | int len = 0; |
| 554 | 552 | ||
| 555 | if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) { | 553 | if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) { |
| 556 | FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; | 554 | FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry; |
| 557 | filename = &pFindData->FileName[0]; | 555 | filename = &pFindData->FileName[0]; |
| 558 | if (cfile->srch_inf.unicode) { | 556 | if (cfile->srch_inf.unicode) { |
| 559 | len = cifs_unicode_bytelen(filename); | 557 | len = cifs_unicode_bytelen(filename); |
| @@ -562,30 +560,30 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile) | |||
| 562 | len = strnlen(filename, 5); | 560 | len = strnlen(filename, 5); |
| 563 | } | 561 | } |
| 564 | } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) { | 562 | } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) { |
| 565 | FILE_DIRECTORY_INFO * pFindData = | 563 | FILE_DIRECTORY_INFO *pFindData = |
| 566 | (FILE_DIRECTORY_INFO *)current_entry; | 564 | (FILE_DIRECTORY_INFO *)current_entry; |
| 567 | filename = &pFindData->FileName[0]; | 565 | filename = &pFindData->FileName[0]; |
| 568 | len = le32_to_cpu(pFindData->FileNameLength); | 566 | len = le32_to_cpu(pFindData->FileNameLength); |
| 569 | } else if (cfile->srch_inf.info_level == | 567 | } else if (cfile->srch_inf.info_level == |
| 570 | SMB_FIND_FILE_FULL_DIRECTORY_INFO) { | 568 | SMB_FIND_FILE_FULL_DIRECTORY_INFO) { |
| 571 | FILE_FULL_DIRECTORY_INFO * pFindData = | 569 | FILE_FULL_DIRECTORY_INFO *pFindData = |
| 572 | (FILE_FULL_DIRECTORY_INFO *)current_entry; | 570 | (FILE_FULL_DIRECTORY_INFO *)current_entry; |
| 573 | filename = &pFindData->FileName[0]; | 571 | filename = &pFindData->FileName[0]; |
| 574 | len = le32_to_cpu(pFindData->FileNameLength); | 572 | len = le32_to_cpu(pFindData->FileNameLength); |
| 575 | } else if (cfile->srch_inf.info_level == | 573 | } else if (cfile->srch_inf.info_level == |
| 576 | SMB_FIND_FILE_ID_FULL_DIR_INFO) { | 574 | SMB_FIND_FILE_ID_FULL_DIR_INFO) { |
| 577 | SEARCH_ID_FULL_DIR_INFO * pFindData = | 575 | SEARCH_ID_FULL_DIR_INFO *pFindData = |
| 578 | (SEARCH_ID_FULL_DIR_INFO *)current_entry; | 576 | (SEARCH_ID_FULL_DIR_INFO *)current_entry; |
| 579 | filename = &pFindData->FileName[0]; | 577 | filename = &pFindData->FileName[0]; |
| 580 | len = le32_to_cpu(pFindData->FileNameLength); | 578 | len = le32_to_cpu(pFindData->FileNameLength); |
| 581 | } else if (cfile->srch_inf.info_level == | 579 | } else if (cfile->srch_inf.info_level == |
| 582 | SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { | 580 | SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { |
| 583 | FILE_BOTH_DIRECTORY_INFO * pFindData = | 581 | FILE_BOTH_DIRECTORY_INFO *pFindData = |
| 584 | (FILE_BOTH_DIRECTORY_INFO *)current_entry; | 582 | (FILE_BOTH_DIRECTORY_INFO *)current_entry; |
| 585 | filename = &pFindData->FileName[0]; | 583 | filename = &pFindData->FileName[0]; |
| 586 | len = le32_to_cpu(pFindData->FileNameLength); | 584 | len = le32_to_cpu(pFindData->FileNameLength); |
| 587 | } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) { | 585 | } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) { |
| 588 | FIND_FILE_STANDARD_INFO * pFindData = | 586 | FIND_FILE_STANDARD_INFO *pFindData = |
| 589 | (FIND_FILE_STANDARD_INFO *)current_entry; | 587 | (FIND_FILE_STANDARD_INFO *)current_entry; |
| 590 | filename = &pFindData->FileName[0]; | 588 | filename = &pFindData->FileName[0]; |
| 591 | len = pFindData->FileNameLength; | 589 | len = pFindData->FileNameLength; |
| @@ -666,9 +664,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, | |||
| 666 | . and .. for the root of a drive and for those we need | 664 | . and .. for the root of a drive and for those we need |
| 667 | to start two entries earlier */ | 665 | to start two entries earlier */ |
| 668 | 666 | ||
| 669 | #ifdef CONFIG_CIFS_DEBUG2 | ||
| 670 | dump_cifs_file_struct(file, "In fce "); | 667 | dump_cifs_file_struct(file, "In fce "); |
| 671 | #endif | ||
| 672 | if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) && | 668 | if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) && |
| 673 | is_dir_changed(file)) || | 669 | is_dir_changed(file)) || |
| 674 | (index_to_find < first_entry_in_buffer)) { | 670 | (index_to_find < first_entry_in_buffer)) { |
| @@ -718,7 +714,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, | |||
| 718 | pos_in_buf = index_to_find - first_entry_in_buffer; | 714 | pos_in_buf = index_to_find - first_entry_in_buffer; |
| 719 | cFYI(1, ("found entry - pos_in_buf %d", pos_in_buf)); | 715 | cFYI(1, ("found entry - pos_in_buf %d", pos_in_buf)); |
| 720 | 716 | ||
| 721 | for (i=0; (i < (pos_in_buf)) && (current_entry != NULL); i++) { | 717 | for (i = 0; (i < (pos_in_buf)) && (current_entry != NULL); i++) { |
| 722 | /* go entry by entry figuring out which is first */ | 718 | /* go entry by entry figuring out which is first */ |
| 723 | current_entry = nxt_dir_entry(current_entry, end_of_smb, | 719 | current_entry = nxt_dir_entry(current_entry, end_of_smb, |
| 724 | cifsFile->srch_inf.info_level); | 720 | cifsFile->srch_inf.info_level); |
| @@ -793,7 +789,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst, | |||
| 793 | filename = &pFindData->FileName[0]; | 789 | filename = &pFindData->FileName[0]; |
| 794 | len = le32_to_cpu(pFindData->FileNameLength); | 790 | len = le32_to_cpu(pFindData->FileNameLength); |
| 795 | } else if (level == SMB_FIND_FILE_INFO_STANDARD) { | 791 | } else if (level == SMB_FIND_FILE_INFO_STANDARD) { |
| 796 | FIND_FILE_STANDARD_INFO * pFindData = | 792 | FIND_FILE_STANDARD_INFO *pFindData = |
| 797 | (FIND_FILE_STANDARD_INFO *)current_entry; | 793 | (FIND_FILE_STANDARD_INFO *)current_entry; |
| 798 | filename = &pFindData->FileName[0]; | 794 | filename = &pFindData->FileName[0]; |
| 799 | /* one byte length, no name conversion */ | 795 | /* one byte length, no name conversion */ |
| @@ -928,7 +924,7 @@ static int cifs_save_resume_key(const char *current_entry, | |||
| 928 | level = cifsFile->srch_inf.info_level; | 924 | level = cifsFile->srch_inf.info_level; |
| 929 | 925 | ||
| 930 | if (level == SMB_FIND_FILE_UNIX) { | 926 | if (level == SMB_FIND_FILE_UNIX) { |
| 931 | FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; | 927 | FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry; |
| 932 | 928 | ||
| 933 | filename = &pFindData->FileName[0]; | 929 | filename = &pFindData->FileName[0]; |
| 934 | if (cifsFile->srch_inf.unicode) { | 930 | if (cifsFile->srch_inf.unicode) { |
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index d2153abcba6d..ed150efbe27c 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
| @@ -417,10 +417,6 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
| 417 | 417 | ||
| 418 | calc_lanman_hash(ses, lnm_session_key); | 418 | calc_lanman_hash(ses, lnm_session_key); |
| 419 | ses->flags |= CIFS_SES_LANMAN; | 419 | ses->flags |= CIFS_SES_LANMAN; |
| 420 | /* #ifdef CONFIG_CIFS_DEBUG2 | ||
| 421 | cifs_dump_mem("cryptkey: ",ses->server->cryptKey, | ||
| 422 | CIFS_SESS_KEY_SIZE); | ||
| 423 | #endif */ | ||
| 424 | memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE); | 420 | memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE); |
| 425 | bcc_ptr += CIFS_SESS_KEY_SIZE; | 421 | bcc_ptr += CIFS_SESS_KEY_SIZE; |
| 426 | 422 | ||
diff --git a/fs/cifs/smbdes.c b/fs/cifs/smbdes.c index cfa6d21fb4e8..04943c976f98 100644 --- a/fs/cifs/smbdes.c +++ b/fs/cifs/smbdes.c | |||
| @@ -114,42 +114,42 @@ static uchar sbox[8][4][16] = { | |||
| 114 | {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, | 114 | {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, |
| 115 | {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, | 115 | {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, |
| 116 | {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, | 116 | {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, |
| 117 | {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, | 117 | {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13} }, |
| 118 | 118 | ||
| 119 | {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, | 119 | {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, |
| 120 | {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, | 120 | {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, |
| 121 | {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, | 121 | {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, |
| 122 | {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, | 122 | {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9} }, |
| 123 | 123 | ||
| 124 | {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, | 124 | {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, |
| 125 | {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, | 125 | {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, |
| 126 | {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, | 126 | {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, |
| 127 | {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, | 127 | {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12} }, |
| 128 | 128 | ||
| 129 | {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, | 129 | {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, |
| 130 | {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, | 130 | {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, |
| 131 | {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, | 131 | {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, |
| 132 | {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, | 132 | {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14} }, |
| 133 | 133 | ||
| 134 | {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, | 134 | {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, |
| 135 | {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, | 135 | {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, |
| 136 | {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, | 136 | {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, |
| 137 | {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, | 137 | {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3} }, |
| 138 | 138 | ||
| 139 | {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, | 139 | {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, |
| 140 | {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, | 140 | {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, |
| 141 | {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, | 141 | {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, |
| 142 | {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, | 142 | {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13} }, |
| 143 | 143 | ||
| 144 | {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, | 144 | {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, |
| 145 | {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, | 145 | {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, |
| 146 | {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, | 146 | {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, |
| 147 | {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, | 147 | {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12} }, |
| 148 | 148 | ||
| 149 | {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, | 149 | {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, |
| 150 | {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, | 150 | {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, |
| 151 | {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, | 151 | {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, |
| 152 | {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}} | 152 | {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} } |
| 153 | }; | 153 | }; |
| 154 | 154 | ||
| 155 | static void | 155 | static void |
| @@ -313,9 +313,8 @@ str_to_key(unsigned char *str, unsigned char *key) | |||
| 313 | key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6); | 313 | key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6); |
| 314 | key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7); | 314 | key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7); |
| 315 | key[7] = str[6] & 0x7F; | 315 | key[7] = str[6] & 0x7F; |
| 316 | for (i = 0; i < 8; i++) { | 316 | for (i = 0; i < 8; i++) |
| 317 | key[i] = (key[i] << 1); | 317 | key[i] = (key[i] << 1); |
| 318 | } | ||
| 319 | } | 318 | } |
| 320 | 319 | ||
| 321 | static void | 320 | static void |
| @@ -344,9 +343,8 @@ smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw) | |||
| 344 | 343 | ||
| 345 | dohash(outb, inb, keyb, forw); | 344 | dohash(outb, inb, keyb, forw); |
| 346 | 345 | ||
| 347 | for (i = 0; i < 8; i++) { | 346 | for (i = 0; i < 8; i++) |
| 348 | out[i] = 0; | 347 | out[i] = 0; |
| 349 | } | ||
| 350 | 348 | ||
| 351 | for (i = 0; i < 64; i++) { | 349 | for (i = 0; i < 64; i++) { |
| 352 | if (outb[i]) | 350 | if (outb[i]) |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 50b623ad9320..3612d6c0a0bb 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * fs/cifs/transport.c | 2 | * fs/cifs/transport.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) International Business Machines Corp., 2002,2007 | 4 | * Copyright (C) International Business Machines Corp., 2002,2008 |
| 5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
| 6 | * Jeremy Allison (jra@samba.org) 2006. | 6 | * Jeremy Allison (jra@samba.org) 2006. |
| 7 | * | 7 | * |
| @@ -358,9 +358,9 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf, | |||
| 358 | } else if (ses->status != CifsGood) { | 358 | } else if (ses->status != CifsGood) { |
| 359 | /* check if SMB session is bad because we are setting it up */ | 359 | /* check if SMB session is bad because we are setting it up */ |
| 360 | if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && | 360 | if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && |
| 361 | (in_buf->Command != SMB_COM_NEGOTIATE)) { | 361 | (in_buf->Command != SMB_COM_NEGOTIATE)) |
| 362 | return -EAGAIN; | 362 | return -EAGAIN; |
| 363 | } /* else ok - we are setting up session */ | 363 | /* else ok - we are setting up session */ |
| 364 | } | 364 | } |
| 365 | *ppmidQ = AllocMidQEntry(in_buf, ses); | 365 | *ppmidQ = AllocMidQEntry(in_buf, ses); |
| 366 | if (*ppmidQ == NULL) | 366 | if (*ppmidQ == NULL) |
| @@ -437,9 +437,8 @@ SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, | |||
| 437 | iov[0].iov_len = in_buf->smb_buf_length + 4; | 437 | iov[0].iov_len = in_buf->smb_buf_length + 4; |
| 438 | flags |= CIFS_NO_RESP; | 438 | flags |= CIFS_NO_RESP; |
| 439 | rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags); | 439 | rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags); |
| 440 | #ifdef CONFIG_CIFS_DEBUG2 | 440 | cFYI(DBG2, ("SendRcvNoRsp flags %d rc %d", flags, rc)); |
| 441 | cFYI(1, ("SendRcvNoR flags %d rc %d", flags, rc)); | 441 | |
| 442 | #endif | ||
| 443 | return rc; | 442 | return rc; |
| 444 | } | 443 | } |
| 445 | 444 | ||
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 54e8ef96cb79..8cd6a445b017 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
| @@ -139,9 +139,9 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, | |||
| 139 | } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) { | 139 | } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) { |
| 140 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) | 140 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) |
| 141 | goto set_ea_exit; | 141 | goto set_ea_exit; |
| 142 | if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) { | 142 | if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) |
| 143 | cFYI(1, ("attempt to set cifs inode metadata")); | 143 | cFYI(1, ("attempt to set cifs inode metadata")); |
| 144 | } | 144 | |
| 145 | ea_name += 5; /* skip past user. prefix */ | 145 | ea_name += 5; /* skip past user. prefix */ |
| 146 | rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value, | 146 | rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value, |
| 147 | (__u16)value_size, cifs_sb->local_nls, | 147 | (__u16)value_size, cifs_sb->local_nls, |
| @@ -262,7 +262,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, | |||
| 262 | cifs_sb->mnt_cifs_flags & | 262 | cifs_sb->mnt_cifs_flags & |
| 263 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 263 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 264 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 264 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
| 265 | else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 265 | else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
| 266 | __u16 fid; | 266 | __u16 fid; |
| 267 | int oplock = FALSE; | 267 | int oplock = FALSE; |
| 268 | struct cifs_ntsd *pacl = NULL; | 268 | struct cifs_ntsd *pacl = NULL; |
| @@ -303,11 +303,10 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, | |||
| 303 | } else if (strncmp(ea_name, | 303 | } else if (strncmp(ea_name, |
| 304 | CIFS_XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) { | 304 | CIFS_XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) { |
| 305 | cFYI(1, ("Security xattr namespace not supported yet")); | 305 | cFYI(1, ("Security xattr namespace not supported yet")); |
| 306 | } else { | 306 | } else |
| 307 | cFYI(1, | 307 | cFYI(1, |
| 308 | ("illegal xattr request %s (only user namespace supported)", | 308 | ("illegal xattr request %s (only user namespace supported)", |
| 309 | ea_name)); | 309 | ea_name)); |
| 310 | } | ||
| 311 | 310 | ||
| 312 | /* We could add an additional check for streams ie | 311 | /* We could add an additional check for streams ie |
| 313 | if proc/fs/cifs/streamstoxattr is set then | 312 | if proc/fs/cifs/streamstoxattr is set then |
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index d26e2826ba5b..e9602d85c11d 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
| @@ -29,10 +29,6 @@ | |||
| 29 | 29 | ||
| 30 | #define DEBUGFS_MAGIC 0x64626720 | 30 | #define DEBUGFS_MAGIC 0x64626720 |
| 31 | 31 | ||
| 32 | /* declared over in file.c */ | ||
| 33 | extern struct file_operations debugfs_file_operations; | ||
| 34 | extern struct inode_operations debugfs_link_operations; | ||
| 35 | |||
| 36 | static struct vfsmount *debugfs_mount; | 32 | static struct vfsmount *debugfs_mount; |
| 37 | static int debugfs_mount_count; | 33 | static int debugfs_mount_count; |
| 38 | 34 | ||
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c index 035e6f9990b0..67522c268c14 100644 --- a/fs/dlm/rcom.c +++ b/fs/dlm/rcom.c | |||
| @@ -215,6 +215,8 @@ int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) | |||
| 215 | ls->ls_recover_nodeid = nodeid; | 215 | ls->ls_recover_nodeid = nodeid; |
| 216 | 216 | ||
| 217 | if (nodeid == dlm_our_nodeid()) { | 217 | if (nodeid == dlm_our_nodeid()) { |
| 218 | ls->ls_recover_buf->rc_header.h_length = | ||
| 219 | dlm_config.ci_buffer_size; | ||
| 218 | dlm_copy_master_names(ls, last_name, last_len, | 220 | dlm_copy_master_names(ls, last_name, last_len, |
| 219 | ls->ls_recover_buf->rc_buf, | 221 | ls->ls_recover_buf->rc_buf, |
| 220 | max_size, nodeid); | 222 | max_size, nodeid); |
diff --git a/fs/dquot.c b/fs/dquot.c index 9c7feb62eed1..41b9dbd68b0e 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
| @@ -1522,8 +1522,8 @@ int vfs_quota_off(struct super_block *sb, int type) | |||
| 1522 | truncate_inode_pages(&toputinode[cnt]->i_data, 0); | 1522 | truncate_inode_pages(&toputinode[cnt]->i_data, 0); |
| 1523 | mutex_unlock(&toputinode[cnt]->i_mutex); | 1523 | mutex_unlock(&toputinode[cnt]->i_mutex); |
| 1524 | mark_inode_dirty(toputinode[cnt]); | 1524 | mark_inode_dirty(toputinode[cnt]); |
| 1525 | iput(toputinode[cnt]); | ||
| 1526 | } | 1525 | } |
| 1526 | iput(toputinode[cnt]); | ||
| 1527 | mutex_unlock(&dqopt->dqonoff_mutex); | 1527 | mutex_unlock(&dqopt->dqonoff_mutex); |
| 1528 | } | 1528 | } |
| 1529 | if (sb->s_bdev) | 1529 | if (sb->s_bdev) |
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c index 841a032050a7..5e596583946c 100644 --- a/fs/ecryptfs/dentry.c +++ b/fs/ecryptfs/dentry.c | |||
| @@ -80,8 +80,8 @@ static void ecryptfs_d_release(struct dentry *dentry) | |||
| 80 | { | 80 | { |
| 81 | if (ecryptfs_dentry_to_private(dentry)) { | 81 | if (ecryptfs_dentry_to_private(dentry)) { |
| 82 | if (ecryptfs_dentry_to_lower(dentry)) { | 82 | if (ecryptfs_dentry_to_lower(dentry)) { |
| 83 | mntput(ecryptfs_dentry_to_lower_mnt(dentry)); | ||
| 84 | dput(ecryptfs_dentry_to_lower(dentry)); | 83 | dput(ecryptfs_dentry_to_lower(dentry)); |
| 84 | mntput(ecryptfs_dentry_to_lower_mnt(dentry)); | ||
| 85 | } | 85 | } |
| 86 | kmem_cache_free(ecryptfs_dentry_info_cache, | 86 | kmem_cache_free(ecryptfs_dentry_info_cache, |
| 87 | ecryptfs_dentry_to_private(dentry)); | 87 | ecryptfs_dentry_to_private(dentry)); |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index dc74b186145d..6df1debdccce 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
| @@ -263,52 +263,102 @@ out: | |||
| 263 | return 0; | 263 | return 0; |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | /* This function must zero any hole we create */ | 266 | /** |
| 267 | * ecryptfs_prepare_write | ||
| 268 | * @file: The eCryptfs file | ||
| 269 | * @page: The eCryptfs page | ||
| 270 | * @from: The start byte from which we will write | ||
| 271 | * @to: The end byte to which we will write | ||
| 272 | * | ||
| 273 | * This function must zero any hole we create | ||
| 274 | * | ||
| 275 | * Returns zero on success; non-zero otherwise | ||
| 276 | */ | ||
| 267 | static int ecryptfs_prepare_write(struct file *file, struct page *page, | 277 | static int ecryptfs_prepare_write(struct file *file, struct page *page, |
| 268 | unsigned from, unsigned to) | 278 | unsigned from, unsigned to) |
| 269 | { | 279 | { |
| 270 | int rc = 0; | ||
| 271 | loff_t prev_page_end_size; | 280 | loff_t prev_page_end_size; |
| 281 | int rc = 0; | ||
| 272 | 282 | ||
| 273 | if (!PageUptodate(page)) { | 283 | if (!PageUptodate(page)) { |
| 274 | rc = ecryptfs_read_lower_page_segment(page, page->index, 0, | 284 | struct ecryptfs_crypt_stat *crypt_stat = |
| 275 | PAGE_CACHE_SIZE, | 285 | &ecryptfs_inode_to_private( |
| 276 | page->mapping->host); | 286 | file->f_path.dentry->d_inode)->crypt_stat; |
| 277 | if (rc) { | 287 | |
| 278 | printk(KERN_ERR "%s: Error attemping to read lower " | 288 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED) |
| 279 | "page segment; rc = [%d]\n", __FUNCTION__, rc); | 289 | || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { |
| 280 | ClearPageUptodate(page); | 290 | rc = ecryptfs_read_lower_page_segment( |
| 281 | goto out; | 291 | page, page->index, 0, PAGE_CACHE_SIZE, |
| 282 | } else | 292 | page->mapping->host); |
| 293 | if (rc) { | ||
| 294 | printk(KERN_ERR "%s: Error attemping to read " | ||
| 295 | "lower page segment; rc = [%d]\n", | ||
| 296 | __FUNCTION__, rc); | ||
| 297 | ClearPageUptodate(page); | ||
| 298 | goto out; | ||
| 299 | } else | ||
| 300 | SetPageUptodate(page); | ||
| 301 | } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) { | ||
| 302 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { | ||
| 303 | rc = ecryptfs_copy_up_encrypted_with_header( | ||
| 304 | page, crypt_stat); | ||
| 305 | if (rc) { | ||
| 306 | printk(KERN_ERR "%s: Error attempting " | ||
| 307 | "to copy the encrypted content " | ||
| 308 | "from the lower file whilst " | ||
| 309 | "inserting the metadata from " | ||
| 310 | "the xattr into the header; rc " | ||
| 311 | "= [%d]\n", __FUNCTION__, rc); | ||
| 312 | ClearPageUptodate(page); | ||
| 313 | goto out; | ||
| 314 | } | ||
| 315 | SetPageUptodate(page); | ||
| 316 | } else { | ||
| 317 | rc = ecryptfs_read_lower_page_segment( | ||
| 318 | page, page->index, 0, PAGE_CACHE_SIZE, | ||
| 319 | page->mapping->host); | ||
| 320 | if (rc) { | ||
| 321 | printk(KERN_ERR "%s: Error reading " | ||
| 322 | "page; rc = [%d]\n", | ||
| 323 | __FUNCTION__, rc); | ||
| 324 | ClearPageUptodate(page); | ||
| 325 | goto out; | ||
| 326 | } | ||
| 327 | SetPageUptodate(page); | ||
| 328 | } | ||
| 329 | } else { | ||
| 330 | rc = ecryptfs_decrypt_page(page); | ||
| 331 | if (rc) { | ||
| 332 | printk(KERN_ERR "%s: Error decrypting page " | ||
| 333 | "at index [%ld]; rc = [%d]\n", | ||
| 334 | __FUNCTION__, page->index, rc); | ||
| 335 | ClearPageUptodate(page); | ||
| 336 | goto out; | ||
| 337 | } | ||
| 283 | SetPageUptodate(page); | 338 | SetPageUptodate(page); |
| 339 | } | ||
| 284 | } | 340 | } |
| 285 | |||
| 286 | prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT); | 341 | prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT); |
| 287 | 342 | /* If creating a page or more of holes, zero them out via truncate. | |
| 288 | /* | 343 | * Note, this will increase i_size. */ |
| 289 | * If creating a page or more of holes, zero them out via truncate. | ||
| 290 | * Note, this will increase i_size. | ||
| 291 | */ | ||
| 292 | if (page->index != 0) { | 344 | if (page->index != 0) { |
| 293 | if (prev_page_end_size > i_size_read(page->mapping->host)) { | 345 | if (prev_page_end_size > i_size_read(page->mapping->host)) { |
| 294 | rc = ecryptfs_truncate(file->f_path.dentry, | 346 | rc = ecryptfs_truncate(file->f_path.dentry, |
| 295 | prev_page_end_size); | 347 | prev_page_end_size); |
| 296 | if (rc) { | 348 | if (rc) { |
| 297 | printk(KERN_ERR "Error on attempt to " | 349 | printk(KERN_ERR "%s: Error on attempt to " |
| 298 | "truncate to (higher) offset [%lld];" | 350 | "truncate to (higher) offset [%lld];" |
| 299 | " rc = [%d]\n", prev_page_end_size, rc); | 351 | " rc = [%d]\n", __FUNCTION__, |
| 352 | prev_page_end_size, rc); | ||
| 300 | goto out; | 353 | goto out; |
| 301 | } | 354 | } |
| 302 | } | 355 | } |
| 303 | } | 356 | } |
| 304 | /* | 357 | /* Writing to a new page, and creating a small hole from start |
| 305 | * Writing to a new page, and creating a small hole from start of page? | 358 | * of page? Zero it out. */ |
| 306 | * Zero it out. | 359 | if ((i_size_read(page->mapping->host) == prev_page_end_size) |
| 307 | */ | 360 | && (from != 0)) |
| 308 | if ((i_size_read(page->mapping->host) == prev_page_end_size) && | ||
| 309 | (from != 0)) { | ||
| 310 | zero_user(page, 0, PAGE_CACHE_SIZE); | 361 | zero_user(page, 0, PAGE_CACHE_SIZE); |
| 311 | } | ||
| 312 | out: | 362 | out: |
| 313 | return rc; | 363 | return rc; |
| 314 | } | 364 | } |
diff --git a/fs/efs/dir.c b/fs/efs/dir.c index dfb5cb400217..49308a29798a 100644 --- a/fs/efs/dir.c +++ b/fs/efs/dir.c | |||
| @@ -5,8 +5,8 @@ | |||
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <linux/buffer_head.h> | 7 | #include <linux/buffer_head.h> |
| 8 | #include <linux/efs_fs.h> | ||
| 9 | #include <linux/smp_lock.h> | 8 | #include <linux/smp_lock.h> |
| 9 | #include "efs.h" | ||
| 10 | 10 | ||
| 11 | static int efs_readdir(struct file *, void *, filldir_t); | 11 | static int efs_readdir(struct file *, void *, filldir_t); |
| 12 | 12 | ||
diff --git a/fs/efs/efs.h b/fs/efs/efs.h new file mode 100644 index 000000000000..d8305b582ab0 --- /dev/null +++ b/fs/efs/efs.h | |||
| @@ -0,0 +1,140 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1999 Al Smith | ||
| 3 | * | ||
| 4 | * Portions derived from work (c) 1995,1996 Christian Vogelgsang. | ||
| 5 | * Portions derived from IRIX header files (c) 1988 Silicon Graphics | ||
| 6 | */ | ||
| 7 | #ifndef _EFS_EFS_H_ | ||
| 8 | #define _EFS_EFS_H_ | ||
| 9 | |||
| 10 | #include <linux/fs.h> | ||
| 11 | #include <asm/uaccess.h> | ||
| 12 | |||
| 13 | #define EFS_VERSION "1.0a" | ||
| 14 | |||
| 15 | static const char cprt[] = "EFS: "EFS_VERSION" - (c) 1999 Al Smith <Al.Smith@aeschi.ch.eu.org>"; | ||
| 16 | |||
| 17 | |||
| 18 | /* 1 block is 512 bytes */ | ||
| 19 | #define EFS_BLOCKSIZE_BITS 9 | ||
| 20 | #define EFS_BLOCKSIZE (1 << EFS_BLOCKSIZE_BITS) | ||
| 21 | |||
| 22 | typedef int32_t efs_block_t; | ||
| 23 | typedef uint32_t efs_ino_t; | ||
| 24 | |||
| 25 | #define EFS_DIRECTEXTENTS 12 | ||
| 26 | |||
| 27 | /* | ||
| 28 | * layout of an extent, in memory and on disk. 8 bytes exactly. | ||
| 29 | */ | ||
| 30 | typedef union extent_u { | ||
| 31 | unsigned char raw[8]; | ||
| 32 | struct extent_s { | ||
| 33 | unsigned int ex_magic:8; /* magic # (zero) */ | ||
| 34 | unsigned int ex_bn:24; /* basic block */ | ||
| 35 | unsigned int ex_length:8; /* numblocks in this extent */ | ||
| 36 | unsigned int ex_offset:24; /* logical offset into file */ | ||
| 37 | } cooked; | ||
| 38 | } efs_extent; | ||
| 39 | |||
| 40 | typedef struct edevs { | ||
| 41 | __be16 odev; | ||
| 42 | __be32 ndev; | ||
| 43 | } efs_devs; | ||
| 44 | |||
| 45 | /* | ||
| 46 | * extent based filesystem inode as it appears on disk. The efs inode | ||
| 47 | * is exactly 128 bytes long. | ||
| 48 | */ | ||
| 49 | struct efs_dinode { | ||
| 50 | __be16 di_mode; /* mode and type of file */ | ||
| 51 | __be16 di_nlink; /* number of links to file */ | ||
| 52 | __be16 di_uid; /* owner's user id */ | ||
| 53 | __be16 di_gid; /* owner's group id */ | ||
| 54 | __be32 di_size; /* number of bytes in file */ | ||
| 55 | __be32 di_atime; /* time last accessed */ | ||
| 56 | __be32 di_mtime; /* time last modified */ | ||
| 57 | __be32 di_ctime; /* time created */ | ||
| 58 | __be32 di_gen; /* generation number */ | ||
| 59 | __be16 di_numextents; /* # of extents */ | ||
| 60 | u_char di_version; /* version of inode */ | ||
| 61 | u_char di_spare; /* spare - used by AFS */ | ||
| 62 | union di_addr { | ||
| 63 | efs_extent di_extents[EFS_DIRECTEXTENTS]; | ||
| 64 | efs_devs di_dev; /* device for IFCHR/IFBLK */ | ||
| 65 | } di_u; | ||
| 66 | }; | ||
| 67 | |||
| 68 | /* efs inode storage in memory */ | ||
| 69 | struct efs_inode_info { | ||
| 70 | int numextents; | ||
| 71 | int lastextent; | ||
| 72 | |||
| 73 | efs_extent extents[EFS_DIRECTEXTENTS]; | ||
| 74 | struct inode vfs_inode; | ||
| 75 | }; | ||
| 76 | |||
| 77 | #include <linux/efs_fs_sb.h> | ||
| 78 | |||
| 79 | #define EFS_DIRBSIZE_BITS EFS_BLOCKSIZE_BITS | ||
| 80 | #define EFS_DIRBSIZE (1 << EFS_DIRBSIZE_BITS) | ||
| 81 | |||
| 82 | struct efs_dentry { | ||
| 83 | __be32 inode; | ||
| 84 | unsigned char namelen; | ||
| 85 | char name[3]; | ||
| 86 | }; | ||
| 87 | |||
| 88 | #define EFS_DENTSIZE (sizeof(struct efs_dentry) - 3 + 1) | ||
| 89 | #define EFS_MAXNAMELEN ((1 << (sizeof(char) * 8)) - 1) | ||
| 90 | |||
| 91 | #define EFS_DIRBLK_HEADERSIZE 4 | ||
| 92 | #define EFS_DIRBLK_MAGIC 0xbeef /* moo */ | ||
| 93 | |||
| 94 | struct efs_dir { | ||
| 95 | __be16 magic; | ||
| 96 | unsigned char firstused; | ||
| 97 | unsigned char slots; | ||
| 98 | |||
| 99 | unsigned char space[EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE]; | ||
| 100 | }; | ||
| 101 | |||
| 102 | #define EFS_MAXENTS \ | ||
| 103 | ((EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE) / \ | ||
| 104 | (EFS_DENTSIZE + sizeof(char))) | ||
| 105 | |||
| 106 | #define EFS_SLOTAT(dir, slot) EFS_REALOFF((dir)->space[slot]) | ||
| 107 | |||
| 108 | #define EFS_REALOFF(offset) ((offset << 1)) | ||
| 109 | |||
| 110 | |||
| 111 | static inline struct efs_inode_info *INODE_INFO(struct inode *inode) | ||
| 112 | { | ||
| 113 | return container_of(inode, struct efs_inode_info, vfs_inode); | ||
| 114 | } | ||
| 115 | |||
| 116 | static inline struct efs_sb_info *SUPER_INFO(struct super_block *sb) | ||
| 117 | { | ||
| 118 | return sb->s_fs_info; | ||
| 119 | } | ||
| 120 | |||
| 121 | struct statfs; | ||
| 122 | struct fid; | ||
| 123 | |||
| 124 | extern const struct inode_operations efs_dir_inode_operations; | ||
| 125 | extern const struct file_operations efs_dir_operations; | ||
| 126 | extern const struct address_space_operations efs_symlink_aops; | ||
| 127 | |||
| 128 | extern struct inode *efs_iget(struct super_block *, unsigned long); | ||
| 129 | extern efs_block_t efs_map_block(struct inode *, efs_block_t); | ||
| 130 | extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int); | ||
| 131 | |||
| 132 | extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *); | ||
| 133 | extern struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid, | ||
| 134 | int fh_len, int fh_type); | ||
| 135 | extern struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid, | ||
| 136 | int fh_len, int fh_type); | ||
| 137 | extern struct dentry *efs_get_parent(struct dentry *); | ||
| 138 | extern int efs_bmap(struct inode *, int); | ||
| 139 | |||
| 140 | #endif /* _EFS_EFS_H_ */ | ||
diff --git a/fs/efs/file.c b/fs/efs/file.c index 5db20129681e..1ccb364ffa63 100644 --- a/fs/efs/file.c +++ b/fs/efs/file.c | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/buffer_head.h> | 9 | #include <linux/buffer_head.h> |
| 10 | #include <linux/efs_fs.h> | 10 | #include "efs.h" |
| 11 | 11 | ||
| 12 | int efs_get_block(struct inode *inode, sector_t iblock, | 12 | int efs_get_block(struct inode *inode, sector_t iblock, |
| 13 | struct buffer_head *bh_result, int create) | 13 | struct buffer_head *bh_result, int create) |
diff --git a/fs/efs/inode.c b/fs/efs/inode.c index 627c3026946d..a8e7797b9477 100644 --- a/fs/efs/inode.c +++ b/fs/efs/inode.c | |||
| @@ -7,11 +7,11 @@ | |||
| 7 | * and from work (c) 1998 Mike Shaver. | 7 | * and from work (c) 1998 Mike Shaver. |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/efs_fs.h> | ||
| 11 | #include <linux/efs_fs_sb.h> | ||
| 12 | #include <linux/buffer_head.h> | 10 | #include <linux/buffer_head.h> |
| 13 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 14 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
| 13 | #include "efs.h" | ||
| 14 | #include <linux/efs_fs_sb.h> | ||
| 15 | 15 | ||
| 16 | static int efs_readpage(struct file *file, struct page *page) | 16 | static int efs_readpage(struct file *file, struct page *page) |
| 17 | { | 17 | { |
| @@ -140,7 +140,7 @@ struct inode *efs_iget(struct super_block *super, unsigned long ino) | |||
| 140 | brelse(bh); | 140 | brelse(bh); |
| 141 | 141 | ||
| 142 | #ifdef DEBUG | 142 | #ifdef DEBUG |
| 143 | printk(KERN_DEBUG "EFS: read_inode(): inode %lu, extents %d, mode %o\n", | 143 | printk(KERN_DEBUG "EFS: efs_iget(): inode %lu, extents %d, mode %o\n", |
| 144 | inode->i_ino, in->numextents, inode->i_mode); | 144 | inode->i_ino, in->numextents, inode->i_mode); |
| 145 | #endif | 145 | #endif |
| 146 | 146 | ||
diff --git a/fs/efs/namei.c b/fs/efs/namei.c index e26704742d41..3a404e7fad53 100644 --- a/fs/efs/namei.c +++ b/fs/efs/namei.c | |||
| @@ -8,9 +8,9 @@ | |||
| 8 | 8 | ||
| 9 | #include <linux/buffer_head.h> | 9 | #include <linux/buffer_head.h> |
| 10 | #include <linux/string.h> | 10 | #include <linux/string.h> |
| 11 | #include <linux/efs_fs.h> | ||
| 12 | #include <linux/smp_lock.h> | 11 | #include <linux/smp_lock.h> |
| 13 | #include <linux/exportfs.h> | 12 | #include <linux/exportfs.h> |
| 13 | #include "efs.h" | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) { | 16 | static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) { |
diff --git a/fs/efs/super.c b/fs/efs/super.c index 14082405cdd1..d733531b55e2 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c | |||
| @@ -8,14 +8,15 @@ | |||
| 8 | 8 | ||
| 9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
| 10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 11 | #include <linux/efs_fs.h> | ||
| 12 | #include <linux/efs_vh.h> | ||
| 13 | #include <linux/efs_fs_sb.h> | ||
| 14 | #include <linux/exportfs.h> | 11 | #include <linux/exportfs.h> |
| 15 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
| 16 | #include <linux/buffer_head.h> | 13 | #include <linux/buffer_head.h> |
| 17 | #include <linux/vfs.h> | 14 | #include <linux/vfs.h> |
| 18 | 15 | ||
| 16 | #include "efs.h" | ||
| 17 | #include <linux/efs_vh.h> | ||
| 18 | #include <linux/efs_fs_sb.h> | ||
| 19 | |||
| 19 | static int efs_statfs(struct dentry *dentry, struct kstatfs *buf); | 20 | static int efs_statfs(struct dentry *dentry, struct kstatfs *buf); |
| 20 | static int efs_fill_super(struct super_block *s, void *d, int silent); | 21 | static int efs_fill_super(struct super_block *s, void *d, int silent); |
| 21 | 22 | ||
diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c index 1d30d2ff440f..41911ec83aaf 100644 --- a/fs/efs/symlink.c +++ b/fs/efs/symlink.c | |||
| @@ -7,10 +7,10 @@ | |||
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
| 10 | #include <linux/efs_fs.h> | ||
| 11 | #include <linux/pagemap.h> | 10 | #include <linux/pagemap.h> |
| 12 | #include <linux/buffer_head.h> | 11 | #include <linux/buffer_head.h> |
| 13 | #include <linux/smp_lock.h> | 12 | #include <linux/smp_lock.h> |
| 13 | #include "efs.h" | ||
| 14 | 14 | ||
| 15 | static int efs_symlink_readpage(struct file *file, struct page *page) | 15 | static int efs_symlink_readpage(struct file *file, struct page *page) |
| 16 | { | 16 | { |
| @@ -173,8 +173,15 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | |||
| 173 | return NULL; | 173 | return NULL; |
| 174 | 174 | ||
| 175 | if (write) { | 175 | if (write) { |
| 176 | struct rlimit *rlim = current->signal->rlim; | ||
| 177 | unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; | 176 | unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; |
| 177 | struct rlimit *rlim; | ||
| 178 | |||
| 179 | /* | ||
| 180 | * We've historically supported up to 32 pages (ARG_MAX) | ||
| 181 | * of argument strings even with small stacks | ||
| 182 | */ | ||
| 183 | if (size <= ARG_MAX) | ||
| 184 | return page; | ||
| 178 | 185 | ||
| 179 | /* | 186 | /* |
| 180 | * Limit to 1/4-th the stack size for the argv+env strings. | 187 | * Limit to 1/4-th the stack size for the argv+env strings. |
| @@ -183,6 +190,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | |||
| 183 | * - the program will have a reasonable amount of stack left | 190 | * - the program will have a reasonable amount of stack left |
| 184 | * to work from. | 191 | * to work from. |
| 185 | */ | 192 | */ |
| 193 | rlim = current->signal->rlim; | ||
| 186 | if (size > rlim[RLIMIT_STACK].rlim_cur / 4) { | 194 | if (size > rlim[RLIMIT_STACK].rlim_cur / 4) { |
| 187 | put_page(page); | 195 | put_page(page); |
| 188 | return NULL; | 196 | return NULL; |
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 3e8683dbb13f..a99d46f3b26e 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c | |||
| @@ -835,7 +835,7 @@ ext2_xattr_cache_insert(struct buffer_head *bh) | |||
| 835 | struct mb_cache_entry *ce; | 835 | struct mb_cache_entry *ce; |
| 836 | int error; | 836 | int error; |
| 837 | 837 | ||
| 838 | ce = mb_cache_entry_alloc(ext2_xattr_cache); | 838 | ce = mb_cache_entry_alloc(ext2_xattr_cache, GFP_NOFS); |
| 839 | if (!ce) | 839 | if (!ce) |
| 840 | return -ENOMEM; | 840 | return -ENOMEM; |
| 841 | error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash); | 841 | error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash); |
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index d34e9967430a..a754d1848173 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c | |||
| @@ -37,7 +37,7 @@ ext3_acl_from_disk(const void *value, size_t size) | |||
| 37 | return ERR_PTR(-EINVAL); | 37 | return ERR_PTR(-EINVAL); |
| 38 | if (count == 0) | 38 | if (count == 0) |
| 39 | return NULL; | 39 | return NULL; |
| 40 | acl = posix_acl_alloc(count, GFP_KERNEL); | 40 | acl = posix_acl_alloc(count, GFP_NOFS); |
| 41 | if (!acl) | 41 | if (!acl) |
| 42 | return ERR_PTR(-ENOMEM); | 42 | return ERR_PTR(-ENOMEM); |
| 43 | for (n=0; n < count; n++) { | 43 | for (n=0; n < count; n++) { |
| @@ -91,7 +91,7 @@ ext3_acl_to_disk(const struct posix_acl *acl, size_t *size) | |||
| 91 | 91 | ||
| 92 | *size = ext3_acl_size(acl->a_count); | 92 | *size = ext3_acl_size(acl->a_count); |
| 93 | ext_acl = kmalloc(sizeof(ext3_acl_header) + acl->a_count * | 93 | ext_acl = kmalloc(sizeof(ext3_acl_header) + acl->a_count * |
| 94 | sizeof(ext3_acl_entry), GFP_KERNEL); | 94 | sizeof(ext3_acl_entry), GFP_NOFS); |
| 95 | if (!ext_acl) | 95 | if (!ext_acl) |
| 96 | return ERR_PTR(-ENOMEM); | 96 | return ERR_PTR(-ENOMEM); |
| 97 | ext_acl->a_version = cpu_to_le32(EXT3_ACL_VERSION); | 97 | ext_acl->a_version = cpu_to_le32(EXT3_ACL_VERSION); |
| @@ -187,7 +187,7 @@ ext3_get_acl(struct inode *inode, int type) | |||
| 187 | } | 187 | } |
| 188 | retval = ext3_xattr_get(inode, name_index, "", NULL, 0); | 188 | retval = ext3_xattr_get(inode, name_index, "", NULL, 0); |
| 189 | if (retval > 0) { | 189 | if (retval > 0) { |
| 190 | value = kmalloc(retval, GFP_KERNEL); | 190 | value = kmalloc(retval, GFP_NOFS); |
| 191 | if (!value) | 191 | if (!value) |
| 192 | return ERR_PTR(-ENOMEM); | 192 | return ERR_PTR(-ENOMEM); |
| 193 | retval = ext3_xattr_get(inode, name_index, "", value, retval); | 193 | retval = ext3_xattr_get(inode, name_index, "", value, retval); |
| @@ -335,7 +335,7 @@ ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) | |||
| 335 | if (error) | 335 | if (error) |
| 336 | goto cleanup; | 336 | goto cleanup; |
| 337 | } | 337 | } |
| 338 | clone = posix_acl_clone(acl, GFP_KERNEL); | 338 | clone = posix_acl_clone(acl, GFP_NOFS); |
| 339 | error = -ENOMEM; | 339 | error = -ENOMEM; |
| 340 | if (!clone) | 340 | if (!clone) |
| 341 | goto cleanup; | 341 | goto cleanup; |
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 9397d779c43d..0e97b6e07cb0 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c | |||
| @@ -485,7 +485,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, | |||
| 485 | goto exit_dindj; | 485 | goto exit_dindj; |
| 486 | 486 | ||
| 487 | n_group_desc = kmalloc((gdb_num + 1) * sizeof(struct buffer_head *), | 487 | n_group_desc = kmalloc((gdb_num + 1) * sizeof(struct buffer_head *), |
| 488 | GFP_KERNEL); | 488 | GFP_NOFS); |
| 489 | if (!n_group_desc) { | 489 | if (!n_group_desc) { |
| 490 | err = -ENOMEM; | 490 | err = -ENOMEM; |
| 491 | ext3_warning (sb, __FUNCTION__, | 491 | ext3_warning (sb, __FUNCTION__, |
| @@ -568,7 +568,7 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode, | |||
| 568 | int res, i; | 568 | int res, i; |
| 569 | int err; | 569 | int err; |
| 570 | 570 | ||
| 571 | primary = kmalloc(reserved_gdb * sizeof(*primary), GFP_KERNEL); | 571 | primary = kmalloc(reserved_gdb * sizeof(*primary), GFP_NOFS); |
| 572 | if (!primary) | 572 | if (!primary) |
| 573 | return -ENOMEM; | 573 | return -ENOMEM; |
| 574 | 574 | ||
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 18769cc32377..ad5360664082 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
| @@ -806,8 +806,8 @@ static match_table_t tokens = { | |||
| 806 | {Opt_quota, "quota"}, | 806 | {Opt_quota, "quota"}, |
| 807 | {Opt_usrquota, "usrquota"}, | 807 | {Opt_usrquota, "usrquota"}, |
| 808 | {Opt_barrier, "barrier=%u"}, | 808 | {Opt_barrier, "barrier=%u"}, |
| 809 | {Opt_err, NULL}, | ||
| 810 | {Opt_resize, "resize"}, | 809 | {Opt_resize, "resize"}, |
| 810 | {Opt_err, NULL}, | ||
| 811 | }; | 811 | }; |
| 812 | 812 | ||
| 813 | static ext3_fsblk_t get_sb_block(void **data) | 813 | static ext3_fsblk_t get_sb_block(void **data) |
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index fb89c299bece..42856541e9a5 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
| @@ -728,7 +728,7 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode, | |||
| 728 | ce = NULL; | 728 | ce = NULL; |
| 729 | } | 729 | } |
| 730 | ea_bdebug(bs->bh, "cloning"); | 730 | ea_bdebug(bs->bh, "cloning"); |
| 731 | s->base = kmalloc(bs->bh->b_size, GFP_KERNEL); | 731 | s->base = kmalloc(bs->bh->b_size, GFP_NOFS); |
| 732 | error = -ENOMEM; | 732 | error = -ENOMEM; |
| 733 | if (s->base == NULL) | 733 | if (s->base == NULL) |
| 734 | goto cleanup; | 734 | goto cleanup; |
| @@ -740,7 +740,7 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode, | |||
| 740 | } | 740 | } |
| 741 | } else { | 741 | } else { |
| 742 | /* Allocate a buffer where we construct the new block. */ | 742 | /* Allocate a buffer where we construct the new block. */ |
| 743 | s->base = kzalloc(sb->s_blocksize, GFP_KERNEL); | 743 | s->base = kzalloc(sb->s_blocksize, GFP_NOFS); |
| 744 | /* assert(header == s->base) */ | 744 | /* assert(header == s->base) */ |
| 745 | error = -ENOMEM; | 745 | error = -ENOMEM; |
| 746 | if (s->base == NULL) | 746 | if (s->base == NULL) |
| @@ -1126,7 +1126,7 @@ ext3_xattr_cache_insert(struct buffer_head *bh) | |||
| 1126 | struct mb_cache_entry *ce; | 1126 | struct mb_cache_entry *ce; |
| 1127 | int error; | 1127 | int error; |
| 1128 | 1128 | ||
| 1129 | ce = mb_cache_entry_alloc(ext3_xattr_cache); | 1129 | ce = mb_cache_entry_alloc(ext3_xattr_cache, GFP_NOFS); |
| 1130 | if (!ce) { | 1130 | if (!ce) { |
| 1131 | ea_bdebug(bh, "out of memory"); | 1131 | ea_bdebug(bh, "out of memory"); |
| 1132 | return; | 1132 | return; |
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 33888bb58144..2c23bade9aa6 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c | |||
| @@ -46,7 +46,7 @@ const struct file_operations ext4_dir_operations = { | |||
| 46 | #ifdef CONFIG_COMPAT | 46 | #ifdef CONFIG_COMPAT |
| 47 | .compat_ioctl = ext4_compat_ioctl, | 47 | .compat_ioctl = ext4_compat_ioctl, |
| 48 | #endif | 48 | #endif |
| 49 | .fsync = ext4_sync_file, /* BKL held */ | 49 | .fsync = ext4_sync_file, |
| 50 | .release = ext4_release_dir, | 50 | .release = ext4_release_dir, |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index bc7081f1fbe8..9ae6e67090cd 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
| @@ -148,6 +148,7 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, | |||
| 148 | { | 148 | { |
| 149 | struct ext4_inode_info *ei = EXT4_I(inode); | 149 | struct ext4_inode_info *ei = EXT4_I(inode); |
| 150 | ext4_fsblk_t bg_start; | 150 | ext4_fsblk_t bg_start; |
| 151 | ext4_fsblk_t last_block; | ||
| 151 | ext4_grpblk_t colour; | 152 | ext4_grpblk_t colour; |
| 152 | int depth; | 153 | int depth; |
| 153 | 154 | ||
| @@ -169,8 +170,13 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, | |||
| 169 | /* OK. use inode's group */ | 170 | /* OK. use inode's group */ |
| 170 | bg_start = (ei->i_block_group * EXT4_BLOCKS_PER_GROUP(inode->i_sb)) + | 171 | bg_start = (ei->i_block_group * EXT4_BLOCKS_PER_GROUP(inode->i_sb)) + |
| 171 | le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_first_data_block); | 172 | le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_first_data_block); |
| 172 | colour = (current->pid % 16) * | 173 | last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1; |
| 174 | |||
| 175 | if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block) | ||
| 176 | colour = (current->pid % 16) * | ||
| 173 | (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); | 177 | (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); |
| 178 | else | ||
| 179 | colour = (current->pid % 16) * ((last_block - bg_start) / 16); | ||
| 174 | return bg_start + colour + block; | 180 | return bg_start + colour + block; |
| 175 | } | 181 | } |
| 176 | 182 | ||
| @@ -349,7 +355,7 @@ static void ext4_ext_show_leaf(struct inode *inode, struct ext4_ext_path *path) | |||
| 349 | #define ext4_ext_show_leaf(inode,path) | 355 | #define ext4_ext_show_leaf(inode,path) |
| 350 | #endif | 356 | #endif |
| 351 | 357 | ||
| 352 | static void ext4_ext_drop_refs(struct ext4_ext_path *path) | 358 | void ext4_ext_drop_refs(struct ext4_ext_path *path) |
| 353 | { | 359 | { |
| 354 | int depth = path->p_depth; | 360 | int depth = path->p_depth; |
| 355 | int i; | 361 | int i; |
| @@ -2168,6 +2174,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
| 2168 | newblock = iblock - ee_block + ext_pblock(ex); | 2174 | newblock = iblock - ee_block + ext_pblock(ex); |
| 2169 | ex2 = ex; | 2175 | ex2 = ex; |
| 2170 | 2176 | ||
| 2177 | err = ext4_ext_get_access(handle, inode, path + depth); | ||
| 2178 | if (err) | ||
| 2179 | goto out; | ||
| 2180 | |||
| 2171 | /* ex1: ee_block to iblock - 1 : uninitialized */ | 2181 | /* ex1: ee_block to iblock - 1 : uninitialized */ |
| 2172 | if (iblock > ee_block) { | 2182 | if (iblock > ee_block) { |
| 2173 | ex1 = ex; | 2183 | ex1 = ex; |
| @@ -2200,16 +2210,20 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
| 2200 | newdepth = ext_depth(inode); | 2210 | newdepth = ext_depth(inode); |
| 2201 | if (newdepth != depth) { | 2211 | if (newdepth != depth) { |
| 2202 | depth = newdepth; | 2212 | depth = newdepth; |
| 2203 | path = ext4_ext_find_extent(inode, iblock, NULL); | 2213 | ext4_ext_drop_refs(path); |
| 2214 | path = ext4_ext_find_extent(inode, iblock, path); | ||
| 2204 | if (IS_ERR(path)) { | 2215 | if (IS_ERR(path)) { |
| 2205 | err = PTR_ERR(path); | 2216 | err = PTR_ERR(path); |
| 2206 | path = NULL; | ||
| 2207 | goto out; | 2217 | goto out; |
| 2208 | } | 2218 | } |
| 2209 | eh = path[depth].p_hdr; | 2219 | eh = path[depth].p_hdr; |
| 2210 | ex = path[depth].p_ext; | 2220 | ex = path[depth].p_ext; |
| 2211 | if (ex2 != &newex) | 2221 | if (ex2 != &newex) |
| 2212 | ex2 = ex; | 2222 | ex2 = ex; |
| 2223 | |||
| 2224 | err = ext4_ext_get_access(handle, inode, path + depth); | ||
| 2225 | if (err) | ||
| 2226 | goto out; | ||
| 2213 | } | 2227 | } |
| 2214 | allocated = max_blocks; | 2228 | allocated = max_blocks; |
| 2215 | } | 2229 | } |
| @@ -2230,9 +2244,6 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
| 2230 | ex2->ee_len = cpu_to_le16(allocated); | 2244 | ex2->ee_len = cpu_to_le16(allocated); |
| 2231 | if (ex2 != ex) | 2245 | if (ex2 != ex) |
| 2232 | goto insert; | 2246 | goto insert; |
| 2233 | err = ext4_ext_get_access(handle, inode, path + depth); | ||
| 2234 | if (err) | ||
| 2235 | goto out; | ||
| 2236 | /* | 2247 | /* |
| 2237 | * New (initialized) extent starts from the first block | 2248 | * New (initialized) extent starts from the first block |
| 2238 | * in the current extent. i.e., ex2 == ex | 2249 | * in the current extent. i.e., ex2 == ex |
| @@ -2276,9 +2287,22 @@ out: | |||
| 2276 | } | 2287 | } |
| 2277 | 2288 | ||
| 2278 | /* | 2289 | /* |
| 2290 | * Block allocation/map/preallocation routine for extents based files | ||
| 2291 | * | ||
| 2292 | * | ||
| 2279 | * Need to be called with | 2293 | * Need to be called with |
| 2280 | * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block | 2294 | * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block |
| 2281 | * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem) | 2295 | * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem) |
| 2296 | * | ||
| 2297 | * return > 0, number of of blocks already mapped/allocated | ||
| 2298 | * if create == 0 and these are pre-allocated blocks | ||
| 2299 | * buffer head is unmapped | ||
| 2300 | * otherwise blocks are mapped | ||
| 2301 | * | ||
| 2302 | * return = 0, if plain look up failed (blocks have not been allocated) | ||
| 2303 | * buffer head is unmapped | ||
| 2304 | * | ||
| 2305 | * return < 0, error case. | ||
| 2282 | */ | 2306 | */ |
| 2283 | int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | 2307 | int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, |
| 2284 | ext4_lblk_t iblock, | 2308 | ext4_lblk_t iblock, |
| @@ -2623,7 +2647,7 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) | |||
| 2623 | * modify 1 super block, 1 block bitmap and 1 group descriptor. | 2647 | * modify 1 super block, 1 block bitmap and 1 group descriptor. |
| 2624 | */ | 2648 | */ |
| 2625 | credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3; | 2649 | credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3; |
| 2626 | down_write((&EXT4_I(inode)->i_data_sem)); | 2650 | mutex_lock(&inode->i_mutex); |
| 2627 | retry: | 2651 | retry: |
| 2628 | while (ret >= 0 && ret < max_blocks) { | 2652 | while (ret >= 0 && ret < max_blocks) { |
| 2629 | block = block + ret; | 2653 | block = block + ret; |
| @@ -2634,16 +2658,17 @@ retry: | |||
| 2634 | break; | 2658 | break; |
| 2635 | } | 2659 | } |
| 2636 | 2660 | ||
| 2637 | ret = ext4_ext_get_blocks(handle, inode, block, | 2661 | ret = ext4_get_blocks_wrap(handle, inode, block, |
| 2638 | max_blocks, &map_bh, | 2662 | max_blocks, &map_bh, |
| 2639 | EXT4_CREATE_UNINITIALIZED_EXT, 0); | 2663 | EXT4_CREATE_UNINITIALIZED_EXT, 0); |
| 2640 | WARN_ON(ret <= 0); | ||
| 2641 | if (ret <= 0) { | 2664 | if (ret <= 0) { |
| 2642 | ext4_error(inode->i_sb, "ext4_fallocate", | 2665 | #ifdef EXT4FS_DEBUG |
| 2643 | "ext4_ext_get_blocks returned error: " | 2666 | WARN_ON(ret <= 0); |
| 2644 | "inode#%lu, block=%u, max_blocks=%lu", | 2667 | printk(KERN_ERR "%s: ext4_ext_get_blocks " |
| 2668 | "returned error inode#%lu, block=%u, " | ||
| 2669 | "max_blocks=%lu", __func__, | ||
| 2645 | inode->i_ino, block, max_blocks); | 2670 | inode->i_ino, block, max_blocks); |
| 2646 | ret = -EIO; | 2671 | #endif |
| 2647 | ext4_mark_inode_dirty(handle, inode); | 2672 | ext4_mark_inode_dirty(handle, inode); |
| 2648 | ret2 = ext4_journal_stop(handle); | 2673 | ret2 = ext4_journal_stop(handle); |
| 2649 | break; | 2674 | break; |
| @@ -2680,7 +2705,6 @@ retry: | |||
| 2680 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) | 2705 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) |
| 2681 | goto retry; | 2706 | goto retry; |
| 2682 | 2707 | ||
| 2683 | up_write((&EXT4_I(inode)->i_data_sem)); | ||
| 2684 | /* | 2708 | /* |
| 2685 | * Time to update the file size. | 2709 | * Time to update the file size. |
| 2686 | * Update only when preallocation was requested beyond the file size. | 2710 | * Update only when preallocation was requested beyond the file size. |
| @@ -2692,21 +2716,18 @@ retry: | |||
| 2692 | * if no error, we assume preallocation succeeded | 2716 | * if no error, we assume preallocation succeeded |
| 2693 | * completely | 2717 | * completely |
| 2694 | */ | 2718 | */ |
| 2695 | mutex_lock(&inode->i_mutex); | ||
| 2696 | i_size_write(inode, offset + len); | 2719 | i_size_write(inode, offset + len); |
| 2697 | EXT4_I(inode)->i_disksize = i_size_read(inode); | 2720 | EXT4_I(inode)->i_disksize = i_size_read(inode); |
| 2698 | mutex_unlock(&inode->i_mutex); | ||
| 2699 | } else if (ret < 0 && nblocks) { | 2721 | } else if (ret < 0 && nblocks) { |
| 2700 | /* Handle partial allocation scenario */ | 2722 | /* Handle partial allocation scenario */ |
| 2701 | loff_t newsize; | 2723 | loff_t newsize; |
| 2702 | 2724 | ||
| 2703 | mutex_lock(&inode->i_mutex); | ||
| 2704 | newsize = (nblocks << blkbits) + i_size_read(inode); | 2725 | newsize = (nblocks << blkbits) + i_size_read(inode); |
| 2705 | i_size_write(inode, EXT4_BLOCK_ALIGN(newsize, blkbits)); | 2726 | i_size_write(inode, EXT4_BLOCK_ALIGN(newsize, blkbits)); |
| 2706 | EXT4_I(inode)->i_disksize = i_size_read(inode); | 2727 | EXT4_I(inode)->i_disksize = i_size_read(inode); |
| 2707 | mutex_unlock(&inode->i_mutex); | ||
| 2708 | } | 2728 | } |
| 2709 | } | 2729 | } |
| 2710 | 2730 | ||
| 2731 | mutex_unlock(&inode->i_mutex); | ||
| 2711 | return ret > 0 ? ret2 : ret; | 2732 | return ret > 0 ? ret2 : ret; |
| 2712 | } | 2733 | } |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index da18a74b966a..8036b9b5376b 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
| @@ -702,7 +702,12 @@ got: | |||
| 702 | ei->i_dir_start_lookup = 0; | 702 | ei->i_dir_start_lookup = 0; |
| 703 | ei->i_disksize = 0; | 703 | ei->i_disksize = 0; |
| 704 | 704 | ||
| 705 | ei->i_flags = EXT4_I(dir)->i_flags & ~EXT4_INDEX_FL; | 705 | /* |
| 706 | * Don't inherit extent flag from directory. We set extent flag on | ||
| 707 | * newly created directory and file only if -o extent mount option is | ||
| 708 | * specified | ||
| 709 | */ | ||
| 710 | ei->i_flags = EXT4_I(dir)->i_flags & ~(EXT4_INDEX_FL|EXT4_EXTENTS_FL); | ||
| 706 | if (S_ISLNK(mode)) | 711 | if (S_ISLNK(mode)) |
| 707 | ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL); | 712 | ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL); |
| 708 | /* dirsync only applies to directories */ | 713 | /* dirsync only applies to directories */ |
| @@ -745,12 +750,15 @@ got: | |||
| 745 | goto fail_free_drop; | 750 | goto fail_free_drop; |
| 746 | } | 751 | } |
| 747 | if (test_opt(sb, EXTENTS)) { | 752 | if (test_opt(sb, EXTENTS)) { |
| 748 | EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL; | 753 | /* set extent flag only for directory and file */ |
| 749 | ext4_ext_tree_init(handle, inode); | 754 | if (S_ISDIR(mode) || S_ISREG(mode)) { |
| 750 | err = ext4_update_incompat_feature(handle, sb, | 755 | EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL; |
| 751 | EXT4_FEATURE_INCOMPAT_EXTENTS); | 756 | ext4_ext_tree_init(handle, inode); |
| 752 | if (err) | 757 | err = ext4_update_incompat_feature(handle, sb, |
| 753 | goto fail; | 758 | EXT4_FEATURE_INCOMPAT_EXTENTS); |
| 759 | if (err) | ||
| 760 | goto fail; | ||
| 761 | } | ||
| 754 | } | 762 | } |
| 755 | 763 | ||
| 756 | ext4_debug("allocating inode %lu\n", inode->i_ino); | 764 | ext4_debug("allocating inode %lu\n", inode->i_ino); |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 7dd9b50d5ebc..945cbf6cb1fc 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -403,6 +403,7 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind) | |||
| 403 | __le32 *start = ind->bh ? (__le32*) ind->bh->b_data : ei->i_data; | 403 | __le32 *start = ind->bh ? (__le32*) ind->bh->b_data : ei->i_data; |
| 404 | __le32 *p; | 404 | __le32 *p; |
| 405 | ext4_fsblk_t bg_start; | 405 | ext4_fsblk_t bg_start; |
| 406 | ext4_fsblk_t last_block; | ||
| 406 | ext4_grpblk_t colour; | 407 | ext4_grpblk_t colour; |
| 407 | 408 | ||
| 408 | /* Try to find previous block */ | 409 | /* Try to find previous block */ |
| @@ -420,8 +421,13 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind) | |||
| 420 | * into the same cylinder group then. | 421 | * into the same cylinder group then. |
| 421 | */ | 422 | */ |
| 422 | bg_start = ext4_group_first_block_no(inode->i_sb, ei->i_block_group); | 423 | bg_start = ext4_group_first_block_no(inode->i_sb, ei->i_block_group); |
| 423 | colour = (current->pid % 16) * | 424 | last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1; |
| 425 | |||
| 426 | if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block) | ||
| 427 | colour = (current->pid % 16) * | ||
| 424 | (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); | 428 | (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); |
| 429 | else | ||
| 430 | colour = (current->pid % 16) * ((last_block - bg_start) / 16); | ||
| 425 | return bg_start + colour; | 431 | return bg_start + colour; |
| 426 | } | 432 | } |
| 427 | 433 | ||
| @@ -768,7 +774,6 @@ err_out: | |||
| 768 | * | 774 | * |
| 769 | * `handle' can be NULL if create == 0. | 775 | * `handle' can be NULL if create == 0. |
| 770 | * | 776 | * |
| 771 | * The BKL may not be held on entry here. Be sure to take it early. | ||
| 772 | * return > 0, # of blocks mapped or allocated. | 777 | * return > 0, # of blocks mapped or allocated. |
| 773 | * return = 0, if plain lookup failed. | 778 | * return = 0, if plain lookup failed. |
| 774 | * return < 0, error case. | 779 | * return < 0, error case. |
| @@ -903,11 +908,38 @@ out: | |||
| 903 | */ | 908 | */ |
| 904 | #define DIO_CREDITS 25 | 909 | #define DIO_CREDITS 25 |
| 905 | 910 | ||
| 911 | |||
| 912 | /* | ||
| 913 | * | ||
| 914 | * | ||
| 915 | * ext4_ext4 get_block() wrapper function | ||
| 916 | * It will do a look up first, and returns if the blocks already mapped. | ||
| 917 | * Otherwise it takes the write lock of the i_data_sem and allocate blocks | ||
| 918 | * and store the allocated blocks in the result buffer head and mark it | ||
| 919 | * mapped. | ||
| 920 | * | ||
| 921 | * If file type is extents based, it will call ext4_ext_get_blocks(), | ||
| 922 | * Otherwise, call with ext4_get_blocks_handle() to handle indirect mapping | ||
| 923 | * based files | ||
| 924 | * | ||
| 925 | * On success, it returns the number of blocks being mapped or allocate. | ||
| 926 | * if create==0 and the blocks are pre-allocated and uninitialized block, | ||
| 927 | * the result buffer head is unmapped. If the create ==1, it will make sure | ||
| 928 | * the buffer head is mapped. | ||
| 929 | * | ||
| 930 | * It returns 0 if plain look up failed (blocks have not been allocated), in | ||
| 931 | * that casem, buffer head is unmapped | ||
| 932 | * | ||
| 933 | * It returns the error in case of allocation failure. | ||
| 934 | */ | ||
| 906 | int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, | 935 | int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, |
| 907 | unsigned long max_blocks, struct buffer_head *bh, | 936 | unsigned long max_blocks, struct buffer_head *bh, |
| 908 | int create, int extend_disksize) | 937 | int create, int extend_disksize) |
| 909 | { | 938 | { |
| 910 | int retval; | 939 | int retval; |
| 940 | |||
| 941 | clear_buffer_mapped(bh); | ||
| 942 | |||
| 911 | /* | 943 | /* |
| 912 | * Try to see if we can get the block without requesting | 944 | * Try to see if we can get the block without requesting |
| 913 | * for new file system block. | 945 | * for new file system block. |
| @@ -921,12 +953,26 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, | |||
| 921 | inode, block, max_blocks, bh, 0, 0); | 953 | inode, block, max_blocks, bh, 0, 0); |
| 922 | } | 954 | } |
| 923 | up_read((&EXT4_I(inode)->i_data_sem)); | 955 | up_read((&EXT4_I(inode)->i_data_sem)); |
| 924 | if (!create || (retval > 0)) | 956 | |
| 957 | /* If it is only a block(s) look up */ | ||
| 958 | if (!create) | ||
| 959 | return retval; | ||
| 960 | |||
| 961 | /* | ||
| 962 | * Returns if the blocks have already allocated | ||
| 963 | * | ||
| 964 | * Note that if blocks have been preallocated | ||
| 965 | * ext4_ext_get_block() returns th create = 0 | ||
| 966 | * with buffer head unmapped. | ||
| 967 | */ | ||
| 968 | if (retval > 0 && buffer_mapped(bh)) | ||
| 925 | return retval; | 969 | return retval; |
| 926 | 970 | ||
| 927 | /* | 971 | /* |
| 928 | * We need to allocate new blocks which will result | 972 | * New blocks allocate and/or writing to uninitialized extent |
| 929 | * in i_data update | 973 | * will possibly result in updating i_data, so we take |
| 974 | * the write lock of i_data_sem, and call get_blocks() | ||
| 975 | * with create == 1 flag. | ||
| 930 | */ | 976 | */ |
| 931 | down_write((&EXT4_I(inode)->i_data_sem)); | 977 | down_write((&EXT4_I(inode)->i_data_sem)); |
| 932 | /* | 978 | /* |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index dd0fcfcb35ce..ef97f19c2f9d 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
| @@ -627,21 +627,19 @@ static ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb, | |||
| 627 | return block; | 627 | return block; |
| 628 | } | 628 | } |
| 629 | 629 | ||
| 630 | static inline void *mb_correct_addr_and_bit(int *bit, void *addr) | ||
| 631 | { | ||
| 630 | #if BITS_PER_LONG == 64 | 632 | #if BITS_PER_LONG == 64 |
| 631 | #define mb_correct_addr_and_bit(bit, addr) \ | 633 | *bit += ((unsigned long) addr & 7UL) << 3; |
| 632 | { \ | 634 | addr = (void *) ((unsigned long) addr & ~7UL); |
| 633 | bit += ((unsigned long) addr & 7UL) << 3; \ | ||
| 634 | addr = (void *) ((unsigned long) addr & ~7UL); \ | ||
| 635 | } | ||
| 636 | #elif BITS_PER_LONG == 32 | 635 | #elif BITS_PER_LONG == 32 |
| 637 | #define mb_correct_addr_and_bit(bit, addr) \ | 636 | *bit += ((unsigned long) addr & 3UL) << 3; |
| 638 | { \ | 637 | addr = (void *) ((unsigned long) addr & ~3UL); |
| 639 | bit += ((unsigned long) addr & 3UL) << 3; \ | ||
| 640 | addr = (void *) ((unsigned long) addr & ~3UL); \ | ||
| 641 | } | ||
| 642 | #else | 638 | #else |
| 643 | #error "how many bits you are?!" | 639 | #error "how many bits you are?!" |
| 644 | #endif | 640 | #endif |
| 641 | return addr; | ||
| 642 | } | ||
| 645 | 643 | ||
| 646 | static inline int mb_test_bit(int bit, void *addr) | 644 | static inline int mb_test_bit(int bit, void *addr) |
| 647 | { | 645 | { |
| @@ -649,34 +647,54 @@ static inline int mb_test_bit(int bit, void *addr) | |||
| 649 | * ext4_test_bit on architecture like powerpc | 647 | * ext4_test_bit on architecture like powerpc |
| 650 | * needs unsigned long aligned address | 648 | * needs unsigned long aligned address |
| 651 | */ | 649 | */ |
| 652 | mb_correct_addr_and_bit(bit, addr); | 650 | addr = mb_correct_addr_and_bit(&bit, addr); |
| 653 | return ext4_test_bit(bit, addr); | 651 | return ext4_test_bit(bit, addr); |
| 654 | } | 652 | } |
| 655 | 653 | ||
| 656 | static inline void mb_set_bit(int bit, void *addr) | 654 | static inline void mb_set_bit(int bit, void *addr) |
| 657 | { | 655 | { |
| 658 | mb_correct_addr_and_bit(bit, addr); | 656 | addr = mb_correct_addr_and_bit(&bit, addr); |
| 659 | ext4_set_bit(bit, addr); | 657 | ext4_set_bit(bit, addr); |
| 660 | } | 658 | } |
| 661 | 659 | ||
| 662 | static inline void mb_set_bit_atomic(spinlock_t *lock, int bit, void *addr) | 660 | static inline void mb_set_bit_atomic(spinlock_t *lock, int bit, void *addr) |
| 663 | { | 661 | { |
| 664 | mb_correct_addr_and_bit(bit, addr); | 662 | addr = mb_correct_addr_and_bit(&bit, addr); |
| 665 | ext4_set_bit_atomic(lock, bit, addr); | 663 | ext4_set_bit_atomic(lock, bit, addr); |
| 666 | } | 664 | } |
| 667 | 665 | ||
| 668 | static inline void mb_clear_bit(int bit, void *addr) | 666 | static inline void mb_clear_bit(int bit, void *addr) |
| 669 | { | 667 | { |
| 670 | mb_correct_addr_and_bit(bit, addr); | 668 | addr = mb_correct_addr_and_bit(&bit, addr); |
| 671 | ext4_clear_bit(bit, addr); | 669 | ext4_clear_bit(bit, addr); |
| 672 | } | 670 | } |
| 673 | 671 | ||
| 674 | static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr) | 672 | static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr) |
| 675 | { | 673 | { |
| 676 | mb_correct_addr_and_bit(bit, addr); | 674 | addr = mb_correct_addr_and_bit(&bit, addr); |
| 677 | ext4_clear_bit_atomic(lock, bit, addr); | 675 | ext4_clear_bit_atomic(lock, bit, addr); |
| 678 | } | 676 | } |
| 679 | 677 | ||
| 678 | static inline int mb_find_next_zero_bit(void *addr, int max, int start) | ||
| 679 | { | ||
| 680 | int fix = 0; | ||
| 681 | addr = mb_correct_addr_and_bit(&fix, addr); | ||
| 682 | max += fix; | ||
| 683 | start += fix; | ||
| 684 | |||
| 685 | return ext4_find_next_zero_bit(addr, max, start) - fix; | ||
| 686 | } | ||
| 687 | |||
| 688 | static inline int mb_find_next_bit(void *addr, int max, int start) | ||
| 689 | { | ||
| 690 | int fix = 0; | ||
| 691 | addr = mb_correct_addr_and_bit(&fix, addr); | ||
| 692 | max += fix; | ||
| 693 | start += fix; | ||
| 694 | |||
| 695 | return ext4_find_next_bit(addr, max, start) - fix; | ||
| 696 | } | ||
| 697 | |||
| 680 | static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max) | 698 | static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max) |
| 681 | { | 699 | { |
| 682 | char *bb; | 700 | char *bb; |
| @@ -906,7 +924,7 @@ static void ext4_mb_mark_free_simple(struct super_block *sb, | |||
| 906 | unsigned short chunk; | 924 | unsigned short chunk; |
| 907 | unsigned short border; | 925 | unsigned short border; |
| 908 | 926 | ||
| 909 | BUG_ON(len >= EXT4_BLOCKS_PER_GROUP(sb)); | 927 | BUG_ON(len > EXT4_BLOCKS_PER_GROUP(sb)); |
| 910 | 928 | ||
| 911 | border = 2 << sb->s_blocksize_bits; | 929 | border = 2 << sb->s_blocksize_bits; |
| 912 | 930 | ||
| @@ -946,12 +964,12 @@ static void ext4_mb_generate_buddy(struct super_block *sb, | |||
| 946 | 964 | ||
| 947 | /* initialize buddy from bitmap which is aggregation | 965 | /* initialize buddy from bitmap which is aggregation |
| 948 | * of on-disk bitmap and preallocations */ | 966 | * of on-disk bitmap and preallocations */ |
| 949 | i = ext4_find_next_zero_bit(bitmap, max, 0); | 967 | i = mb_find_next_zero_bit(bitmap, max, 0); |
| 950 | grp->bb_first_free = i; | 968 | grp->bb_first_free = i; |
| 951 | while (i < max) { | 969 | while (i < max) { |
| 952 | fragments++; | 970 | fragments++; |
| 953 | first = i; | 971 | first = i; |
| 954 | i = ext4_find_next_bit(bitmap, max, i); | 972 | i = mb_find_next_bit(bitmap, max, i); |
| 955 | len = i - first; | 973 | len = i - first; |
| 956 | free += len; | 974 | free += len; |
| 957 | if (len > 1) | 975 | if (len > 1) |
| @@ -959,7 +977,7 @@ static void ext4_mb_generate_buddy(struct super_block *sb, | |||
| 959 | else | 977 | else |
| 960 | grp->bb_counters[0]++; | 978 | grp->bb_counters[0]++; |
| 961 | if (i < max) | 979 | if (i < max) |
| 962 | i = ext4_find_next_zero_bit(bitmap, max, i); | 980 | i = mb_find_next_zero_bit(bitmap, max, i); |
| 963 | } | 981 | } |
| 964 | grp->bb_fragments = fragments; | 982 | grp->bb_fragments = fragments; |
| 965 | 983 | ||
| @@ -967,6 +985,10 @@ static void ext4_mb_generate_buddy(struct super_block *sb, | |||
| 967 | ext4_error(sb, __FUNCTION__, | 985 | ext4_error(sb, __FUNCTION__, |
| 968 | "EXT4-fs: group %lu: %u blocks in bitmap, %u in gd\n", | 986 | "EXT4-fs: group %lu: %u blocks in bitmap, %u in gd\n", |
| 969 | group, free, grp->bb_free); | 987 | group, free, grp->bb_free); |
| 988 | /* | ||
| 989 | * If we intent to continue, we consider group descritor | ||
| 990 | * corrupt and update bb_free using bitmap value | ||
| 991 | */ | ||
| 970 | grp->bb_free = free; | 992 | grp->bb_free = free; |
| 971 | } | 993 | } |
| 972 | 994 | ||
| @@ -1778,7 +1800,7 @@ static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, | |||
| 1778 | buddy = mb_find_buddy(e4b, i, &max); | 1800 | buddy = mb_find_buddy(e4b, i, &max); |
| 1779 | BUG_ON(buddy == NULL); | 1801 | BUG_ON(buddy == NULL); |
| 1780 | 1802 | ||
| 1781 | k = ext4_find_next_zero_bit(buddy, max, 0); | 1803 | k = mb_find_next_zero_bit(buddy, max, 0); |
| 1782 | BUG_ON(k >= max); | 1804 | BUG_ON(k >= max); |
| 1783 | 1805 | ||
| 1784 | ac->ac_found++; | 1806 | ac->ac_found++; |
| @@ -1818,11 +1840,11 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, | |||
| 1818 | i = e4b->bd_info->bb_first_free; | 1840 | i = e4b->bd_info->bb_first_free; |
| 1819 | 1841 | ||
| 1820 | while (free && ac->ac_status == AC_STATUS_CONTINUE) { | 1842 | while (free && ac->ac_status == AC_STATUS_CONTINUE) { |
| 1821 | i = ext4_find_next_zero_bit(bitmap, | 1843 | i = mb_find_next_zero_bit(bitmap, |
| 1822 | EXT4_BLOCKS_PER_GROUP(sb), i); | 1844 | EXT4_BLOCKS_PER_GROUP(sb), i); |
| 1823 | if (i >= EXT4_BLOCKS_PER_GROUP(sb)) { | 1845 | if (i >= EXT4_BLOCKS_PER_GROUP(sb)) { |
| 1824 | /* | 1846 | /* |
| 1825 | * IF we corrupt the bitmap we won't find any | 1847 | * IF we have corrupt bitmap, we won't find any |
| 1826 | * free blocks even though group info says we | 1848 | * free blocks even though group info says we |
| 1827 | * we have free blocks | 1849 | * we have free blocks |
| 1828 | */ | 1850 | */ |
| @@ -1838,6 +1860,12 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, | |||
| 1838 | ext4_error(sb, __FUNCTION__, "%d free blocks as per " | 1860 | ext4_error(sb, __FUNCTION__, "%d free blocks as per " |
| 1839 | "group info. But got %d blocks\n", | 1861 | "group info. But got %d blocks\n", |
| 1840 | free, ex.fe_len); | 1862 | free, ex.fe_len); |
| 1863 | /* | ||
| 1864 | * The number of free blocks differs. This mostly | ||
| 1865 | * indicate that the bitmap is corrupt. So exit | ||
| 1866 | * without claiming the space. | ||
| 1867 | */ | ||
| 1868 | break; | ||
| 1841 | } | 1869 | } |
| 1842 | 1870 | ||
| 1843 | ext4_mb_measure_extent(ac, &ex, e4b); | 1871 | ext4_mb_measure_extent(ac, &ex, e4b); |
| @@ -3740,10 +3768,10 @@ static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b, | |||
| 3740 | } | 3768 | } |
| 3741 | 3769 | ||
| 3742 | while (bit < end) { | 3770 | while (bit < end) { |
| 3743 | bit = ext4_find_next_zero_bit(bitmap_bh->b_data, end, bit); | 3771 | bit = mb_find_next_zero_bit(bitmap_bh->b_data, end, bit); |
| 3744 | if (bit >= end) | 3772 | if (bit >= end) |
| 3745 | break; | 3773 | break; |
| 3746 | next = ext4_find_next_bit(bitmap_bh->b_data, end, bit); | 3774 | next = mb_find_next_bit(bitmap_bh->b_data, end, bit); |
| 3747 | if (next > end) | 3775 | if (next > end) |
| 3748 | next = end; | 3776 | next = end; |
| 3749 | start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit + | 3777 | start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit + |
| @@ -3771,6 +3799,10 @@ static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b, | |||
| 3771 | (unsigned long) pa->pa_len); | 3799 | (unsigned long) pa->pa_len); |
| 3772 | ext4_error(sb, __FUNCTION__, "free %u, pa_free %u\n", | 3800 | ext4_error(sb, __FUNCTION__, "free %u, pa_free %u\n", |
| 3773 | free, pa->pa_free); | 3801 | free, pa->pa_free); |
| 3802 | /* | ||
| 3803 | * pa is already deleted so we use the value obtained | ||
| 3804 | * from the bitmap and continue. | ||
| 3805 | */ | ||
| 3774 | } | 3806 | } |
| 3775 | atomic_add(free, &sbi->s_mb_discarded); | 3807 | atomic_add(free, &sbi->s_mb_discarded); |
| 3776 | if (ac) | 3808 | if (ac) |
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index 8c6c685b9d22..5c1e27de7755 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c | |||
| @@ -43,6 +43,7 @@ static int finish_range(handle_t *handle, struct inode *inode, | |||
| 43 | 43 | ||
| 44 | if (IS_ERR(path)) { | 44 | if (IS_ERR(path)) { |
| 45 | retval = PTR_ERR(path); | 45 | retval = PTR_ERR(path); |
| 46 | path = NULL; | ||
| 46 | goto err_out; | 47 | goto err_out; |
| 47 | } | 48 | } |
| 48 | 49 | ||
| @@ -74,6 +75,10 @@ static int finish_range(handle_t *handle, struct inode *inode, | |||
| 74 | } | 75 | } |
| 75 | retval = ext4_ext_insert_extent(handle, inode, path, &newext); | 76 | retval = ext4_ext_insert_extent(handle, inode, path, &newext); |
| 76 | err_out: | 77 | err_out: |
| 78 | if (path) { | ||
| 79 | ext4_ext_drop_refs(path); | ||
| 80 | kfree(path); | ||
| 81 | } | ||
| 77 | lb->first_pblock = 0; | 82 | lb->first_pblock = 0; |
| 78 | return retval; | 83 | return retval; |
| 79 | } | 84 | } |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index a9347fb43bcc..28aa2ed4297e 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
| @@ -1804,12 +1804,8 @@ retry: | |||
| 1804 | inode->i_fop = &ext4_dir_operations; | 1804 | inode->i_fop = &ext4_dir_operations; |
| 1805 | inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize; | 1805 | inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize; |
| 1806 | dir_block = ext4_bread (handle, inode, 0, 1, &err); | 1806 | dir_block = ext4_bread (handle, inode, 0, 1, &err); |
| 1807 | if (!dir_block) { | 1807 | if (!dir_block) |
| 1808 | ext4_dec_count(handle, inode); /* is this nlink == 0? */ | 1808 | goto out_clear_inode; |
| 1809 | ext4_mark_inode_dirty(handle, inode); | ||
| 1810 | iput (inode); | ||
| 1811 | goto out_stop; | ||
| 1812 | } | ||
| 1813 | BUFFER_TRACE(dir_block, "get_write_access"); | 1809 | BUFFER_TRACE(dir_block, "get_write_access"); |
| 1814 | ext4_journal_get_write_access(handle, dir_block); | 1810 | ext4_journal_get_write_access(handle, dir_block); |
| 1815 | de = (struct ext4_dir_entry_2 *) dir_block->b_data; | 1811 | de = (struct ext4_dir_entry_2 *) dir_block->b_data; |
| @@ -1832,7 +1828,8 @@ retry: | |||
| 1832 | ext4_mark_inode_dirty(handle, inode); | 1828 | ext4_mark_inode_dirty(handle, inode); |
| 1833 | err = ext4_add_entry (handle, dentry, inode); | 1829 | err = ext4_add_entry (handle, dentry, inode); |
| 1834 | if (err) { | 1830 | if (err) { |
| 1835 | inode->i_nlink = 0; | 1831 | out_clear_inode: |
| 1832 | clear_nlink(inode); | ||
| 1836 | ext4_mark_inode_dirty(handle, inode); | 1833 | ext4_mark_inode_dirty(handle, inode); |
| 1837 | iput (inode); | 1834 | iput (inode); |
| 1838 | goto out_stop; | 1835 | goto out_stop; |
| @@ -2164,7 +2161,7 @@ static int ext4_unlink(struct inode * dir, struct dentry *dentry) | |||
| 2164 | dir->i_ctime = dir->i_mtime = ext4_current_time(dir); | 2161 | dir->i_ctime = dir->i_mtime = ext4_current_time(dir); |
| 2165 | ext4_update_dx_flag(dir); | 2162 | ext4_update_dx_flag(dir); |
| 2166 | ext4_mark_inode_dirty(handle, dir); | 2163 | ext4_mark_inode_dirty(handle, dir); |
| 2167 | ext4_dec_count(handle, inode); | 2164 | drop_nlink(inode); |
| 2168 | if (!inode->i_nlink) | 2165 | if (!inode->i_nlink) |
| 2169 | ext4_orphan_add(handle, inode); | 2166 | ext4_orphan_add(handle, inode); |
| 2170 | inode->i_ctime = ext4_current_time(inode); | 2167 | inode->i_ctime = ext4_current_time(inode); |
| @@ -2214,7 +2211,7 @@ retry: | |||
| 2214 | err = __page_symlink(inode, symname, l, | 2211 | err = __page_symlink(inode, symname, l, |
| 2215 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | 2212 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); |
| 2216 | if (err) { | 2213 | if (err) { |
| 2217 | ext4_dec_count(handle, inode); | 2214 | clear_nlink(inode); |
| 2218 | ext4_mark_inode_dirty(handle, inode); | 2215 | ext4_mark_inode_dirty(handle, inode); |
| 2219 | iput (inode); | 2216 | iput (inode); |
| 2220 | goto out_stop; | 2217 | goto out_stop; |
| @@ -2223,7 +2220,6 @@ retry: | |||
| 2223 | inode->i_op = &ext4_fast_symlink_inode_operations; | 2220 | inode->i_op = &ext4_fast_symlink_inode_operations; |
| 2224 | memcpy((char*)&EXT4_I(inode)->i_data,symname,l); | 2221 | memcpy((char*)&EXT4_I(inode)->i_data,symname,l); |
| 2225 | inode->i_size = l-1; | 2222 | inode->i_size = l-1; |
| 2226 | EXT4_I(inode)->i_flags &= ~EXT4_EXTENTS_FL; | ||
| 2227 | } | 2223 | } |
| 2228 | EXT4_I(inode)->i_disksize = inode->i_size; | 2224 | EXT4_I(inode)->i_disksize = inode->i_size; |
| 2229 | err = ext4_add_nondir(handle, dentry, inode); | 2225 | err = ext4_add_nondir(handle, dentry, inode); |
| @@ -2407,7 +2403,7 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry, | |||
| 2407 | ext4_dec_count(handle, old_dir); | 2403 | ext4_dec_count(handle, old_dir); |
| 2408 | if (new_inode) { | 2404 | if (new_inode) { |
| 2409 | /* checked empty_dir above, can't have another parent, | 2405 | /* checked empty_dir above, can't have another parent, |
| 2410 | * ext3_dec_count() won't work for many-linked dirs */ | 2406 | * ext4_dec_count() won't work for many-linked dirs */ |
| 2411 | new_inode->i_nlink = 0; | 2407 | new_inode->i_nlink = 0; |
| 2412 | } else { | 2408 | } else { |
| 2413 | ext4_inc_count(handle, new_dir); | 2409 | ext4_inc_count(handle, new_dir); |
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 9477a2bd6ff2..e29efa0f9d62 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
| @@ -1037,6 +1037,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
| 1037 | ext4_warning(sb, __FUNCTION__, | 1037 | ext4_warning(sb, __FUNCTION__, |
| 1038 | "multiple resizers run on filesystem!"); | 1038 | "multiple resizers run on filesystem!"); |
| 1039 | unlock_super(sb); | 1039 | unlock_super(sb); |
| 1040 | ext4_journal_stop(handle); | ||
| 1040 | err = -EBUSY; | 1041 | err = -EBUSY; |
| 1041 | goto exit_put; | 1042 | goto exit_put; |
| 1042 | } | 1043 | } |
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index d7962139c010..e9054c1c7d93 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
| @@ -1386,7 +1386,7 @@ ext4_xattr_cache_insert(struct buffer_head *bh) | |||
| 1386 | struct mb_cache_entry *ce; | 1386 | struct mb_cache_entry *ce; |
| 1387 | int error; | 1387 | int error; |
| 1388 | 1388 | ||
| 1389 | ce = mb_cache_entry_alloc(ext4_xattr_cache); | 1389 | ce = mb_cache_entry_alloc(ext4_xattr_cache, GFP_NOFS); |
| 1390 | if (!ce) { | 1390 | if (!ce) { |
| 1391 | ea_bdebug(bh, "out of memory"); | 1391 | ea_bdebug(bh, "out of memory"); |
| 1392 | return; | 1392 | return; |
diff --git a/fs/file_table.c b/fs/file_table.c index 6d27befe2d48..986ff4ed0a7c 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
| @@ -83,6 +83,12 @@ int proc_nr_files(ctl_table *table, int write, struct file *filp, | |||
| 83 | /* Find an unused file structure and return a pointer to it. | 83 | /* Find an unused file structure and return a pointer to it. |
| 84 | * Returns NULL, if there are no more free file structures or | 84 | * Returns NULL, if there are no more free file structures or |
| 85 | * we run out of memory. | 85 | * we run out of memory. |
| 86 | * | ||
| 87 | * Be very careful using this. You are responsible for | ||
| 88 | * getting write access to any mount that you might assign | ||
| 89 | * to this filp, if it is opened for write. If this is not | ||
| 90 | * done, you will imbalance int the mount's writer count | ||
| 91 | * and a warning at __fput() time. | ||
| 86 | */ | 92 | */ |
| 87 | struct file *get_empty_filp(void) | 93 | struct file *get_empty_filp(void) |
| 88 | { | 94 | { |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index c0076077d338..06557679ca41 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
| @@ -751,7 +751,7 @@ int generic_osync_inode(struct inode *inode, struct address_space *mapping, int | |||
| 751 | EXPORT_SYMBOL(generic_osync_inode); | 751 | EXPORT_SYMBOL(generic_osync_inode); |
| 752 | 752 | ||
| 753 | /** | 753 | /** |
| 754 | * writeback_acquire: attempt to get exclusive writeback access to a device | 754 | * writeback_acquire - attempt to get exclusive writeback access to a device |
| 755 | * @bdi: the device's backing_dev_info structure | 755 | * @bdi: the device's backing_dev_info structure |
| 756 | * | 756 | * |
| 757 | * It is a waste of resources to have more than one pdflush thread blocked on | 757 | * It is a waste of resources to have more than one pdflush thread blocked on |
| @@ -768,7 +768,7 @@ int writeback_acquire(struct backing_dev_info *bdi) | |||
| 768 | } | 768 | } |
| 769 | 769 | ||
| 770 | /** | 770 | /** |
| 771 | * writeback_in_progress: determine whether there is writeback in progress | 771 | * writeback_in_progress - determine whether there is writeback in progress |
| 772 | * @bdi: the device's backing_dev_info structure. | 772 | * @bdi: the device's backing_dev_info structure. |
| 773 | * | 773 | * |
| 774 | * Determine whether there is writeback in progress against a backing device. | 774 | * Determine whether there is writeback in progress against a backing device. |
| @@ -779,7 +779,7 @@ int writeback_in_progress(struct backing_dev_info *bdi) | |||
| 779 | } | 779 | } |
| 780 | 780 | ||
| 781 | /** | 781 | /** |
| 782 | * writeback_release: relinquish exclusive writeback access against a device. | 782 | * writeback_release - relinquish exclusive writeback access against a device. |
| 783 | * @bdi: the device's backing_dev_info structure | 783 | * @bdi: the device's backing_dev_info structure |
| 784 | */ | 784 | */ |
| 785 | void writeback_release(struct backing_dev_info *bdi) | 785 | void writeback_release(struct backing_dev_info *bdi) |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 7fb514b6d852..c4807b3fc8a3 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
| @@ -906,7 +906,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
| 906 | } | 906 | } |
| 907 | 907 | ||
| 908 | if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { | 908 | if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { |
| 909 | int err = generic_permission(inode, mask, NULL); | 909 | err = generic_permission(inode, mask, NULL); |
| 910 | 910 | ||
| 911 | /* If permission is denied, try to refresh file | 911 | /* If permission is denied, try to refresh file |
| 912 | attributes. This is also needed, because the root | 912 | attributes. This is also needed, because the root |
diff --git a/fs/hfs/brec.c b/fs/hfs/brec.c index 878bf25dbc6a..92fb358ce824 100644 --- a/fs/hfs/brec.c +++ b/fs/hfs/brec.c | |||
| @@ -229,7 +229,7 @@ skip: | |||
| 229 | static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) | 229 | static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) |
| 230 | { | 230 | { |
| 231 | struct hfs_btree *tree; | 231 | struct hfs_btree *tree; |
| 232 | struct hfs_bnode *node, *new_node; | 232 | struct hfs_bnode *node, *new_node, *next_node; |
| 233 | struct hfs_bnode_desc node_desc; | 233 | struct hfs_bnode_desc node_desc; |
| 234 | int num_recs, new_rec_off, new_off, old_rec_off; | 234 | int num_recs, new_rec_off, new_off, old_rec_off; |
| 235 | int data_start, data_end, size; | 235 | int data_start, data_end, size; |
| @@ -248,6 +248,17 @@ static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) | |||
| 248 | new_node->type = node->type; | 248 | new_node->type = node->type; |
| 249 | new_node->height = node->height; | 249 | new_node->height = node->height; |
| 250 | 250 | ||
| 251 | if (node->next) | ||
| 252 | next_node = hfs_bnode_find(tree, node->next); | ||
| 253 | else | ||
| 254 | next_node = NULL; | ||
| 255 | |||
| 256 | if (IS_ERR(next_node)) { | ||
| 257 | hfs_bnode_put(node); | ||
| 258 | hfs_bnode_put(new_node); | ||
| 259 | return next_node; | ||
| 260 | } | ||
| 261 | |||
| 251 | size = tree->node_size / 2 - node->num_recs * 2 - 14; | 262 | size = tree->node_size / 2 - node->num_recs * 2 - 14; |
| 252 | old_rec_off = tree->node_size - 4; | 263 | old_rec_off = tree->node_size - 4; |
| 253 | num_recs = 1; | 264 | num_recs = 1; |
| @@ -261,6 +272,8 @@ static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) | |||
| 261 | /* panic? */ | 272 | /* panic? */ |
| 262 | hfs_bnode_put(node); | 273 | hfs_bnode_put(node); |
| 263 | hfs_bnode_put(new_node); | 274 | hfs_bnode_put(new_node); |
| 275 | if (next_node) | ||
| 276 | hfs_bnode_put(next_node); | ||
| 264 | return ERR_PTR(-ENOSPC); | 277 | return ERR_PTR(-ENOSPC); |
| 265 | } | 278 | } |
| 266 | 279 | ||
| @@ -315,8 +328,7 @@ static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) | |||
| 315 | hfs_bnode_write(node, &node_desc, 0, sizeof(node_desc)); | 328 | hfs_bnode_write(node, &node_desc, 0, sizeof(node_desc)); |
| 316 | 329 | ||
| 317 | /* update next bnode header */ | 330 | /* update next bnode header */ |
| 318 | if (new_node->next) { | 331 | if (next_node) { |
| 319 | struct hfs_bnode *next_node = hfs_bnode_find(tree, new_node->next); | ||
| 320 | next_node->prev = new_node->this; | 332 | next_node->prev = new_node->this; |
| 321 | hfs_bnode_read(next_node, &node_desc, 0, sizeof(node_desc)); | 333 | hfs_bnode_read(next_node, &node_desc, 0, sizeof(node_desc)); |
| 322 | node_desc.prev = cpu_to_be32(next_node->prev); | 334 | node_desc.prev = cpu_to_be32(next_node->prev); |
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 29683645fa0a..5f4023678251 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
| @@ -340,16 +340,23 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) | |||
| 340 | 340 | ||
| 341 | if (inode->i_nlink > 0) | 341 | if (inode->i_nlink > 0) |
| 342 | drop_nlink(inode); | 342 | drop_nlink(inode); |
| 343 | hfsplus_delete_inode(inode); | 343 | if (inode->i_ino == cnid) |
| 344 | if (inode->i_ino != cnid && !inode->i_nlink) { | 344 | clear_nlink(inode); |
| 345 | if (!atomic_read(&HFSPLUS_I(inode).opencnt)) { | 345 | if (!inode->i_nlink) { |
| 346 | res = hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL); | 346 | if (inode->i_ino != cnid) { |
| 347 | if (!res) | 347 | HFSPLUS_SB(sb).file_count--; |
| 348 | hfsplus_delete_inode(inode); | 348 | if (!atomic_read(&HFSPLUS_I(inode).opencnt)) { |
| 349 | res = hfsplus_delete_cat(inode->i_ino, | ||
| 350 | HFSPLUS_SB(sb).hidden_dir, | ||
| 351 | NULL); | ||
| 352 | if (!res) | ||
| 353 | hfsplus_delete_inode(inode); | ||
| 354 | } else | ||
| 355 | inode->i_flags |= S_DEAD; | ||
| 349 | } else | 356 | } else |
| 350 | inode->i_flags |= S_DEAD; | 357 | hfsplus_delete_inode(inode); |
| 351 | } else | 358 | } else |
| 352 | clear_nlink(inode); | 359 | HFSPLUS_SB(sb).file_count--; |
| 353 | inode->i_ctime = CURRENT_TIME_SEC; | 360 | inode->i_ctime = CURRENT_TIME_SEC; |
| 354 | mark_inode_dirty(inode); | 361 | mark_inode_dirty(inode); |
| 355 | 362 | ||
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c index a1e1f0f61aa5..8601d8ef3b55 100644 --- a/fs/hppfs/hppfs_kern.c +++ b/fs/hppfs/hppfs_kern.c | |||
| @@ -1,23 +1,24 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
| 3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <linux/fs.h> | 6 | #include <linux/ctype.h> |
| 7 | #include <linux/dcache.h> | ||
| 7 | #include <linux/file.h> | 8 | #include <linux/file.h> |
| 8 | #include <linux/module.h> | 9 | #include <linux/fs.h> |
| 9 | #include <linux/init.h> | 10 | #include <linux/init.h> |
| 10 | #include <linux/slab.h> | ||
| 11 | #include <linux/list.h> | ||
| 12 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 13 | #include <linux/ctype.h> | 12 | #include <linux/list.h> |
| 14 | #include <linux/dcache.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/mount.h> | ||
| 15 | #include <linux/slab.h> | ||
| 15 | #include <linux/statfs.h> | 16 | #include <linux/statfs.h> |
| 17 | #include <linux/types.h> | ||
| 16 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
| 17 | #include <asm/fcntl.h> | ||
| 18 | #include "os.h" | 19 | #include "os.h" |
| 19 | 20 | ||
| 20 | static int init_inode(struct inode *inode, struct dentry *dentry); | 21 | static struct inode *get_inode(struct super_block *, struct dentry *); |
| 21 | 22 | ||
| 22 | struct hppfs_data { | 23 | struct hppfs_data { |
| 23 | struct list_head list; | 24 | struct list_head list; |
| @@ -51,14 +52,14 @@ static int is_pid(struct dentry *dentry) | |||
| 51 | int i; | 52 | int i; |
| 52 | 53 | ||
| 53 | sb = dentry->d_sb; | 54 | sb = dentry->d_sb; |
| 54 | if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root)) | 55 | if ((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root)) |
| 55 | return(0); | 56 | return 0; |
| 56 | 57 | ||
| 57 | for(i = 0; i < dentry->d_name.len; i++){ | 58 | for (i = 0; i < dentry->d_name.len; i++) { |
| 58 | if(!isdigit(dentry->d_name.name[i])) | 59 | if (!isdigit(dentry->d_name.name[i])) |
| 59 | return(0); | 60 | return 0; |
| 60 | } | 61 | } |
| 61 | return(1); | 62 | return 1; |
| 62 | } | 63 | } |
| 63 | 64 | ||
| 64 | static char *dentry_name(struct dentry *dentry, int extra) | 65 | static char *dentry_name(struct dentry *dentry, int extra) |
| @@ -70,8 +71,8 @@ static char *dentry_name(struct dentry *dentry, int extra) | |||
| 70 | 71 | ||
| 71 | len = 0; | 72 | len = 0; |
| 72 | parent = dentry; | 73 | parent = dentry; |
| 73 | while(parent->d_parent != parent){ | 74 | while (parent->d_parent != parent) { |
| 74 | if(is_pid(parent)) | 75 | if (is_pid(parent)) |
| 75 | len += strlen("pid") + 1; | 76 | len += strlen("pid") + 1; |
| 76 | else len += parent->d_name.len + 1; | 77 | else len += parent->d_name.len + 1; |
| 77 | parent = parent->d_parent; | 78 | parent = parent->d_parent; |
| @@ -80,12 +81,13 @@ static char *dentry_name(struct dentry *dentry, int extra) | |||
| 80 | root = "proc"; | 81 | root = "proc"; |
| 81 | len += strlen(root); | 82 | len += strlen(root); |
| 82 | name = kmalloc(len + extra + 1, GFP_KERNEL); | 83 | name = kmalloc(len + extra + 1, GFP_KERNEL); |
| 83 | if(name == NULL) return(NULL); | 84 | if (name == NULL) |
| 85 | return NULL; | ||
| 84 | 86 | ||
| 85 | name[len] = '\0'; | 87 | name[len] = '\0'; |
| 86 | parent = dentry; | 88 | parent = dentry; |
| 87 | while(parent->d_parent != parent){ | 89 | while (parent->d_parent != parent) { |
| 88 | if(is_pid(parent)){ | 90 | if (is_pid(parent)) { |
| 89 | seg_name = "pid"; | 91 | seg_name = "pid"; |
| 90 | seg_len = strlen("pid"); | 92 | seg_len = strlen("pid"); |
| 91 | } | 93 | } |
| @@ -100,27 +102,25 @@ static char *dentry_name(struct dentry *dentry, int extra) | |||
| 100 | parent = parent->d_parent; | 102 | parent = parent->d_parent; |
| 101 | } | 103 | } |
| 102 | strncpy(name, root, strlen(root)); | 104 | strncpy(name, root, strlen(root)); |
| 103 | return(name); | 105 | return name; |
| 104 | } | 106 | } |
| 105 | 107 | ||
| 106 | struct dentry_operations hppfs_dentry_ops = { | ||
| 107 | }; | ||
| 108 | |||
| 109 | static int file_removed(struct dentry *dentry, const char *file) | 108 | static int file_removed(struct dentry *dentry, const char *file) |
| 110 | { | 109 | { |
| 111 | char *host_file; | 110 | char *host_file; |
| 112 | int extra, fd; | 111 | int extra, fd; |
| 113 | 112 | ||
| 114 | extra = 0; | 113 | extra = 0; |
| 115 | if(file != NULL) extra += strlen(file) + 1; | 114 | if (file != NULL) |
| 115 | extra += strlen(file) + 1; | ||
| 116 | 116 | ||
| 117 | host_file = dentry_name(dentry, extra + strlen("/remove")); | 117 | host_file = dentry_name(dentry, extra + strlen("/remove")); |
| 118 | if(host_file == NULL){ | 118 | if (host_file == NULL) { |
| 119 | printk("file_removed : allocation failed\n"); | 119 | printk(KERN_ERR "file_removed : allocation failed\n"); |
| 120 | return(-ENOMEM); | 120 | return -ENOMEM; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | if(file != NULL){ | 123 | if (file != NULL) { |
| 124 | strcat(host_file, "/"); | 124 | strcat(host_file, "/"); |
| 125 | strcat(host_file, file); | 125 | strcat(host_file, file); |
| 126 | } | 126 | } |
| @@ -128,45 +128,11 @@ static int file_removed(struct dentry *dentry, const char *file) | |||
| 128 | 128 | ||
| 129 | fd = os_open_file(host_file, of_read(OPENFLAGS()), 0); | 129 | fd = os_open_file(host_file, of_read(OPENFLAGS()), 0); |
| 130 | kfree(host_file); | 130 | kfree(host_file); |
| 131 | if(fd > 0){ | 131 | if (fd > 0) { |
| 132 | os_close_file(fd); | 132 | os_close_file(fd); |
| 133 | return(1); | 133 | return 1; |
| 134 | } | ||
| 135 | return(0); | ||
| 136 | } | ||
| 137 | |||
| 138 | static void hppfs_read_inode(struct inode *ino) | ||
| 139 | { | ||
| 140 | struct inode *proc_ino; | ||
| 141 | |||
| 142 | if(HPPFS_I(ino)->proc_dentry == NULL) | ||
| 143 | return; | ||
| 144 | |||
| 145 | proc_ino = HPPFS_I(ino)->proc_dentry->d_inode; | ||
| 146 | ino->i_uid = proc_ino->i_uid; | ||
| 147 | ino->i_gid = proc_ino->i_gid; | ||
| 148 | ino->i_atime = proc_ino->i_atime; | ||
| 149 | ino->i_mtime = proc_ino->i_mtime; | ||
| 150 | ino->i_ctime = proc_ino->i_ctime; | ||
| 151 | ino->i_ino = proc_ino->i_ino; | ||
| 152 | ino->i_mode = proc_ino->i_mode; | ||
| 153 | ino->i_nlink = proc_ino->i_nlink; | ||
| 154 | ino->i_size = proc_ino->i_size; | ||
| 155 | ino->i_blocks = proc_ino->i_blocks; | ||
| 156 | } | ||
| 157 | |||
| 158 | static struct inode *hppfs_iget(struct super_block *sb) | ||
| 159 | { | ||
| 160 | struct inode *inode; | ||
| 161 | |||
| 162 | inode = iget_locked(sb, 0); | ||
| 163 | if (!inode) | ||
| 164 | return ERR_PTR(-ENOMEM); | ||
| 165 | if (inode->i_state & I_NEW) { | ||
| 166 | hppfs_read_inode(inode); | ||
| 167 | unlock_new_inode(inode); | ||
| 168 | } | 134 | } |
| 169 | return inode; | 135 | return 0; |
| 170 | } | 136 | } |
| 171 | 137 | ||
| 172 | static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, | 138 | static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, |
| @@ -177,55 +143,45 @@ static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, | |||
| 177 | int err, deleted; | 143 | int err, deleted; |
| 178 | 144 | ||
| 179 | deleted = file_removed(dentry, NULL); | 145 | deleted = file_removed(dentry, NULL); |
| 180 | if(deleted < 0) | 146 | if (deleted < 0) |
| 181 | return(ERR_PTR(deleted)); | 147 | return ERR_PTR(deleted); |
| 182 | else if(deleted) | 148 | else if (deleted) |
| 183 | return(ERR_PTR(-ENOENT)); | 149 | return ERR_PTR(-ENOENT); |
| 184 | 150 | ||
| 185 | err = -ENOMEM; | 151 | err = -ENOMEM; |
| 186 | parent = HPPFS_I(ino)->proc_dentry; | 152 | parent = HPPFS_I(ino)->proc_dentry; |
| 187 | mutex_lock(&parent->d_inode->i_mutex); | 153 | mutex_lock(&parent->d_inode->i_mutex); |
| 188 | proc_dentry = d_lookup(parent, &dentry->d_name); | 154 | proc_dentry = d_lookup(parent, &dentry->d_name); |
| 189 | if(proc_dentry == NULL){ | 155 | if (proc_dentry == NULL) { |
| 190 | proc_dentry = d_alloc(parent, &dentry->d_name); | 156 | proc_dentry = d_alloc(parent, &dentry->d_name); |
| 191 | if(proc_dentry == NULL){ | 157 | if (proc_dentry == NULL) { |
| 192 | mutex_unlock(&parent->d_inode->i_mutex); | 158 | mutex_unlock(&parent->d_inode->i_mutex); |
| 193 | goto out; | 159 | goto out; |
| 194 | } | 160 | } |
| 195 | new = (*parent->d_inode->i_op->lookup)(parent->d_inode, | 161 | new = (*parent->d_inode->i_op->lookup)(parent->d_inode, |
| 196 | proc_dentry, NULL); | 162 | proc_dentry, NULL); |
| 197 | if(new){ | 163 | if (new) { |
| 198 | dput(proc_dentry); | 164 | dput(proc_dentry); |
| 199 | proc_dentry = new; | 165 | proc_dentry = new; |
| 200 | } | 166 | } |
| 201 | } | 167 | } |
| 202 | mutex_unlock(&parent->d_inode->i_mutex); | 168 | mutex_unlock(&parent->d_inode->i_mutex); |
| 203 | 169 | ||
| 204 | if(IS_ERR(proc_dentry)) | 170 | if (IS_ERR(proc_dentry)) |
| 205 | return(proc_dentry); | 171 | return proc_dentry; |
| 206 | 172 | ||
| 207 | inode = hppfs_iget(ino->i_sb); | 173 | err = -ENOMEM; |
| 208 | if (IS_ERR(inode)) { | 174 | inode = get_inode(ino->i_sb, proc_dentry); |
| 209 | err = PTR_ERR(inode); | 175 | if (!inode) |
| 210 | goto out_dput; | 176 | goto out_dput; |
| 211 | } | ||
| 212 | |||
| 213 | err = init_inode(inode, proc_dentry); | ||
| 214 | if(err) | ||
| 215 | goto out_put; | ||
| 216 | |||
| 217 | hppfs_read_inode(inode); | ||
| 218 | 177 | ||
| 219 | d_add(dentry, inode); | 178 | d_add(dentry, inode); |
| 220 | dentry->d_op = &hppfs_dentry_ops; | 179 | return NULL; |
| 221 | return(NULL); | ||
| 222 | 180 | ||
| 223 | out_put: | ||
| 224 | iput(inode); | ||
| 225 | out_dput: | 181 | out_dput: |
| 226 | dput(proc_dentry); | 182 | dput(proc_dentry); |
| 227 | out: | 183 | out: |
| 228 | return(ERR_PTR(err)); | 184 | return ERR_PTR(err); |
| 229 | } | 185 | } |
| 230 | 186 | ||
| 231 | static const struct inode_operations hppfs_file_iops = { | 187 | static const struct inode_operations hppfs_file_iops = { |
| @@ -239,15 +195,16 @@ static ssize_t read_proc(struct file *file, char __user *buf, ssize_t count, | |||
| 239 | 195 | ||
| 240 | read = file->f_path.dentry->d_inode->i_fop->read; | 196 | read = file->f_path.dentry->d_inode->i_fop->read; |
| 241 | 197 | ||
| 242 | if(!is_user) | 198 | if (!is_user) |
| 243 | set_fs(KERNEL_DS); | 199 | set_fs(KERNEL_DS); |
| 244 | 200 | ||
| 245 | n = (*read)(file, buf, count, &file->f_pos); | 201 | n = (*read)(file, buf, count, &file->f_pos); |
| 246 | 202 | ||
| 247 | if(!is_user) | 203 | if (!is_user) |
| 248 | set_fs(USER_DS); | 204 | set_fs(USER_DS); |
| 249 | 205 | ||
| 250 | if(ppos) *ppos = file->f_pos; | 206 | if (ppos) |
| 207 | *ppos = file->f_pos; | ||
| 251 | return n; | 208 | return n; |
| 252 | } | 209 | } |
| 253 | 210 | ||
| @@ -259,24 +216,23 @@ static ssize_t hppfs_read_file(int fd, char __user *buf, ssize_t count) | |||
| 259 | 216 | ||
| 260 | n = -ENOMEM; | 217 | n = -ENOMEM; |
| 261 | new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | 218 | new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); |
| 262 | if(new_buf == NULL){ | 219 | if (new_buf == NULL) { |
| 263 | printk("hppfs_read_file : kmalloc failed\n"); | 220 | printk(KERN_ERR "hppfs_read_file : kmalloc failed\n"); |
| 264 | goto out; | 221 | goto out; |
| 265 | } | 222 | } |
| 266 | n = 0; | 223 | n = 0; |
| 267 | while(count > 0){ | 224 | while (count > 0) { |
| 268 | cur = min_t(ssize_t, count, PAGE_SIZE); | 225 | cur = min_t(ssize_t, count, PAGE_SIZE); |
| 269 | err = os_read_file(fd, new_buf, cur); | 226 | err = os_read_file(fd, new_buf, cur); |
| 270 | if(err < 0){ | 227 | if (err < 0) { |
| 271 | printk("hppfs_read : read failed, errno = %d\n", | 228 | printk(KERN_ERR "hppfs_read : read failed, " |
| 272 | err); | 229 | "errno = %d\n", err); |
| 273 | n = err; | 230 | n = err; |
| 274 | goto out_free; | 231 | goto out_free; |
| 275 | } | 232 | } else if (err == 0) |
| 276 | else if(err == 0) | ||
| 277 | break; | 233 | break; |
| 278 | 234 | ||
| 279 | if(copy_to_user(buf, new_buf, err)){ | 235 | if (copy_to_user(buf, new_buf, err)) { |
| 280 | n = -EFAULT; | 236 | n = -EFAULT; |
| 281 | goto out_free; | 237 | goto out_free; |
| 282 | } | 238 | } |
| @@ -297,35 +253,36 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count, | |||
| 297 | loff_t off; | 253 | loff_t off; |
| 298 | int err; | 254 | int err; |
| 299 | 255 | ||
| 300 | if(hppfs->contents != NULL){ | 256 | if (hppfs->contents != NULL) { |
| 301 | if(*ppos >= hppfs->len) return(0); | 257 | if (*ppos >= hppfs->len) |
| 258 | return 0; | ||
| 302 | 259 | ||
| 303 | data = hppfs->contents; | 260 | data = hppfs->contents; |
| 304 | off = *ppos; | 261 | off = *ppos; |
| 305 | while(off >= sizeof(data->contents)){ | 262 | while (off >= sizeof(data->contents)) { |
| 306 | data = list_entry(data->list.next, struct hppfs_data, | 263 | data = list_entry(data->list.next, struct hppfs_data, |
| 307 | list); | 264 | list); |
| 308 | off -= sizeof(data->contents); | 265 | off -= sizeof(data->contents); |
| 309 | } | 266 | } |
| 310 | 267 | ||
| 311 | if(off + count > hppfs->len) | 268 | if (off + count > hppfs->len) |
| 312 | count = hppfs->len - off; | 269 | count = hppfs->len - off; |
| 313 | copy_to_user(buf, &data->contents[off], count); | 270 | copy_to_user(buf, &data->contents[off], count); |
| 314 | *ppos += count; | 271 | *ppos += count; |
| 315 | } | 272 | } else if (hppfs->host_fd != -1) { |
| 316 | else if(hppfs->host_fd != -1){ | ||
| 317 | err = os_seek_file(hppfs->host_fd, *ppos); | 273 | err = os_seek_file(hppfs->host_fd, *ppos); |
| 318 | if(err){ | 274 | if (err) { |
| 319 | printk("hppfs_read : seek failed, errno = %d\n", err); | 275 | printk(KERN_ERR "hppfs_read : seek failed, " |
| 320 | return(err); | 276 | "errno = %d\n", err); |
| 277 | return err; | ||
| 321 | } | 278 | } |
| 322 | count = hppfs_read_file(hppfs->host_fd, buf, count); | 279 | count = hppfs_read_file(hppfs->host_fd, buf, count); |
| 323 | if(count > 0) | 280 | if (count > 0) |
| 324 | *ppos += count; | 281 | *ppos += count; |
| 325 | } | 282 | } |
| 326 | else count = read_proc(hppfs->proc_file, buf, count, ppos, 1); | 283 | else count = read_proc(hppfs->proc_file, buf, count, ppos, 1); |
| 327 | 284 | ||
| 328 | return(count); | 285 | return count; |
| 329 | } | 286 | } |
| 330 | 287 | ||
| 331 | static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len, | 288 | static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len, |
| @@ -342,7 +299,7 @@ static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len | |||
| 342 | err = (*write)(proc_file, buf, len, &proc_file->f_pos); | 299 | err = (*write)(proc_file, buf, len, &proc_file->f_pos); |
| 343 | file->f_pos = proc_file->f_pos; | 300 | file->f_pos = proc_file->f_pos; |
| 344 | 301 | ||
| 345 | return(err); | 302 | return err; |
| 346 | } | 303 | } |
| 347 | 304 | ||
| 348 | static int open_host_sock(char *host_file, int *filter_out) | 305 | static int open_host_sock(char *host_file, int *filter_out) |
| @@ -354,13 +311,13 @@ static int open_host_sock(char *host_file, int *filter_out) | |||
| 354 | strcpy(end, "/rw"); | 311 | strcpy(end, "/rw"); |
| 355 | *filter_out = 1; | 312 | *filter_out = 1; |
| 356 | fd = os_connect_socket(host_file); | 313 | fd = os_connect_socket(host_file); |
| 357 | if(fd > 0) | 314 | if (fd > 0) |
| 358 | return(fd); | 315 | return fd; |
| 359 | 316 | ||
| 360 | strcpy(end, "/r"); | 317 | strcpy(end, "/r"); |
| 361 | *filter_out = 0; | 318 | *filter_out = 0; |
| 362 | fd = os_connect_socket(host_file); | 319 | fd = os_connect_socket(host_file); |
| 363 | return(fd); | 320 | return fd; |
| 364 | } | 321 | } |
| 365 | 322 | ||
| 366 | static void free_contents(struct hppfs_data *head) | 323 | static void free_contents(struct hppfs_data *head) |
| @@ -368,9 +325,10 @@ static void free_contents(struct hppfs_data *head) | |||
| 368 | struct hppfs_data *data; | 325 | struct hppfs_data *data; |
| 369 | struct list_head *ele, *next; | 326 | struct list_head *ele, *next; |
| 370 | 327 | ||
| 371 | if(head == NULL) return; | 328 | if (head == NULL) |
| 329 | return; | ||
| 372 | 330 | ||
| 373 | list_for_each_safe(ele, next, &head->list){ | 331 | list_for_each_safe(ele, next, &head->list) { |
| 374 | data = list_entry(ele, struct hppfs_data, list); | 332 | data = list_entry(ele, struct hppfs_data, list); |
| 375 | kfree(data); | 333 | kfree(data); |
| 376 | } | 334 | } |
| @@ -387,8 +345,8 @@ static struct hppfs_data *hppfs_get_data(int fd, int filter, | |||
| 387 | 345 | ||
| 388 | err = -ENOMEM; | 346 | err = -ENOMEM; |
| 389 | data = kmalloc(sizeof(*data), GFP_KERNEL); | 347 | data = kmalloc(sizeof(*data), GFP_KERNEL); |
| 390 | if(data == NULL){ | 348 | if (data == NULL) { |
| 391 | printk("hppfs_get_data : head allocation failed\n"); | 349 | printk(KERN_ERR "hppfs_get_data : head allocation failed\n"); |
| 392 | goto failed; | 350 | goto failed; |
| 393 | } | 351 | } |
| 394 | 352 | ||
| @@ -397,36 +355,36 @@ static struct hppfs_data *hppfs_get_data(int fd, int filter, | |||
| 397 | head = data; | 355 | head = data; |
| 398 | *size_out = 0; | 356 | *size_out = 0; |
| 399 | 357 | ||
| 400 | if(filter){ | 358 | if (filter) { |
| 401 | while((n = read_proc(proc_file, data->contents, | 359 | while ((n = read_proc(proc_file, data->contents, |
| 402 | sizeof(data->contents), NULL, 0)) > 0) | 360 | sizeof(data->contents), NULL, 0)) > 0) |
| 403 | os_write_file(fd, data->contents, n); | 361 | os_write_file(fd, data->contents, n); |
| 404 | err = os_shutdown_socket(fd, 0, 1); | 362 | err = os_shutdown_socket(fd, 0, 1); |
| 405 | if(err){ | 363 | if (err) { |
| 406 | printk("hppfs_get_data : failed to shut down " | 364 | printk(KERN_ERR "hppfs_get_data : failed to shut down " |
| 407 | "socket\n"); | 365 | "socket\n"); |
| 408 | goto failed_free; | 366 | goto failed_free; |
| 409 | } | 367 | } |
| 410 | } | 368 | } |
| 411 | while(1){ | 369 | while (1) { |
| 412 | n = os_read_file(fd, data->contents, sizeof(data->contents)); | 370 | n = os_read_file(fd, data->contents, sizeof(data->contents)); |
| 413 | if(n < 0){ | 371 | if (n < 0) { |
| 414 | err = n; | 372 | err = n; |
| 415 | printk("hppfs_get_data : read failed, errno = %d\n", | 373 | printk(KERN_ERR "hppfs_get_data : read failed, " |
| 416 | err); | 374 | "errno = %d\n", err); |
| 417 | goto failed_free; | 375 | goto failed_free; |
| 418 | } | 376 | } else if (n == 0) |
| 419 | else if(n == 0) | ||
| 420 | break; | 377 | break; |
| 421 | 378 | ||
| 422 | *size_out += n; | 379 | *size_out += n; |
| 423 | 380 | ||
| 424 | if(n < sizeof(data->contents)) | 381 | if (n < sizeof(data->contents)) |
| 425 | break; | 382 | break; |
| 426 | 383 | ||
| 427 | new = kmalloc(sizeof(*data), GFP_KERNEL); | 384 | new = kmalloc(sizeof(*data), GFP_KERNEL); |
| 428 | if(new == 0){ | 385 | if (new == 0) { |
| 429 | printk("hppfs_get_data : data allocation failed\n"); | 386 | printk(KERN_ERR "hppfs_get_data : data allocation " |
| 387 | "failed\n"); | ||
| 430 | err = -ENOMEM; | 388 | err = -ENOMEM; |
| 431 | goto failed_free; | 389 | goto failed_free; |
| 432 | } | 390 | } |
| @@ -435,12 +393,12 @@ static struct hppfs_data *hppfs_get_data(int fd, int filter, | |||
| 435 | list_add(&new->list, &data->list); | 393 | list_add(&new->list, &data->list); |
| 436 | data = new; | 394 | data = new; |
| 437 | } | 395 | } |
| 438 | return(head); | 396 | return head; |
| 439 | 397 | ||
| 440 | failed_free: | 398 | failed_free: |
| 441 | free_contents(head); | 399 | free_contents(head); |
| 442 | failed: | 400 | failed: |
| 443 | return(ERR_PTR(err)); | 401 | return ERR_PTR(err); |
| 444 | } | 402 | } |
| 445 | 403 | ||
| 446 | static struct hppfs_private *hppfs_data(void) | 404 | static struct hppfs_private *hppfs_data(void) |
| @@ -448,77 +406,79 @@ static struct hppfs_private *hppfs_data(void) | |||
| 448 | struct hppfs_private *data; | 406 | struct hppfs_private *data; |
| 449 | 407 | ||
| 450 | data = kmalloc(sizeof(*data), GFP_KERNEL); | 408 | data = kmalloc(sizeof(*data), GFP_KERNEL); |
| 451 | if(data == NULL) | 409 | if (data == NULL) |
| 452 | return(data); | 410 | return data; |
| 453 | 411 | ||
| 454 | *data = ((struct hppfs_private ) { .host_fd = -1, | 412 | *data = ((struct hppfs_private ) { .host_fd = -1, |
| 455 | .len = -1, | 413 | .len = -1, |
| 456 | .contents = NULL } ); | 414 | .contents = NULL } ); |
| 457 | return(data); | 415 | return data; |
| 458 | } | 416 | } |
| 459 | 417 | ||
| 460 | static int file_mode(int fmode) | 418 | static int file_mode(int fmode) |
| 461 | { | 419 | { |
| 462 | if(fmode == (FMODE_READ | FMODE_WRITE)) | 420 | if (fmode == (FMODE_READ | FMODE_WRITE)) |
| 463 | return(O_RDWR); | 421 | return O_RDWR; |
| 464 | if(fmode == FMODE_READ) | 422 | if (fmode == FMODE_READ) |
| 465 | return(O_RDONLY); | 423 | return O_RDONLY; |
| 466 | if(fmode == FMODE_WRITE) | 424 | if (fmode == FMODE_WRITE) |
| 467 | return(O_WRONLY); | 425 | return O_WRONLY; |
| 468 | return(0); | 426 | return 0; |
| 469 | } | 427 | } |
| 470 | 428 | ||
| 471 | static int hppfs_open(struct inode *inode, struct file *file) | 429 | static int hppfs_open(struct inode *inode, struct file *file) |
| 472 | { | 430 | { |
| 473 | struct hppfs_private *data; | 431 | struct hppfs_private *data; |
| 474 | struct dentry *proc_dentry; | 432 | struct dentry *proc_dentry; |
| 433 | struct vfsmount *proc_mnt; | ||
| 475 | char *host_file; | 434 | char *host_file; |
| 476 | int err, fd, type, filter; | 435 | int err, fd, type, filter; |
| 477 | 436 | ||
| 478 | err = -ENOMEM; | 437 | err = -ENOMEM; |
| 479 | data = hppfs_data(); | 438 | data = hppfs_data(); |
| 480 | if(data == NULL) | 439 | if (data == NULL) |
| 481 | goto out; | 440 | goto out; |
| 482 | 441 | ||
| 483 | host_file = dentry_name(file->f_path.dentry, strlen("/rw")); | 442 | host_file = dentry_name(file->f_path.dentry, strlen("/rw")); |
| 484 | if(host_file == NULL) | 443 | if (host_file == NULL) |
| 485 | goto out_free2; | 444 | goto out_free2; |
| 486 | 445 | ||
| 487 | proc_dentry = HPPFS_I(inode)->proc_dentry; | 446 | proc_dentry = HPPFS_I(inode)->proc_dentry; |
| 447 | proc_mnt = inode->i_sb->s_fs_info; | ||
| 488 | 448 | ||
| 489 | /* XXX This isn't closed anywhere */ | 449 | /* XXX This isn't closed anywhere */ |
| 490 | data->proc_file = dentry_open(dget(proc_dentry), NULL, | 450 | data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), |
| 491 | file_mode(file->f_mode)); | 451 | file_mode(file->f_mode)); |
| 492 | err = PTR_ERR(data->proc_file); | 452 | err = PTR_ERR(data->proc_file); |
| 493 | if(IS_ERR(data->proc_file)) | 453 | if (IS_ERR(data->proc_file)) |
| 494 | goto out_free1; | 454 | goto out_free1; |
| 495 | 455 | ||
| 496 | type = os_file_type(host_file); | 456 | type = os_file_type(host_file); |
| 497 | if(type == OS_TYPE_FILE){ | 457 | if (type == OS_TYPE_FILE) { |
| 498 | fd = os_open_file(host_file, of_read(OPENFLAGS()), 0); | 458 | fd = os_open_file(host_file, of_read(OPENFLAGS()), 0); |
| 499 | if(fd >= 0) | 459 | if (fd >= 0) |
| 500 | data->host_fd = fd; | 460 | data->host_fd = fd; |
| 501 | else printk("hppfs_open : failed to open '%s', errno = %d\n", | 461 | else |
| 502 | host_file, -fd); | 462 | printk(KERN_ERR "hppfs_open : failed to open '%s', " |
| 463 | "errno = %d\n", host_file, -fd); | ||
| 503 | 464 | ||
| 504 | data->contents = NULL; | 465 | data->contents = NULL; |
| 505 | } | 466 | } else if (type == OS_TYPE_DIR) { |
| 506 | else if(type == OS_TYPE_DIR){ | ||
| 507 | fd = open_host_sock(host_file, &filter); | 467 | fd = open_host_sock(host_file, &filter); |
| 508 | if(fd > 0){ | 468 | if (fd > 0) { |
| 509 | data->contents = hppfs_get_data(fd, filter, | 469 | data->contents = hppfs_get_data(fd, filter, |
| 510 | data->proc_file, | 470 | data->proc_file, |
| 511 | file, &data->len); | 471 | file, &data->len); |
| 512 | if(!IS_ERR(data->contents)) | 472 | if (!IS_ERR(data->contents)) |
| 513 | data->host_fd = fd; | 473 | data->host_fd = fd; |
| 514 | } | 474 | } else |
| 515 | else printk("hppfs_open : failed to open a socket in " | 475 | printk(KERN_ERR "hppfs_open : failed to open a socket " |
| 516 | "'%s', errno = %d\n", host_file, -fd); | 476 | "in '%s', errno = %d\n", host_file, -fd); |
| 517 | } | 477 | } |
| 518 | kfree(host_file); | 478 | kfree(host_file); |
| 519 | 479 | ||
| 520 | file->private_data = data; | 480 | file->private_data = data; |
| 521 | return(0); | 481 | return 0; |
| 522 | 482 | ||
| 523 | out_free1: | 483 | out_free1: |
| 524 | kfree(host_file); | 484 | kfree(host_file); |
| @@ -526,34 +486,36 @@ static int hppfs_open(struct inode *inode, struct file *file) | |||
| 526 | free_contents(data->contents); | 486 | free_contents(data->contents); |
| 527 | kfree(data); | 487 | kfree(data); |
| 528 | out: | 488 | out: |
| 529 | return(err); | 489 | return err; |
| 530 | } | 490 | } |
| 531 | 491 | ||
| 532 | static int hppfs_dir_open(struct inode *inode, struct file *file) | 492 | static int hppfs_dir_open(struct inode *inode, struct file *file) |
| 533 | { | 493 | { |
| 534 | struct hppfs_private *data; | 494 | struct hppfs_private *data; |
| 535 | struct dentry *proc_dentry; | 495 | struct dentry *proc_dentry; |
| 496 | struct vfsmount *proc_mnt; | ||
| 536 | int err; | 497 | int err; |
| 537 | 498 | ||
| 538 | err = -ENOMEM; | 499 | err = -ENOMEM; |
| 539 | data = hppfs_data(); | 500 | data = hppfs_data(); |
| 540 | if(data == NULL) | 501 | if (data == NULL) |
| 541 | goto out; | 502 | goto out; |
| 542 | 503 | ||
| 543 | proc_dentry = HPPFS_I(inode)->proc_dentry; | 504 | proc_dentry = HPPFS_I(inode)->proc_dentry; |
| 544 | data->proc_file = dentry_open(dget(proc_dentry), NULL, | 505 | proc_mnt = inode->i_sb->s_fs_info; |
| 506 | data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), | ||
| 545 | file_mode(file->f_mode)); | 507 | file_mode(file->f_mode)); |
| 546 | err = PTR_ERR(data->proc_file); | 508 | err = PTR_ERR(data->proc_file); |
| 547 | if(IS_ERR(data->proc_file)) | 509 | if (IS_ERR(data->proc_file)) |
| 548 | goto out_free; | 510 | goto out_free; |
| 549 | 511 | ||
| 550 | file->private_data = data; | 512 | file->private_data = data; |
| 551 | return(0); | 513 | return 0; |
| 552 | 514 | ||
| 553 | out_free: | 515 | out_free: |
| 554 | kfree(data); | 516 | kfree(data); |
| 555 | out: | 517 | out: |
| 556 | return(err); | 518 | return err; |
| 557 | } | 519 | } |
| 558 | 520 | ||
| 559 | static loff_t hppfs_llseek(struct file *file, loff_t off, int where) | 521 | static loff_t hppfs_llseek(struct file *file, loff_t off, int where) |
| @@ -564,13 +526,13 @@ static loff_t hppfs_llseek(struct file *file, loff_t off, int where) | |||
| 564 | loff_t ret; | 526 | loff_t ret; |
| 565 | 527 | ||
| 566 | llseek = proc_file->f_path.dentry->d_inode->i_fop->llseek; | 528 | llseek = proc_file->f_path.dentry->d_inode->i_fop->llseek; |
| 567 | if(llseek != NULL){ | 529 | if (llseek != NULL) { |
| 568 | ret = (*llseek)(proc_file, off, where); | 530 | ret = (*llseek)(proc_file, off, where); |
| 569 | if(ret < 0) | 531 | if (ret < 0) |
| 570 | return(ret); | 532 | return ret; |
| 571 | } | 533 | } |
| 572 | 534 | ||
| 573 | return(default_llseek(file, off, where)); | 535 | return default_llseek(file, off, where); |
| 574 | } | 536 | } |
| 575 | 537 | ||
| 576 | static const struct file_operations hppfs_file_fops = { | 538 | static const struct file_operations hppfs_file_fops = { |
| @@ -592,11 +554,11 @@ static int hppfs_filldir(void *d, const char *name, int size, | |||
| 592 | { | 554 | { |
| 593 | struct hppfs_dirent *dirent = d; | 555 | struct hppfs_dirent *dirent = d; |
| 594 | 556 | ||
| 595 | if(file_removed(dirent->dentry, name)) | 557 | if (file_removed(dirent->dentry, name)) |
| 596 | return(0); | 558 | return 0; |
| 597 | 559 | ||
| 598 | return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset, | 560 | return (*dirent->filldir)(dirent->vfs_dirent, name, size, offset, |
| 599 | inode, type)); | 561 | inode, type); |
| 600 | } | 562 | } |
| 601 | 563 | ||
| 602 | static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir) | 564 | static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir) |
| @@ -607,7 +569,8 @@ static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir) | |||
| 607 | struct hppfs_dirent dirent = ((struct hppfs_dirent) | 569 | struct hppfs_dirent dirent = ((struct hppfs_dirent) |
| 608 | { .vfs_dirent = ent, | 570 | { .vfs_dirent = ent, |
| 609 | .filldir = filldir, | 571 | .filldir = filldir, |
| 610 | .dentry = file->f_path.dentry } ); | 572 | .dentry = file->f_path.dentry |
| 573 | }); | ||
| 611 | int err; | 574 | int err; |
| 612 | 575 | ||
| 613 | readdir = proc_file->f_path.dentry->d_inode->i_fop->readdir; | 576 | readdir = proc_file->f_path.dentry->d_inode->i_fop->readdir; |
| @@ -616,12 +579,12 @@ static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir) | |||
| 616 | err = (*readdir)(proc_file, &dirent, hppfs_filldir); | 579 | err = (*readdir)(proc_file, &dirent, hppfs_filldir); |
| 617 | file->f_pos = proc_file->f_pos; | 580 | file->f_pos = proc_file->f_pos; |
| 618 | 581 | ||
| 619 | return(err); | 582 | return err; |
| 620 | } | 583 | } |
| 621 | 584 | ||
| 622 | static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 585 | static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync) |
| 623 | { | 586 | { |
| 624 | return(0); | 587 | return 0; |
| 625 | } | 588 | } |
| 626 | 589 | ||
| 627 | static const struct file_operations hppfs_dir_fops = { | 590 | static const struct file_operations hppfs_dir_fops = { |
| @@ -639,7 +602,7 @@ static int hppfs_statfs(struct dentry *dentry, struct kstatfs *sf) | |||
| 639 | sf->f_files = 0; | 602 | sf->f_files = 0; |
| 640 | sf->f_ffree = 0; | 603 | sf->f_ffree = 0; |
| 641 | sf->f_type = HPPFS_SUPER_MAGIC; | 604 | sf->f_type = HPPFS_SUPER_MAGIC; |
| 642 | return(0); | 605 | return 0; |
| 643 | } | 606 | } |
| 644 | 607 | ||
| 645 | static struct inode *hppfs_alloc_inode(struct super_block *sb) | 608 | static struct inode *hppfs_alloc_inode(struct super_block *sb) |
| @@ -647,12 +610,12 @@ static struct inode *hppfs_alloc_inode(struct super_block *sb) | |||
| 647 | struct hppfs_inode_info *hi; | 610 | struct hppfs_inode_info *hi; |
| 648 | 611 | ||
| 649 | hi = kmalloc(sizeof(*hi), GFP_KERNEL); | 612 | hi = kmalloc(sizeof(*hi), GFP_KERNEL); |
| 650 | if(hi == NULL) | 613 | if (!hi) |
| 651 | return(NULL); | 614 | return NULL; |
| 652 | 615 | ||
| 653 | *hi = ((struct hppfs_inode_info) { .proc_dentry = NULL }); | 616 | hi->proc_dentry = NULL; |
| 654 | inode_init_once(&hi->vfs_inode); | 617 | inode_init_once(&hi->vfs_inode); |
| 655 | return(&hi->vfs_inode); | 618 | return &hi->vfs_inode; |
| 656 | } | 619 | } |
| 657 | 620 | ||
| 658 | void hppfs_delete_inode(struct inode *ino) | 621 | void hppfs_delete_inode(struct inode *ino) |
| @@ -665,21 +628,31 @@ static void hppfs_destroy_inode(struct inode *inode) | |||
| 665 | kfree(HPPFS_I(inode)); | 628 | kfree(HPPFS_I(inode)); |
| 666 | } | 629 | } |
| 667 | 630 | ||
| 631 | static void hppfs_put_super(struct super_block *sb) | ||
| 632 | { | ||
| 633 | mntput(sb->s_fs_info); | ||
| 634 | } | ||
| 635 | |||
| 668 | static const struct super_operations hppfs_sbops = { | 636 | static const struct super_operations hppfs_sbops = { |
| 669 | .alloc_inode = hppfs_alloc_inode, | 637 | .alloc_inode = hppfs_alloc_inode, |
| 670 | .destroy_inode = hppfs_destroy_inode, | 638 | .destroy_inode = hppfs_destroy_inode, |
| 671 | .delete_inode = hppfs_delete_inode, | 639 | .delete_inode = hppfs_delete_inode, |
| 672 | .statfs = hppfs_statfs, | 640 | .statfs = hppfs_statfs, |
| 641 | .put_super = hppfs_put_super, | ||
| 673 | }; | 642 | }; |
| 674 | 643 | ||
| 675 | static int hppfs_readlink(struct dentry *dentry, char __user *buffer, int buflen) | 644 | static int hppfs_readlink(struct dentry *dentry, char __user *buffer, |
| 645 | int buflen) | ||
| 676 | { | 646 | { |
| 677 | struct file *proc_file; | 647 | struct file *proc_file; |
| 678 | struct dentry *proc_dentry; | 648 | struct dentry *proc_dentry; |
| 649 | struct vfsmount *proc_mnt; | ||
| 679 | int ret; | 650 | int ret; |
| 680 | 651 | ||
| 681 | proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; | 652 | proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; |
| 682 | proc_file = dentry_open(dget(proc_dentry), NULL, O_RDONLY); | 653 | proc_mnt = dentry->d_sb->s_fs_info; |
| 654 | |||
| 655 | proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY); | ||
| 683 | if (IS_ERR(proc_file)) | 656 | if (IS_ERR(proc_file)) |
| 684 | return PTR_ERR(proc_file); | 657 | return PTR_ERR(proc_file); |
| 685 | 658 | ||
| @@ -694,10 +667,13 @@ static void* hppfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
| 694 | { | 667 | { |
| 695 | struct file *proc_file; | 668 | struct file *proc_file; |
| 696 | struct dentry *proc_dentry; | 669 | struct dentry *proc_dentry; |
| 670 | struct vfsmount *proc_mnt; | ||
| 697 | void *ret; | 671 | void *ret; |
| 698 | 672 | ||
| 699 | proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; | 673 | proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; |
| 700 | proc_file = dentry_open(dget(proc_dentry), NULL, O_RDONLY); | 674 | proc_mnt = dentry->d_sb->s_fs_info; |
| 675 | |||
| 676 | proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY); | ||
| 701 | if (IS_ERR(proc_file)) | 677 | if (IS_ERR(proc_file)) |
| 702 | return proc_file; | 678 | return proc_file; |
| 703 | 679 | ||
| @@ -717,70 +693,72 @@ static const struct inode_operations hppfs_link_iops = { | |||
| 717 | .follow_link = hppfs_follow_link, | 693 | .follow_link = hppfs_follow_link, |
| 718 | }; | 694 | }; |
| 719 | 695 | ||
| 720 | static int init_inode(struct inode *inode, struct dentry *dentry) | 696 | static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) |
| 721 | { | 697 | { |
| 722 | if(S_ISDIR(dentry->d_inode->i_mode)){ | 698 | struct inode *proc_ino = dentry->d_inode; |
| 699 | struct inode *inode = new_inode(sb); | ||
| 700 | |||
| 701 | if (!inode) | ||
| 702 | return ERR_PTR(-ENOMEM); | ||
| 703 | |||
| 704 | if (S_ISDIR(dentry->d_inode->i_mode)) { | ||
| 723 | inode->i_op = &hppfs_dir_iops; | 705 | inode->i_op = &hppfs_dir_iops; |
| 724 | inode->i_fop = &hppfs_dir_fops; | 706 | inode->i_fop = &hppfs_dir_fops; |
| 725 | } | 707 | } else if (S_ISLNK(dentry->d_inode->i_mode)) { |
| 726 | else if(S_ISLNK(dentry->d_inode->i_mode)){ | ||
| 727 | inode->i_op = &hppfs_link_iops; | 708 | inode->i_op = &hppfs_link_iops; |
| 728 | inode->i_fop = &hppfs_file_fops; | 709 | inode->i_fop = &hppfs_file_fops; |
| 729 | } | 710 | } else { |
| 730 | else { | ||
| 731 | inode->i_op = &hppfs_file_iops; | 711 | inode->i_op = &hppfs_file_iops; |
| 732 | inode->i_fop = &hppfs_file_fops; | 712 | inode->i_fop = &hppfs_file_fops; |
| 733 | } | 713 | } |
| 734 | 714 | ||
| 735 | HPPFS_I(inode)->proc_dentry = dentry; | 715 | HPPFS_I(inode)->proc_dentry = dentry; |
| 736 | 716 | ||
| 737 | return(0); | 717 | inode->i_uid = proc_ino->i_uid; |
| 718 | inode->i_gid = proc_ino->i_gid; | ||
| 719 | inode->i_atime = proc_ino->i_atime; | ||
| 720 | inode->i_mtime = proc_ino->i_mtime; | ||
| 721 | inode->i_ctime = proc_ino->i_ctime; | ||
| 722 | inode->i_ino = proc_ino->i_ino; | ||
| 723 | inode->i_mode = proc_ino->i_mode; | ||
| 724 | inode->i_nlink = proc_ino->i_nlink; | ||
| 725 | inode->i_size = proc_ino->i_size; | ||
| 726 | inode->i_blocks = proc_ino->i_blocks; | ||
| 727 | |||
| 728 | return 0; | ||
| 738 | } | 729 | } |
| 739 | 730 | ||
| 740 | static int hppfs_fill_super(struct super_block *sb, void *d, int silent) | 731 | static int hppfs_fill_super(struct super_block *sb, void *d, int silent) |
| 741 | { | 732 | { |
| 742 | struct inode *root_inode; | 733 | struct inode *root_inode; |
| 743 | struct file_system_type *procfs; | 734 | struct vfsmount *proc_mnt; |
| 744 | struct super_block *proc_sb; | 735 | int err = -ENOENT; |
| 745 | int err; | ||
| 746 | 736 | ||
| 747 | err = -ENOENT; | 737 | proc_mnt = do_kern_mount("proc", 0, "proc", NULL); |
| 748 | procfs = get_fs_type("proc"); | 738 | if (IS_ERR(proc_mnt)) |
| 749 | if(procfs == NULL) | ||
| 750 | goto out; | 739 | goto out; |
| 751 | 740 | ||
| 752 | if(list_empty(&procfs->fs_supers)) | ||
| 753 | goto out; | ||
| 754 | |||
| 755 | proc_sb = list_entry(procfs->fs_supers.next, struct super_block, | ||
| 756 | s_instances); | ||
| 757 | |||
| 758 | sb->s_blocksize = 1024; | 741 | sb->s_blocksize = 1024; |
| 759 | sb->s_blocksize_bits = 10; | 742 | sb->s_blocksize_bits = 10; |
| 760 | sb->s_magic = HPPFS_SUPER_MAGIC; | 743 | sb->s_magic = HPPFS_SUPER_MAGIC; |
| 761 | sb->s_op = &hppfs_sbops; | 744 | sb->s_op = &hppfs_sbops; |
| 762 | 745 | sb->s_fs_info = proc_mnt; | |
| 763 | root_inode = hppfs_iget(sb); | ||
| 764 | if (IS_ERR(root_inode)) { | ||
| 765 | err = PTR_ERR(root_inode); | ||
| 766 | goto out; | ||
| 767 | } | ||
| 768 | |||
| 769 | err = init_inode(root_inode, proc_sb->s_root); | ||
| 770 | if(err) | ||
| 771 | goto out_put; | ||
| 772 | 746 | ||
| 773 | err = -ENOMEM; | 747 | err = -ENOMEM; |
| 774 | sb->s_root = d_alloc_root(root_inode); | 748 | root_inode = get_inode(sb, proc_mnt->mnt_sb->s_root); |
| 775 | if(sb->s_root == NULL) | 749 | if (!root_inode) |
| 776 | goto out_put; | 750 | goto out_mntput; |
| 777 | 751 | ||
| 778 | hppfs_read_inode(root_inode); | 752 | sb->s_root = d_alloc_root(root_inode); |
| 753 | if (!sb->s_root) | ||
| 754 | goto out_iput; | ||
| 779 | 755 | ||
| 780 | return(0); | 756 | return 0; |
| 781 | 757 | ||
| 782 | out_put: | 758 | out_iput: |
| 783 | iput(root_inode); | 759 | iput(root_inode); |
| 760 | out_mntput: | ||
| 761 | mntput(proc_mnt); | ||
| 784 | out: | 762 | out: |
| 785 | return(err); | 763 | return(err); |
| 786 | } | 764 | } |
| @@ -802,7 +780,7 @@ static struct file_system_type hppfs_type = { | |||
| 802 | 780 | ||
| 803 | static int __init init_hppfs(void) | 781 | static int __init init_hppfs(void) |
| 804 | { | 782 | { |
| 805 | return(register_filesystem(&hppfs_type)); | 783 | return register_filesystem(&hppfs_type); |
| 806 | } | 784 | } |
| 807 | 785 | ||
| 808 | static void __exit exit_hppfs(void) | 786 | static void __exit exit_hppfs(void) |
| @@ -813,14 +791,3 @@ static void __exit exit_hppfs(void) | |||
| 813 | module_init(init_hppfs) | 791 | module_init(init_hppfs) |
| 814 | module_exit(exit_hppfs) | 792 | module_exit(exit_hppfs) |
| 815 | MODULE_LICENSE("GPL"); | 793 | MODULE_LICENSE("GPL"); |
| 816 | |||
| 817 | /* | ||
| 818 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
| 819 | * Emacs will notice this stuff at the end of the file and automatically | ||
| 820 | * adjust the settings for this buffer only. This must remain at the end | ||
| 821 | * of the file. | ||
| 822 | * --------------------------------------------------------------------------- | ||
| 823 | * Local variables: | ||
| 824 | * c-file-style: "linux" | ||
| 825 | * End: | ||
| 826 | */ | ||
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index eee9487ae47f..6846785fe904 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
| @@ -954,7 +954,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size) | |||
| 954 | FMODE_WRITE | FMODE_READ, | 954 | FMODE_WRITE | FMODE_READ, |
| 955 | &hugetlbfs_file_operations); | 955 | &hugetlbfs_file_operations); |
| 956 | if (!file) | 956 | if (!file) |
| 957 | goto out_inode; | 957 | goto out_dentry; /* inode is already attached */ |
| 958 | 958 | ||
| 959 | return file; | 959 | return file; |
| 960 | 960 | ||
diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c index 37dbd6404787..defb932eee9a 100644 --- a/fs/isofs/compress.c +++ b/fs/isofs/compress.c | |||
| @@ -72,6 +72,17 @@ static int zisofs_readpage(struct file *file, struct page *page) | |||
| 72 | offset = index & ~zisofs_block_page_mask; | 72 | offset = index & ~zisofs_block_page_mask; |
| 73 | blockindex = offset >> zisofs_block_page_shift; | 73 | blockindex = offset >> zisofs_block_page_shift; |
| 74 | maxpage = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 74 | maxpage = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
| 75 | |||
| 76 | /* | ||
| 77 | * If this page is wholly outside i_size we just return zero; | ||
| 78 | * do_generic_file_read() will handle this for us | ||
| 79 | */ | ||
| 80 | if (page->index >= maxpage) { | ||
| 81 | SetPageUptodate(page); | ||
| 82 | unlock_page(page); | ||
| 83 | return 0; | ||
| 84 | } | ||
| 85 | |||
| 75 | maxpage = min(zisofs_block_pages, maxpage-offset); | 86 | maxpage = min(zisofs_block_pages, maxpage-offset); |
| 76 | 87 | ||
| 77 | for ( i = 0 ; i < maxpage ; i++, offset++ ) { | 88 | for ( i = 0 ; i < maxpage ; i++, offset++ ) { |
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 3943a8905eb2..0e081d5f32e8 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
| @@ -697,13 +697,14 @@ fail: | |||
| 697 | */ | 697 | */ |
| 698 | 698 | ||
| 699 | /** | 699 | /** |
| 700 | * journal_t * journal_init_dev() - creates an initialises a journal structure | 700 | * journal_t * journal_init_dev() - creates and initialises a journal structure |
| 701 | * @bdev: Block device on which to create the journal | 701 | * @bdev: Block device on which to create the journal |
| 702 | * @fs_dev: Device which hold journalled filesystem for this journal. | 702 | * @fs_dev: Device which hold journalled filesystem for this journal. |
| 703 | * @start: Block nr Start of journal. | 703 | * @start: Block nr Start of journal. |
| 704 | * @len: Length of the journal in blocks. | 704 | * @len: Length of the journal in blocks. |
| 705 | * @blocksize: blocksize of journalling device | 705 | * @blocksize: blocksize of journalling device |
| 706 | * @returns: a newly created journal_t * | 706 | * |
| 707 | * Returns: a newly created journal_t * | ||
| 707 | * | 708 | * |
| 708 | * journal_init_dev creates a journal which maps a fixed contiguous | 709 | * journal_init_dev creates a journal which maps a fixed contiguous |
| 709 | * range of blocks on an arbitrary block device. | 710 | * range of blocks on an arbitrary block device. |
| @@ -1619,14 +1620,14 @@ static int journal_init_journal_head_cache(void) | |||
| 1619 | { | 1620 | { |
| 1620 | int retval; | 1621 | int retval; |
| 1621 | 1622 | ||
| 1622 | J_ASSERT(journal_head_cache == 0); | 1623 | J_ASSERT(journal_head_cache == NULL); |
| 1623 | journal_head_cache = kmem_cache_create("journal_head", | 1624 | journal_head_cache = kmem_cache_create("journal_head", |
| 1624 | sizeof(struct journal_head), | 1625 | sizeof(struct journal_head), |
| 1625 | 0, /* offset */ | 1626 | 0, /* offset */ |
| 1626 | SLAB_TEMPORARY, /* flags */ | 1627 | SLAB_TEMPORARY, /* flags */ |
| 1627 | NULL); /* ctor */ | 1628 | NULL); /* ctor */ |
| 1628 | retval = 0; | 1629 | retval = 0; |
| 1629 | if (journal_head_cache == 0) { | 1630 | if (!journal_head_cache) { |
| 1630 | retval = -ENOMEM; | 1631 | retval = -ENOMEM; |
| 1631 | printk(KERN_EMERG "JBD: no memory for journal_head cache\n"); | 1632 | printk(KERN_EMERG "JBD: no memory for journal_head cache\n"); |
| 1632 | } | 1633 | } |
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c index 2b8edf4d6eaa..43bc5e5ed064 100644 --- a/fs/jbd/recovery.c +++ b/fs/jbd/recovery.c | |||
| @@ -478,7 +478,7 @@ static int do_one_pass(journal_t *journal, | |||
| 478 | memcpy(nbh->b_data, obh->b_data, | 478 | memcpy(nbh->b_data, obh->b_data, |
| 479 | journal->j_blocksize); | 479 | journal->j_blocksize); |
| 480 | if (flags & JFS_FLAG_ESCAPE) { | 480 | if (flags & JFS_FLAG_ESCAPE) { |
| 481 | *((__be32 *)bh->b_data) = | 481 | *((__be32 *)nbh->b_data) = |
| 482 | cpu_to_be32(JFS_MAGIC_NUMBER); | 482 | cpu_to_be32(JFS_MAGIC_NUMBER); |
| 483 | } | 483 | } |
| 484 | 484 | ||
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c index ad2eacf570c6..d5f8eee7c88c 100644 --- a/fs/jbd/revoke.c +++ b/fs/jbd/revoke.c | |||
| @@ -173,13 +173,13 @@ int __init journal_init_revoke_caches(void) | |||
| 173 | 0, | 173 | 0, |
| 174 | SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY, | 174 | SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY, |
| 175 | NULL); | 175 | NULL); |
| 176 | if (revoke_record_cache == 0) | 176 | if (!revoke_record_cache) |
| 177 | return -ENOMEM; | 177 | return -ENOMEM; |
| 178 | 178 | ||
| 179 | revoke_table_cache = kmem_cache_create("revoke_table", | 179 | revoke_table_cache = kmem_cache_create("revoke_table", |
| 180 | sizeof(struct jbd_revoke_table_s), | 180 | sizeof(struct jbd_revoke_table_s), |
| 181 | 0, SLAB_TEMPORARY, NULL); | 181 | 0, SLAB_TEMPORARY, NULL); |
| 182 | if (revoke_table_cache == 0) { | 182 | if (!revoke_table_cache) { |
| 183 | kmem_cache_destroy(revoke_record_cache); | 183 | kmem_cache_destroy(revoke_record_cache); |
| 184 | revoke_record_cache = NULL; | 184 | revoke_record_cache = NULL; |
| 185 | return -ENOMEM; | 185 | return -ENOMEM; |
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 038ed7436199..2c9e8f5d13aa 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c | |||
| @@ -369,7 +369,7 @@ out: | |||
| 369 | 369 | ||
| 370 | 370 | ||
| 371 | /** | 371 | /** |
| 372 | * int journal_restart() - restart a handle . | 372 | * int journal_restart() - restart a handle. |
| 373 | * @handle: handle to restart | 373 | * @handle: handle to restart |
| 374 | * @nblocks: nr credits requested | 374 | * @nblocks: nr credits requested |
| 375 | * | 375 | * |
| @@ -844,8 +844,7 @@ out: | |||
| 844 | } | 844 | } |
| 845 | 845 | ||
| 846 | /** | 846 | /** |
| 847 | * int journal_get_undo_access() - Notify intent to modify metadata with | 847 | * int journal_get_undo_access() - Notify intent to modify metadata with non-rewindable consequences |
| 848 | * non-rewindable consequences | ||
| 849 | * @handle: transaction | 848 | * @handle: transaction |
| 850 | * @bh: buffer to undo | 849 | * @bh: buffer to undo |
| 851 | * @credits: store the number of taken credits here (if not NULL) | 850 | * @credits: store the number of taken credits here (if not NULL) |
| @@ -921,12 +920,14 @@ out: | |||
| 921 | } | 920 | } |
| 922 | 921 | ||
| 923 | /** | 922 | /** |
| 924 | * int journal_dirty_data() - mark a buffer as containing dirty data which | 923 | * int journal_dirty_data() - mark a buffer as containing dirty data to be flushed |
| 925 | * needs to be flushed before we can commit the | ||
| 926 | * current transaction. | ||
| 927 | * @handle: transaction | 924 | * @handle: transaction |
| 928 | * @bh: bufferhead to mark | 925 | * @bh: bufferhead to mark |
| 929 | * | 926 | * |
| 927 | * Description: | ||
| 928 | * Mark a buffer as containing dirty data which needs to be flushed before | ||
| 929 | * we can commit the current transaction. | ||
| 930 | * | ||
| 930 | * The buffer is placed on the transaction's data list and is marked as | 931 | * The buffer is placed on the transaction's data list and is marked as |
| 931 | * belonging to the transaction. | 932 | * belonging to the transaction. |
| 932 | * | 933 | * |
| @@ -1098,11 +1099,11 @@ no_journal: | |||
| 1098 | } | 1099 | } |
| 1099 | 1100 | ||
| 1100 | /** | 1101 | /** |
| 1101 | * int journal_dirty_metadata() - mark a buffer as containing dirty metadata | 1102 | * int journal_dirty_metadata() - mark a buffer as containing dirty metadata |
| 1102 | * @handle: transaction to add buffer to. | 1103 | * @handle: transaction to add buffer to. |
| 1103 | * @bh: buffer to mark | 1104 | * @bh: buffer to mark |
| 1104 | * | 1105 | * |
| 1105 | * mark dirty metadata which needs to be journaled as part of the current | 1106 | * Mark dirty metadata which needs to be journaled as part of the current |
| 1106 | * transaction. | 1107 | * transaction. |
| 1107 | * | 1108 | * |
| 1108 | * The buffer is placed on the transaction's metadata list and is marked | 1109 | * The buffer is placed on the transaction's metadata list and is marked |
| @@ -1425,7 +1426,8 @@ int journal_stop(handle_t *handle) | |||
| 1425 | return err; | 1426 | return err; |
| 1426 | } | 1427 | } |
| 1427 | 1428 | ||
| 1428 | /**int journal_force_commit() - force any uncommitted transactions | 1429 | /** |
| 1430 | * int journal_force_commit() - force any uncommitted transactions | ||
| 1429 | * @journal: journal to force | 1431 | * @journal: journal to force |
| 1430 | * | 1432 | * |
| 1431 | * For synchronous operations: force any uncommitted transactions | 1433 | * For synchronous operations: force any uncommitted transactions |
| @@ -1902,13 +1904,12 @@ zap_buffer_unlocked: | |||
| 1902 | } | 1904 | } |
| 1903 | 1905 | ||
| 1904 | /** | 1906 | /** |
| 1905 | * void journal_invalidatepage() | 1907 | * void journal_invalidatepage() - invalidate a journal page |
| 1906 | * @journal: journal to use for flush... | 1908 | * @journal: journal to use for flush |
| 1907 | * @page: page to flush | 1909 | * @page: page to flush |
| 1908 | * @offset: length of page to invalidate. | 1910 | * @offset: length of page to invalidate. |
| 1909 | * | 1911 | * |
| 1910 | * Reap page buffers containing data after offset in page. | 1912 | * Reap page buffers containing data after offset in page. |
| 1911 | * | ||
| 1912 | */ | 1913 | */ |
| 1913 | void journal_invalidatepage(journal_t *journal, | 1914 | void journal_invalidatepage(journal_t *journal, |
| 1914 | struct page *page, | 1915 | struct page *page, |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 96ba846992e9..954cff001df6 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
| @@ -219,7 +219,7 @@ static int jbd2_journal_start_thread(journal_t *journal) | |||
| 219 | if (IS_ERR(t)) | 219 | if (IS_ERR(t)) |
| 220 | return PTR_ERR(t); | 220 | return PTR_ERR(t); |
| 221 | 221 | ||
| 222 | wait_event(journal->j_wait_done_commit, journal->j_task != 0); | 222 | wait_event(journal->j_wait_done_commit, journal->j_task != NULL); |
| 223 | return 0; | 223 | return 0; |
| 224 | } | 224 | } |
| 225 | 225 | ||
| @@ -231,7 +231,7 @@ static void journal_kill_thread(journal_t *journal) | |||
| 231 | while (journal->j_task) { | 231 | while (journal->j_task) { |
| 232 | wake_up(&journal->j_wait_commit); | 232 | wake_up(&journal->j_wait_commit); |
| 233 | spin_unlock(&journal->j_state_lock); | 233 | spin_unlock(&journal->j_state_lock); |
| 234 | wait_event(journal->j_wait_done_commit, journal->j_task == 0); | 234 | wait_event(journal->j_wait_done_commit, journal->j_task == NULL); |
| 235 | spin_lock(&journal->j_state_lock); | 235 | spin_lock(&journal->j_state_lock); |
| 236 | } | 236 | } |
| 237 | spin_unlock(&journal->j_state_lock); | 237 | spin_unlock(&journal->j_state_lock); |
| @@ -1969,14 +1969,14 @@ static int journal_init_jbd2_journal_head_cache(void) | |||
| 1969 | { | 1969 | { |
| 1970 | int retval; | 1970 | int retval; |
| 1971 | 1971 | ||
| 1972 | J_ASSERT(jbd2_journal_head_cache == 0); | 1972 | J_ASSERT(jbd2_journal_head_cache == NULL); |
| 1973 | jbd2_journal_head_cache = kmem_cache_create("jbd2_journal_head", | 1973 | jbd2_journal_head_cache = kmem_cache_create("jbd2_journal_head", |
| 1974 | sizeof(struct journal_head), | 1974 | sizeof(struct journal_head), |
| 1975 | 0, /* offset */ | 1975 | 0, /* offset */ |
| 1976 | SLAB_TEMPORARY, /* flags */ | 1976 | SLAB_TEMPORARY, /* flags */ |
| 1977 | NULL); /* ctor */ | 1977 | NULL); /* ctor */ |
| 1978 | retval = 0; | 1978 | retval = 0; |
| 1979 | if (jbd2_journal_head_cache == 0) { | 1979 | if (!jbd2_journal_head_cache) { |
| 1980 | retval = -ENOMEM; | 1980 | retval = -ENOMEM; |
| 1981 | printk(KERN_EMERG "JBD: no memory for journal_head cache\n"); | 1981 | printk(KERN_EMERG "JBD: no memory for journal_head cache\n"); |
| 1982 | } | 1982 | } |
| @@ -2002,14 +2002,14 @@ static struct journal_head *journal_alloc_journal_head(void) | |||
| 2002 | atomic_inc(&nr_journal_heads); | 2002 | atomic_inc(&nr_journal_heads); |
| 2003 | #endif | 2003 | #endif |
| 2004 | ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS); | 2004 | ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS); |
| 2005 | if (ret == 0) { | 2005 | if (!ret) { |
| 2006 | jbd_debug(1, "out of memory for journal_head\n"); | 2006 | jbd_debug(1, "out of memory for journal_head\n"); |
| 2007 | if (time_after(jiffies, last_warning + 5*HZ)) { | 2007 | if (time_after(jiffies, last_warning + 5*HZ)) { |
| 2008 | printk(KERN_NOTICE "ENOMEM in %s, retrying.\n", | 2008 | printk(KERN_NOTICE "ENOMEM in %s, retrying.\n", |
| 2009 | __FUNCTION__); | 2009 | __FUNCTION__); |
| 2010 | last_warning = jiffies; | 2010 | last_warning = jiffies; |
| 2011 | } | 2011 | } |
| 2012 | while (ret == 0) { | 2012 | while (!ret) { |
| 2013 | yield(); | 2013 | yield(); |
| 2014 | ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS); | 2014 | ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS); |
| 2015 | } | 2015 | } |
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c index 146411387ada..5d0405a9e7ca 100644 --- a/fs/jbd2/recovery.c +++ b/fs/jbd2/recovery.c | |||
| @@ -535,7 +535,7 @@ static int do_one_pass(journal_t *journal, | |||
| 535 | memcpy(nbh->b_data, obh->b_data, | 535 | memcpy(nbh->b_data, obh->b_data, |
| 536 | journal->j_blocksize); | 536 | journal->j_blocksize); |
| 537 | if (flags & JBD2_FLAG_ESCAPE) { | 537 | if (flags & JBD2_FLAG_ESCAPE) { |
| 538 | *((__be32 *)bh->b_data) = | 538 | *((__be32 *)nbh->b_data) = |
| 539 | cpu_to_be32(JBD2_MAGIC_NUMBER); | 539 | cpu_to_be32(JBD2_MAGIC_NUMBER); |
| 540 | } | 540 | } |
| 541 | 541 | ||
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c index df36f42e19e1..2e1453a5e998 100644 --- a/fs/jbd2/revoke.c +++ b/fs/jbd2/revoke.c | |||
| @@ -174,13 +174,13 @@ int __init jbd2_journal_init_revoke_caches(void) | |||
| 174 | 0, | 174 | 0, |
| 175 | SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY, | 175 | SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY, |
| 176 | NULL); | 176 | NULL); |
| 177 | if (jbd2_revoke_record_cache == 0) | 177 | if (!jbd2_revoke_record_cache) |
| 178 | return -ENOMEM; | 178 | return -ENOMEM; |
| 179 | 179 | ||
| 180 | jbd2_revoke_table_cache = kmem_cache_create("jbd2_revoke_table", | 180 | jbd2_revoke_table_cache = kmem_cache_create("jbd2_revoke_table", |
| 181 | sizeof(struct jbd2_revoke_table_s), | 181 | sizeof(struct jbd2_revoke_table_s), |
| 182 | 0, SLAB_TEMPORARY, NULL); | 182 | 0, SLAB_TEMPORARY, NULL); |
| 183 | if (jbd2_revoke_table_cache == 0) { | 183 | if (!jbd2_revoke_table_cache) { |
| 184 | kmem_cache_destroy(jbd2_revoke_record_cache); | 184 | kmem_cache_destroy(jbd2_revoke_record_cache); |
| 185 | jbd2_revoke_record_cache = NULL; | 185 | jbd2_revoke_record_cache = NULL; |
| 186 | return -ENOMEM; | 186 | return -ENOMEM; |
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index f9c5dd6f4b64..dcc2734e0b5d 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c | |||
| @@ -129,7 +129,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, | |||
| 129 | struct inode *inode = mapping->host; | 129 | struct inode *inode = mapping->host; |
| 130 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); | 130 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); |
| 131 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; | 131 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; |
| 132 | uint32_t pageofs = pos & (PAGE_CACHE_SIZE - 1); | 132 | uint32_t pageofs = index << PAGE_CACHE_SHIFT; |
| 133 | int ret = 0; | 133 | int ret = 0; |
| 134 | 134 | ||
| 135 | pg = __grab_cache_page(mapping, index); | 135 | pg = __grab_cache_page(mapping, index); |
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 08226464e563..1ed8bd4de941 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
| @@ -153,7 +153,7 @@ lockd(struct svc_rqst *rqstp) | |||
| 153 | */ | 153 | */ |
| 154 | while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) { | 154 | while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) { |
| 155 | long timeout = MAX_SCHEDULE_TIMEOUT; | 155 | long timeout = MAX_SCHEDULE_TIMEOUT; |
| 156 | char buf[RPC_MAX_ADDRBUFLEN]; | 156 | RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); |
| 157 | 157 | ||
| 158 | if (signalled()) { | 158 | if (signalled()) { |
| 159 | flush_signals(current); | 159 | flush_signals(current); |
diff --git a/fs/locks.c b/fs/locks.c index f36f0e61558d..43c0af21a0c5 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
| @@ -1275,13 +1275,13 @@ out: | |||
| 1275 | EXPORT_SYMBOL(__break_lease); | 1275 | EXPORT_SYMBOL(__break_lease); |
| 1276 | 1276 | ||
| 1277 | /** | 1277 | /** |
| 1278 | * lease_get_mtime | 1278 | * lease_get_mtime - get the last modified time of an inode |
| 1279 | * @inode: the inode | 1279 | * @inode: the inode |
| 1280 | * @time: pointer to a timespec which will contain the last modified time | 1280 | * @time: pointer to a timespec which will contain the last modified time |
| 1281 | * | 1281 | * |
| 1282 | * This is to force NFS clients to flush their caches for files with | 1282 | * This is to force NFS clients to flush their caches for files with |
| 1283 | * exclusive leases. The justification is that if someone has an | 1283 | * exclusive leases. The justification is that if someone has an |
| 1284 | * exclusive lease, then they could be modifiying it. | 1284 | * exclusive lease, then they could be modifying it. |
| 1285 | */ | 1285 | */ |
| 1286 | void lease_get_mtime(struct inode *inode, struct timespec *time) | 1286 | void lease_get_mtime(struct inode *inode, struct timespec *time) |
| 1287 | { | 1287 | { |
| @@ -1801,17 +1801,21 @@ again: | |||
| 1801 | if (error) | 1801 | if (error) |
| 1802 | goto out; | 1802 | goto out; |
| 1803 | 1803 | ||
| 1804 | for (;;) { | 1804 | if (filp->f_op && filp->f_op->lock != NULL) |
| 1805 | error = vfs_lock_file(filp, cmd, file_lock, NULL); | 1805 | error = filp->f_op->lock(filp, cmd, file_lock); |
| 1806 | if (error != -EAGAIN || cmd == F_SETLK) | 1806 | else { |
| 1807 | break; | 1807 | for (;;) { |
| 1808 | error = wait_event_interruptible(file_lock->fl_wait, | 1808 | error = posix_lock_file(filp, file_lock, NULL); |
| 1809 | !file_lock->fl_next); | 1809 | if (error != -EAGAIN || cmd == F_SETLK) |
| 1810 | if (!error) | 1810 | break; |
| 1811 | continue; | 1811 | error = wait_event_interruptible(file_lock->fl_wait, |
| 1812 | !file_lock->fl_next); | ||
| 1813 | if (!error) | ||
| 1814 | continue; | ||
| 1812 | 1815 | ||
| 1813 | locks_delete_block(file_lock); | 1816 | locks_delete_block(file_lock); |
| 1814 | break; | 1817 | break; |
| 1818 | } | ||
| 1815 | } | 1819 | } |
| 1816 | 1820 | ||
| 1817 | /* | 1821 | /* |
| @@ -1925,17 +1929,21 @@ again: | |||
| 1925 | if (error) | 1929 | if (error) |
| 1926 | goto out; | 1930 | goto out; |
| 1927 | 1931 | ||
| 1928 | for (;;) { | 1932 | if (filp->f_op && filp->f_op->lock != NULL) |
| 1929 | error = vfs_lock_file(filp, cmd, file_lock, NULL); | 1933 | error = filp->f_op->lock(filp, cmd, file_lock); |
| 1930 | if (error != -EAGAIN || cmd == F_SETLK64) | 1934 | else { |
| 1931 | break; | 1935 | for (;;) { |
| 1932 | error = wait_event_interruptible(file_lock->fl_wait, | 1936 | error = posix_lock_file(filp, file_lock, NULL); |
| 1933 | !file_lock->fl_next); | 1937 | if (error != -EAGAIN || cmd == F_SETLK64) |
| 1934 | if (!error) | 1938 | break; |
| 1935 | continue; | 1939 | error = wait_event_interruptible(file_lock->fl_wait, |
| 1940 | !file_lock->fl_next); | ||
| 1941 | if (!error) | ||
| 1942 | continue; | ||
| 1936 | 1943 | ||
| 1937 | locks_delete_block(file_lock); | 1944 | locks_delete_block(file_lock); |
| 1938 | break; | 1945 | break; |
| 1946 | } | ||
| 1939 | } | 1947 | } |
| 1940 | 1948 | ||
| 1941 | /* | 1949 | /* |
diff --git a/fs/mbcache.c b/fs/mbcache.c index eb31b73e7d69..ec88ff3d04a9 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c | |||
| @@ -399,11 +399,11 @@ mb_cache_destroy(struct mb_cache *cache) | |||
| 399 | * if no more memory was available. | 399 | * if no more memory was available. |
| 400 | */ | 400 | */ |
| 401 | struct mb_cache_entry * | 401 | struct mb_cache_entry * |
| 402 | mb_cache_entry_alloc(struct mb_cache *cache) | 402 | mb_cache_entry_alloc(struct mb_cache *cache, gfp_t gfp_flags) |
| 403 | { | 403 | { |
| 404 | struct mb_cache_entry *ce; | 404 | struct mb_cache_entry *ce; |
| 405 | 405 | ||
| 406 | ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL); | 406 | ce = kmem_cache_alloc(cache->c_entry_cache, gfp_flags); |
| 407 | if (ce) { | 407 | if (ce) { |
| 408 | atomic_inc(&cache->c_entry_count); | 408 | atomic_inc(&cache->c_entry_count); |
| 409 | INIT_LIST_HEAD(&ce->e_lru_list); | 409 | INIT_LIST_HEAD(&ce->e_lru_list); |
diff --git a/fs/mpage.c b/fs/mpage.c index 5df564366f36..235e4d3873a8 100644 --- a/fs/mpage.c +++ b/fs/mpage.c | |||
| @@ -325,16 +325,12 @@ confused: | |||
| 325 | } | 325 | } |
| 326 | 326 | ||
| 327 | /** | 327 | /** |
| 328 | * mpage_readpages - populate an address space with some pages, and | 328 | * mpage_readpages - populate an address space with some pages & start reads against them |
| 329 | * start reads against them. | ||
| 330 | * | ||
| 331 | * @mapping: the address_space | 329 | * @mapping: the address_space |
| 332 | * @pages: The address of a list_head which contains the target pages. These | 330 | * @pages: The address of a list_head which contains the target pages. These |
| 333 | * pages have their ->index populated and are otherwise uninitialised. | 331 | * pages have their ->index populated and are otherwise uninitialised. |
| 334 | * | ||
| 335 | * The page at @pages->prev has the lowest file offset, and reads should be | 332 | * The page at @pages->prev has the lowest file offset, and reads should be |
| 336 | * issued in @pages->prev to @pages->next order. | 333 | * issued in @pages->prev to @pages->next order. |
| 337 | * | ||
| 338 | * @nr_pages: The number of pages at *@pages | 334 | * @nr_pages: The number of pages at *@pages |
| 339 | * @get_block: The filesystem's block mapper function. | 335 | * @get_block: The filesystem's block mapper function. |
| 340 | * | 336 | * |
| @@ -360,6 +356,7 @@ confused: | |||
| 360 | * So an mpage read of the first 16 blocks of an ext2 file will cause I/O to be | 356 | * So an mpage read of the first 16 blocks of an ext2 file will cause I/O to be |
| 361 | * submitted in the following order: | 357 | * submitted in the following order: |
| 362 | * 12 0 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 | 358 | * 12 0 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 |
| 359 | * | ||
| 363 | * because the indirect block has to be read to get the mappings of blocks | 360 | * because the indirect block has to be read to get the mappings of blocks |
| 364 | * 13,14,15,16. Obviously, this impacts performance. | 361 | * 13,14,15,16. Obviously, this impacts performance. |
| 365 | * | 362 | * |
| @@ -656,9 +653,7 @@ out: | |||
| 656 | } | 653 | } |
| 657 | 654 | ||
| 658 | /** | 655 | /** |
| 659 | * mpage_writepages - walk the list of dirty pages of the given | 656 | * mpage_writepages - walk the list of dirty pages of the given address space & writepage() all of them |
| 660 | * address space and writepage() all of them. | ||
| 661 | * | ||
| 662 | * @mapping: address space structure to write | 657 | * @mapping: address space structure to write |
| 663 | * @wbc: subtract the number of written pages from *@wbc->nr_to_write | 658 | * @wbc: subtract the number of written pages from *@wbc->nr_to_write |
| 664 | * @get_block: the filesystem's block mapper function. | 659 | * @get_block: the filesystem's block mapper function. |
diff --git a/fs/namei.c b/fs/namei.c index 941c8e8228c0..8cf9bb9c2fc0 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -106,7 +106,7 @@ | |||
| 106 | * any extra contention... | 106 | * any extra contention... |
| 107 | */ | 107 | */ |
| 108 | 108 | ||
| 109 | static int link_path_walk(const char *name, struct nameidata *nd); | 109 | static int __link_path_walk(const char *name, struct nameidata *nd); |
| 110 | 110 | ||
| 111 | /* In order to reduce some races, while at the same time doing additional | 111 | /* In order to reduce some races, while at the same time doing additional |
| 112 | * checking and hopefully speeding things up, we copy filenames to the | 112 | * checking and hopefully speeding things up, we copy filenames to the |
| @@ -563,6 +563,37 @@ walk_init_root(const char *name, struct nameidata *nd) | |||
| 563 | return 1; | 563 | return 1; |
| 564 | } | 564 | } |
| 565 | 565 | ||
| 566 | /* | ||
| 567 | * Wrapper to retry pathname resolution whenever the underlying | ||
| 568 | * file system returns an ESTALE. | ||
| 569 | * | ||
| 570 | * Retry the whole path once, forcing real lookup requests | ||
| 571 | * instead of relying on the dcache. | ||
| 572 | */ | ||
| 573 | static __always_inline int link_path_walk(const char *name, struct nameidata *nd) | ||
| 574 | { | ||
| 575 | struct path save = nd->path; | ||
| 576 | int result; | ||
| 577 | |||
| 578 | /* make sure the stuff we saved doesn't go away */ | ||
| 579 | dget(save.dentry); | ||
| 580 | mntget(save.mnt); | ||
| 581 | |||
| 582 | result = __link_path_walk(name, nd); | ||
| 583 | if (result == -ESTALE) { | ||
| 584 | /* nd->path had been dropped */ | ||
| 585 | nd->path = save; | ||
| 586 | dget(nd->path.dentry); | ||
| 587 | mntget(nd->path.mnt); | ||
| 588 | nd->flags |= LOOKUP_REVAL; | ||
| 589 | result = __link_path_walk(name, nd); | ||
| 590 | } | ||
| 591 | |||
| 592 | path_put(&save); | ||
| 593 | |||
| 594 | return result; | ||
| 595 | } | ||
| 596 | |||
| 566 | static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link) | 597 | static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link) |
| 567 | { | 598 | { |
| 568 | int res = 0; | 599 | int res = 0; |
| @@ -1020,36 +1051,6 @@ return_err: | |||
| 1020 | return err; | 1051 | return err; |
| 1021 | } | 1052 | } |
| 1022 | 1053 | ||
| 1023 | /* | ||
| 1024 | * Wrapper to retry pathname resolution whenever the underlying | ||
| 1025 | * file system returns an ESTALE. | ||
| 1026 | * | ||
| 1027 | * Retry the whole path once, forcing real lookup requests | ||
| 1028 | * instead of relying on the dcache. | ||
| 1029 | */ | ||
| 1030 | static int link_path_walk(const char *name, struct nameidata *nd) | ||
| 1031 | { | ||
| 1032 | struct nameidata save = *nd; | ||
| 1033 | int result; | ||
| 1034 | |||
| 1035 | /* make sure the stuff we saved doesn't go away */ | ||
| 1036 | dget(save.path.dentry); | ||
| 1037 | mntget(save.path.mnt); | ||
| 1038 | |||
| 1039 | result = __link_path_walk(name, nd); | ||
| 1040 | if (result == -ESTALE) { | ||
| 1041 | *nd = save; | ||
| 1042 | dget(nd->path.dentry); | ||
| 1043 | mntget(nd->path.mnt); | ||
| 1044 | nd->flags |= LOOKUP_REVAL; | ||
| 1045 | result = __link_path_walk(name, nd); | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | path_put(&save.path); | ||
| 1049 | |||
| 1050 | return result; | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | static int path_walk(const char *name, struct nameidata *nd) | 1054 | static int path_walk(const char *name, struct nameidata *nd) |
| 1054 | { | 1055 | { |
| 1055 | current->total_link_count = 0; | 1056 | current->total_link_count = 0; |
| @@ -1364,13 +1365,13 @@ static int __lookup_one_len(const char *name, struct qstr *this, | |||
| 1364 | } | 1365 | } |
| 1365 | 1366 | ||
| 1366 | /** | 1367 | /** |
| 1367 | * lookup_one_len: filesystem helper to lookup single pathname component | 1368 | * lookup_one_len - filesystem helper to lookup single pathname component |
| 1368 | * @name: pathname component to lookup | 1369 | * @name: pathname component to lookup |
| 1369 | * @base: base directory to lookup from | 1370 | * @base: base directory to lookup from |
| 1370 | * @len: maximum length @len should be interpreted to | 1371 | * @len: maximum length @len should be interpreted to |
| 1371 | * | 1372 | * |
| 1372 | * Note that this routine is purely a helper for filesystem useage and should | 1373 | * Note that this routine is purely a helper for filesystem usage and should |
| 1373 | * not be called by generic code. Also note that by using this function to | 1374 | * not be called by generic code. Also note that by using this function the |
| 1374 | * nameidata argument is passed to the filesystem methods and a filesystem | 1375 | * nameidata argument is passed to the filesystem methods and a filesystem |
| 1375 | * using this helper needs to be prepared for that. | 1376 | * using this helper needs to be prepared for that. |
| 1376 | */ | 1377 | */ |
diff --git a/fs/namespace.c b/fs/namespace.c index 7953c96a2071..94f026ec990a 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
| @@ -155,15 +155,15 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns) | |||
| 155 | } | 155 | } |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd) | 158 | static void detach_mnt(struct vfsmount *mnt, struct path *old_path) |
| 159 | { | 159 | { |
| 160 | old_nd->path.dentry = mnt->mnt_mountpoint; | 160 | old_path->dentry = mnt->mnt_mountpoint; |
| 161 | old_nd->path.mnt = mnt->mnt_parent; | 161 | old_path->mnt = mnt->mnt_parent; |
| 162 | mnt->mnt_parent = mnt; | 162 | mnt->mnt_parent = mnt; |
| 163 | mnt->mnt_mountpoint = mnt->mnt_root; | 163 | mnt->mnt_mountpoint = mnt->mnt_root; |
| 164 | list_del_init(&mnt->mnt_child); | 164 | list_del_init(&mnt->mnt_child); |
| 165 | list_del_init(&mnt->mnt_hash); | 165 | list_del_init(&mnt->mnt_hash); |
| 166 | old_nd->path.dentry->d_mounted--; | 166 | old_path->dentry->d_mounted--; |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, | 169 | void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, |
| @@ -174,12 +174,12 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, | |||
| 174 | dentry->d_mounted++; | 174 | dentry->d_mounted++; |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd) | 177 | static void attach_mnt(struct vfsmount *mnt, struct path *path) |
| 178 | { | 178 | { |
| 179 | mnt_set_mountpoint(nd->path.mnt, nd->path.dentry, mnt); | 179 | mnt_set_mountpoint(path->mnt, path->dentry, mnt); |
| 180 | list_add_tail(&mnt->mnt_hash, mount_hashtable + | 180 | list_add_tail(&mnt->mnt_hash, mount_hashtable + |
| 181 | hash(nd->path.mnt, nd->path.dentry)); | 181 | hash(path->mnt, path->dentry)); |
| 182 | list_add_tail(&mnt->mnt_child, &nd->path.mnt->mnt_mounts); | 182 | list_add_tail(&mnt->mnt_child, &path->mnt->mnt_mounts); |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | /* | 185 | /* |
| @@ -262,10 +262,8 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root, | |||
| 262 | /* stick the duplicate mount on the same expiry list | 262 | /* stick the duplicate mount on the same expiry list |
| 263 | * as the original if that was on one */ | 263 | * as the original if that was on one */ |
| 264 | if (flag & CL_EXPIRE) { | 264 | if (flag & CL_EXPIRE) { |
| 265 | spin_lock(&vfsmount_lock); | ||
| 266 | if (!list_empty(&old->mnt_expire)) | 265 | if (!list_empty(&old->mnt_expire)) |
| 267 | list_add(&mnt->mnt_expire, &old->mnt_expire); | 266 | list_add(&mnt->mnt_expire, &old->mnt_expire); |
| 268 | spin_unlock(&vfsmount_lock); | ||
| 269 | } | 267 | } |
| 270 | } | 268 | } |
| 271 | return mnt; | 269 | return mnt; |
| @@ -548,6 +546,7 @@ void release_mounts(struct list_head *head) | |||
| 548 | m = mnt->mnt_parent; | 546 | m = mnt->mnt_parent; |
| 549 | mnt->mnt_mountpoint = mnt->mnt_root; | 547 | mnt->mnt_mountpoint = mnt->mnt_root; |
| 550 | mnt->mnt_parent = mnt; | 548 | mnt->mnt_parent = mnt; |
| 549 | m->mnt_ghosts--; | ||
| 551 | spin_unlock(&vfsmount_lock); | 550 | spin_unlock(&vfsmount_lock); |
| 552 | dput(dentry); | 551 | dput(dentry); |
| 553 | mntput(m); | 552 | mntput(m); |
| @@ -572,12 +571,16 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) | |||
| 572 | __touch_mnt_namespace(p->mnt_ns); | 571 | __touch_mnt_namespace(p->mnt_ns); |
| 573 | p->mnt_ns = NULL; | 572 | p->mnt_ns = NULL; |
| 574 | list_del_init(&p->mnt_child); | 573 | list_del_init(&p->mnt_child); |
| 575 | if (p->mnt_parent != p) | 574 | if (p->mnt_parent != p) { |
| 575 | p->mnt_parent->mnt_ghosts++; | ||
| 576 | p->mnt_mountpoint->d_mounted--; | 576 | p->mnt_mountpoint->d_mounted--; |
| 577 | } | ||
| 577 | change_mnt_propagation(p, MS_PRIVATE); | 578 | change_mnt_propagation(p, MS_PRIVATE); |
| 578 | } | 579 | } |
| 579 | } | 580 | } |
| 580 | 581 | ||
| 582 | static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts); | ||
| 583 | |||
| 581 | static int do_umount(struct vfsmount *mnt, int flags) | 584 | static int do_umount(struct vfsmount *mnt, int flags) |
| 582 | { | 585 | { |
| 583 | struct super_block *sb = mnt->mnt_sb; | 586 | struct super_block *sb = mnt->mnt_sb; |
| @@ -650,6 +653,9 @@ static int do_umount(struct vfsmount *mnt, int flags) | |||
| 650 | spin_lock(&vfsmount_lock); | 653 | spin_lock(&vfsmount_lock); |
| 651 | event++; | 654 | event++; |
| 652 | 655 | ||
| 656 | if (!(flags & MNT_DETACH)) | ||
| 657 | shrink_submounts(mnt, &umount_list); | ||
| 658 | |||
| 653 | retval = -EBUSY; | 659 | retval = -EBUSY; |
| 654 | if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) { | 660 | if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) { |
| 655 | if (!list_empty(&mnt->mnt_list)) | 661 | if (!list_empty(&mnt->mnt_list)) |
| @@ -744,7 +750,7 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, | |||
| 744 | int flag) | 750 | int flag) |
| 745 | { | 751 | { |
| 746 | struct vfsmount *res, *p, *q, *r, *s; | 752 | struct vfsmount *res, *p, *q, *r, *s; |
| 747 | struct nameidata nd; | 753 | struct path path; |
| 748 | 754 | ||
| 749 | if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) | 755 | if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) |
| 750 | return NULL; | 756 | return NULL; |
| @@ -769,14 +775,14 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, | |||
| 769 | q = q->mnt_parent; | 775 | q = q->mnt_parent; |
| 770 | } | 776 | } |
| 771 | p = s; | 777 | p = s; |
| 772 | nd.path.mnt = q; | 778 | path.mnt = q; |
| 773 | nd.path.dentry = p->mnt_mountpoint; | 779 | path.dentry = p->mnt_mountpoint; |
| 774 | q = clone_mnt(p, p->mnt_root, flag); | 780 | q = clone_mnt(p, p->mnt_root, flag); |
| 775 | if (!q) | 781 | if (!q) |
| 776 | goto Enomem; | 782 | goto Enomem; |
| 777 | spin_lock(&vfsmount_lock); | 783 | spin_lock(&vfsmount_lock); |
| 778 | list_add_tail(&q->mnt_list, &res->mnt_list); | 784 | list_add_tail(&q->mnt_list, &res->mnt_list); |
| 779 | attach_mnt(q, &nd); | 785 | attach_mnt(q, &path); |
| 780 | spin_unlock(&vfsmount_lock); | 786 | spin_unlock(&vfsmount_lock); |
| 781 | } | 787 | } |
| 782 | } | 788 | } |
| @@ -876,11 +882,11 @@ void drop_collected_mounts(struct vfsmount *mnt) | |||
| 876 | * in allocations. | 882 | * in allocations. |
| 877 | */ | 883 | */ |
| 878 | static int attach_recursive_mnt(struct vfsmount *source_mnt, | 884 | static int attach_recursive_mnt(struct vfsmount *source_mnt, |
| 879 | struct nameidata *nd, struct nameidata *parent_nd) | 885 | struct path *path, struct path *parent_path) |
| 880 | { | 886 | { |
| 881 | LIST_HEAD(tree_list); | 887 | LIST_HEAD(tree_list); |
| 882 | struct vfsmount *dest_mnt = nd->path.mnt; | 888 | struct vfsmount *dest_mnt = path->mnt; |
| 883 | struct dentry *dest_dentry = nd->path.dentry; | 889 | struct dentry *dest_dentry = path->dentry; |
| 884 | struct vfsmount *child, *p; | 890 | struct vfsmount *child, *p; |
| 885 | 891 | ||
| 886 | if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list)) | 892 | if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list)) |
| @@ -892,9 +898,9 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt, | |||
| 892 | } | 898 | } |
| 893 | 899 | ||
| 894 | spin_lock(&vfsmount_lock); | 900 | spin_lock(&vfsmount_lock); |
| 895 | if (parent_nd) { | 901 | if (parent_path) { |
| 896 | detach_mnt(source_mnt, parent_nd); | 902 | detach_mnt(source_mnt, parent_path); |
| 897 | attach_mnt(source_mnt, nd); | 903 | attach_mnt(source_mnt, path); |
| 898 | touch_mnt_namespace(current->nsproxy->mnt_ns); | 904 | touch_mnt_namespace(current->nsproxy->mnt_ns); |
| 899 | } else { | 905 | } else { |
| 900 | mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt); | 906 | mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt); |
| @@ -930,7 +936,7 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd) | |||
| 930 | 936 | ||
| 931 | err = -ENOENT; | 937 | err = -ENOENT; |
| 932 | if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry)) | 938 | if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry)) |
| 933 | err = attach_recursive_mnt(mnt, nd, NULL); | 939 | err = attach_recursive_mnt(mnt, &nd->path, NULL); |
| 934 | out_unlock: | 940 | out_unlock: |
| 935 | mutex_unlock(&nd->path.dentry->d_inode->i_mutex); | 941 | mutex_unlock(&nd->path.dentry->d_inode->i_mutex); |
| 936 | if (!err) | 942 | if (!err) |
| @@ -1059,7 +1065,8 @@ static inline int tree_contains_unbindable(struct vfsmount *mnt) | |||
| 1059 | */ | 1065 | */ |
| 1060 | static noinline int do_move_mount(struct nameidata *nd, char *old_name) | 1066 | static noinline int do_move_mount(struct nameidata *nd, char *old_name) |
| 1061 | { | 1067 | { |
| 1062 | struct nameidata old_nd, parent_nd; | 1068 | struct nameidata old_nd; |
| 1069 | struct path parent_path; | ||
| 1063 | struct vfsmount *p; | 1070 | struct vfsmount *p; |
| 1064 | int err = 0; | 1071 | int err = 0; |
| 1065 | if (!capable(CAP_SYS_ADMIN)) | 1072 | if (!capable(CAP_SYS_ADMIN)) |
| @@ -1114,21 +1121,19 @@ static noinline int do_move_mount(struct nameidata *nd, char *old_name) | |||
| 1114 | if (p == old_nd.path.mnt) | 1121 | if (p == old_nd.path.mnt) |
| 1115 | goto out1; | 1122 | goto out1; |
| 1116 | 1123 | ||
| 1117 | err = attach_recursive_mnt(old_nd.path.mnt, nd, &parent_nd); | 1124 | err = attach_recursive_mnt(old_nd.path.mnt, &nd->path, &parent_path); |
| 1118 | if (err) | 1125 | if (err) |
| 1119 | goto out1; | 1126 | goto out1; |
| 1120 | 1127 | ||
| 1121 | spin_lock(&vfsmount_lock); | ||
| 1122 | /* if the mount is moved, it should no longer be expire | 1128 | /* if the mount is moved, it should no longer be expire |
| 1123 | * automatically */ | 1129 | * automatically */ |
| 1124 | list_del_init(&old_nd.path.mnt->mnt_expire); | 1130 | list_del_init(&old_nd.path.mnt->mnt_expire); |
| 1125 | spin_unlock(&vfsmount_lock); | ||
| 1126 | out1: | 1131 | out1: |
| 1127 | mutex_unlock(&nd->path.dentry->d_inode->i_mutex); | 1132 | mutex_unlock(&nd->path.dentry->d_inode->i_mutex); |
| 1128 | out: | 1133 | out: |
| 1129 | up_write(&namespace_sem); | 1134 | up_write(&namespace_sem); |
| 1130 | if (!err) | 1135 | if (!err) |
| 1131 | path_put(&parent_nd.path); | 1136 | path_put(&parent_path); |
| 1132 | path_put(&old_nd.path); | 1137 | path_put(&old_nd.path); |
| 1133 | return err; | 1138 | return err; |
| 1134 | } | 1139 | } |
| @@ -1189,12 +1194,9 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd, | |||
| 1189 | if ((err = graft_tree(newmnt, nd))) | 1194 | if ((err = graft_tree(newmnt, nd))) |
| 1190 | goto unlock; | 1195 | goto unlock; |
| 1191 | 1196 | ||
| 1192 | if (fslist) { | 1197 | if (fslist) /* add to the specified expiration list */ |
| 1193 | /* add to the specified expiration list */ | ||
| 1194 | spin_lock(&vfsmount_lock); | ||
| 1195 | list_add_tail(&newmnt->mnt_expire, fslist); | 1198 | list_add_tail(&newmnt->mnt_expire, fslist); |
| 1196 | spin_unlock(&vfsmount_lock); | 1199 | |
| 1197 | } | ||
| 1198 | up_write(&namespace_sem); | 1200 | up_write(&namespace_sem); |
| 1199 | return 0; | 1201 | return 0; |
| 1200 | 1202 | ||
| @@ -1206,75 +1208,6 @@ unlock: | |||
| 1206 | 1208 | ||
| 1207 | EXPORT_SYMBOL_GPL(do_add_mount); | 1209 | EXPORT_SYMBOL_GPL(do_add_mount); |
| 1208 | 1210 | ||
| 1209 | static void expire_mount(struct vfsmount *mnt, struct list_head *mounts, | ||
| 1210 | struct list_head *umounts) | ||
| 1211 | { | ||
| 1212 | spin_lock(&vfsmount_lock); | ||
| 1213 | |||
| 1214 | /* | ||
| 1215 | * Check if mount is still attached, if not, let whoever holds it deal | ||
| 1216 | * with the sucker | ||
| 1217 | */ | ||
| 1218 | if (mnt->mnt_parent == mnt) { | ||
| 1219 | spin_unlock(&vfsmount_lock); | ||
| 1220 | return; | ||
| 1221 | } | ||
| 1222 | |||
| 1223 | /* | ||
| 1224 | * Check that it is still dead: the count should now be 2 - as | ||
| 1225 | * contributed by the vfsmount parent and the mntget above | ||
| 1226 | */ | ||
| 1227 | if (!propagate_mount_busy(mnt, 2)) { | ||
| 1228 | /* delete from the namespace */ | ||
| 1229 | touch_mnt_namespace(mnt->mnt_ns); | ||
| 1230 | list_del_init(&mnt->mnt_list); | ||
| 1231 | mnt->mnt_ns = NULL; | ||
| 1232 | umount_tree(mnt, 1, umounts); | ||
| 1233 | spin_unlock(&vfsmount_lock); | ||
| 1234 | } else { | ||
| 1235 | /* | ||
| 1236 | * Someone brought it back to life whilst we didn't have any | ||
| 1237 | * locks held so return it to the expiration list | ||
| 1238 | */ | ||
| 1239 | list_add_tail(&mnt->mnt_expire, mounts); | ||
| 1240 | spin_unlock(&vfsmount_lock); | ||
| 1241 | } | ||
| 1242 | } | ||
| 1243 | |||
| 1244 | /* | ||
| 1245 | * go through the vfsmounts we've just consigned to the graveyard to | ||
| 1246 | * - check that they're still dead | ||
| 1247 | * - delete the vfsmount from the appropriate namespace under lock | ||
| 1248 | * - dispose of the corpse | ||
| 1249 | */ | ||
| 1250 | static void expire_mount_list(struct list_head *graveyard, struct list_head *mounts) | ||
| 1251 | { | ||
| 1252 | struct mnt_namespace *ns; | ||
| 1253 | struct vfsmount *mnt; | ||
| 1254 | |||
| 1255 | while (!list_empty(graveyard)) { | ||
| 1256 | LIST_HEAD(umounts); | ||
| 1257 | mnt = list_first_entry(graveyard, struct vfsmount, mnt_expire); | ||
| 1258 | list_del_init(&mnt->mnt_expire); | ||
| 1259 | |||
| 1260 | /* don't do anything if the namespace is dead - all the | ||
| 1261 | * vfsmounts from it are going away anyway */ | ||
| 1262 | ns = mnt->mnt_ns; | ||
| 1263 | if (!ns || !ns->root) | ||
| 1264 | continue; | ||
| 1265 | get_mnt_ns(ns); | ||
| 1266 | |||
| 1267 | spin_unlock(&vfsmount_lock); | ||
| 1268 | down_write(&namespace_sem); | ||
| 1269 | expire_mount(mnt, mounts, &umounts); | ||
| 1270 | up_write(&namespace_sem); | ||
| 1271 | release_mounts(&umounts); | ||
| 1272 | mntput(mnt); | ||
| 1273 | put_mnt_ns(ns); | ||
| 1274 | spin_lock(&vfsmount_lock); | ||
| 1275 | } | ||
| 1276 | } | ||
| 1277 | |||
| 1278 | /* | 1211 | /* |
| 1279 | * process a list of expirable mountpoints with the intent of discarding any | 1212 | * process a list of expirable mountpoints with the intent of discarding any |
| 1280 | * mountpoints that aren't in use and haven't been touched since last we came | 1213 | * mountpoints that aren't in use and haven't been touched since last we came |
| @@ -1284,10 +1217,12 @@ void mark_mounts_for_expiry(struct list_head *mounts) | |||
| 1284 | { | 1217 | { |
| 1285 | struct vfsmount *mnt, *next; | 1218 | struct vfsmount *mnt, *next; |
| 1286 | LIST_HEAD(graveyard); | 1219 | LIST_HEAD(graveyard); |
| 1220 | LIST_HEAD(umounts); | ||
| 1287 | 1221 | ||
| 1288 | if (list_empty(mounts)) | 1222 | if (list_empty(mounts)) |
| 1289 | return; | 1223 | return; |
| 1290 | 1224 | ||
| 1225 | down_write(&namespace_sem); | ||
| 1291 | spin_lock(&vfsmount_lock); | 1226 | spin_lock(&vfsmount_lock); |
| 1292 | 1227 | ||
| 1293 | /* extract from the expiration list every vfsmount that matches the | 1228 | /* extract from the expiration list every vfsmount that matches the |
| @@ -1298,16 +1233,19 @@ void mark_mounts_for_expiry(struct list_head *mounts) | |||
| 1298 | */ | 1233 | */ |
| 1299 | list_for_each_entry_safe(mnt, next, mounts, mnt_expire) { | 1234 | list_for_each_entry_safe(mnt, next, mounts, mnt_expire) { |
| 1300 | if (!xchg(&mnt->mnt_expiry_mark, 1) || | 1235 | if (!xchg(&mnt->mnt_expiry_mark, 1) || |
| 1301 | atomic_read(&mnt->mnt_count) != 1) | 1236 | propagate_mount_busy(mnt, 1)) |
| 1302 | continue; | 1237 | continue; |
| 1303 | |||
| 1304 | mntget(mnt); | ||
| 1305 | list_move(&mnt->mnt_expire, &graveyard); | 1238 | list_move(&mnt->mnt_expire, &graveyard); |
| 1306 | } | 1239 | } |
| 1307 | 1240 | while (!list_empty(&graveyard)) { | |
| 1308 | expire_mount_list(&graveyard, mounts); | 1241 | mnt = list_first_entry(&graveyard, struct vfsmount, mnt_expire); |
| 1309 | 1242 | touch_mnt_namespace(mnt->mnt_ns); | |
| 1243 | umount_tree(mnt, 1, &umounts); | ||
| 1244 | } | ||
| 1310 | spin_unlock(&vfsmount_lock); | 1245 | spin_unlock(&vfsmount_lock); |
| 1246 | up_write(&namespace_sem); | ||
| 1247 | |||
| 1248 | release_mounts(&umounts); | ||
| 1311 | } | 1249 | } |
| 1312 | 1250 | ||
| 1313 | EXPORT_SYMBOL_GPL(mark_mounts_for_expiry); | 1251 | EXPORT_SYMBOL_GPL(mark_mounts_for_expiry); |
| @@ -1343,7 +1281,6 @@ resume: | |||
| 1343 | } | 1281 | } |
| 1344 | 1282 | ||
| 1345 | if (!propagate_mount_busy(mnt, 1)) { | 1283 | if (!propagate_mount_busy(mnt, 1)) { |
| 1346 | mntget(mnt); | ||
| 1347 | list_move_tail(&mnt->mnt_expire, graveyard); | 1284 | list_move_tail(&mnt->mnt_expire, graveyard); |
| 1348 | found++; | 1285 | found++; |
| 1349 | } | 1286 | } |
| @@ -1363,22 +1300,22 @@ resume: | |||
| 1363 | * process a list of expirable mountpoints with the intent of discarding any | 1300 | * process a list of expirable mountpoints with the intent of discarding any |
| 1364 | * submounts of a specific parent mountpoint | 1301 | * submounts of a specific parent mountpoint |
| 1365 | */ | 1302 | */ |
| 1366 | void shrink_submounts(struct vfsmount *mountpoint, struct list_head *mounts) | 1303 | static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts) |
| 1367 | { | 1304 | { |
| 1368 | LIST_HEAD(graveyard); | 1305 | LIST_HEAD(graveyard); |
| 1369 | int found; | 1306 | struct vfsmount *m; |
| 1370 | |||
| 1371 | spin_lock(&vfsmount_lock); | ||
| 1372 | 1307 | ||
| 1373 | /* extract submounts of 'mountpoint' from the expiration list */ | 1308 | /* extract submounts of 'mountpoint' from the expiration list */ |
| 1374 | while ((found = select_submounts(mountpoint, &graveyard)) != 0) | 1309 | while (select_submounts(mnt, &graveyard)) { |
| 1375 | expire_mount_list(&graveyard, mounts); | 1310 | while (!list_empty(&graveyard)) { |
| 1376 | 1311 | m = list_first_entry(&graveyard, struct vfsmount, | |
| 1377 | spin_unlock(&vfsmount_lock); | 1312 | mnt_expire); |
| 1313 | touch_mnt_namespace(mnt->mnt_ns); | ||
| 1314 | umount_tree(mnt, 1, umounts); | ||
| 1315 | } | ||
| 1316 | } | ||
| 1378 | } | 1317 | } |
| 1379 | 1318 | ||
| 1380 | EXPORT_SYMBOL_GPL(shrink_submounts); | ||
| 1381 | |||
| 1382 | /* | 1319 | /* |
| 1383 | * Some copy_from_user() implementations do not return the exact number of | 1320 | * Some copy_from_user() implementations do not return the exact number of |
| 1384 | * bytes remaining to copy on a fault. But copy_mount_options() requires that. | 1321 | * bytes remaining to copy on a fault. But copy_mount_options() requires that. |
| @@ -1683,7 +1620,7 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path) | |||
| 1683 | path_put(&old_pwd); | 1620 | path_put(&old_pwd); |
| 1684 | } | 1621 | } |
| 1685 | 1622 | ||
| 1686 | static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd) | 1623 | static void chroot_fs_refs(struct path *old_root, struct path *new_root) |
| 1687 | { | 1624 | { |
| 1688 | struct task_struct *g, *p; | 1625 | struct task_struct *g, *p; |
| 1689 | struct fs_struct *fs; | 1626 | struct fs_struct *fs; |
| @@ -1695,12 +1632,12 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd) | |||
| 1695 | if (fs) { | 1632 | if (fs) { |
| 1696 | atomic_inc(&fs->count); | 1633 | atomic_inc(&fs->count); |
| 1697 | task_unlock(p); | 1634 | task_unlock(p); |
| 1698 | if (fs->root.dentry == old_nd->path.dentry | 1635 | if (fs->root.dentry == old_root->dentry |
| 1699 | && fs->root.mnt == old_nd->path.mnt) | 1636 | && fs->root.mnt == old_root->mnt) |
| 1700 | set_fs_root(fs, &new_nd->path); | 1637 | set_fs_root(fs, new_root); |
| 1701 | if (fs->pwd.dentry == old_nd->path.dentry | 1638 | if (fs->pwd.dentry == old_root->dentry |
| 1702 | && fs->pwd.mnt == old_nd->path.mnt) | 1639 | && fs->pwd.mnt == old_root->mnt) |
| 1703 | set_fs_pwd(fs, &new_nd->path); | 1640 | set_fs_pwd(fs, new_root); |
| 1704 | put_fs_struct(fs); | 1641 | put_fs_struct(fs); |
| 1705 | } else | 1642 | } else |
| 1706 | task_unlock(p); | 1643 | task_unlock(p); |
| @@ -1737,7 +1674,8 @@ asmlinkage long sys_pivot_root(const char __user * new_root, | |||
| 1737 | const char __user * put_old) | 1674 | const char __user * put_old) |
| 1738 | { | 1675 | { |
| 1739 | struct vfsmount *tmp; | 1676 | struct vfsmount *tmp; |
| 1740 | struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd; | 1677 | struct nameidata new_nd, old_nd, user_nd; |
| 1678 | struct path parent_path, root_parent; | ||
| 1741 | int error; | 1679 | int error; |
| 1742 | 1680 | ||
| 1743 | if (!capable(CAP_SYS_ADMIN)) | 1681 | if (!capable(CAP_SYS_ADMIN)) |
| @@ -1811,19 +1749,19 @@ asmlinkage long sys_pivot_root(const char __user * new_root, | |||
| 1811 | goto out3; | 1749 | goto out3; |
| 1812 | } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry)) | 1750 | } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry)) |
| 1813 | goto out3; | 1751 | goto out3; |
| 1814 | detach_mnt(new_nd.path.mnt, &parent_nd); | 1752 | detach_mnt(new_nd.path.mnt, &parent_path); |
| 1815 | detach_mnt(user_nd.path.mnt, &root_parent); | 1753 | detach_mnt(user_nd.path.mnt, &root_parent); |
| 1816 | /* mount old root on put_old */ | 1754 | /* mount old root on put_old */ |
| 1817 | attach_mnt(user_nd.path.mnt, &old_nd); | 1755 | attach_mnt(user_nd.path.mnt, &old_nd.path); |
| 1818 | /* mount new_root on / */ | 1756 | /* mount new_root on / */ |
| 1819 | attach_mnt(new_nd.path.mnt, &root_parent); | 1757 | attach_mnt(new_nd.path.mnt, &root_parent); |
| 1820 | touch_mnt_namespace(current->nsproxy->mnt_ns); | 1758 | touch_mnt_namespace(current->nsproxy->mnt_ns); |
| 1821 | spin_unlock(&vfsmount_lock); | 1759 | spin_unlock(&vfsmount_lock); |
| 1822 | chroot_fs_refs(&user_nd, &new_nd); | 1760 | chroot_fs_refs(&user_nd.path, &new_nd.path); |
| 1823 | security_sb_post_pivotroot(&user_nd, &new_nd); | 1761 | security_sb_post_pivotroot(&user_nd, &new_nd); |
| 1824 | error = 0; | 1762 | error = 0; |
| 1825 | path_put(&root_parent.path); | 1763 | path_put(&root_parent); |
| 1826 | path_put(&parent_nd.path); | 1764 | path_put(&parent_path); |
| 1827 | out2: | 1765 | out2: |
| 1828 | mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex); | 1766 | mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex); |
| 1829 | up_write(&namespace_sem); | 1767 | up_write(&namespace_sem); |
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index ecc06c619494..66648dd92d97 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
| @@ -93,6 +93,7 @@ static void nfs_callback_svc(struct svc_rqst *rqstp) | |||
| 93 | svc_process(rqstp); | 93 | svc_process(rqstp); |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | flush_signals(current); | ||
| 96 | svc_exit_thread(rqstp); | 97 | svc_exit_thread(rqstp); |
| 97 | nfs_callback_info.pid = 0; | 98 | nfs_callback_info.pid = 0; |
| 98 | complete(&nfs_callback_info.stopped); | 99 | complete(&nfs_callback_info.stopped); |
| @@ -171,7 +172,7 @@ void nfs_callback_down(void) | |||
| 171 | static int nfs_callback_authenticate(struct svc_rqst *rqstp) | 172 | static int nfs_callback_authenticate(struct svc_rqst *rqstp) |
| 172 | { | 173 | { |
| 173 | struct nfs_client *clp; | 174 | struct nfs_client *clp; |
| 174 | char buf[RPC_MAX_ADDRBUFLEN]; | 175 | RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); |
| 175 | 176 | ||
| 176 | /* Don't talk to strangers */ | 177 | /* Don't talk to strangers */ |
| 177 | clp = nfs_find_client(svc_addr(rqstp), 4); | 178 | clp = nfs_find_client(svc_addr(rqstp), 4); |
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index c63eb720b68b..13619d24f023 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c | |||
| @@ -254,7 +254,7 @@ static __be32 encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap, | |||
| 254 | if (!(bitmap[0] & FATTR4_WORD0_CHANGE)) | 254 | if (!(bitmap[0] & FATTR4_WORD0_CHANGE)) |
| 255 | return 0; | 255 | return 0; |
| 256 | p = xdr_reserve_space(xdr, 8); | 256 | p = xdr_reserve_space(xdr, 8); |
| 257 | if (unlikely(p == 0)) | 257 | if (unlikely(!p)) |
| 258 | return htonl(NFS4ERR_RESOURCE); | 258 | return htonl(NFS4ERR_RESOURCE); |
| 259 | p = xdr_encode_hyper(p, change); | 259 | p = xdr_encode_hyper(p, change); |
| 260 | return 0; | 260 | return 0; |
| @@ -267,7 +267,7 @@ static __be32 encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, u | |||
| 267 | if (!(bitmap[0] & FATTR4_WORD0_SIZE)) | 267 | if (!(bitmap[0] & FATTR4_WORD0_SIZE)) |
| 268 | return 0; | 268 | return 0; |
| 269 | p = xdr_reserve_space(xdr, 8); | 269 | p = xdr_reserve_space(xdr, 8); |
| 270 | if (unlikely(p == 0)) | 270 | if (unlikely(!p)) |
| 271 | return htonl(NFS4ERR_RESOURCE); | 271 | return htonl(NFS4ERR_RESOURCE); |
| 272 | p = xdr_encode_hyper(p, size); | 272 | p = xdr_encode_hyper(p, size); |
| 273 | return 0; | 273 | return 0; |
| @@ -278,7 +278,7 @@ static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *ti | |||
| 278 | __be32 *p; | 278 | __be32 *p; |
| 279 | 279 | ||
| 280 | p = xdr_reserve_space(xdr, 12); | 280 | p = xdr_reserve_space(xdr, 12); |
| 281 | if (unlikely(p == 0)) | 281 | if (unlikely(!p)) |
| 282 | return htonl(NFS4ERR_RESOURCE); | 282 | return htonl(NFS4ERR_RESOURCE); |
| 283 | p = xdr_encode_hyper(p, time->tv_sec); | 283 | p = xdr_encode_hyper(p, time->tv_sec); |
| 284 | *p = htonl(time->tv_nsec); | 284 | *p = htonl(time->tv_nsec); |
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index b9eadd18ba70..00a5e4405e16 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
| @@ -49,7 +49,7 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_ | |||
| 49 | struct file_lock *fl; | 49 | struct file_lock *fl; |
| 50 | int status; | 50 | int status; |
| 51 | 51 | ||
| 52 | for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) { | 52 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { |
| 53 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) | 53 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) |
| 54 | continue; | 54 | continue; |
| 55 | if (nfs_file_open_context(fl->fl_file) != ctx) | 55 | if (nfs_file_open_context(fl->fl_file) != ctx) |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index ae04892a5e5d..6cea7479c5b4 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -710,6 +710,8 @@ int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd) | |||
| 710 | { | 710 | { |
| 711 | struct nfs_server *server = NFS_SERVER(inode); | 711 | struct nfs_server *server = NFS_SERVER(inode); |
| 712 | 712 | ||
| 713 | if (test_bit(NFS_INO_MOUNTPOINT, &NFS_I(inode)->flags)) | ||
| 714 | return 0; | ||
| 713 | if (nd != NULL) { | 715 | if (nd != NULL) { |
| 714 | /* VFS wants an on-the-wire revalidation */ | 716 | /* VFS wants an on-the-wire revalidation */ |
| 715 | if (nd->flags & LOOKUP_REVAL) | 717 | if (nd->flags & LOOKUP_REVAL) |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index ef57a5ae5904..5d2e9d9a4e28 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
| @@ -64,7 +64,11 @@ const struct file_operations nfs_file_operations = { | |||
| 64 | .write = do_sync_write, | 64 | .write = do_sync_write, |
| 65 | .aio_read = nfs_file_read, | 65 | .aio_read = nfs_file_read, |
| 66 | .aio_write = nfs_file_write, | 66 | .aio_write = nfs_file_write, |
| 67 | #ifdef CONFIG_MMU | ||
| 67 | .mmap = nfs_file_mmap, | 68 | .mmap = nfs_file_mmap, |
| 69 | #else | ||
| 70 | .mmap = generic_file_mmap, | ||
| 71 | #endif | ||
| 68 | .open = nfs_file_open, | 72 | .open = nfs_file_open, |
| 69 | .flush = nfs_file_flush, | 73 | .flush = nfs_file_flush, |
| 70 | .release = nfs_file_release, | 74 | .release = nfs_file_release, |
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 8ae5dba2d4e5..86147b0ab2cf 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
| @@ -309,7 +309,7 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h, | |||
| 309 | mutex_lock(&idmap->idmap_im_lock); | 309 | mutex_lock(&idmap->idmap_im_lock); |
| 310 | 310 | ||
| 311 | he = idmap_lookup_id(h, id); | 311 | he = idmap_lookup_id(h, id); |
| 312 | if (he != 0) { | 312 | if (he) { |
| 313 | memcpy(name, he->ih_name, he->ih_namelen); | 313 | memcpy(name, he->ih_name, he->ih_namelen); |
| 314 | ret = he->ih_namelen; | 314 | ret = he->ih_namelen; |
| 315 | goto out; | 315 | goto out; |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 966a8850aa30..6f88d7c77ac9 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
| @@ -299,6 +299,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
| 299 | else | 299 | else |
| 300 | inode->i_op = &nfs_mountpoint_inode_operations; | 300 | inode->i_op = &nfs_mountpoint_inode_operations; |
| 301 | inode->i_fop = NULL; | 301 | inode->i_fop = NULL; |
| 302 | set_bit(NFS_INO_MOUNTPOINT, &nfsi->flags); | ||
| 302 | } | 303 | } |
| 303 | } else if (S_ISLNK(inode->i_mode)) | 304 | } else if (S_ISLNK(inode->i_mode)) |
| 304 | inode->i_op = &nfs_symlink_inode_operations; | 305 | inode->i_op = &nfs_symlink_inode_operations; |
| @@ -505,6 +506,7 @@ static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, str | |||
| 505 | ctx->cred = get_rpccred(cred); | 506 | ctx->cred = get_rpccred(cred); |
| 506 | ctx->state = NULL; | 507 | ctx->state = NULL; |
| 507 | ctx->lockowner = current->files; | 508 | ctx->lockowner = current->files; |
| 509 | ctx->flags = 0; | ||
| 508 | ctx->error = 0; | 510 | ctx->error = 0; |
| 509 | ctx->dir_cookie = 0; | 511 | ctx->dir_cookie = 0; |
| 510 | atomic_set(&ctx->count, 1); | 512 | atomic_set(&ctx->count, 1); |
| @@ -1003,8 +1005,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
| 1003 | 1005 | ||
| 1004 | server = NFS_SERVER(inode); | 1006 | server = NFS_SERVER(inode); |
| 1005 | /* Update the fsid? */ | 1007 | /* Update the fsid? */ |
| 1006 | if (S_ISDIR(inode->i_mode) | 1008 | if (S_ISDIR(inode->i_mode) && |
| 1007 | && !nfs_fsid_equal(&server->fsid, &fattr->fsid)) | 1009 | !nfs_fsid_equal(&server->fsid, &fattr->fsid) && |
| 1010 | !test_bit(NFS_INO_MOUNTPOINT, &nfsi->flags)) | ||
| 1008 | server->fsid = fattr->fsid; | 1011 | server->fsid = fattr->fsid; |
| 1009 | 1012 | ||
| 1010 | /* | 1013 | /* |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 0f5619611b8d..931992763e68 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | */ | 3 | */ |
| 4 | 4 | ||
| 5 | #include <linux/mount.h> | 5 | #include <linux/mount.h> |
| 6 | #include <linux/security.h> | ||
| 6 | 7 | ||
| 7 | struct nfs_string; | 8 | struct nfs_string; |
| 8 | 9 | ||
| @@ -57,6 +58,8 @@ struct nfs_parsed_mount_data { | |||
| 57 | char *export_path; | 58 | char *export_path; |
| 58 | int protocol; | 59 | int protocol; |
| 59 | } nfs_server; | 60 | } nfs_server; |
| 61 | |||
| 62 | struct security_mnt_opts lsm_opts; | ||
| 60 | }; | 63 | }; |
| 61 | 64 | ||
| 62 | /* client.c */ | 65 | /* client.c */ |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 6233eb5e98c1..b962397004c1 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
| @@ -785,7 +785,7 @@ static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_s | |||
| 785 | struct file_lock *fl; | 785 | struct file_lock *fl; |
| 786 | int status = 0; | 786 | int status = 0; |
| 787 | 787 | ||
| 788 | for (fl = inode->i_flock; fl != 0; fl = fl->fl_next) { | 788 | for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { |
| 789 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) | 789 | if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) |
| 790 | continue; | 790 | continue; |
| 791 | if (nfs_file_open_context(fl->fl_file)->state != state) | 791 | if (nfs_file_open_context(fl->fl_file)->state != state) |
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 3d7d9631e125..5a70be589bbe 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
| @@ -533,7 +533,10 @@ readpage_async_filler(void *data, struct page *page) | |||
| 533 | 533 | ||
| 534 | if (len < PAGE_CACHE_SIZE) | 534 | if (len < PAGE_CACHE_SIZE) |
| 535 | zero_user_segment(page, len, PAGE_CACHE_SIZE); | 535 | zero_user_segment(page, len, PAGE_CACHE_SIZE); |
| 536 | nfs_pageio_add_request(desc->pgio, new); | 536 | if (!nfs_pageio_add_request(desc->pgio, new)) { |
| 537 | error = desc->pgio->pg_error; | ||
| 538 | goto out_unlock; | ||
| 539 | } | ||
| 537 | return 0; | 540 | return 0; |
| 538 | out_error: | 541 | out_error: |
| 539 | error = PTR_ERR(new); | 542 | error = PTR_ERR(new); |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 1fb381843650..f9219024f31a 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
| @@ -589,8 +589,6 @@ static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags) | |||
| 589 | struct nfs_server *server = NFS_SB(vfsmnt->mnt_sb); | 589 | struct nfs_server *server = NFS_SB(vfsmnt->mnt_sb); |
| 590 | struct rpc_clnt *rpc; | 590 | struct rpc_clnt *rpc; |
| 591 | 591 | ||
| 592 | shrink_submounts(vfsmnt, &nfs_automount_list); | ||
| 593 | |||
| 594 | if (!(flags & MNT_FORCE)) | 592 | if (!(flags & MNT_FORCE)) |
| 595 | return; | 593 | return; |
| 596 | /* -EIO all pending I/O */ | 594 | /* -EIO all pending I/O */ |
| @@ -632,7 +630,7 @@ static int nfs_verify_server_address(struct sockaddr *addr) | |||
| 632 | switch (addr->sa_family) { | 630 | switch (addr->sa_family) { |
| 633 | case AF_INET: { | 631 | case AF_INET: { |
| 634 | struct sockaddr_in *sa = (struct sockaddr_in *)addr; | 632 | struct sockaddr_in *sa = (struct sockaddr_in *)addr; |
| 635 | return sa->sin_addr.s_addr != INADDR_ANY; | 633 | return sa->sin_addr.s_addr != htonl(INADDR_ANY); |
| 636 | } | 634 | } |
| 637 | case AF_INET6: { | 635 | case AF_INET6: { |
| 638 | struct in6_addr *sa = &((struct sockaddr_in6 *)addr)->sin6_addr; | 636 | struct in6_addr *sa = &((struct sockaddr_in6 *)addr)->sin6_addr; |
| @@ -684,8 +682,9 @@ static void nfs_parse_server_address(char *value, | |||
| 684 | static int nfs_parse_mount_options(char *raw, | 682 | static int nfs_parse_mount_options(char *raw, |
| 685 | struct nfs_parsed_mount_data *mnt) | 683 | struct nfs_parsed_mount_data *mnt) |
| 686 | { | 684 | { |
| 687 | char *p, *string; | 685 | char *p, *string, *secdata; |
| 688 | unsigned short port = 0; | 686 | unsigned short port = 0; |
| 687 | int rc; | ||
| 689 | 688 | ||
| 690 | if (!raw) { | 689 | if (!raw) { |
| 691 | dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); | 690 | dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); |
| @@ -693,6 +692,20 @@ static int nfs_parse_mount_options(char *raw, | |||
| 693 | } | 692 | } |
| 694 | dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw); | 693 | dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw); |
| 695 | 694 | ||
| 695 | secdata = alloc_secdata(); | ||
| 696 | if (!secdata) | ||
| 697 | goto out_nomem; | ||
| 698 | |||
| 699 | rc = security_sb_copy_data(raw, secdata); | ||
| 700 | if (rc) | ||
| 701 | goto out_security_failure; | ||
| 702 | |||
| 703 | rc = security_sb_parse_opts_str(secdata, &mnt->lsm_opts); | ||
| 704 | if (rc) | ||
| 705 | goto out_security_failure; | ||
| 706 | |||
| 707 | free_secdata(secdata); | ||
| 708 | |||
| 696 | while ((p = strsep(&raw, ",")) != NULL) { | 709 | while ((p = strsep(&raw, ",")) != NULL) { |
| 697 | substring_t args[MAX_OPT_ARGS]; | 710 | substring_t args[MAX_OPT_ARGS]; |
| 698 | int option, token; | 711 | int option, token; |
| @@ -1042,7 +1055,10 @@ static int nfs_parse_mount_options(char *raw, | |||
| 1042 | out_nomem: | 1055 | out_nomem: |
| 1043 | printk(KERN_INFO "NFS: not enough memory to parse option\n"); | 1056 | printk(KERN_INFO "NFS: not enough memory to parse option\n"); |
| 1044 | return 0; | 1057 | return 0; |
| 1045 | 1058 | out_security_failure: | |
| 1059 | free_secdata(secdata); | ||
| 1060 | printk(KERN_INFO "NFS: security options invalid: %d\n", rc); | ||
| 1061 | return 0; | ||
| 1046 | out_unrec_vers: | 1062 | out_unrec_vers: |
| 1047 | printk(KERN_INFO "NFS: unrecognized NFS version number\n"); | 1063 | printk(KERN_INFO "NFS: unrecognized NFS version number\n"); |
| 1048 | return 0; | 1064 | return 0; |
| @@ -1214,6 +1230,33 @@ static int nfs_validate_mount_data(void *options, | |||
| 1214 | args->namlen = data->namlen; | 1230 | args->namlen = data->namlen; |
| 1215 | args->bsize = data->bsize; | 1231 | args->bsize = data->bsize; |
| 1216 | args->auth_flavors[0] = data->pseudoflavor; | 1232 | args->auth_flavors[0] = data->pseudoflavor; |
| 1233 | |||
| 1234 | /* | ||
| 1235 | * The legacy version 6 binary mount data from userspace has a | ||
| 1236 | * field used only to transport selinux information into the | ||
| 1237 | * the kernel. To continue to support that functionality we | ||
| 1238 | * have a touch of selinux knowledge here in the NFS code. The | ||
| 1239 | * userspace code converted context=blah to just blah so we are | ||
| 1240 | * converting back to the full string selinux understands. | ||
| 1241 | */ | ||
| 1242 | if (data->context[0]){ | ||
| 1243 | #ifdef CONFIG_SECURITY_SELINUX | ||
| 1244 | int rc; | ||
| 1245 | char *opts_str = kmalloc(sizeof(data->context) + 8, GFP_KERNEL); | ||
| 1246 | if (!opts_str) | ||
| 1247 | return -ENOMEM; | ||
| 1248 | strcpy(opts_str, "context="); | ||
| 1249 | data->context[NFS_MAX_CONTEXT_LEN] = '\0'; | ||
| 1250 | strcat(opts_str, &data->context[0]); | ||
| 1251 | rc = security_sb_parse_opts_str(opts_str, &args->lsm_opts); | ||
| 1252 | kfree(opts_str); | ||
| 1253 | if (rc) | ||
| 1254 | return rc; | ||
| 1255 | #else | ||
| 1256 | return -EINVAL; | ||
| 1257 | #endif | ||
| 1258 | } | ||
| 1259 | |||
| 1217 | break; | 1260 | break; |
| 1218 | default: { | 1261 | default: { |
| 1219 | unsigned int len; | 1262 | unsigned int len; |
| @@ -1476,6 +1519,8 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
| 1476 | }; | 1519 | }; |
| 1477 | int error; | 1520 | int error; |
| 1478 | 1521 | ||
| 1522 | security_init_mnt_opts(&data.lsm_opts); | ||
| 1523 | |||
| 1479 | /* Validate the mount data */ | 1524 | /* Validate the mount data */ |
| 1480 | error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name); | 1525 | error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name); |
| 1481 | if (error < 0) | 1526 | if (error < 0) |
| @@ -1515,6 +1560,10 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
| 1515 | goto error_splat_super; | 1560 | goto error_splat_super; |
| 1516 | } | 1561 | } |
| 1517 | 1562 | ||
| 1563 | error = security_sb_set_mnt_opts(s, &data.lsm_opts); | ||
| 1564 | if (error) | ||
| 1565 | goto error_splat_root; | ||
| 1566 | |||
| 1518 | s->s_flags |= MS_ACTIVE; | 1567 | s->s_flags |= MS_ACTIVE; |
| 1519 | mnt->mnt_sb = s; | 1568 | mnt->mnt_sb = s; |
| 1520 | mnt->mnt_root = mntroot; | 1569 | mnt->mnt_root = mntroot; |
| @@ -1523,12 +1572,15 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
| 1523 | out: | 1572 | out: |
| 1524 | kfree(data.nfs_server.hostname); | 1573 | kfree(data.nfs_server.hostname); |
| 1525 | kfree(data.mount_server.hostname); | 1574 | kfree(data.mount_server.hostname); |
| 1575 | security_free_mnt_opts(&data.lsm_opts); | ||
| 1526 | return error; | 1576 | return error; |
| 1527 | 1577 | ||
| 1528 | out_err_nosb: | 1578 | out_err_nosb: |
| 1529 | nfs_free_server(server); | 1579 | nfs_free_server(server); |
| 1530 | goto out; | 1580 | goto out; |
| 1531 | 1581 | ||
| 1582 | error_splat_root: | ||
| 1583 | dput(mntroot); | ||
| 1532 | error_splat_super: | 1584 | error_splat_super: |
| 1533 | up_write(&s->s_umount); | 1585 | up_write(&s->s_umount); |
| 1534 | deactivate_super(s); | 1586 | deactivate_super(s); |
| @@ -1608,6 +1660,9 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
| 1608 | mnt->mnt_sb = s; | 1660 | mnt->mnt_sb = s; |
| 1609 | mnt->mnt_root = mntroot; | 1661 | mnt->mnt_root = mntroot; |
| 1610 | 1662 | ||
| 1663 | /* clone any lsm security options from the parent to the new sb */ | ||
| 1664 | security_sb_clone_mnt_opts(data->sb, s); | ||
| 1665 | |||
| 1611 | dprintk("<-- nfs_xdev_get_sb() = 0\n"); | 1666 | dprintk("<-- nfs_xdev_get_sb() = 0\n"); |
| 1612 | return 0; | 1667 | return 0; |
| 1613 | 1668 | ||
| @@ -1850,6 +1905,8 @@ static int nfs4_get_sb(struct file_system_type *fs_type, | |||
| 1850 | }; | 1905 | }; |
| 1851 | int error; | 1906 | int error; |
| 1852 | 1907 | ||
| 1908 | security_init_mnt_opts(&data.lsm_opts); | ||
| 1909 | |||
| 1853 | /* Validate the mount data */ | 1910 | /* Validate the mount data */ |
| 1854 | error = nfs4_validate_mount_data(raw_data, &data, dev_name); | 1911 | error = nfs4_validate_mount_data(raw_data, &data, dev_name); |
| 1855 | if (error < 0) | 1912 | if (error < 0) |
| @@ -1898,6 +1955,7 @@ out: | |||
| 1898 | kfree(data.client_address); | 1955 | kfree(data.client_address); |
| 1899 | kfree(data.nfs_server.export_path); | 1956 | kfree(data.nfs_server.export_path); |
| 1900 | kfree(data.nfs_server.hostname); | 1957 | kfree(data.nfs_server.hostname); |
| 1958 | security_free_mnt_opts(&data.lsm_opts); | ||
| 1901 | return error; | 1959 | return error; |
| 1902 | 1960 | ||
| 1903 | out_free: | 1961 | out_free: |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index f55c437124a2..bed63416a55b 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
| @@ -39,6 +39,7 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context*, | |||
| 39 | unsigned int, unsigned int); | 39 | unsigned int, unsigned int); |
| 40 | static void nfs_pageio_init_write(struct nfs_pageio_descriptor *desc, | 40 | static void nfs_pageio_init_write(struct nfs_pageio_descriptor *desc, |
| 41 | struct inode *inode, int ioflags); | 41 | struct inode *inode, int ioflags); |
| 42 | static void nfs_redirty_request(struct nfs_page *req); | ||
| 42 | static const struct rpc_call_ops nfs_write_partial_ops; | 43 | static const struct rpc_call_ops nfs_write_partial_ops; |
| 43 | static const struct rpc_call_ops nfs_write_full_ops; | 44 | static const struct rpc_call_ops nfs_write_full_ops; |
| 44 | static const struct rpc_call_ops nfs_commit_ops; | 45 | static const struct rpc_call_ops nfs_commit_ops; |
| @@ -288,7 +289,12 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, | |||
| 288 | BUG(); | 289 | BUG(); |
| 289 | } | 290 | } |
| 290 | spin_unlock(&inode->i_lock); | 291 | spin_unlock(&inode->i_lock); |
| 291 | nfs_pageio_add_request(pgio, req); | 292 | if (!nfs_pageio_add_request(pgio, req)) { |
| 293 | nfs_redirty_request(req); | ||
| 294 | nfs_end_page_writeback(page); | ||
| 295 | nfs_clear_page_tag_locked(req); | ||
| 296 | return pgio->pg_error; | ||
| 297 | } | ||
| 292 | return 0; | 298 | return 0; |
| 293 | } | 299 | } |
| 294 | 300 | ||
| @@ -734,7 +740,7 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
| 734 | */ | 740 | */ |
| 735 | if (nfs_write_pageuptodate(page, inode) && | 741 | if (nfs_write_pageuptodate(page, inode) && |
| 736 | inode->i_flock == NULL && | 742 | inode->i_flock == NULL && |
| 737 | !(file->f_mode & O_SYNC)) { | 743 | !(file->f_flags & O_SYNC)) { |
| 738 | count = max(count + offset, nfs_page_length(page)); | 744 | count = max(count + offset, nfs_page_length(page)); |
| 739 | offset = 0; | 745 | offset = 0; |
| 740 | } | 746 | } |
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 0130b345234d..3e6b3f41ee1f 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
| @@ -101,7 +101,7 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, | |||
| 101 | { | 101 | { |
| 102 | /* Check if the request originated from a secure port. */ | 102 | /* Check if the request originated from a secure port. */ |
| 103 | if (!rqstp->rq_secure && EX_SECURE(exp)) { | 103 | if (!rqstp->rq_secure && EX_SECURE(exp)) { |
| 104 | char buf[RPC_MAX_ADDRBUFLEN]; | 104 | RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); |
| 105 | dprintk(KERN_WARNING | 105 | dprintk(KERN_WARNING |
| 106 | "nfsd: request from insecure port %s!\n", | 106 | "nfsd: request from insecure port %s!\n", |
| 107 | svc_print_addr(rqstp, buf, sizeof(buf))); | 107 | svc_print_addr(rqstp, buf, sizeof(buf))); |
| @@ -232,6 +232,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
| 232 | fhp->fh_dentry = dentry; | 232 | fhp->fh_dentry = dentry; |
| 233 | fhp->fh_export = exp; | 233 | fhp->fh_export = exp; |
| 234 | nfsd_nr_verified++; | 234 | nfsd_nr_verified++; |
| 235 | cache_get(&exp->h); | ||
| 235 | } else { | 236 | } else { |
| 236 | /* | 237 | /* |
| 237 | * just rechecking permissions | 238 | * just rechecking permissions |
| @@ -241,6 +242,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
| 241 | dprintk("nfsd: fh_verify - just checking\n"); | 242 | dprintk("nfsd: fh_verify - just checking\n"); |
| 242 | dentry = fhp->fh_dentry; | 243 | dentry = fhp->fh_dentry; |
| 243 | exp = fhp->fh_export; | 244 | exp = fhp->fh_export; |
| 245 | cache_get(&exp->h); | ||
| 244 | /* | 246 | /* |
| 245 | * Set user creds for this exportpoint; necessary even | 247 | * Set user creds for this exportpoint; necessary even |
| 246 | * in the "just checking" case because this may be a | 248 | * in the "just checking" case because this may be a |
| @@ -252,8 +254,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
| 252 | if (error) | 254 | if (error) |
| 253 | goto out; | 255 | goto out; |
| 254 | } | 256 | } |
| 255 | cache_get(&exp->h); | ||
| 256 | |||
| 257 | 257 | ||
| 258 | error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type); | 258 | error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type); |
| 259 | if (error) | 259 | if (error) |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 82243127eebf..90383ed61005 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
| @@ -257,7 +257,7 @@ static int ocfs2_readpage_inline(struct inode *inode, struct page *page) | |||
| 257 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 257 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 258 | 258 | ||
| 259 | BUG_ON(!PageLocked(page)); | 259 | BUG_ON(!PageLocked(page)); |
| 260 | BUG_ON(!OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL); | 260 | BUG_ON(!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)); |
| 261 | 261 | ||
| 262 | ret = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno, &di_bh, | 262 | ret = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno, &di_bh, |
| 263 | OCFS2_BH_CACHED, inode); | 263 | OCFS2_BH_CACHED, inode); |
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index ee50c9610e7f..b8057c51b205 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
| @@ -451,9 +451,9 @@ static void o2net_set_nn_state(struct o2net_node *nn, | |||
| 451 | /* delay if we're withing a RECONNECT_DELAY of the | 451 | /* delay if we're withing a RECONNECT_DELAY of the |
| 452 | * last attempt */ | 452 | * last attempt */ |
| 453 | delay = (nn->nn_last_connect_attempt + | 453 | delay = (nn->nn_last_connect_attempt + |
| 454 | msecs_to_jiffies(o2net_reconnect_delay(sc->sc_node))) | 454 | msecs_to_jiffies(o2net_reconnect_delay(NULL))) |
| 455 | - jiffies; | 455 | - jiffies; |
| 456 | if (delay > msecs_to_jiffies(o2net_reconnect_delay(sc->sc_node))) | 456 | if (delay > msecs_to_jiffies(o2net_reconnect_delay(NULL))) |
| 457 | delay = 0; | 457 | delay = 0; |
| 458 | mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay); | 458 | mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay); |
| 459 | queue_delayed_work(o2net_wq, &nn->nn_connect_work, delay); | 459 | queue_delayed_work(o2net_wq, &nn->nn_connect_work, delay); |
| @@ -1552,12 +1552,11 @@ static void o2net_connect_expired(struct work_struct *work) | |||
| 1552 | 1552 | ||
| 1553 | spin_lock(&nn->nn_lock); | 1553 | spin_lock(&nn->nn_lock); |
| 1554 | if (!nn->nn_sc_valid) { | 1554 | if (!nn->nn_sc_valid) { |
| 1555 | struct o2nm_node *node = nn->nn_sc->sc_node; | ||
| 1556 | mlog(ML_ERROR, "no connection established with node %u after " | 1555 | mlog(ML_ERROR, "no connection established with node %u after " |
| 1557 | "%u.%u seconds, giving up and returning errors.\n", | 1556 | "%u.%u seconds, giving up and returning errors.\n", |
| 1558 | o2net_num_from_nn(nn), | 1557 | o2net_num_from_nn(nn), |
| 1559 | o2net_idle_timeout(node) / 1000, | 1558 | o2net_idle_timeout(NULL) / 1000, |
| 1560 | o2net_idle_timeout(node) % 1000); | 1559 | o2net_idle_timeout(NULL) % 1000); |
| 1561 | 1560 | ||
| 1562 | o2net_set_nn_state(nn, NULL, 0, -ENOTCONN); | 1561 | o2net_set_nn_state(nn, NULL, 0, -ENOTCONN); |
| 1563 | } | 1562 | } |
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index e280833ceb9a..8a1875848080 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
| @@ -390,9 +390,8 @@ static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir, | |||
| 390 | goto bail; | 390 | goto bail; |
| 391 | } | 391 | } |
| 392 | if (pde) | 392 | if (pde) |
| 393 | pde->rec_len = | 393 | le16_add_cpu(&pde->rec_len, |
| 394 | cpu_to_le16(le16_to_cpu(pde->rec_len) + | 394 | le16_to_cpu(de->rec_len)); |
| 395 | le16_to_cpu(de->rec_len)); | ||
| 396 | else | 395 | else |
| 397 | de->inode = 0; | 396 | de->inode = 0; |
| 398 | dir->i_version++; | 397 | dir->i_version++; |
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 9843ee17ea27..dc8ea666efdb 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h | |||
| @@ -176,6 +176,7 @@ struct dlm_mig_lockres_priv | |||
| 176 | { | 176 | { |
| 177 | struct dlm_lock_resource *lockres; | 177 | struct dlm_lock_resource *lockres; |
| 178 | u8 real_master; | 178 | u8 real_master; |
| 179 | u8 extra_ref; | ||
| 179 | }; | 180 | }; |
| 180 | 181 | ||
| 181 | struct dlm_assert_master_priv | 182 | struct dlm_assert_master_priv |
| @@ -602,17 +603,19 @@ enum dlm_query_join_response_code { | |||
| 602 | JOIN_PROTOCOL_MISMATCH, | 603 | JOIN_PROTOCOL_MISMATCH, |
| 603 | }; | 604 | }; |
| 604 | 605 | ||
| 606 | struct dlm_query_join_packet { | ||
| 607 | u8 code; /* Response code. dlm_minor and fs_minor | ||
| 608 | are only valid if this is JOIN_OK */ | ||
| 609 | u8 dlm_minor; /* The minor version of the protocol the | ||
| 610 | dlm is speaking. */ | ||
| 611 | u8 fs_minor; /* The minor version of the protocol the | ||
| 612 | filesystem is speaking. */ | ||
| 613 | u8 reserved; | ||
| 614 | }; | ||
| 615 | |||
| 605 | union dlm_query_join_response { | 616 | union dlm_query_join_response { |
| 606 | u32 intval; | 617 | u32 intval; |
| 607 | struct { | 618 | struct dlm_query_join_packet packet; |
| 608 | u8 code; /* Response code. dlm_minor and fs_minor | ||
| 609 | are only valid if this is JOIN_OK */ | ||
| 610 | u8 dlm_minor; /* The minor version of the protocol the | ||
| 611 | dlm is speaking. */ | ||
| 612 | u8 fs_minor; /* The minor version of the protocol the | ||
| 613 | filesystem is speaking. */ | ||
| 614 | u8 reserved; | ||
| 615 | } packet; | ||
| 616 | }; | 619 | }; |
| 617 | 620 | ||
| 618 | struct dlm_lock_request | 621 | struct dlm_lock_request |
diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c index ecb4d997221e..75997b4deaf3 100644 --- a/fs/ocfs2/dlm/dlmconvert.c +++ b/fs/ocfs2/dlm/dlmconvert.c | |||
| @@ -487,7 +487,7 @@ int dlm_convert_lock_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 487 | "cookie=%u:%llu\n", | 487 | "cookie=%u:%llu\n", |
| 488 | dlm_get_lock_cookie_node(be64_to_cpu(cnv->cookie)), | 488 | dlm_get_lock_cookie_node(be64_to_cpu(cnv->cookie)), |
| 489 | dlm_get_lock_cookie_seq(be64_to_cpu(cnv->cookie))); | 489 | dlm_get_lock_cookie_seq(be64_to_cpu(cnv->cookie))); |
| 490 | __dlm_print_one_lock_resource(res); | 490 | dlm_print_one_lock_resource(res); |
| 491 | goto leave; | 491 | goto leave; |
| 492 | } | 492 | } |
| 493 | 493 | ||
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 638d2ebb892b..0879d86113e3 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
| @@ -713,14 +713,46 @@ static int dlm_query_join_proto_check(char *proto_type, int node, | |||
| 713 | return rc; | 713 | return rc; |
| 714 | } | 714 | } |
| 715 | 715 | ||
| 716 | /* | ||
| 717 | * struct dlm_query_join_packet is made up of four one-byte fields. They | ||
| 718 | * are effectively in big-endian order already. However, little-endian | ||
| 719 | * machines swap them before putting the packet on the wire (because | ||
| 720 | * query_join's response is a status, and that status is treated as a u32 | ||
| 721 | * on the wire). Thus, a big-endian and little-endian machines will treat | ||
| 722 | * this structure differently. | ||
| 723 | * | ||
| 724 | * The solution is to have little-endian machines swap the structure when | ||
| 725 | * converting from the structure to the u32 representation. This will | ||
| 726 | * result in the structure having the correct format on the wire no matter | ||
| 727 | * the host endian format. | ||
| 728 | */ | ||
| 729 | static void dlm_query_join_packet_to_wire(struct dlm_query_join_packet *packet, | ||
| 730 | u32 *wire) | ||
| 731 | { | ||
| 732 | union dlm_query_join_response response; | ||
| 733 | |||
| 734 | response.packet = *packet; | ||
| 735 | *wire = cpu_to_be32(response.intval); | ||
| 736 | } | ||
| 737 | |||
| 738 | static void dlm_query_join_wire_to_packet(u32 wire, | ||
| 739 | struct dlm_query_join_packet *packet) | ||
| 740 | { | ||
| 741 | union dlm_query_join_response response; | ||
| 742 | |||
| 743 | response.intval = cpu_to_be32(wire); | ||
| 744 | *packet = response.packet; | ||
| 745 | } | ||
| 746 | |||
| 716 | static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, | 747 | static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, |
| 717 | void **ret_data) | 748 | void **ret_data) |
| 718 | { | 749 | { |
| 719 | struct dlm_query_join_request *query; | 750 | struct dlm_query_join_request *query; |
| 720 | union dlm_query_join_response response = { | 751 | struct dlm_query_join_packet packet = { |
| 721 | .packet.code = JOIN_DISALLOW, | 752 | .code = JOIN_DISALLOW, |
| 722 | }; | 753 | }; |
| 723 | struct dlm_ctxt *dlm = NULL; | 754 | struct dlm_ctxt *dlm = NULL; |
| 755 | u32 response; | ||
| 724 | u8 nodenum; | 756 | u8 nodenum; |
| 725 | 757 | ||
| 726 | query = (struct dlm_query_join_request *) msg->buf; | 758 | query = (struct dlm_query_join_request *) msg->buf; |
| @@ -737,11 +769,11 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 737 | mlog(0, "node %u is not in our live map yet\n", | 769 | mlog(0, "node %u is not in our live map yet\n", |
| 738 | query->node_idx); | 770 | query->node_idx); |
| 739 | 771 | ||
| 740 | response.packet.code = JOIN_DISALLOW; | 772 | packet.code = JOIN_DISALLOW; |
| 741 | goto respond; | 773 | goto respond; |
| 742 | } | 774 | } |
| 743 | 775 | ||
| 744 | response.packet.code = JOIN_OK_NO_MAP; | 776 | packet.code = JOIN_OK_NO_MAP; |
| 745 | 777 | ||
| 746 | spin_lock(&dlm_domain_lock); | 778 | spin_lock(&dlm_domain_lock); |
| 747 | dlm = __dlm_lookup_domain_full(query->domain, query->name_len); | 779 | dlm = __dlm_lookup_domain_full(query->domain, query->name_len); |
| @@ -760,7 +792,7 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 760 | mlog(0, "disallow join as node %u does not " | 792 | mlog(0, "disallow join as node %u does not " |
| 761 | "have node %u in its nodemap\n", | 793 | "have node %u in its nodemap\n", |
| 762 | query->node_idx, nodenum); | 794 | query->node_idx, nodenum); |
| 763 | response.packet.code = JOIN_DISALLOW; | 795 | packet.code = JOIN_DISALLOW; |
| 764 | goto unlock_respond; | 796 | goto unlock_respond; |
| 765 | } | 797 | } |
| 766 | } | 798 | } |
| @@ -780,23 +812,23 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 780 | /*If this is a brand new context and we | 812 | /*If this is a brand new context and we |
| 781 | * haven't started our join process yet, then | 813 | * haven't started our join process yet, then |
| 782 | * the other node won the race. */ | 814 | * the other node won the race. */ |
| 783 | response.packet.code = JOIN_OK_NO_MAP; | 815 | packet.code = JOIN_OK_NO_MAP; |
| 784 | } else if (dlm->joining_node != DLM_LOCK_RES_OWNER_UNKNOWN) { | 816 | } else if (dlm->joining_node != DLM_LOCK_RES_OWNER_UNKNOWN) { |
| 785 | /* Disallow parallel joins. */ | 817 | /* Disallow parallel joins. */ |
| 786 | response.packet.code = JOIN_DISALLOW; | 818 | packet.code = JOIN_DISALLOW; |
| 787 | } else if (dlm->reco.state & DLM_RECO_STATE_ACTIVE) { | 819 | } else if (dlm->reco.state & DLM_RECO_STATE_ACTIVE) { |
| 788 | mlog(0, "node %u trying to join, but recovery " | 820 | mlog(0, "node %u trying to join, but recovery " |
| 789 | "is ongoing.\n", bit); | 821 | "is ongoing.\n", bit); |
| 790 | response.packet.code = JOIN_DISALLOW; | 822 | packet.code = JOIN_DISALLOW; |
| 791 | } else if (test_bit(bit, dlm->recovery_map)) { | 823 | } else if (test_bit(bit, dlm->recovery_map)) { |
| 792 | mlog(0, "node %u trying to join, but it " | 824 | mlog(0, "node %u trying to join, but it " |
| 793 | "still needs recovery.\n", bit); | 825 | "still needs recovery.\n", bit); |
| 794 | response.packet.code = JOIN_DISALLOW; | 826 | packet.code = JOIN_DISALLOW; |
| 795 | } else if (test_bit(bit, dlm->domain_map)) { | 827 | } else if (test_bit(bit, dlm->domain_map)) { |
| 796 | mlog(0, "node %u trying to join, but it " | 828 | mlog(0, "node %u trying to join, but it " |
| 797 | "is still in the domain! needs recovery?\n", | 829 | "is still in the domain! needs recovery?\n", |
| 798 | bit); | 830 | bit); |
| 799 | response.packet.code = JOIN_DISALLOW; | 831 | packet.code = JOIN_DISALLOW; |
| 800 | } else { | 832 | } else { |
| 801 | /* Alright we're fully a part of this domain | 833 | /* Alright we're fully a part of this domain |
| 802 | * so we keep some state as to who's joining | 834 | * so we keep some state as to who's joining |
| @@ -807,19 +839,15 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 807 | if (dlm_query_join_proto_check("DLM", bit, | 839 | if (dlm_query_join_proto_check("DLM", bit, |
| 808 | &dlm->dlm_locking_proto, | 840 | &dlm->dlm_locking_proto, |
| 809 | &query->dlm_proto)) { | 841 | &query->dlm_proto)) { |
| 810 | response.packet.code = | 842 | packet.code = JOIN_PROTOCOL_MISMATCH; |
| 811 | JOIN_PROTOCOL_MISMATCH; | ||
| 812 | } else if (dlm_query_join_proto_check("fs", bit, | 843 | } else if (dlm_query_join_proto_check("fs", bit, |
| 813 | &dlm->fs_locking_proto, | 844 | &dlm->fs_locking_proto, |
| 814 | &query->fs_proto)) { | 845 | &query->fs_proto)) { |
| 815 | response.packet.code = | 846 | packet.code = JOIN_PROTOCOL_MISMATCH; |
| 816 | JOIN_PROTOCOL_MISMATCH; | ||
| 817 | } else { | 847 | } else { |
| 818 | response.packet.dlm_minor = | 848 | packet.dlm_minor = query->dlm_proto.pv_minor; |
| 819 | query->dlm_proto.pv_minor; | 849 | packet.fs_minor = query->fs_proto.pv_minor; |
| 820 | response.packet.fs_minor = | 850 | packet.code = JOIN_OK; |
| 821 | query->fs_proto.pv_minor; | ||
| 822 | response.packet.code = JOIN_OK; | ||
| 823 | __dlm_set_joining_node(dlm, query->node_idx); | 851 | __dlm_set_joining_node(dlm, query->node_idx); |
| 824 | } | 852 | } |
| 825 | } | 853 | } |
| @@ -830,9 +858,10 @@ unlock_respond: | |||
| 830 | spin_unlock(&dlm_domain_lock); | 858 | spin_unlock(&dlm_domain_lock); |
| 831 | 859 | ||
| 832 | respond: | 860 | respond: |
| 833 | mlog(0, "We respond with %u\n", response.packet.code); | 861 | mlog(0, "We respond with %u\n", packet.code); |
| 834 | 862 | ||
| 835 | return response.intval; | 863 | dlm_query_join_packet_to_wire(&packet, &response); |
| 864 | return response; | ||
| 836 | } | 865 | } |
| 837 | 866 | ||
| 838 | static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data, | 867 | static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data, |
| @@ -937,7 +966,7 @@ static int dlm_send_join_cancels(struct dlm_ctxt *dlm, | |||
| 937 | sizeof(unsigned long))) { | 966 | sizeof(unsigned long))) { |
| 938 | mlog(ML_ERROR, | 967 | mlog(ML_ERROR, |
| 939 | "map_size %u != BITS_TO_LONGS(O2NM_MAX_NODES) %u\n", | 968 | "map_size %u != BITS_TO_LONGS(O2NM_MAX_NODES) %u\n", |
| 940 | map_size, BITS_TO_LONGS(O2NM_MAX_NODES)); | 969 | map_size, (unsigned)BITS_TO_LONGS(O2NM_MAX_NODES)); |
| 941 | return -EINVAL; | 970 | return -EINVAL; |
| 942 | } | 971 | } |
| 943 | 972 | ||
| @@ -968,7 +997,8 @@ static int dlm_request_join(struct dlm_ctxt *dlm, | |||
| 968 | { | 997 | { |
| 969 | int status; | 998 | int status; |
| 970 | struct dlm_query_join_request join_msg; | 999 | struct dlm_query_join_request join_msg; |
| 971 | union dlm_query_join_response join_resp; | 1000 | struct dlm_query_join_packet packet; |
| 1001 | u32 join_resp; | ||
| 972 | 1002 | ||
| 973 | mlog(0, "querying node %d\n", node); | 1003 | mlog(0, "querying node %d\n", node); |
| 974 | 1004 | ||
| @@ -984,11 +1014,12 @@ static int dlm_request_join(struct dlm_ctxt *dlm, | |||
| 984 | 1014 | ||
| 985 | status = o2net_send_message(DLM_QUERY_JOIN_MSG, DLM_MOD_KEY, &join_msg, | 1015 | status = o2net_send_message(DLM_QUERY_JOIN_MSG, DLM_MOD_KEY, &join_msg, |
| 986 | sizeof(join_msg), node, | 1016 | sizeof(join_msg), node, |
| 987 | &join_resp.intval); | 1017 | &join_resp); |
| 988 | if (status < 0 && status != -ENOPROTOOPT) { | 1018 | if (status < 0 && status != -ENOPROTOOPT) { |
| 989 | mlog_errno(status); | 1019 | mlog_errno(status); |
| 990 | goto bail; | 1020 | goto bail; |
| 991 | } | 1021 | } |
| 1022 | dlm_query_join_wire_to_packet(join_resp, &packet); | ||
| 992 | 1023 | ||
| 993 | /* -ENOPROTOOPT from the net code means the other side isn't | 1024 | /* -ENOPROTOOPT from the net code means the other side isn't |
| 994 | listening for our message type -- that's fine, it means | 1025 | listening for our message type -- that's fine, it means |
| @@ -997,10 +1028,10 @@ static int dlm_request_join(struct dlm_ctxt *dlm, | |||
| 997 | if (status == -ENOPROTOOPT) { | 1028 | if (status == -ENOPROTOOPT) { |
| 998 | status = 0; | 1029 | status = 0; |
| 999 | *response = JOIN_OK_NO_MAP; | 1030 | *response = JOIN_OK_NO_MAP; |
| 1000 | } else if (join_resp.packet.code == JOIN_DISALLOW || | 1031 | } else if (packet.code == JOIN_DISALLOW || |
| 1001 | join_resp.packet.code == JOIN_OK_NO_MAP) { | 1032 | packet.code == JOIN_OK_NO_MAP) { |
| 1002 | *response = join_resp.packet.code; | 1033 | *response = packet.code; |
| 1003 | } else if (join_resp.packet.code == JOIN_PROTOCOL_MISMATCH) { | 1034 | } else if (packet.code == JOIN_PROTOCOL_MISMATCH) { |
| 1004 | mlog(ML_NOTICE, | 1035 | mlog(ML_NOTICE, |
| 1005 | "This node requested DLM locking protocol %u.%u and " | 1036 | "This node requested DLM locking protocol %u.%u and " |
| 1006 | "filesystem locking protocol %u.%u. At least one of " | 1037 | "filesystem locking protocol %u.%u. At least one of " |
| @@ -1012,14 +1043,12 @@ static int dlm_request_join(struct dlm_ctxt *dlm, | |||
| 1012 | dlm->fs_locking_proto.pv_minor, | 1043 | dlm->fs_locking_proto.pv_minor, |
| 1013 | node); | 1044 | node); |
| 1014 | status = -EPROTO; | 1045 | status = -EPROTO; |
| 1015 | *response = join_resp.packet.code; | 1046 | *response = packet.code; |
| 1016 | } else if (join_resp.packet.code == JOIN_OK) { | 1047 | } else if (packet.code == JOIN_OK) { |
| 1017 | *response = join_resp.packet.code; | 1048 | *response = packet.code; |
| 1018 | /* Use the same locking protocol as the remote node */ | 1049 | /* Use the same locking protocol as the remote node */ |
| 1019 | dlm->dlm_locking_proto.pv_minor = | 1050 | dlm->dlm_locking_proto.pv_minor = packet.dlm_minor; |
| 1020 | join_resp.packet.dlm_minor; | 1051 | dlm->fs_locking_proto.pv_minor = packet.fs_minor; |
| 1021 | dlm->fs_locking_proto.pv_minor = | ||
| 1022 | join_resp.packet.fs_minor; | ||
| 1023 | mlog(0, | 1052 | mlog(0, |
| 1024 | "Node %d responds JOIN_OK with DLM locking protocol " | 1053 | "Node %d responds JOIN_OK with DLM locking protocol " |
| 1025 | "%u.%u and fs locking protocol %u.%u\n", | 1054 | "%u.%u and fs locking protocol %u.%u\n", |
| @@ -1031,11 +1060,11 @@ static int dlm_request_join(struct dlm_ctxt *dlm, | |||
| 1031 | } else { | 1060 | } else { |
| 1032 | status = -EINVAL; | 1061 | status = -EINVAL; |
| 1033 | mlog(ML_ERROR, "invalid response %d from node %u\n", | 1062 | mlog(ML_ERROR, "invalid response %d from node %u\n", |
| 1034 | join_resp.packet.code, node); | 1063 | packet.code, node); |
| 1035 | } | 1064 | } |
| 1036 | 1065 | ||
| 1037 | mlog(0, "status %d, node %d response is %d\n", status, node, | 1066 | mlog(0, "status %d, node %d response is %d\n", status, node, |
| 1038 | *response); | 1067 | *response); |
| 1039 | 1068 | ||
| 1040 | bail: | 1069 | bail: |
| 1041 | return status; | 1070 | return status; |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index a54d33d95ada..ea6b89577860 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
| @@ -1663,7 +1663,12 @@ way_up_top: | |||
| 1663 | dlm_put_mle(tmpmle); | 1663 | dlm_put_mle(tmpmle); |
| 1664 | } | 1664 | } |
| 1665 | send_response: | 1665 | send_response: |
| 1666 | 1666 | /* | |
| 1667 | * __dlm_lookup_lockres() grabbed a reference to this lockres. | ||
| 1668 | * The reference is released by dlm_assert_master_worker() under | ||
| 1669 | * the call to dlm_dispatch_assert_master(). If | ||
| 1670 | * dlm_assert_master_worker() isn't called, we drop it here. | ||
| 1671 | */ | ||
| 1667 | if (dispatch_assert) { | 1672 | if (dispatch_assert) { |
| 1668 | if (response != DLM_MASTER_RESP_YES) | 1673 | if (response != DLM_MASTER_RESP_YES) |
| 1669 | mlog(ML_ERROR, "invalid response %d\n", response); | 1674 | mlog(ML_ERROR, "invalid response %d\n", response); |
| @@ -1678,7 +1683,11 @@ send_response: | |||
| 1678 | if (ret < 0) { | 1683 | if (ret < 0) { |
| 1679 | mlog(ML_ERROR, "failed to dispatch assert master work\n"); | 1684 | mlog(ML_ERROR, "failed to dispatch assert master work\n"); |
| 1680 | response = DLM_MASTER_RESP_ERROR; | 1685 | response = DLM_MASTER_RESP_ERROR; |
| 1686 | dlm_lockres_put(res); | ||
| 1681 | } | 1687 | } |
| 1688 | } else { | ||
| 1689 | if (res) | ||
| 1690 | dlm_lockres_put(res); | ||
| 1682 | } | 1691 | } |
| 1683 | 1692 | ||
| 1684 | dlm_put(dlm); | 1693 | dlm_put(dlm); |
| @@ -1695,9 +1704,9 @@ send_response: | |||
| 1695 | * can periodically run all locks owned by this node | 1704 | * can periodically run all locks owned by this node |
| 1696 | * and re-assert across the cluster... | 1705 | * and re-assert across the cluster... |
| 1697 | */ | 1706 | */ |
| 1698 | int dlm_do_assert_master(struct dlm_ctxt *dlm, | 1707 | static int dlm_do_assert_master(struct dlm_ctxt *dlm, |
| 1699 | struct dlm_lock_resource *res, | 1708 | struct dlm_lock_resource *res, |
| 1700 | void *nodemap, u32 flags) | 1709 | void *nodemap, u32 flags) |
| 1701 | { | 1710 | { |
| 1702 | struct dlm_assert_master assert; | 1711 | struct dlm_assert_master assert; |
| 1703 | int to, tmpret; | 1712 | int to, tmpret; |
| @@ -2348,7 +2357,7 @@ int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 2348 | mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref " | 2357 | mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref " |
| 2349 | "but it is already dropped!\n", dlm->name, | 2358 | "but it is already dropped!\n", dlm->name, |
| 2350 | res->lockname.len, res->lockname.name, node); | 2359 | res->lockname.len, res->lockname.name, node); |
| 2351 | __dlm_print_one_lock_resource(res); | 2360 | dlm_print_one_lock_resource(res); |
| 2352 | } | 2361 | } |
| 2353 | ret = 0; | 2362 | ret = 0; |
| 2354 | goto done; | 2363 | goto done; |
| @@ -2408,7 +2417,7 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data) | |||
| 2408 | mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref " | 2417 | mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref " |
| 2409 | "but it is already dropped!\n", dlm->name, | 2418 | "but it is already dropped!\n", dlm->name, |
| 2410 | res->lockname.len, res->lockname.name, node); | 2419 | res->lockname.len, res->lockname.name, node); |
| 2411 | __dlm_print_one_lock_resource(res); | 2420 | dlm_print_one_lock_resource(res); |
| 2412 | } | 2421 | } |
| 2413 | 2422 | ||
| 2414 | dlm_lockres_put(res); | 2423 | dlm_lockres_put(res); |
| @@ -2933,6 +2942,9 @@ static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm, | |||
| 2933 | dlm_lockres_clear_refmap_bit(lock->ml.node, res); | 2942 | dlm_lockres_clear_refmap_bit(lock->ml.node, res); |
| 2934 | list_del_init(&lock->list); | 2943 | list_del_init(&lock->list); |
| 2935 | dlm_lock_put(lock); | 2944 | dlm_lock_put(lock); |
| 2945 | /* In a normal unlock, we would have added a | ||
| 2946 | * DLM_UNLOCK_FREE_LOCK action. Force it. */ | ||
| 2947 | dlm_lock_put(lock); | ||
| 2936 | } | 2948 | } |
| 2937 | } | 2949 | } |
| 2938 | queue++; | 2950 | queue++; |
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 91f747b8a538..bcb9260c3735 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
| @@ -519,9 +519,9 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) | |||
| 519 | return 0; | 519 | return 0; |
| 520 | 520 | ||
| 521 | master_here: | 521 | master_here: |
| 522 | mlog(0, "(%d) mastering recovery of %s:%u here(this=%u)!\n", | 522 | mlog(ML_NOTICE, "(%d) Node %u is the Recovery Master for the Dead Node " |
| 523 | task_pid_nr(dlm->dlm_reco_thread_task), | 523 | "%u for Domain %s\n", task_pid_nr(dlm->dlm_reco_thread_task), |
| 524 | dlm->name, dlm->reco.dead_node, dlm->node_num); | 524 | dlm->node_num, dlm->reco.dead_node, dlm->name); |
| 525 | 525 | ||
| 526 | status = dlm_remaster_locks(dlm, dlm->reco.dead_node); | 526 | status = dlm_remaster_locks(dlm, dlm->reco.dead_node); |
| 527 | if (status < 0) { | 527 | if (status < 0) { |
| @@ -1191,7 +1191,7 @@ static int dlm_add_lock_to_array(struct dlm_lock *lock, | |||
| 1191 | (ml->type == LKM_EXMODE || | 1191 | (ml->type == LKM_EXMODE || |
| 1192 | memcmp(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN))) { | 1192 | memcmp(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN))) { |
| 1193 | mlog(ML_ERROR, "mismatched lvbs!\n"); | 1193 | mlog(ML_ERROR, "mismatched lvbs!\n"); |
| 1194 | __dlm_print_one_lock_resource(lock->lockres); | 1194 | dlm_print_one_lock_resource(lock->lockres); |
| 1195 | BUG(); | 1195 | BUG(); |
| 1196 | } | 1196 | } |
| 1197 | memcpy(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN); | 1197 | memcpy(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN); |
| @@ -1327,6 +1327,7 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 1327 | (struct dlm_migratable_lockres *)msg->buf; | 1327 | (struct dlm_migratable_lockres *)msg->buf; |
| 1328 | int ret = 0; | 1328 | int ret = 0; |
| 1329 | u8 real_master; | 1329 | u8 real_master; |
| 1330 | u8 extra_refs = 0; | ||
| 1330 | char *buf = NULL; | 1331 | char *buf = NULL; |
| 1331 | struct dlm_work_item *item = NULL; | 1332 | struct dlm_work_item *item = NULL; |
| 1332 | struct dlm_lock_resource *res = NULL; | 1333 | struct dlm_lock_resource *res = NULL; |
| @@ -1404,16 +1405,28 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 1404 | __dlm_insert_lockres(dlm, res); | 1405 | __dlm_insert_lockres(dlm, res); |
| 1405 | spin_unlock(&dlm->spinlock); | 1406 | spin_unlock(&dlm->spinlock); |
| 1406 | 1407 | ||
| 1408 | /* Add an extra ref for this lock-less lockres lest the | ||
| 1409 | * dlm_thread purges it before we get the chance to add | ||
| 1410 | * locks to it */ | ||
| 1411 | dlm_lockres_get(res); | ||
| 1412 | |||
| 1413 | /* There are three refs that need to be put. | ||
| 1414 | * 1. Taken above. | ||
| 1415 | * 2. kref_init in dlm_new_lockres()->dlm_init_lockres(). | ||
| 1416 | * 3. dlm_lookup_lockres() | ||
| 1417 | * The first one is handled at the end of this function. The | ||
| 1418 | * other two are handled in the worker thread after locks have | ||
| 1419 | * been attached. Yes, we don't wait for purge time to match | ||
| 1420 | * kref_init. The lockres will still have atleast one ref | ||
| 1421 | * added because it is in the hash __dlm_insert_lockres() */ | ||
| 1422 | extra_refs++; | ||
| 1423 | |||
| 1407 | /* now that the new lockres is inserted, | 1424 | /* now that the new lockres is inserted, |
| 1408 | * make it usable by other processes */ | 1425 | * make it usable by other processes */ |
| 1409 | spin_lock(&res->spinlock); | 1426 | spin_lock(&res->spinlock); |
| 1410 | res->state &= ~DLM_LOCK_RES_IN_PROGRESS; | 1427 | res->state &= ~DLM_LOCK_RES_IN_PROGRESS; |
| 1411 | spin_unlock(&res->spinlock); | 1428 | spin_unlock(&res->spinlock); |
| 1412 | wake_up(&res->wq); | 1429 | wake_up(&res->wq); |
| 1413 | |||
| 1414 | /* add an extra ref for just-allocated lockres | ||
| 1415 | * otherwise the lockres will be purged immediately */ | ||
| 1416 | dlm_lockres_get(res); | ||
| 1417 | } | 1430 | } |
| 1418 | 1431 | ||
| 1419 | /* at this point we have allocated everything we need, | 1432 | /* at this point we have allocated everything we need, |
| @@ -1443,12 +1456,17 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 1443 | dlm_init_work_item(dlm, item, dlm_mig_lockres_worker, buf); | 1456 | dlm_init_work_item(dlm, item, dlm_mig_lockres_worker, buf); |
| 1444 | item->u.ml.lockres = res; /* already have a ref */ | 1457 | item->u.ml.lockres = res; /* already have a ref */ |
| 1445 | item->u.ml.real_master = real_master; | 1458 | item->u.ml.real_master = real_master; |
| 1459 | item->u.ml.extra_ref = extra_refs; | ||
| 1446 | spin_lock(&dlm->work_lock); | 1460 | spin_lock(&dlm->work_lock); |
| 1447 | list_add_tail(&item->list, &dlm->work_list); | 1461 | list_add_tail(&item->list, &dlm->work_list); |
| 1448 | spin_unlock(&dlm->work_lock); | 1462 | spin_unlock(&dlm->work_lock); |
| 1449 | queue_work(dlm->dlm_worker, &dlm->dispatched_work); | 1463 | queue_work(dlm->dlm_worker, &dlm->dispatched_work); |
| 1450 | 1464 | ||
| 1451 | leave: | 1465 | leave: |
| 1466 | /* One extra ref taken needs to be put here */ | ||
| 1467 | if (extra_refs) | ||
| 1468 | dlm_lockres_put(res); | ||
| 1469 | |||
| 1452 | dlm_put(dlm); | 1470 | dlm_put(dlm); |
| 1453 | if (ret < 0) { | 1471 | if (ret < 0) { |
| 1454 | if (buf) | 1472 | if (buf) |
| @@ -1464,17 +1482,19 @@ leave: | |||
| 1464 | 1482 | ||
| 1465 | static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data) | 1483 | static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data) |
| 1466 | { | 1484 | { |
| 1467 | struct dlm_ctxt *dlm = data; | 1485 | struct dlm_ctxt *dlm; |
| 1468 | struct dlm_migratable_lockres *mres; | 1486 | struct dlm_migratable_lockres *mres; |
| 1469 | int ret = 0; | 1487 | int ret = 0; |
| 1470 | struct dlm_lock_resource *res; | 1488 | struct dlm_lock_resource *res; |
| 1471 | u8 real_master; | 1489 | u8 real_master; |
| 1490 | u8 extra_ref; | ||
| 1472 | 1491 | ||
| 1473 | dlm = item->dlm; | 1492 | dlm = item->dlm; |
| 1474 | mres = (struct dlm_migratable_lockres *)data; | 1493 | mres = (struct dlm_migratable_lockres *)data; |
| 1475 | 1494 | ||
| 1476 | res = item->u.ml.lockres; | 1495 | res = item->u.ml.lockres; |
| 1477 | real_master = item->u.ml.real_master; | 1496 | real_master = item->u.ml.real_master; |
| 1497 | extra_ref = item->u.ml.extra_ref; | ||
| 1478 | 1498 | ||
| 1479 | if (real_master == DLM_LOCK_RES_OWNER_UNKNOWN) { | 1499 | if (real_master == DLM_LOCK_RES_OWNER_UNKNOWN) { |
| 1480 | /* this case is super-rare. only occurs if | 1500 | /* this case is super-rare. only occurs if |
| @@ -1517,6 +1537,12 @@ again: | |||
| 1517 | } | 1537 | } |
| 1518 | 1538 | ||
| 1519 | leave: | 1539 | leave: |
| 1540 | /* See comment in dlm_mig_lockres_handler() */ | ||
| 1541 | if (res) { | ||
| 1542 | if (extra_ref) | ||
| 1543 | dlm_lockres_put(res); | ||
| 1544 | dlm_lockres_put(res); | ||
| 1545 | } | ||
| 1520 | kfree(data); | 1546 | kfree(data); |
| 1521 | mlog_exit(ret); | 1547 | mlog_exit(ret); |
| 1522 | } | 1548 | } |
| @@ -1644,7 +1670,8 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 1644 | /* retry!? */ | 1670 | /* retry!? */ |
| 1645 | BUG(); | 1671 | BUG(); |
| 1646 | } | 1672 | } |
| 1647 | } | 1673 | } else /* put.. incase we are not the master */ |
| 1674 | dlm_lockres_put(res); | ||
| 1648 | spin_unlock(&res->spinlock); | 1675 | spin_unlock(&res->spinlock); |
| 1649 | } | 1676 | } |
| 1650 | spin_unlock(&dlm->spinlock); | 1677 | spin_unlock(&dlm->spinlock); |
| @@ -1921,6 +1948,7 @@ void dlm_move_lockres_to_recovery_list(struct dlm_ctxt *dlm, | |||
| 1921 | "Recovering res %s:%.*s, is already on recovery list!\n", | 1948 | "Recovering res %s:%.*s, is already on recovery list!\n", |
| 1922 | dlm->name, res->lockname.len, res->lockname.name); | 1949 | dlm->name, res->lockname.len, res->lockname.name); |
| 1923 | list_del_init(&res->recovering); | 1950 | list_del_init(&res->recovering); |
| 1951 | dlm_lockres_put(res); | ||
| 1924 | } | 1952 | } |
| 1925 | /* We need to hold a reference while on the recovery list */ | 1953 | /* We need to hold a reference while on the recovery list */ |
| 1926 | dlm_lockres_get(res); | 1954 | dlm_lockres_get(res); |
| @@ -2130,11 +2158,16 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, | |||
| 2130 | assert_spin_locked(&dlm->spinlock); | 2158 | assert_spin_locked(&dlm->spinlock); |
| 2131 | assert_spin_locked(&res->spinlock); | 2159 | assert_spin_locked(&res->spinlock); |
| 2132 | 2160 | ||
| 2161 | /* We do two dlm_lock_put(). One for removing from list and the other is | ||
| 2162 | * to force the DLM_UNLOCK_FREE_LOCK action so as to free the locks */ | ||
| 2163 | |||
| 2133 | /* TODO: check pending_asts, pending_basts here */ | 2164 | /* TODO: check pending_asts, pending_basts here */ |
| 2134 | list_for_each_entry_safe(lock, next, &res->granted, list) { | 2165 | list_for_each_entry_safe(lock, next, &res->granted, list) { |
| 2135 | if (lock->ml.node == dead_node) { | 2166 | if (lock->ml.node == dead_node) { |
| 2136 | list_del_init(&lock->list); | 2167 | list_del_init(&lock->list); |
| 2137 | dlm_lock_put(lock); | 2168 | dlm_lock_put(lock); |
| 2169 | /* Can't schedule DLM_UNLOCK_FREE_LOCK - do manually */ | ||
| 2170 | dlm_lock_put(lock); | ||
| 2138 | freed++; | 2171 | freed++; |
| 2139 | } | 2172 | } |
| 2140 | } | 2173 | } |
| @@ -2142,6 +2175,8 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, | |||
| 2142 | if (lock->ml.node == dead_node) { | 2175 | if (lock->ml.node == dead_node) { |
| 2143 | list_del_init(&lock->list); | 2176 | list_del_init(&lock->list); |
| 2144 | dlm_lock_put(lock); | 2177 | dlm_lock_put(lock); |
| 2178 | /* Can't schedule DLM_UNLOCK_FREE_LOCK - do manually */ | ||
| 2179 | dlm_lock_put(lock); | ||
| 2145 | freed++; | 2180 | freed++; |
| 2146 | } | 2181 | } |
| 2147 | } | 2182 | } |
| @@ -2149,6 +2184,8 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, | |||
| 2149 | if (lock->ml.node == dead_node) { | 2184 | if (lock->ml.node == dead_node) { |
| 2150 | list_del_init(&lock->list); | 2185 | list_del_init(&lock->list); |
| 2151 | dlm_lock_put(lock); | 2186 | dlm_lock_put(lock); |
| 2187 | /* Can't schedule DLM_UNLOCK_FREE_LOCK - do manually */ | ||
| 2188 | dlm_lock_put(lock); | ||
| 2152 | freed++; | 2189 | freed++; |
| 2153 | } | 2190 | } |
| 2154 | } | 2191 | } |
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index cebd089f8955..4060bb328bc8 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c | |||
| @@ -176,12 +176,14 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm, | |||
| 176 | res->lockname.name, master); | 176 | res->lockname.name, master); |
| 177 | 177 | ||
| 178 | if (!master) { | 178 | if (!master) { |
| 179 | /* drop spinlock... retake below */ | ||
| 180 | spin_unlock(&dlm->spinlock); | ||
| 181 | |||
| 179 | spin_lock(&res->spinlock); | 182 | spin_lock(&res->spinlock); |
| 180 | /* This ensures that clear refmap is sent after the set */ | 183 | /* This ensures that clear refmap is sent after the set */ |
| 181 | __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG); | 184 | __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG); |
| 182 | spin_unlock(&res->spinlock); | 185 | spin_unlock(&res->spinlock); |
| 183 | /* drop spinlock to do messaging, retake below */ | 186 | |
| 184 | spin_unlock(&dlm->spinlock); | ||
| 185 | /* clear our bit from the master's refmap, ignore errors */ | 187 | /* clear our bit from the master's refmap, ignore errors */ |
| 186 | ret = dlm_drop_lockres_ref(dlm, res); | 188 | ret = dlm_drop_lockres_ref(dlm, res); |
| 187 | if (ret < 0) { | 189 | if (ret < 0) { |
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 351130c9b734..1f1873bf41fb 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
| @@ -2409,7 +2409,7 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) | |||
| 2409 | return 0; | 2409 | return 0; |
| 2410 | } | 2410 | } |
| 2411 | 2411 | ||
| 2412 | static struct seq_operations ocfs2_dlm_seq_ops = { | 2412 | static const struct seq_operations ocfs2_dlm_seq_ops = { |
| 2413 | .start = ocfs2_dlm_seq_start, | 2413 | .start = ocfs2_dlm_seq_start, |
| 2414 | .stop = ocfs2_dlm_seq_stop, | 2414 | .stop = ocfs2_dlm_seq_stop, |
| 2415 | .next = ocfs2_dlm_seq_next, | 2415 | .next = ocfs2_dlm_seq_next, |
| @@ -3042,7 +3042,7 @@ static int ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres, | |||
| 3042 | inode = ocfs2_lock_res_inode(lockres); | 3042 | inode = ocfs2_lock_res_inode(lockres); |
| 3043 | mapping = inode->i_mapping; | 3043 | mapping = inode->i_mapping; |
| 3044 | 3044 | ||
| 3045 | if (S_ISREG(inode->i_mode)) | 3045 | if (!S_ISREG(inode->i_mode)) |
| 3046 | goto out; | 3046 | goto out; |
| 3047 | 3047 | ||
| 3048 | /* | 3048 | /* |
| @@ -3219,8 +3219,8 @@ static int ocfs2_dentry_convert_worker(struct ocfs2_lock_res *lockres, | |||
| 3219 | return UNBLOCK_CONTINUE_POST; | 3219 | return UNBLOCK_CONTINUE_POST; |
| 3220 | } | 3220 | } |
| 3221 | 3221 | ||
| 3222 | void ocfs2_process_blocked_lock(struct ocfs2_super *osb, | 3222 | static void ocfs2_process_blocked_lock(struct ocfs2_super *osb, |
| 3223 | struct ocfs2_lock_res *lockres) | 3223 | struct ocfs2_lock_res *lockres) |
| 3224 | { | 3224 | { |
| 3225 | int status; | 3225 | int status; |
| 3226 | struct ocfs2_unblock_ctl ctl = {0, 0,}; | 3226 | struct ocfs2_unblock_ctl ctl = {0, 0,}; |
| @@ -3356,7 +3356,7 @@ static int ocfs2_downconvert_thread_should_wake(struct ocfs2_super *osb) | |||
| 3356 | return should_wake; | 3356 | return should_wake; |
| 3357 | } | 3357 | } |
| 3358 | 3358 | ||
| 3359 | int ocfs2_downconvert_thread(void *arg) | 3359 | static int ocfs2_downconvert_thread(void *arg) |
| 3360 | { | 3360 | { |
| 3361 | int status = 0; | 3361 | int status = 0; |
| 3362 | struct ocfs2_super *osb = arg; | 3362 | struct ocfs2_super *osb = arg; |
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h index 1d5b0699d0a9..e3cf902404b4 100644 --- a/fs/ocfs2/dlmglue.h +++ b/fs/ocfs2/dlmglue.h | |||
| @@ -109,8 +109,6 @@ void ocfs2_simple_drop_lockres(struct ocfs2_super *osb, | |||
| 109 | struct ocfs2_lock_res *lockres); | 109 | struct ocfs2_lock_res *lockres); |
| 110 | 110 | ||
| 111 | /* for the downconvert thread */ | 111 | /* for the downconvert thread */ |
| 112 | void ocfs2_process_blocked_lock(struct ocfs2_super *osb, | ||
| 113 | struct ocfs2_lock_res *lockres); | ||
| 114 | void ocfs2_wake_downconvert_thread(struct ocfs2_super *osb); | 112 | void ocfs2_wake_downconvert_thread(struct ocfs2_super *osb); |
| 115 | 113 | ||
| 116 | struct ocfs2_dlm_debug *ocfs2_new_dlm_debug(void); | 114 | struct ocfs2_dlm_debug *ocfs2_new_dlm_debug(void); |
diff --git a/fs/ocfs2/heartbeat.c b/fs/ocfs2/heartbeat.c index c0efd9489fe8..0758daf64da0 100644 --- a/fs/ocfs2/heartbeat.c +++ b/fs/ocfs2/heartbeat.c | |||
| @@ -49,10 +49,15 @@ static inline void __ocfs2_node_map_set_bit(struct ocfs2_node_map *map, | |||
| 49 | static inline void __ocfs2_node_map_clear_bit(struct ocfs2_node_map *map, | 49 | static inline void __ocfs2_node_map_clear_bit(struct ocfs2_node_map *map, |
| 50 | int bit); | 50 | int bit); |
| 51 | static inline int __ocfs2_node_map_is_empty(struct ocfs2_node_map *map); | 51 | static inline int __ocfs2_node_map_is_empty(struct ocfs2_node_map *map); |
| 52 | static void __ocfs2_node_map_dup(struct ocfs2_node_map *target, | 52 | |
| 53 | struct ocfs2_node_map *from); | 53 | /* special case -1 for now |
| 54 | static void __ocfs2_node_map_set(struct ocfs2_node_map *target, | 54 | * TODO: should *really* make sure the calling func never passes -1!! */ |
| 55 | struct ocfs2_node_map *from); | 55 | static void ocfs2_node_map_init(struct ocfs2_node_map *map) |
| 56 | { | ||
| 57 | map->num_nodes = OCFS2_NODE_MAP_MAX_NODES; | ||
| 58 | memset(map->map, 0, BITS_TO_LONGS(OCFS2_NODE_MAP_MAX_NODES) * | ||
| 59 | sizeof(unsigned long)); | ||
| 60 | } | ||
| 56 | 61 | ||
| 57 | void ocfs2_init_node_maps(struct ocfs2_super *osb) | 62 | void ocfs2_init_node_maps(struct ocfs2_super *osb) |
| 58 | { | 63 | { |
| @@ -136,15 +141,6 @@ void ocfs2_stop_heartbeat(struct ocfs2_super *osb) | |||
| 136 | mlog_errno(ret); | 141 | mlog_errno(ret); |
| 137 | } | 142 | } |
| 138 | 143 | ||
| 139 | /* special case -1 for now | ||
| 140 | * TODO: should *really* make sure the calling func never passes -1!! */ | ||
| 141 | void ocfs2_node_map_init(struct ocfs2_node_map *map) | ||
| 142 | { | ||
| 143 | map->num_nodes = OCFS2_NODE_MAP_MAX_NODES; | ||
| 144 | memset(map->map, 0, BITS_TO_LONGS(OCFS2_NODE_MAP_MAX_NODES) * | ||
| 145 | sizeof(unsigned long)); | ||
| 146 | } | ||
| 147 | |||
| 148 | static inline void __ocfs2_node_map_set_bit(struct ocfs2_node_map *map, | 144 | static inline void __ocfs2_node_map_set_bit(struct ocfs2_node_map *map, |
| 149 | int bit) | 145 | int bit) |
| 150 | { | 146 | { |
| @@ -216,6 +212,8 @@ int ocfs2_node_map_is_empty(struct ocfs2_super *osb, | |||
| 216 | return ret; | 212 | return ret; |
| 217 | } | 213 | } |
| 218 | 214 | ||
| 215 | #if 0 | ||
| 216 | |||
| 219 | static void __ocfs2_node_map_dup(struct ocfs2_node_map *target, | 217 | static void __ocfs2_node_map_dup(struct ocfs2_node_map *target, |
| 220 | struct ocfs2_node_map *from) | 218 | struct ocfs2_node_map *from) |
| 221 | { | 219 | { |
| @@ -254,6 +252,8 @@ static void __ocfs2_node_map_set(struct ocfs2_node_map *target, | |||
| 254 | target->map[i] = from->map[i]; | 252 | target->map[i] = from->map[i]; |
| 255 | } | 253 | } |
| 256 | 254 | ||
| 255 | #endif /* 0 */ | ||
| 256 | |||
| 257 | /* Returns whether the recovery bit was actually set - it may not be | 257 | /* Returns whether the recovery bit was actually set - it may not be |
| 258 | * if a node is still marked as needing recovery */ | 258 | * if a node is still marked as needing recovery */ |
| 259 | int ocfs2_recovery_map_set(struct ocfs2_super *osb, | 259 | int ocfs2_recovery_map_set(struct ocfs2_super *osb, |
diff --git a/fs/ocfs2/heartbeat.h b/fs/ocfs2/heartbeat.h index 56859211888a..eac63aed7611 100644 --- a/fs/ocfs2/heartbeat.h +++ b/fs/ocfs2/heartbeat.h | |||
| @@ -33,7 +33,6 @@ void ocfs2_stop_heartbeat(struct ocfs2_super *osb); | |||
| 33 | 33 | ||
| 34 | /* node map functions - used to keep track of mounted and in-recovery | 34 | /* node map functions - used to keep track of mounted and in-recovery |
| 35 | * nodes. */ | 35 | * nodes. */ |
| 36 | void ocfs2_node_map_init(struct ocfs2_node_map *map); | ||
| 37 | int ocfs2_node_map_is_empty(struct ocfs2_super *osb, | 36 | int ocfs2_node_map_is_empty(struct ocfs2_super *osb, |
| 38 | struct ocfs2_node_map *map); | 37 | struct ocfs2_node_map *map); |
| 39 | void ocfs2_node_map_set_bit(struct ocfs2_super *osb, | 38 | void ocfs2_node_map_set_bit(struct ocfs2_super *osb, |
| @@ -57,9 +56,5 @@ int ocfs2_recovery_map_set(struct ocfs2_super *osb, | |||
| 57 | int num); | 56 | int num); |
| 58 | void ocfs2_recovery_map_clear(struct ocfs2_super *osb, | 57 | void ocfs2_recovery_map_clear(struct ocfs2_super *osb, |
| 59 | int num); | 58 | int num); |
| 60 | /* returns 1 if bit is the only bit set in target, 0 otherwise */ | ||
| 61 | int ocfs2_node_map_is_only(struct ocfs2_super *osb, | ||
| 62 | struct ocfs2_node_map *target, | ||
| 63 | int bit); | ||
| 64 | 59 | ||
| 65 | #endif /* OCFS2_HEARTBEAT_H */ | 60 | #endif /* OCFS2_HEARTBEAT_H */ |
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index add1ffdc5c6c..ab83fd562429 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c | |||
| @@ -120,9 +120,6 @@ int ocfs2_load_local_alloc(struct ocfs2_super *osb) | |||
| 120 | 120 | ||
| 121 | mlog_entry_void(); | 121 | mlog_entry_void(); |
| 122 | 122 | ||
| 123 | if (ocfs2_mount_local(osb)) | ||
| 124 | goto bail; | ||
| 125 | |||
| 126 | if (osb->local_alloc_size == 0) | 123 | if (osb->local_alloc_size == 0) |
| 127 | goto bail; | 124 | goto bail; |
| 128 | 125 | ||
| @@ -588,8 +585,7 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, | |||
| 588 | while(bits_wanted--) | 585 | while(bits_wanted--) |
| 589 | ocfs2_set_bit(start++, bitmap); | 586 | ocfs2_set_bit(start++, bitmap); |
| 590 | 587 | ||
| 591 | alloc->id1.bitmap1.i_used = cpu_to_le32(*num_bits + | 588 | le32_add_cpu(&alloc->id1.bitmap1.i_used, *num_bits); |
| 592 | le32_to_cpu(alloc->id1.bitmap1.i_used)); | ||
| 593 | 589 | ||
| 594 | status = ocfs2_journal_dirty(handle, osb->local_alloc_bh); | 590 | status = ocfs2_journal_dirty(handle, osb->local_alloc_bh); |
| 595 | if (status < 0) { | 591 | if (status < 0) { |
diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c index 37835ffcb039..8166968e9015 100644 --- a/fs/ocfs2/resize.c +++ b/fs/ocfs2/resize.c | |||
| @@ -597,7 +597,7 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) | |||
| 597 | memset(cr, 0, sizeof(struct ocfs2_chain_rec)); | 597 | memset(cr, 0, sizeof(struct ocfs2_chain_rec)); |
| 598 | } | 598 | } |
| 599 | 599 | ||
| 600 | cr->c_blkno = le64_to_cpu(input->group); | 600 | cr->c_blkno = cpu_to_le64(input->group); |
| 601 | le32_add_cpu(&cr->c_total, input->clusters * cl_bpc); | 601 | le32_add_cpu(&cr->c_total, input->clusters * cl_bpc); |
| 602 | le32_add_cpu(&cr->c_free, input->frees * cl_bpc); | 602 | le32_add_cpu(&cr->c_free, input->frees * cl_bpc); |
| 603 | 603 | ||
| @@ -335,7 +335,7 @@ asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length) | |||
| 335 | { | 335 | { |
| 336 | long ret = do_sys_ftruncate(fd, length, 1); | 336 | long ret = do_sys_ftruncate(fd, length, 1); |
| 337 | /* avoid REGPARM breakage on x86: */ | 337 | /* avoid REGPARM breakage on x86: */ |
| 338 | prevent_tail_call(ret); | 338 | asmlinkage_protect(2, ret, fd, length); |
| 339 | return ret; | 339 | return ret; |
| 340 | } | 340 | } |
| 341 | 341 | ||
| @@ -350,7 +350,7 @@ asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) | |||
| 350 | { | 350 | { |
| 351 | long ret = do_sys_ftruncate(fd, length, 0); | 351 | long ret = do_sys_ftruncate(fd, length, 0); |
| 352 | /* avoid REGPARM breakage on x86: */ | 352 | /* avoid REGPARM breakage on x86: */ |
| 353 | prevent_tail_call(ret); | 353 | asmlinkage_protect(2, ret, fd, length); |
| 354 | return ret; | 354 | return ret; |
| 355 | } | 355 | } |
| 356 | #endif | 356 | #endif |
| @@ -903,6 +903,18 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) | |||
| 903 | int error; | 903 | int error; |
| 904 | struct file *f; | 904 | struct file *f; |
| 905 | 905 | ||
| 906 | /* | ||
| 907 | * We must always pass in a valid mount pointer. Historically | ||
| 908 | * callers got away with not passing it, but we must enforce this at | ||
| 909 | * the earliest possible point now to avoid strange problems deep in the | ||
| 910 | * filesystem stack. | ||
| 911 | */ | ||
| 912 | if (!mnt) { | ||
| 913 | printk(KERN_WARNING "%s called with NULL vfsmount\n", __func__); | ||
| 914 | dump_stack(); | ||
| 915 | return ERR_PTR(-EINVAL); | ||
| 916 | } | ||
| 917 | |||
| 906 | error = -ENFILE; | 918 | error = -ENFILE; |
| 907 | f = get_empty_filp(); | 919 | f = get_empty_filp(); |
| 908 | if (f == NULL) { | 920 | if (f == NULL) { |
| @@ -1055,7 +1067,7 @@ asmlinkage long sys_open(const char __user *filename, int flags, int mode) | |||
| 1055 | 1067 | ||
| 1056 | ret = do_sys_open(AT_FDCWD, filename, flags, mode); | 1068 | ret = do_sys_open(AT_FDCWD, filename, flags, mode); |
| 1057 | /* avoid REGPARM breakage on x86: */ | 1069 | /* avoid REGPARM breakage on x86: */ |
| 1058 | prevent_tail_call(ret); | 1070 | asmlinkage_protect(3, ret, filename, flags, mode); |
| 1059 | return ret; | 1071 | return ret; |
| 1060 | } | 1072 | } |
| 1061 | 1073 | ||
| @@ -1069,7 +1081,7 @@ asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, | |||
| 1069 | 1081 | ||
| 1070 | ret = do_sys_open(dfd, filename, flags, mode); | 1082 | ret = do_sys_open(dfd, filename, flags, mode); |
| 1071 | /* avoid REGPARM breakage on x86: */ | 1083 | /* avoid REGPARM breakage on x86: */ |
| 1072 | prevent_tail_call(ret); | 1084 | asmlinkage_protect(4, ret, dfd, filename, flags, mode); |
| 1073 | return ret; | 1085 | return ret; |
| 1074 | } | 1086 | } |
| 1075 | 1087 | ||
| @@ -957,13 +957,10 @@ struct file *create_write_pipe(void) | |||
| 957 | struct dentry *dentry; | 957 | struct dentry *dentry; |
| 958 | struct qstr name = { .name = "" }; | 958 | struct qstr name = { .name = "" }; |
| 959 | 959 | ||
| 960 | f = get_empty_filp(); | ||
| 961 | if (!f) | ||
| 962 | return ERR_PTR(-ENFILE); | ||
| 963 | err = -ENFILE; | 960 | err = -ENFILE; |
| 964 | inode = get_pipe_inode(); | 961 | inode = get_pipe_inode(); |
| 965 | if (!inode) | 962 | if (!inode) |
| 966 | goto err_file; | 963 | goto err; |
| 967 | 964 | ||
| 968 | err = -ENOMEM; | 965 | err = -ENOMEM; |
| 969 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name); | 966 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name); |
| @@ -978,22 +975,24 @@ struct file *create_write_pipe(void) | |||
| 978 | */ | 975 | */ |
| 979 | dentry->d_flags &= ~DCACHE_UNHASHED; | 976 | dentry->d_flags &= ~DCACHE_UNHASHED; |
| 980 | d_instantiate(dentry, inode); | 977 | d_instantiate(dentry, inode); |
| 981 | f->f_path.mnt = mntget(pipe_mnt); | 978 | |
| 982 | f->f_path.dentry = dentry; | 979 | err = -ENFILE; |
| 980 | f = alloc_file(pipe_mnt, dentry, FMODE_WRITE, &write_pipe_fops); | ||
| 981 | if (!f) | ||
| 982 | goto err_dentry; | ||
| 983 | f->f_mapping = inode->i_mapping; | 983 | f->f_mapping = inode->i_mapping; |
| 984 | 984 | ||
| 985 | f->f_flags = O_WRONLY; | 985 | f->f_flags = O_WRONLY; |
| 986 | f->f_op = &write_pipe_fops; | ||
| 987 | f->f_mode = FMODE_WRITE; | ||
| 988 | f->f_version = 0; | 986 | f->f_version = 0; |
| 989 | 987 | ||
| 990 | return f; | 988 | return f; |
| 991 | 989 | ||
| 990 | err_dentry: | ||
| 991 | dput(dentry); | ||
| 992 | err_inode: | 992 | err_inode: |
| 993 | free_pipe_info(inode); | 993 | free_pipe_info(inode); |
| 994 | iput(inode); | 994 | iput(inode); |
| 995 | err_file: | 995 | err: |
| 996 | put_filp(f); | ||
| 997 | return ERR_PTR(err); | 996 | return ERR_PTR(err); |
| 998 | } | 997 | } |
| 999 | 998 | ||
diff --git a/fs/pnode.c b/fs/pnode.c index 05ba692bc540..1d8f5447f3f7 100644 --- a/fs/pnode.c +++ b/fs/pnode.c | |||
| @@ -225,7 +225,7 @@ out: | |||
| 225 | */ | 225 | */ |
| 226 | static inline int do_refcount_check(struct vfsmount *mnt, int count) | 226 | static inline int do_refcount_check(struct vfsmount *mnt, int count) |
| 227 | { | 227 | { |
| 228 | int mycount = atomic_read(&mnt->mnt_count); | 228 | int mycount = atomic_read(&mnt->mnt_count) - mnt->mnt_ghosts; |
| 229 | return (mycount > count); | 229 | return (mycount > count); |
| 230 | } | 230 | } |
| 231 | 231 | ||
diff --git a/fs/proc/base.c b/fs/proc/base.c index 88f8edf18258..81d7d145292a 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
| @@ -314,9 +314,12 @@ static int proc_pid_schedstat(struct task_struct *task, char *buffer) | |||
| 314 | static int lstats_show_proc(struct seq_file *m, void *v) | 314 | static int lstats_show_proc(struct seq_file *m, void *v) |
| 315 | { | 315 | { |
| 316 | int i; | 316 | int i; |
| 317 | struct task_struct *task = m->private; | 317 | struct inode *inode = m->private; |
| 318 | seq_puts(m, "Latency Top version : v0.1\n"); | 318 | struct task_struct *task = get_proc_task(inode); |
| 319 | 319 | ||
| 320 | if (!task) | ||
| 321 | return -ESRCH; | ||
| 322 | seq_puts(m, "Latency Top version : v0.1\n"); | ||
| 320 | for (i = 0; i < 32; i++) { | 323 | for (i = 0; i < 32; i++) { |
| 321 | if (task->latency_record[i].backtrace[0]) { | 324 | if (task->latency_record[i].backtrace[0]) { |
| 322 | int q; | 325 | int q; |
| @@ -341,32 +344,24 @@ static int lstats_show_proc(struct seq_file *m, void *v) | |||
| 341 | } | 344 | } |
| 342 | 345 | ||
| 343 | } | 346 | } |
| 347 | put_task_struct(task); | ||
| 344 | return 0; | 348 | return 0; |
| 345 | } | 349 | } |
| 346 | 350 | ||
| 347 | static int lstats_open(struct inode *inode, struct file *file) | 351 | static int lstats_open(struct inode *inode, struct file *file) |
| 348 | { | 352 | { |
| 349 | int ret; | 353 | return single_open(file, lstats_show_proc, inode); |
| 350 | struct seq_file *m; | ||
| 351 | struct task_struct *task = get_proc_task(inode); | ||
| 352 | |||
| 353 | ret = single_open(file, lstats_show_proc, NULL); | ||
| 354 | if (!ret) { | ||
| 355 | m = file->private_data; | ||
| 356 | m->private = task; | ||
| 357 | } | ||
| 358 | return ret; | ||
| 359 | } | 354 | } |
| 360 | 355 | ||
| 361 | static ssize_t lstats_write(struct file *file, const char __user *buf, | 356 | static ssize_t lstats_write(struct file *file, const char __user *buf, |
| 362 | size_t count, loff_t *offs) | 357 | size_t count, loff_t *offs) |
| 363 | { | 358 | { |
| 364 | struct seq_file *m; | 359 | struct task_struct *task = get_proc_task(file->f_dentry->d_inode); |
| 365 | struct task_struct *task; | ||
| 366 | 360 | ||
| 367 | m = file->private_data; | 361 | if (!task) |
| 368 | task = m->private; | 362 | return -ESRCH; |
| 369 | clear_all_latency_tracing(task); | 363 | clear_all_latency_tracing(task); |
| 364 | put_task_struct(task); | ||
| 370 | 365 | ||
| 371 | return count; | 366 | return count; |
| 372 | } | 367 | } |
| @@ -416,6 +411,7 @@ static const struct limit_names lnames[RLIM_NLIMITS] = { | |||
| 416 | [RLIMIT_MSGQUEUE] = {"Max msgqueue size", "bytes"}, | 411 | [RLIMIT_MSGQUEUE] = {"Max msgqueue size", "bytes"}, |
| 417 | [RLIMIT_NICE] = {"Max nice priority", NULL}, | 412 | [RLIMIT_NICE] = {"Max nice priority", NULL}, |
| 418 | [RLIMIT_RTPRIO] = {"Max realtime priority", NULL}, | 413 | [RLIMIT_RTPRIO] = {"Max realtime priority", NULL}, |
| 414 | [RLIMIT_RTTIME] = {"Max realtime timeout", "us"}, | ||
| 419 | }; | 415 | }; |
| 420 | 416 | ||
| 421 | /* Display limits for a process */ | 417 | /* Display limits for a process */ |
| @@ -1040,6 +1036,26 @@ static const struct file_operations proc_loginuid_operations = { | |||
| 1040 | .read = proc_loginuid_read, | 1036 | .read = proc_loginuid_read, |
| 1041 | .write = proc_loginuid_write, | 1037 | .write = proc_loginuid_write, |
| 1042 | }; | 1038 | }; |
| 1039 | |||
| 1040 | static ssize_t proc_sessionid_read(struct file * file, char __user * buf, | ||
| 1041 | size_t count, loff_t *ppos) | ||
| 1042 | { | ||
| 1043 | struct inode * inode = file->f_path.dentry->d_inode; | ||
| 1044 | struct task_struct *task = get_proc_task(inode); | ||
| 1045 | ssize_t length; | ||
| 1046 | char tmpbuf[TMPBUFLEN]; | ||
| 1047 | |||
| 1048 | if (!task) | ||
| 1049 | return -ESRCH; | ||
| 1050 | length = scnprintf(tmpbuf, TMPBUFLEN, "%u", | ||
| 1051 | audit_get_sessionid(task)); | ||
| 1052 | put_task_struct(task); | ||
| 1053 | return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); | ||
| 1054 | } | ||
| 1055 | |||
| 1056 | static const struct file_operations proc_sessionid_operations = { | ||
| 1057 | .read = proc_sessionid_read, | ||
| 1058 | }; | ||
| 1043 | #endif | 1059 | #endif |
| 1044 | 1060 | ||
| 1045 | #ifdef CONFIG_FAULT_INJECTION | 1061 | #ifdef CONFIG_FAULT_INJECTION |
| @@ -2273,6 +2289,9 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
| 2273 | DIR("task", S_IRUGO|S_IXUGO, task), | 2289 | DIR("task", S_IRUGO|S_IXUGO, task), |
| 2274 | DIR("fd", S_IRUSR|S_IXUSR, fd), | 2290 | DIR("fd", S_IRUSR|S_IXUSR, fd), |
| 2275 | DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), | 2291 | DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), |
| 2292 | #ifdef CONFIG_NET | ||
| 2293 | DIR("net", S_IRUGO|S_IXUGO, net), | ||
| 2294 | #endif | ||
| 2276 | REG("environ", S_IRUSR, environ), | 2295 | REG("environ", S_IRUSR, environ), |
| 2277 | INF("auxv", S_IRUSR, pid_auxv), | 2296 | INF("auxv", S_IRUSR, pid_auxv), |
| 2278 | ONE("status", S_IRUGO, pid_status), | 2297 | ONE("status", S_IRUGO, pid_status), |
| @@ -2320,6 +2339,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
| 2320 | REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), | 2339 | REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), |
| 2321 | #ifdef CONFIG_AUDITSYSCALL | 2340 | #ifdef CONFIG_AUDITSYSCALL |
| 2322 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), | 2341 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), |
| 2342 | REG("sessionid", S_IRUSR, sessionid), | ||
| 2323 | #endif | 2343 | #endif |
| 2324 | #ifdef CONFIG_FAULT_INJECTION | 2344 | #ifdef CONFIG_FAULT_INJECTION |
| 2325 | REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), | 2345 | REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), |
| @@ -2650,6 +2670,7 @@ static const struct pid_entry tid_base_stuff[] = { | |||
| 2650 | REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), | 2670 | REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), |
| 2651 | #ifdef CONFIG_AUDITSYSCALL | 2671 | #ifdef CONFIG_AUDITSYSCALL |
| 2652 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), | 2672 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), |
| 2673 | REG("sessionid", S_IRUSR, sessionid), | ||
| 2653 | #endif | 2674 | #endif |
| 2654 | #ifdef CONFIG_FAULT_INJECTION | 2675 | #ifdef CONFIG_FAULT_INJECTION |
| 2655 | REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), | 2676 | REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 68971e66cd41..a36ad3c75cf4 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
| @@ -377,15 +377,14 @@ static struct dentry_operations proc_dentry_operations = | |||
| 377 | * Don't create negative dentries here, return -ENOENT by hand | 377 | * Don't create negative dentries here, return -ENOENT by hand |
| 378 | * instead. | 378 | * instead. |
| 379 | */ | 379 | */ |
| 380 | struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) | 380 | struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir, |
| 381 | struct dentry *dentry) | ||
| 381 | { | 382 | { |
| 382 | struct inode *inode = NULL; | 383 | struct inode *inode = NULL; |
| 383 | struct proc_dir_entry * de; | ||
| 384 | int error = -ENOENT; | 384 | int error = -ENOENT; |
| 385 | 385 | ||
| 386 | lock_kernel(); | 386 | lock_kernel(); |
| 387 | spin_lock(&proc_subdir_lock); | 387 | spin_lock(&proc_subdir_lock); |
| 388 | de = PDE(dir); | ||
| 389 | if (de) { | 388 | if (de) { |
| 390 | for (de = de->subdir; de ; de = de->next) { | 389 | for (de = de->subdir; de ; de = de->next) { |
| 391 | if (de->namelen != dentry->d_name.len) | 390 | if (de->namelen != dentry->d_name.len) |
| @@ -393,8 +392,6 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nam | |||
| 393 | if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { | 392 | if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { |
| 394 | unsigned int ino; | 393 | unsigned int ino; |
| 395 | 394 | ||
| 396 | if (de->shadow_proc) | ||
| 397 | de = de->shadow_proc(current, de); | ||
| 398 | ino = de->low_ino; | 395 | ino = de->low_ino; |
| 399 | de_get(de); | 396 | de_get(de); |
| 400 | spin_unlock(&proc_subdir_lock); | 397 | spin_unlock(&proc_subdir_lock); |
| @@ -417,6 +414,12 @@ out_unlock: | |||
| 417 | return ERR_PTR(error); | 414 | return ERR_PTR(error); |
| 418 | } | 415 | } |
| 419 | 416 | ||
| 417 | struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry, | ||
| 418 | struct nameidata *nd) | ||
| 419 | { | ||
| 420 | return proc_lookup_de(PDE(dir), dir, dentry); | ||
| 421 | } | ||
| 422 | |||
| 420 | /* | 423 | /* |
| 421 | * This returns non-zero if at EOF, so that the /proc | 424 | * This returns non-zero if at EOF, so that the /proc |
| 422 | * root directory can use this and check if it should | 425 | * root directory can use this and check if it should |
| @@ -426,10 +429,9 @@ out_unlock: | |||
| 426 | * value of the readdir() call, as long as it's non-negative | 429 | * value of the readdir() call, as long as it's non-negative |
| 427 | * for success.. | 430 | * for success.. |
| 428 | */ | 431 | */ |
| 429 | int proc_readdir(struct file * filp, | 432 | int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, |
| 430 | void * dirent, filldir_t filldir) | 433 | filldir_t filldir) |
| 431 | { | 434 | { |
| 432 | struct proc_dir_entry * de; | ||
| 433 | unsigned int ino; | 435 | unsigned int ino; |
| 434 | int i; | 436 | int i; |
| 435 | struct inode *inode = filp->f_path.dentry->d_inode; | 437 | struct inode *inode = filp->f_path.dentry->d_inode; |
| @@ -438,7 +440,6 @@ int proc_readdir(struct file * filp, | |||
| 438 | lock_kernel(); | 440 | lock_kernel(); |
| 439 | 441 | ||
| 440 | ino = inode->i_ino; | 442 | ino = inode->i_ino; |
| 441 | de = PDE(inode); | ||
| 442 | if (!de) { | 443 | if (!de) { |
| 443 | ret = -EINVAL; | 444 | ret = -EINVAL; |
| 444 | goto out; | 445 | goto out; |
| @@ -499,6 +500,13 @@ out: unlock_kernel(); | |||
| 499 | return ret; | 500 | return ret; |
| 500 | } | 501 | } |
| 501 | 502 | ||
| 503 | int proc_readdir(struct file *filp, void *dirent, filldir_t filldir) | ||
| 504 | { | ||
| 505 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
| 506 | |||
| 507 | return proc_readdir_de(PDE(inode), filp, dirent, filldir); | ||
| 508 | } | ||
| 509 | |||
| 502 | /* | 510 | /* |
| 503 | * These are the generic /proc directory operations. They | 511 | * These are the generic /proc directory operations. They |
| 504 | * use the in-memory "struct proc_dir_entry" tree to parse | 512 | * use the in-memory "struct proc_dir_entry" tree to parse |
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 1c81c8f1aeed..bc72f5c8c47d 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
| @@ -64,6 +64,8 @@ extern const struct file_operations proc_numa_maps_operations; | |||
| 64 | extern const struct file_operations proc_smaps_operations; | 64 | extern const struct file_operations proc_smaps_operations; |
| 65 | extern const struct file_operations proc_clear_refs_operations; | 65 | extern const struct file_operations proc_clear_refs_operations; |
| 66 | extern const struct file_operations proc_pagemap_operations; | 66 | extern const struct file_operations proc_pagemap_operations; |
| 67 | extern const struct file_operations proc_net_operations; | ||
| 68 | extern const struct inode_operations proc_net_inode_operations; | ||
| 67 | 69 | ||
| 68 | void free_proc_entry(struct proc_dir_entry *de); | 70 | void free_proc_entry(struct proc_dir_entry *de); |
| 69 | 71 | ||
| @@ -83,3 +85,8 @@ static inline int proc_fd(struct inode *inode) | |||
| 83 | { | 85 | { |
| 84 | return PROC_I(inode)->fd; | 86 | return PROC_I(inode)->fd; |
| 85 | } | 87 | } |
| 88 | |||
| 89 | struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *ino, | ||
| 90 | struct dentry *dentry); | ||
| 91 | int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, | ||
| 92 | filldir_t filldir); | ||
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 468805d40e2b..2d563979cb02 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
| 33 | #include <linux/swap.h> | 33 | #include <linux/swap.h> |
| 34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
| 35 | #include <linux/genhd.h> | ||
| 35 | #include <linux/smp.h> | 36 | #include <linux/smp.h> |
| 36 | #include <linux/signal.h> | 37 | #include <linux/signal.h> |
| 37 | #include <linux/module.h> | 38 | #include <linux/module.h> |
| @@ -377,7 +378,6 @@ static int stram_read_proc(char *page, char **start, off_t off, | |||
| 377 | #endif | 378 | #endif |
| 378 | 379 | ||
| 379 | #ifdef CONFIG_BLOCK | 380 | #ifdef CONFIG_BLOCK |
| 380 | extern const struct seq_operations partitions_op; | ||
| 381 | static int partitions_open(struct inode *inode, struct file *file) | 381 | static int partitions_open(struct inode *inode, struct file *file) |
| 382 | { | 382 | { |
| 383 | return seq_open(file, &partitions_op); | 383 | return seq_open(file, &partitions_op); |
| @@ -389,7 +389,6 @@ static const struct file_operations proc_partitions_operations = { | |||
| 389 | .release = seq_release, | 389 | .release = seq_release, |
| 390 | }; | 390 | }; |
| 391 | 391 | ||
| 392 | extern const struct seq_operations diskstats_op; | ||
| 393 | static int diskstats_open(struct inode *inode, struct file *file) | 392 | static int diskstats_open(struct inode *inode, struct file *file) |
| 394 | { | 393 | { |
| 395 | return seq_open(file, &diskstats_op); | 394 | return seq_open(file, &diskstats_op); |
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 14e9b5aaf863..4caa5f774fb7 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c | |||
| @@ -63,6 +63,82 @@ int seq_release_net(struct inode *ino, struct file *f) | |||
| 63 | } | 63 | } |
| 64 | EXPORT_SYMBOL_GPL(seq_release_net); | 64 | EXPORT_SYMBOL_GPL(seq_release_net); |
| 65 | 65 | ||
| 66 | static struct net *get_proc_task_net(struct inode *dir) | ||
| 67 | { | ||
| 68 | struct task_struct *task; | ||
| 69 | struct nsproxy *ns; | ||
| 70 | struct net *net = NULL; | ||
| 71 | |||
| 72 | rcu_read_lock(); | ||
| 73 | task = pid_task(proc_pid(dir), PIDTYPE_PID); | ||
| 74 | if (task != NULL) { | ||
| 75 | ns = task_nsproxy(task); | ||
| 76 | if (ns != NULL) | ||
| 77 | net = get_net(ns->net_ns); | ||
| 78 | } | ||
| 79 | rcu_read_unlock(); | ||
| 80 | |||
| 81 | return net; | ||
| 82 | } | ||
| 83 | |||
| 84 | static struct dentry *proc_tgid_net_lookup(struct inode *dir, | ||
| 85 | struct dentry *dentry, struct nameidata *nd) | ||
| 86 | { | ||
| 87 | struct dentry *de; | ||
| 88 | struct net *net; | ||
| 89 | |||
| 90 | de = ERR_PTR(-ENOENT); | ||
| 91 | net = get_proc_task_net(dir); | ||
| 92 | if (net != NULL) { | ||
| 93 | de = proc_lookup_de(net->proc_net, dir, dentry); | ||
| 94 | put_net(net); | ||
| 95 | } | ||
| 96 | return de; | ||
| 97 | } | ||
| 98 | |||
| 99 | static int proc_tgid_net_getattr(struct vfsmount *mnt, struct dentry *dentry, | ||
| 100 | struct kstat *stat) | ||
| 101 | { | ||
| 102 | struct inode *inode = dentry->d_inode; | ||
| 103 | struct net *net; | ||
| 104 | |||
| 105 | net = get_proc_task_net(inode); | ||
| 106 | |||
| 107 | generic_fillattr(inode, stat); | ||
| 108 | |||
| 109 | if (net != NULL) { | ||
| 110 | stat->nlink = net->proc_net->nlink; | ||
| 111 | put_net(net); | ||
| 112 | } | ||
| 113 | |||
| 114 | return 0; | ||
| 115 | } | ||
| 116 | |||
| 117 | const struct inode_operations proc_net_inode_operations = { | ||
| 118 | .lookup = proc_tgid_net_lookup, | ||
| 119 | .getattr = proc_tgid_net_getattr, | ||
| 120 | }; | ||
| 121 | |||
| 122 | static int proc_tgid_net_readdir(struct file *filp, void *dirent, | ||
| 123 | filldir_t filldir) | ||
| 124 | { | ||
| 125 | int ret; | ||
| 126 | struct net *net; | ||
| 127 | |||
| 128 | ret = -EINVAL; | ||
| 129 | net = get_proc_task_net(filp->f_path.dentry->d_inode); | ||
| 130 | if (net != NULL) { | ||
| 131 | ret = proc_readdir_de(net->proc_net, filp, dirent, filldir); | ||
| 132 | put_net(net); | ||
| 133 | } | ||
| 134 | return ret; | ||
| 135 | } | ||
| 136 | |||
| 137 | const struct file_operations proc_net_operations = { | ||
| 138 | .read = generic_read_dir, | ||
| 139 | .readdir = proc_tgid_net_readdir, | ||
| 140 | }; | ||
| 141 | |||
| 66 | 142 | ||
| 67 | struct proc_dir_entry *proc_net_fops_create(struct net *net, | 143 | struct proc_dir_entry *proc_net_fops_create(struct net *net, |
| 68 | const char *name, mode_t mode, const struct file_operations *fops) | 144 | const char *name, mode_t mode, const struct file_operations *fops) |
| @@ -83,14 +159,6 @@ struct net *get_proc_net(const struct inode *inode) | |||
| 83 | } | 159 | } |
| 84 | EXPORT_SYMBOL_GPL(get_proc_net); | 160 | EXPORT_SYMBOL_GPL(get_proc_net); |
| 85 | 161 | ||
| 86 | static struct proc_dir_entry *shadow_pde; | ||
| 87 | |||
| 88 | static struct proc_dir_entry *proc_net_shadow(struct task_struct *task, | ||
| 89 | struct proc_dir_entry *de) | ||
| 90 | { | ||
| 91 | return task->nsproxy->net_ns->proc_net; | ||
| 92 | } | ||
| 93 | |||
| 94 | struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, | 162 | struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, |
| 95 | struct proc_dir_entry *parent) | 163 | struct proc_dir_entry *parent) |
| 96 | { | 164 | { |
| @@ -104,45 +172,39 @@ EXPORT_SYMBOL_GPL(proc_net_mkdir); | |||
| 104 | 172 | ||
| 105 | static __net_init int proc_net_ns_init(struct net *net) | 173 | static __net_init int proc_net_ns_init(struct net *net) |
| 106 | { | 174 | { |
| 107 | struct proc_dir_entry *root, *netd, *net_statd; | 175 | struct proc_dir_entry *netd, *net_statd; |
| 108 | int err; | 176 | int err; |
| 109 | 177 | ||
| 110 | err = -ENOMEM; | 178 | err = -ENOMEM; |
| 111 | root = kzalloc(sizeof(*root), GFP_KERNEL); | 179 | netd = kzalloc(sizeof(*netd), GFP_KERNEL); |
| 112 | if (!root) | 180 | if (!netd) |
| 113 | goto out; | 181 | goto out; |
| 114 | 182 | ||
| 115 | err = -EEXIST; | 183 | netd->data = net; |
| 116 | netd = proc_net_mkdir(net, "net", root); | 184 | netd->nlink = 2; |
| 117 | if (!netd) | 185 | netd->name = "net"; |
| 118 | goto free_root; | 186 | netd->namelen = 3; |
| 187 | netd->parent = &proc_root; | ||
| 119 | 188 | ||
| 120 | err = -EEXIST; | 189 | err = -EEXIST; |
| 121 | net_statd = proc_net_mkdir(net, "stat", netd); | 190 | net_statd = proc_net_mkdir(net, "stat", netd); |
| 122 | if (!net_statd) | 191 | if (!net_statd) |
| 123 | goto free_net; | 192 | goto free_net; |
| 124 | 193 | ||
| 125 | root->data = net; | ||
| 126 | |||
| 127 | net->proc_net_root = root; | ||
| 128 | net->proc_net = netd; | 194 | net->proc_net = netd; |
| 129 | net->proc_net_stat = net_statd; | 195 | net->proc_net_stat = net_statd; |
| 130 | err = 0; | 196 | return 0; |
| 131 | 197 | ||
| 198 | free_net: | ||
| 199 | kfree(netd); | ||
| 132 | out: | 200 | out: |
| 133 | return err; | 201 | return err; |
| 134 | free_net: | ||
| 135 | remove_proc_entry("net", root); | ||
| 136 | free_root: | ||
| 137 | kfree(root); | ||
| 138 | goto out; | ||
| 139 | } | 202 | } |
| 140 | 203 | ||
| 141 | static __net_exit void proc_net_ns_exit(struct net *net) | 204 | static __net_exit void proc_net_ns_exit(struct net *net) |
| 142 | { | 205 | { |
| 143 | remove_proc_entry("stat", net->proc_net); | 206 | remove_proc_entry("stat", net->proc_net); |
| 144 | remove_proc_entry("net", net->proc_net_root); | 207 | kfree(net->proc_net); |
| 145 | kfree(net->proc_net_root); | ||
| 146 | } | 208 | } |
| 147 | 209 | ||
| 148 | static struct pernet_operations __net_initdata proc_net_ns_ops = { | 210 | static struct pernet_operations __net_initdata proc_net_ns_ops = { |
| @@ -152,8 +214,7 @@ static struct pernet_operations __net_initdata proc_net_ns_ops = { | |||
| 152 | 214 | ||
| 153 | int __init proc_net_init(void) | 215 | int __init proc_net_init(void) |
| 154 | { | 216 | { |
| 155 | shadow_pde = proc_mkdir("net", NULL); | 217 | proc_symlink("net", NULL, "self/net"); |
| 156 | shadow_pde->shadow_proc = proc_net_shadow; | ||
| 157 | 218 | ||
| 158 | return register_pernet_subsys(&proc_net_ns_ops); | 219 | return register_pernet_subsys(&proc_net_ns_ops); |
| 159 | } | 220 | } |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 49958cffbd8d..9dfb5ff24209 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
| @@ -527,13 +527,21 @@ struct pagemapread { | |||
| 527 | char __user *out, *end; | 527 | char __user *out, *end; |
| 528 | }; | 528 | }; |
| 529 | 529 | ||
| 530 | #define PM_ENTRY_BYTES sizeof(u64) | 530 | #define PM_ENTRY_BYTES sizeof(u64) |
| 531 | #define PM_RESERVED_BITS 3 | 531 | #define PM_STATUS_BITS 3 |
| 532 | #define PM_RESERVED_OFFSET (64 - PM_RESERVED_BITS) | 532 | #define PM_STATUS_OFFSET (64 - PM_STATUS_BITS) |
| 533 | #define PM_RESERVED_MASK (((1LL<<PM_RESERVED_BITS)-1) << PM_RESERVED_OFFSET) | 533 | #define PM_STATUS_MASK (((1LL << PM_STATUS_BITS) - 1) << PM_STATUS_OFFSET) |
| 534 | #define PM_SPECIAL(nr) (((nr) << PM_RESERVED_OFFSET) | PM_RESERVED_MASK) | 534 | #define PM_STATUS(nr) (((nr) << PM_STATUS_OFFSET) & PM_STATUS_MASK) |
| 535 | #define PM_NOT_PRESENT PM_SPECIAL(1LL) | 535 | #define PM_PSHIFT_BITS 6 |
| 536 | #define PM_SWAP PM_SPECIAL(2LL) | 536 | #define PM_PSHIFT_OFFSET (PM_STATUS_OFFSET - PM_PSHIFT_BITS) |
| 537 | #define PM_PSHIFT_MASK (((1LL << PM_PSHIFT_BITS) - 1) << PM_PSHIFT_OFFSET) | ||
| 538 | #define PM_PSHIFT(x) (((u64) (x) << PM_PSHIFT_OFFSET) & PM_PSHIFT_MASK) | ||
| 539 | #define PM_PFRAME_MASK ((1LL << PM_PSHIFT_OFFSET) - 1) | ||
| 540 | #define PM_PFRAME(x) ((x) & PM_PFRAME_MASK) | ||
| 541 | |||
| 542 | #define PM_PRESENT PM_STATUS(4LL) | ||
| 543 | #define PM_SWAP PM_STATUS(2LL) | ||
| 544 | #define PM_NOT_PRESENT PM_PSHIFT(PAGE_SHIFT) | ||
| 537 | #define PM_END_OF_BUFFER 1 | 545 | #define PM_END_OF_BUFFER 1 |
| 538 | 546 | ||
| 539 | static int add_to_pagemap(unsigned long addr, u64 pfn, | 547 | static int add_to_pagemap(unsigned long addr, u64 pfn, |
| @@ -574,7 +582,7 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end, | |||
| 574 | u64 swap_pte_to_pagemap_entry(pte_t pte) | 582 | u64 swap_pte_to_pagemap_entry(pte_t pte) |
| 575 | { | 583 | { |
| 576 | swp_entry_t e = pte_to_swp_entry(pte); | 584 | swp_entry_t e = pte_to_swp_entry(pte); |
| 577 | return PM_SWAP | swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT); | 585 | return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT); |
| 578 | } | 586 | } |
| 579 | 587 | ||
| 580 | static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | 588 | static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, |
| @@ -588,9 +596,11 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | |||
| 588 | u64 pfn = PM_NOT_PRESENT; | 596 | u64 pfn = PM_NOT_PRESENT; |
| 589 | pte = pte_offset_map(pmd, addr); | 597 | pte = pte_offset_map(pmd, addr); |
| 590 | if (is_swap_pte(*pte)) | 598 | if (is_swap_pte(*pte)) |
| 591 | pfn = swap_pte_to_pagemap_entry(*pte); | 599 | pfn = PM_PFRAME(swap_pte_to_pagemap_entry(*pte)) |
| 600 | | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP; | ||
| 592 | else if (pte_present(*pte)) | 601 | else if (pte_present(*pte)) |
| 593 | pfn = pte_pfn(*pte); | 602 | pfn = PM_PFRAME(pte_pfn(*pte)) |
| 603 | | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT; | ||
| 594 | /* unmap so we're not in atomic when we copy to userspace */ | 604 | /* unmap so we're not in atomic when we copy to userspace */ |
| 595 | pte_unmap(pte); | 605 | pte_unmap(pte); |
| 596 | err = add_to_pagemap(addr, pfn, pm); | 606 | err = add_to_pagemap(addr, pfn, pm); |
| @@ -611,12 +621,20 @@ static struct mm_walk pagemap_walk = { | |||
| 611 | /* | 621 | /* |
| 612 | * /proc/pid/pagemap - an array mapping virtual pages to pfns | 622 | * /proc/pid/pagemap - an array mapping virtual pages to pfns |
| 613 | * | 623 | * |
| 614 | * For each page in the address space, this file contains one 64-bit | 624 | * For each page in the address space, this file contains one 64-bit entry |
| 615 | * entry representing the corresponding physical page frame number | 625 | * consisting of the following: |
| 616 | * (PFN) if the page is present. If there is a swap entry for the | 626 | * |
| 617 | * physical page, then an encoding of the swap file number and the | 627 | * Bits 0-55 page frame number (PFN) if present |
| 618 | * page's offset into the swap file are returned. If no page is | 628 | * Bits 0-4 swap type if swapped |
| 619 | * present at all, PM_NOT_PRESENT is returned. This allows determining | 629 | * Bits 5-55 swap offset if swapped |
| 630 | * Bits 55-60 page shift (page size = 1<<page shift) | ||
| 631 | * Bit 61 reserved for future use | ||
| 632 | * Bit 62 page swapped | ||
| 633 | * Bit 63 page present | ||
| 634 | * | ||
| 635 | * If the page is not present but in swap, then the PFN contains an | ||
| 636 | * encoding of the swap file number and the page's offset into the | ||
| 637 | * swap. Unmapped pages return a null PFN. This allows determining | ||
| 620 | * precisely which pages are mapped (or in swap) and comparing mapped | 638 | * precisely which pages are mapped (or in swap) and comparing mapped |
| 621 | * pages between processes. | 639 | * pages between processes. |
| 622 | * | 640 | * |
| @@ -640,17 +658,17 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, | |||
| 640 | 658 | ||
| 641 | ret = -EACCES; | 659 | ret = -EACCES; |
| 642 | if (!ptrace_may_attach(task)) | 660 | if (!ptrace_may_attach(task)) |
| 643 | goto out; | 661 | goto out_task; |
| 644 | 662 | ||
| 645 | ret = -EINVAL; | 663 | ret = -EINVAL; |
| 646 | /* file position must be aligned */ | 664 | /* file position must be aligned */ |
| 647 | if (*ppos % PM_ENTRY_BYTES) | 665 | if (*ppos % PM_ENTRY_BYTES) |
| 648 | goto out; | 666 | goto out_task; |
| 649 | 667 | ||
| 650 | ret = 0; | 668 | ret = 0; |
| 651 | mm = get_task_mm(task); | 669 | mm = get_task_mm(task); |
| 652 | if (!mm) | 670 | if (!mm) |
| 653 | goto out; | 671 | goto out_task; |
| 654 | 672 | ||
| 655 | ret = -ENOMEM; | 673 | ret = -ENOMEM; |
| 656 | uaddr = (unsigned long)buf & PAGE_MASK; | 674 | uaddr = (unsigned long)buf & PAGE_MASK; |
| @@ -658,7 +676,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, | |||
| 658 | pagecount = (PAGE_ALIGN(uend) - uaddr) / PAGE_SIZE; | 676 | pagecount = (PAGE_ALIGN(uend) - uaddr) / PAGE_SIZE; |
| 659 | pages = kmalloc(pagecount * sizeof(struct page *), GFP_KERNEL); | 677 | pages = kmalloc(pagecount * sizeof(struct page *), GFP_KERNEL); |
| 660 | if (!pages) | 678 | if (!pages) |
| 661 | goto out_task; | 679 | goto out_mm; |
| 662 | 680 | ||
| 663 | down_read(¤t->mm->mmap_sem); | 681 | down_read(¤t->mm->mmap_sem); |
| 664 | ret = get_user_pages(current, current->mm, uaddr, pagecount, | 682 | ret = get_user_pages(current, current->mm, uaddr, pagecount, |
| @@ -668,6 +686,12 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, | |||
| 668 | if (ret < 0) | 686 | if (ret < 0) |
| 669 | goto out_free; | 687 | goto out_free; |
| 670 | 688 | ||
| 689 | if (ret != pagecount) { | ||
| 690 | pagecount = ret; | ||
| 691 | ret = -EFAULT; | ||
| 692 | goto out_pages; | ||
| 693 | } | ||
| 694 | |||
| 671 | pm.out = buf; | 695 | pm.out = buf; |
| 672 | pm.end = buf + count; | 696 | pm.end = buf + count; |
| 673 | 697 | ||
| @@ -699,15 +723,17 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, | |||
| 699 | ret = pm.out - buf; | 723 | ret = pm.out - buf; |
| 700 | } | 724 | } |
| 701 | 725 | ||
| 726 | out_pages: | ||
| 702 | for (; pagecount; pagecount--) { | 727 | for (; pagecount; pagecount--) { |
| 703 | page = pages[pagecount-1]; | 728 | page = pages[pagecount-1]; |
| 704 | if (!PageReserved(page)) | 729 | if (!PageReserved(page)) |
| 705 | SetPageDirty(page); | 730 | SetPageDirty(page); |
| 706 | page_cache_release(page); | 731 | page_cache_release(page); |
| 707 | } | 732 | } |
| 708 | mmput(mm); | ||
| 709 | out_free: | 733 | out_free: |
| 710 | kfree(pages); | 734 | kfree(pages); |
| 735 | out_mm: | ||
| 736 | mmput(mm); | ||
| 711 | out_task: | 737 | out_task: |
| 712 | put_task_struct(task); | 738 | put_task_struct(task); |
| 713 | out: | 739 | out: |
diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c index f85c5cf4934c..7ee4208793b6 100644 --- a/fs/reiserfs/do_balan.c +++ b/fs/reiserfs/do_balan.c | |||
| @@ -283,7 +283,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, /* item h | |||
| 283 | return balance_leaf_when_delete(tb, flag); | 283 | return balance_leaf_when_delete(tb, flag); |
| 284 | 284 | ||
| 285 | zeros_num = 0; | 285 | zeros_num = 0; |
| 286 | if (flag == M_INSERT && body == 0) | 286 | if (flag == M_INSERT && !body) |
| 287 | zeros_num = ih_item_len(ih); | 287 | zeros_num = ih_item_len(ih); |
| 288 | 288 | ||
| 289 | pos_in_item = tb->tb_path->pos_in_item; | 289 | pos_in_item = tb->tb_path->pos_in_item; |
| @@ -1728,7 +1728,7 @@ struct buffer_head *get_FEB(struct tree_balance *tb) | |||
| 1728 | struct buffer_info bi; | 1728 | struct buffer_info bi; |
| 1729 | 1729 | ||
| 1730 | for (i = 0; i < MAX_FEB_SIZE; i++) | 1730 | for (i = 0; i < MAX_FEB_SIZE; i++) |
| 1731 | if (tb->FEB[i] != 0) | 1731 | if (tb->FEB[i] != NULL) |
| 1732 | break; | 1732 | break; |
| 1733 | 1733 | ||
| 1734 | if (i == MAX_FEB_SIZE) | 1734 | if (i == MAX_FEB_SIZE) |
| @@ -1827,7 +1827,7 @@ int get_left_neighbor_position(struct tree_balance *tb, int h) | |||
| 1827 | { | 1827 | { |
| 1828 | int Sh_position = PATH_H_POSITION(tb->tb_path, h + 1); | 1828 | int Sh_position = PATH_H_POSITION(tb->tb_path, h + 1); |
| 1829 | 1829 | ||
| 1830 | RFALSE(PATH_H_PPARENT(tb->tb_path, h) == 0 || tb->FL[h] == 0, | 1830 | RFALSE(PATH_H_PPARENT(tb->tb_path, h) == NULL || tb->FL[h] == NULL, |
| 1831 | "vs-12325: FL[%d](%p) or F[%d](%p) does not exist", | 1831 | "vs-12325: FL[%d](%p) or F[%d](%p) does not exist", |
| 1832 | h, tb->FL[h], h, PATH_H_PPARENT(tb->tb_path, h)); | 1832 | h, tb->FL[h], h, PATH_H_PPARENT(tb->tb_path, h)); |
| 1833 | 1833 | ||
| @@ -1841,7 +1841,7 @@ int get_right_neighbor_position(struct tree_balance *tb, int h) | |||
| 1841 | { | 1841 | { |
| 1842 | int Sh_position = PATH_H_POSITION(tb->tb_path, h + 1); | 1842 | int Sh_position = PATH_H_POSITION(tb->tb_path, h + 1); |
| 1843 | 1843 | ||
| 1844 | RFALSE(PATH_H_PPARENT(tb->tb_path, h) == 0 || tb->FR[h] == 0, | 1844 | RFALSE(PATH_H_PPARENT(tb->tb_path, h) == NULL || tb->FR[h] == NULL, |
| 1845 | "vs-12330: F[%d](%p) or FR[%d](%p) does not exist", | 1845 | "vs-12330: F[%d](%p) or FR[%d](%p) does not exist", |
| 1846 | h, PATH_H_PPARENT(tb->tb_path, h), h, tb->FR[h]); | 1846 | h, PATH_H_PPARENT(tb->tb_path, h), h, tb->FR[h]); |
| 1847 | 1847 | ||
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c index 0ee35c6c9b72..07d05e0842b7 100644 --- a/fs/reiserfs/fix_node.c +++ b/fs/reiserfs/fix_node.c | |||
| @@ -153,7 +153,7 @@ static void create_virtual_node(struct tree_balance *tb, int h) | |||
| 153 | if (vn->vn_mode == M_INSERT) { | 153 | if (vn->vn_mode == M_INSERT) { |
| 154 | struct virtual_item *vi = vn->vn_vi + vn->vn_affected_item_num; | 154 | struct virtual_item *vi = vn->vn_vi + vn->vn_affected_item_num; |
| 155 | 155 | ||
| 156 | RFALSE(vn->vn_ins_ih == 0, | 156 | RFALSE(vn->vn_ins_ih == NULL, |
| 157 | "vs-8040: item header of inserted item is not specified"); | 157 | "vs-8040: item header of inserted item is not specified"); |
| 158 | vi->vi_item_len = tb->insert_size[0]; | 158 | vi->vi_item_len = tb->insert_size[0]; |
| 159 | vi->vi_ih = vn->vn_ins_ih; | 159 | vi->vi_ih = vn->vn_ins_ih; |
| @@ -857,7 +857,8 @@ static int get_lfree(struct tree_balance *tb, int h) | |||
| 857 | struct buffer_head *l, *f; | 857 | struct buffer_head *l, *f; |
| 858 | int order; | 858 | int order; |
| 859 | 859 | ||
| 860 | if ((f = PATH_H_PPARENT(tb->tb_path, h)) == 0 || (l = tb->FL[h]) == 0) | 860 | if ((f = PATH_H_PPARENT(tb->tb_path, h)) == NULL || |
| 861 | (l = tb->FL[h]) == NULL) | ||
| 861 | return 0; | 862 | return 0; |
| 862 | 863 | ||
| 863 | if (f == l) | 864 | if (f == l) |
| @@ -878,7 +879,8 @@ static int get_rfree(struct tree_balance *tb, int h) | |||
| 878 | struct buffer_head *r, *f; | 879 | struct buffer_head *r, *f; |
| 879 | int order; | 880 | int order; |
| 880 | 881 | ||
| 881 | if ((f = PATH_H_PPARENT(tb->tb_path, h)) == 0 || (r = tb->FR[h]) == 0) | 882 | if ((f = PATH_H_PPARENT(tb->tb_path, h)) == NULL || |
| 883 | (r = tb->FR[h]) == NULL) | ||
| 882 | return 0; | 884 | return 0; |
| 883 | 885 | ||
| 884 | if (f == r) | 886 | if (f == r) |
diff --git a/fs/reiserfs/lbalance.c b/fs/reiserfs/lbalance.c index 281f8061ac58..6de060a6aa7f 100644 --- a/fs/reiserfs/lbalance.c +++ b/fs/reiserfs/lbalance.c | |||
| @@ -626,7 +626,7 @@ static void leaf_define_dest_src_infos(int shift_mode, struct tree_balance *tb, | |||
| 626 | "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)", | 626 | "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)", |
| 627 | shift_mode); | 627 | shift_mode); |
| 628 | } | 628 | } |
| 629 | RFALSE(src_bi->bi_bh == 0 || dest_bi->bi_bh == 0, | 629 | RFALSE(!src_bi->bi_bh || !dest_bi->bi_bh, |
| 630 | "vs-10260: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly", | 630 | "vs-10260: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly", |
| 631 | shift_mode, src_bi->bi_bh, dest_bi->bi_bh); | 631 | shift_mode, src_bi->bi_bh, dest_bi->bi_bh); |
| 632 | } | 632 | } |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index b378eea332ca..8867533cb727 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
| @@ -452,7 +452,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, | |||
| 452 | buflen = DEH_SIZE + ROUND_UP(namelen); | 452 | buflen = DEH_SIZE + ROUND_UP(namelen); |
| 453 | if (buflen > sizeof(small_buf)) { | 453 | if (buflen > sizeof(small_buf)) { |
| 454 | buffer = kmalloc(buflen, GFP_NOFS); | 454 | buffer = kmalloc(buflen, GFP_NOFS); |
| 455 | if (buffer == 0) | 455 | if (!buffer) |
| 456 | return -ENOMEM; | 456 | return -ENOMEM; |
| 457 | } else | 457 | } else |
| 458 | buffer = small_buf; | 458 | buffer = small_buf; |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 6841452e0dea..393cc22c1717 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
| @@ -2031,7 +2031,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, | |||
| 2031 | return -EXDEV; | 2031 | return -EXDEV; |
| 2032 | } | 2032 | } |
| 2033 | /* We must not pack tails for quota files on reiserfs for quota IO to work */ | 2033 | /* We must not pack tails for quota files on reiserfs for quota IO to work */ |
| 2034 | if (!REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask) { | 2034 | if (!(REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask)) { |
| 2035 | reiserfs_warning(sb, | 2035 | reiserfs_warning(sb, |
| 2036 | "reiserfs: Quota file must have tail packing disabled."); | 2036 | "reiserfs: Quota file must have tail packing disabled."); |
| 2037 | path_put(&nd.path); | 2037 | path_put(&nd.path); |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index eba037b3338f..344b9b96cc56 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
| @@ -191,28 +191,11 @@ static struct dentry *get_xa_file_dentry(const struct inode *inode, | |||
| 191 | dput(xadir); | 191 | dput(xadir); |
| 192 | if (err) | 192 | if (err) |
| 193 | xafile = ERR_PTR(err); | 193 | xafile = ERR_PTR(err); |
| 194 | return xafile; | ||
| 195 | } | ||
| 196 | |||
| 197 | /* Opens a file pointer to the attribute associated with inode */ | ||
| 198 | static struct file *open_xa_file(const struct inode *inode, const char *name, | ||
| 199 | int flags) | ||
| 200 | { | ||
| 201 | struct dentry *xafile; | ||
| 202 | struct file *fp; | ||
| 203 | |||
| 204 | xafile = get_xa_file_dentry(inode, name, flags); | ||
| 205 | if (IS_ERR(xafile)) | ||
| 206 | return ERR_PTR(PTR_ERR(xafile)); | ||
| 207 | else if (!xafile->d_inode) { | 194 | else if (!xafile->d_inode) { |
| 208 | dput(xafile); | 195 | dput(xafile); |
| 209 | return ERR_PTR(-ENODATA); | 196 | xafile = ERR_PTR(-ENODATA); |
| 210 | } | 197 | } |
| 211 | 198 | return xafile; | |
| 212 | fp = dentry_open(xafile, NULL, O_RDWR); | ||
| 213 | /* dentry_open dputs the dentry if it fails */ | ||
| 214 | |||
| 215 | return fp; | ||
| 216 | } | 199 | } |
| 217 | 200 | ||
| 218 | /* | 201 | /* |
| @@ -228,9 +211,8 @@ static struct file *open_xa_file(const struct inode *inode, const char *name, | |||
| 228 | * we're called with i_mutex held, so there are no worries about the directory | 211 | * we're called with i_mutex held, so there are no worries about the directory |
| 229 | * changing underneath us. | 212 | * changing underneath us. |
| 230 | */ | 213 | */ |
| 231 | static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir) | 214 | static int __xattr_readdir(struct inode *inode, void *dirent, filldir_t filldir) |
| 232 | { | 215 | { |
| 233 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
| 234 | struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ | 216 | struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ |
| 235 | INITIALIZE_PATH(path_to_entry); | 217 | INITIALIZE_PATH(path_to_entry); |
| 236 | struct buffer_head *bh; | 218 | struct buffer_head *bh; |
| @@ -374,23 +356,16 @@ static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
| 374 | * | 356 | * |
| 375 | */ | 357 | */ |
| 376 | static | 358 | static |
| 377 | int xattr_readdir(struct file *file, filldir_t filler, void *buf) | 359 | int xattr_readdir(struct inode *inode, filldir_t filler, void *buf) |
| 378 | { | 360 | { |
| 379 | struct inode *inode = file->f_path.dentry->d_inode; | 361 | int res = -ENOENT; |
| 380 | int res = -ENOTDIR; | ||
| 381 | if (!file->f_op || !file->f_op->readdir) | ||
| 382 | goto out; | ||
| 383 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR); | 362 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR); |
| 384 | // down(&inode->i_zombie); | ||
| 385 | res = -ENOENT; | ||
| 386 | if (!IS_DEADDIR(inode)) { | 363 | if (!IS_DEADDIR(inode)) { |
| 387 | lock_kernel(); | 364 | lock_kernel(); |
| 388 | res = __xattr_readdir(file, buf, filler); | 365 | res = __xattr_readdir(inode, buf, filler); |
| 389 | unlock_kernel(); | 366 | unlock_kernel(); |
| 390 | } | 367 | } |
| 391 | // up(&inode->i_zombie); | ||
| 392 | mutex_unlock(&inode->i_mutex); | 368 | mutex_unlock(&inode->i_mutex); |
| 393 | out: | ||
| 394 | return res; | 369 | return res; |
| 395 | } | 370 | } |
| 396 | 371 | ||
| @@ -442,7 +417,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | |||
| 442 | size_t buffer_size, int flags) | 417 | size_t buffer_size, int flags) |
| 443 | { | 418 | { |
| 444 | int err = 0; | 419 | int err = 0; |
| 445 | struct file *fp; | 420 | struct dentry *dentry; |
| 446 | struct page *page; | 421 | struct page *page; |
| 447 | char *data; | 422 | char *data; |
| 448 | struct address_space *mapping; | 423 | struct address_space *mapping; |
| @@ -460,18 +435,18 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | |||
| 460 | xahash = xattr_hash(buffer, buffer_size); | 435 | xahash = xattr_hash(buffer, buffer_size); |
| 461 | 436 | ||
| 462 | open_file: | 437 | open_file: |
| 463 | fp = open_xa_file(inode, name, flags); | 438 | dentry = get_xa_file_dentry(inode, name, flags); |
| 464 | if (IS_ERR(fp)) { | 439 | if (IS_ERR(dentry)) { |
| 465 | err = PTR_ERR(fp); | 440 | err = PTR_ERR(dentry); |
| 466 | goto out; | 441 | goto out; |
| 467 | } | 442 | } |
| 468 | 443 | ||
| 469 | xinode = fp->f_path.dentry->d_inode; | 444 | xinode = dentry->d_inode; |
| 470 | REISERFS_I(inode)->i_flags |= i_has_xattr_dir; | 445 | REISERFS_I(inode)->i_flags |= i_has_xattr_dir; |
| 471 | 446 | ||
| 472 | /* we need to copy it off.. */ | 447 | /* we need to copy it off.. */ |
| 473 | if (xinode->i_nlink > 1) { | 448 | if (xinode->i_nlink > 1) { |
| 474 | fput(fp); | 449 | dput(dentry); |
| 475 | err = reiserfs_xattr_del(inode, name); | 450 | err = reiserfs_xattr_del(inode, name); |
| 476 | if (err < 0) | 451 | if (err < 0) |
| 477 | goto out; | 452 | goto out; |
| @@ -485,7 +460,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | |||
| 485 | newattrs.ia_size = buffer_size; | 460 | newattrs.ia_size = buffer_size; |
| 486 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; | 461 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; |
| 487 | mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR); | 462 | mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR); |
| 488 | err = notify_change(fp->f_path.dentry, &newattrs); | 463 | err = notify_change(dentry, &newattrs); |
| 489 | if (err) | 464 | if (err) |
| 490 | goto out_filp; | 465 | goto out_filp; |
| 491 | 466 | ||
| @@ -518,15 +493,14 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | |||
| 518 | rxh->h_hash = cpu_to_le32(xahash); | 493 | rxh->h_hash = cpu_to_le32(xahash); |
| 519 | } | 494 | } |
| 520 | 495 | ||
| 521 | err = reiserfs_prepare_write(fp, page, page_offset, | 496 | err = reiserfs_prepare_write(NULL, page, page_offset, |
| 522 | page_offset + chunk + skip); | 497 | page_offset + chunk + skip); |
| 523 | if (!err) { | 498 | if (!err) { |
| 524 | if (buffer) | 499 | if (buffer) |
| 525 | memcpy(data + skip, buffer + buffer_pos, chunk); | 500 | memcpy(data + skip, buffer + buffer_pos, chunk); |
| 526 | err = | 501 | err = reiserfs_commit_write(NULL, page, page_offset, |
| 527 | reiserfs_commit_write(fp, page, page_offset, | 502 | page_offset + chunk + |
| 528 | page_offset + chunk + | 503 | skip); |
| 529 | skip); | ||
| 530 | } | 504 | } |
| 531 | unlock_page(page); | 505 | unlock_page(page); |
| 532 | reiserfs_put_page(page); | 506 | reiserfs_put_page(page); |
| @@ -548,7 +522,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | |||
| 548 | 522 | ||
| 549 | out_filp: | 523 | out_filp: |
| 550 | mutex_unlock(&xinode->i_mutex); | 524 | mutex_unlock(&xinode->i_mutex); |
| 551 | fput(fp); | 525 | dput(dentry); |
| 552 | 526 | ||
| 553 | out: | 527 | out: |
| 554 | return err; | 528 | return err; |
| @@ -562,7 +536,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, | |||
| 562 | size_t buffer_size) | 536 | size_t buffer_size) |
| 563 | { | 537 | { |
| 564 | ssize_t err = 0; | 538 | ssize_t err = 0; |
| 565 | struct file *fp; | 539 | struct dentry *dentry; |
| 566 | size_t isize; | 540 | size_t isize; |
| 567 | size_t file_pos = 0; | 541 | size_t file_pos = 0; |
| 568 | size_t buffer_pos = 0; | 542 | size_t buffer_pos = 0; |
| @@ -578,13 +552,13 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, | |||
| 578 | if (get_inode_sd_version(inode) == STAT_DATA_V1) | 552 | if (get_inode_sd_version(inode) == STAT_DATA_V1) |
| 579 | return -EOPNOTSUPP; | 553 | return -EOPNOTSUPP; |
| 580 | 554 | ||
| 581 | fp = open_xa_file(inode, name, FL_READONLY); | 555 | dentry = get_xa_file_dentry(inode, name, FL_READONLY); |
| 582 | if (IS_ERR(fp)) { | 556 | if (IS_ERR(dentry)) { |
| 583 | err = PTR_ERR(fp); | 557 | err = PTR_ERR(dentry); |
| 584 | goto out; | 558 | goto out; |
| 585 | } | 559 | } |
| 586 | 560 | ||
| 587 | xinode = fp->f_path.dentry->d_inode; | 561 | xinode = dentry->d_inode; |
| 588 | isize = xinode->i_size; | 562 | isize = xinode->i_size; |
| 589 | REISERFS_I(inode)->i_flags |= i_has_xattr_dir; | 563 | REISERFS_I(inode)->i_flags |= i_has_xattr_dir; |
| 590 | 564 | ||
| @@ -652,7 +626,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, | |||
| 652 | } | 626 | } |
| 653 | 627 | ||
| 654 | out_dput: | 628 | out_dput: |
| 655 | fput(fp); | 629 | dput(dentry); |
| 656 | 630 | ||
| 657 | out: | 631 | out: |
| 658 | return err; | 632 | return err; |
| @@ -742,7 +716,6 @@ reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, | |||
| 742 | /* This is called w/ inode->i_mutex downed */ | 716 | /* This is called w/ inode->i_mutex downed */ |
| 743 | int reiserfs_delete_xattrs(struct inode *inode) | 717 | int reiserfs_delete_xattrs(struct inode *inode) |
| 744 | { | 718 | { |
| 745 | struct file *fp; | ||
| 746 | struct dentry *dir, *root; | 719 | struct dentry *dir, *root; |
| 747 | int err = 0; | 720 | int err = 0; |
| 748 | 721 | ||
| @@ -763,15 +736,8 @@ int reiserfs_delete_xattrs(struct inode *inode) | |||
| 763 | return 0; | 736 | return 0; |
| 764 | } | 737 | } |
| 765 | 738 | ||
| 766 | fp = dentry_open(dir, NULL, O_RDWR); | ||
| 767 | if (IS_ERR(fp)) { | ||
| 768 | err = PTR_ERR(fp); | ||
| 769 | /* dentry_open dputs the dentry if it fails */ | ||
| 770 | goto out; | ||
| 771 | } | ||
| 772 | |||
| 773 | lock_kernel(); | 739 | lock_kernel(); |
| 774 | err = xattr_readdir(fp, reiserfs_delete_xattrs_filler, dir); | 740 | err = xattr_readdir(dir->d_inode, reiserfs_delete_xattrs_filler, dir); |
| 775 | if (err) { | 741 | if (err) { |
| 776 | unlock_kernel(); | 742 | unlock_kernel(); |
| 777 | goto out_dir; | 743 | goto out_dir; |
| @@ -791,7 +757,7 @@ int reiserfs_delete_xattrs(struct inode *inode) | |||
| 791 | unlock_kernel(); | 757 | unlock_kernel(); |
| 792 | 758 | ||
| 793 | out_dir: | 759 | out_dir: |
| 794 | fput(fp); | 760 | dput(dir); |
| 795 | 761 | ||
| 796 | out: | 762 | out: |
| 797 | if (!err) | 763 | if (!err) |
| @@ -833,7 +799,6 @@ reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen, | |||
| 833 | 799 | ||
| 834 | int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) | 800 | int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) |
| 835 | { | 801 | { |
| 836 | struct file *fp; | ||
| 837 | struct dentry *dir; | 802 | struct dentry *dir; |
| 838 | int err = 0; | 803 | int err = 0; |
| 839 | struct reiserfs_chown_buf buf; | 804 | struct reiserfs_chown_buf buf; |
| @@ -857,13 +822,6 @@ int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) | |||
| 857 | goto out; | 822 | goto out; |
| 858 | } | 823 | } |
| 859 | 824 | ||
| 860 | fp = dentry_open(dir, NULL, O_RDWR); | ||
| 861 | if (IS_ERR(fp)) { | ||
| 862 | err = PTR_ERR(fp); | ||
| 863 | /* dentry_open dputs the dentry if it fails */ | ||
| 864 | goto out; | ||
| 865 | } | ||
| 866 | |||
| 867 | lock_kernel(); | 825 | lock_kernel(); |
| 868 | 826 | ||
| 869 | attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME); | 827 | attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME); |
| @@ -871,7 +829,7 @@ int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) | |||
| 871 | buf.attrs = attrs; | 829 | buf.attrs = attrs; |
| 872 | buf.inode = inode; | 830 | buf.inode = inode; |
| 873 | 831 | ||
| 874 | err = xattr_readdir(fp, reiserfs_chown_xattrs_filler, &buf); | 832 | err = xattr_readdir(dir->d_inode, reiserfs_chown_xattrs_filler, &buf); |
| 875 | if (err) { | 833 | if (err) { |
| 876 | unlock_kernel(); | 834 | unlock_kernel(); |
| 877 | goto out_dir; | 835 | goto out_dir; |
| @@ -881,7 +839,7 @@ int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs) | |||
| 881 | unlock_kernel(); | 839 | unlock_kernel(); |
| 882 | 840 | ||
| 883 | out_dir: | 841 | out_dir: |
| 884 | fput(fp); | 842 | dput(dir); |
| 885 | 843 | ||
| 886 | out: | 844 | out: |
| 887 | attrs->ia_valid = ia_valid; | 845 | attrs->ia_valid = ia_valid; |
| @@ -1029,7 +987,6 @@ reiserfs_listxattr_filler(void *buf, const char *name, int namelen, | |||
| 1029 | */ | 987 | */ |
| 1030 | ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) | 988 | ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) |
| 1031 | { | 989 | { |
| 1032 | struct file *fp; | ||
| 1033 | struct dentry *dir; | 990 | struct dentry *dir; |
| 1034 | int err = 0; | 991 | int err = 0; |
| 1035 | struct reiserfs_listxattr_buf buf; | 992 | struct reiserfs_listxattr_buf buf; |
| @@ -1052,13 +1009,6 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) | |||
| 1052 | goto out; | 1009 | goto out; |
| 1053 | } | 1010 | } |
| 1054 | 1011 | ||
| 1055 | fp = dentry_open(dir, NULL, O_RDWR); | ||
| 1056 | if (IS_ERR(fp)) { | ||
| 1057 | err = PTR_ERR(fp); | ||
| 1058 | /* dentry_open dputs the dentry if it fails */ | ||
| 1059 | goto out; | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | buf.r_buf = buffer; | 1012 | buf.r_buf = buffer; |
| 1063 | buf.r_size = buffer ? size : 0; | 1013 | buf.r_size = buffer ? size : 0; |
| 1064 | buf.r_pos = 0; | 1014 | buf.r_pos = 0; |
| @@ -1066,7 +1016,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) | |||
| 1066 | 1016 | ||
| 1067 | REISERFS_I(dentry->d_inode)->i_flags |= i_has_xattr_dir; | 1017 | REISERFS_I(dentry->d_inode)->i_flags |= i_has_xattr_dir; |
| 1068 | 1018 | ||
| 1069 | err = xattr_readdir(fp, reiserfs_listxattr_filler, &buf); | 1019 | err = xattr_readdir(dir->d_inode, reiserfs_listxattr_filler, &buf); |
| 1070 | if (err) | 1020 | if (err) |
| 1071 | goto out_dir; | 1021 | goto out_dir; |
| 1072 | 1022 | ||
| @@ -1076,7 +1026,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) | |||
| 1076 | err = buf.r_pos; | 1026 | err = buf.r_pos; |
| 1077 | 1027 | ||
| 1078 | out_dir: | 1028 | out_dir: |
| 1079 | fput(fp); | 1029 | dput(dir); |
| 1080 | 1030 | ||
| 1081 | out: | 1031 | out: |
| 1082 | reiserfs_read_unlock_xattr_i(dentry->d_inode); | 1032 | reiserfs_read_unlock_xattr_i(dentry->d_inode); |
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c index 00b6f0a518c8..3f13d491c7c7 100644 --- a/fs/romfs/inode.c +++ b/fs/romfs/inode.c | |||
| @@ -340,8 +340,9 @@ static struct dentry * | |||
| 340 | romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 340 | romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) |
| 341 | { | 341 | { |
| 342 | unsigned long offset, maxoff; | 342 | unsigned long offset, maxoff; |
| 343 | int fslen, res; | 343 | long res; |
| 344 | struct inode *inode; | 344 | int fslen; |
| 345 | struct inode *inode = NULL; | ||
| 345 | char fsname[ROMFS_MAXFN]; /* XXX dynamic? */ | 346 | char fsname[ROMFS_MAXFN]; /* XXX dynamic? */ |
| 346 | struct romfs_inode ri; | 347 | struct romfs_inode ri; |
| 347 | const char *name; /* got from dentry */ | 348 | const char *name; /* got from dentry */ |
| @@ -351,7 +352,7 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
| 351 | offset = dir->i_ino & ROMFH_MASK; | 352 | offset = dir->i_ino & ROMFH_MASK; |
| 352 | lock_kernel(); | 353 | lock_kernel(); |
| 353 | if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0) | 354 | if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0) |
| 354 | goto out; | 355 | goto error; |
| 355 | 356 | ||
| 356 | maxoff = romfs_maxsize(dir->i_sb); | 357 | maxoff = romfs_maxsize(dir->i_sb); |
| 357 | offset = be32_to_cpu(ri.spec) & ROMFH_MASK; | 358 | offset = be32_to_cpu(ri.spec) & ROMFH_MASK; |
| @@ -364,9 +365,9 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
| 364 | 365 | ||
| 365 | for(;;) { | 366 | for(;;) { |
| 366 | if (!offset || offset >= maxoff) | 367 | if (!offset || offset >= maxoff) |
| 367 | goto out0; | 368 | goto success; /* negative success */ |
| 368 | if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0) | 369 | if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0) |
| 369 | goto out; | 370 | goto error; |
| 370 | 371 | ||
| 371 | /* try to match the first 16 bytes of name */ | 372 | /* try to match the first 16 bytes of name */ |
| 372 | fslen = romfs_strnlen(dir, offset+ROMFH_SIZE, ROMFH_SIZE); | 373 | fslen = romfs_strnlen(dir, offset+ROMFH_SIZE, ROMFH_SIZE); |
| @@ -397,23 +398,14 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
| 397 | inode = romfs_iget(dir->i_sb, offset); | 398 | inode = romfs_iget(dir->i_sb, offset); |
| 398 | if (IS_ERR(inode)) { | 399 | if (IS_ERR(inode)) { |
| 399 | res = PTR_ERR(inode); | 400 | res = PTR_ERR(inode); |
| 400 | goto out; | 401 | goto error; |
| 401 | } | 402 | } |
| 402 | 403 | ||
| 403 | /* | 404 | success: |
| 404 | * it's a bit funky, _lookup needs to return an error code | 405 | d_add(dentry, inode); |
| 405 | * (negative) or a NULL, both as a dentry. ENOENT should not | ||
| 406 | * be returned, instead we need to create a negative dentry by | ||
| 407 | * d_add(dentry, NULL); and return 0 as no error. | ||
| 408 | * (Although as I see, it only matters on writable file | ||
| 409 | * systems). | ||
| 410 | */ | ||
| 411 | |||
| 412 | out0: inode = NULL; | ||
| 413 | res = 0; | 406 | res = 0; |
| 414 | d_add (dentry, inode); | 407 | error: |
| 415 | 408 | unlock_kernel(); | |
| 416 | out: unlock_kernel(); | ||
| 417 | return ERR_PTR(res); | 409 | return ERR_PTR(res); |
| 418 | } | 410 | } |
| 419 | 411 | ||
diff --git a/fs/signalfd.c b/fs/signalfd.c index cb2b63ae0bf4..8ead0db35933 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
| @@ -111,9 +111,14 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo, | |||
| 111 | err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid); | 111 | err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid); |
| 112 | err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr); | 112 | err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr); |
| 113 | break; | 113 | break; |
| 114 | default: /* this is just in case for now ... */ | 114 | default: |
| 115 | /* | ||
| 116 | * This case catches also the signals queued by sigqueue(). | ||
| 117 | */ | ||
| 115 | err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid); | 118 | err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid); |
| 116 | err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid); | 119 | err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid); |
| 120 | err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr); | ||
| 121 | err |= __put_user(kinfo->si_int, &uinfo->ssi_int); | ||
| 117 | break; | 122 | break; |
| 118 | } | 123 | } |
| 119 | 124 | ||
diff --git a/fs/smbfs/smbiod.c b/fs/smbfs/smbiod.c index fae8e85af0ed..6bd9b691a463 100644 --- a/fs/smbfs/smbiod.c +++ b/fs/smbfs/smbiod.c | |||
| @@ -206,7 +206,7 @@ int smbiod_retry(struct smb_sb_info *server) | |||
| 206 | 206 | ||
| 207 | smb_close_socket(server); | 207 | smb_close_socket(server); |
| 208 | 208 | ||
| 209 | if (pid == 0) { | 209 | if (!pid) { |
| 210 | /* FIXME: this is fatal, umount? */ | 210 | /* FIXME: this is fatal, umount? */ |
| 211 | printk(KERN_ERR "smb_retry: no connection process\n"); | 211 | printk(KERN_ERR "smb_retry: no connection process\n"); |
| 212 | server->state = CONN_RETRIED; | 212 | server->state = CONN_RETRIED; |
diff --git a/fs/splice.c b/fs/splice.c index 9b559ee711a8..eeb1a86a7014 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
| @@ -320,7 +320,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
| 320 | break; | 320 | break; |
| 321 | 321 | ||
| 322 | error = add_to_page_cache_lru(page, mapping, index, | 322 | error = add_to_page_cache_lru(page, mapping, index, |
| 323 | GFP_KERNEL); | 323 | mapping_gfp_mask(mapping)); |
| 324 | if (unlikely(error)) { | 324 | if (unlikely(error)) { |
| 325 | page_cache_release(page); | 325 | page_cache_release(page); |
| 326 | if (error == -EEXIST) | 326 | if (error == -EEXIST) |
| @@ -370,8 +370,10 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
| 370 | * for an in-flight io page | 370 | * for an in-flight io page |
| 371 | */ | 371 | */ |
| 372 | if (flags & SPLICE_F_NONBLOCK) { | 372 | if (flags & SPLICE_F_NONBLOCK) { |
| 373 | if (TestSetPageLocked(page)) | 373 | if (TestSetPageLocked(page)) { |
| 374 | error = -EAGAIN; | ||
| 374 | break; | 375 | break; |
| 376 | } | ||
| 375 | } else | 377 | } else |
| 376 | lock_page(page); | 378 | lock_page(page); |
| 377 | 379 | ||
| @@ -479,9 +481,8 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, | |||
| 479 | struct pipe_inode_info *pipe, size_t len, | 481 | struct pipe_inode_info *pipe, size_t len, |
| 480 | unsigned int flags) | 482 | unsigned int flags) |
| 481 | { | 483 | { |
| 482 | ssize_t spliced; | ||
| 483 | int ret; | ||
| 484 | loff_t isize, left; | 484 | loff_t isize, left; |
| 485 | int ret; | ||
| 485 | 486 | ||
| 486 | isize = i_size_read(in->f_mapping->host); | 487 | isize = i_size_read(in->f_mapping->host); |
| 487 | if (unlikely(*ppos >= isize)) | 488 | if (unlikely(*ppos >= isize)) |
| @@ -491,29 +492,9 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, | |||
| 491 | if (unlikely(left < len)) | 492 | if (unlikely(left < len)) |
| 492 | len = left; | 493 | len = left; |
| 493 | 494 | ||
| 494 | ret = 0; | 495 | ret = __generic_file_splice_read(in, ppos, pipe, len, flags); |
| 495 | spliced = 0; | 496 | if (ret > 0) |
| 496 | while (len && !spliced) { | ||
| 497 | ret = __generic_file_splice_read(in, ppos, pipe, len, flags); | ||
| 498 | |||
| 499 | if (ret < 0) | ||
| 500 | break; | ||
| 501 | else if (!ret) { | ||
| 502 | if (spliced) | ||
| 503 | break; | ||
| 504 | if (flags & SPLICE_F_NONBLOCK) { | ||
| 505 | ret = -EAGAIN; | ||
| 506 | break; | ||
| 507 | } | ||
| 508 | } | ||
| 509 | |||
| 510 | *ppos += ret; | 497 | *ppos += ret; |
| 511 | len -= ret; | ||
| 512 | spliced += ret; | ||
| 513 | } | ||
| 514 | |||
| 515 | if (spliced) | ||
| 516 | return spliced; | ||
| 517 | 498 | ||
| 518 | return ret; | 499 | return ret; |
| 519 | } | 500 | } |
| @@ -1669,6 +1650,13 @@ static int link_pipe(struct pipe_inode_info *ipipe, | |||
| 1669 | i++; | 1650 | i++; |
| 1670 | } while (len); | 1651 | } while (len); |
| 1671 | 1652 | ||
| 1653 | /* | ||
| 1654 | * return EAGAIN if we have the potential of some data in the | ||
| 1655 | * future, otherwise just return 0 | ||
| 1656 | */ | ||
| 1657 | if (!ret && ipipe->waiting_writers && (flags & SPLICE_F_NONBLOCK)) | ||
| 1658 | ret = -EAGAIN; | ||
| 1659 | |||
| 1672 | inode_double_unlock(ipipe->inode, opipe->inode); | 1660 | inode_double_unlock(ipipe->inode, opipe->inode); |
| 1673 | 1661 | ||
| 1674 | /* | 1662 | /* |
| @@ -1709,11 +1697,8 @@ static long do_tee(struct file *in, struct file *out, size_t len, | |||
| 1709 | ret = link_ipipe_prep(ipipe, flags); | 1697 | ret = link_ipipe_prep(ipipe, flags); |
| 1710 | if (!ret) { | 1698 | if (!ret) { |
| 1711 | ret = link_opipe_prep(opipe, flags); | 1699 | ret = link_opipe_prep(opipe, flags); |
| 1712 | if (!ret) { | 1700 | if (!ret) |
| 1713 | ret = link_pipe(ipipe, opipe, len, flags); | 1701 | ret = link_pipe(ipipe, opipe, len, flags); |
| 1714 | if (!ret && (flags & SPLICE_F_NONBLOCK)) | ||
| 1715 | ret = -EAGAIN; | ||
| 1716 | } | ||
| 1717 | } | 1702 | } |
| 1718 | } | 1703 | } |
| 1719 | 1704 | ||
diff --git a/fs/super.c b/fs/super.c index 88811f60c8de..09008dbd264e 100644 --- a/fs/super.c +++ b/fs/super.c | |||
| @@ -556,11 +556,11 @@ out: | |||
| 556 | } | 556 | } |
| 557 | 557 | ||
| 558 | /** | 558 | /** |
| 559 | * mark_files_ro | 559 | * mark_files_ro - mark all files read-only |
| 560 | * @sb: superblock in question | 560 | * @sb: superblock in question |
| 561 | * | 561 | * |
| 562 | * All files are marked read/only. We don't care about pending | 562 | * All files are marked read-only. We don't care about pending |
| 563 | * delete files so this should be used in 'force' mode only | 563 | * delete files so this should be used in 'force' mode only. |
| 564 | */ | 564 | */ |
| 565 | 565 | ||
| 566 | static void mark_files_ro(struct super_block *sb) | 566 | static void mark_files_ro(struct super_block *sb) |
| @@ -870,12 +870,12 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void | |||
| 870 | if (!mnt) | 870 | if (!mnt) |
| 871 | goto out; | 871 | goto out; |
| 872 | 872 | ||
| 873 | if (data) { | 873 | if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { |
| 874 | secdata = alloc_secdata(); | 874 | secdata = alloc_secdata(); |
| 875 | if (!secdata) | 875 | if (!secdata) |
| 876 | goto out_mnt; | 876 | goto out_mnt; |
| 877 | 877 | ||
| 878 | error = security_sb_copy_data(type, data, secdata); | 878 | error = security_sb_copy_data(data, secdata); |
| 879 | if (error) | 879 | if (error) |
| 880 | goto out_free_secdata; | 880 | goto out_free_secdata; |
| 881 | } | 881 | } |
| @@ -945,6 +945,7 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data) | |||
| 945 | put_filesystem(type); | 945 | put_filesystem(type); |
| 946 | return mnt; | 946 | return mnt; |
| 947 | } | 947 | } |
| 948 | EXPORT_SYMBOL_GPL(do_kern_mount); | ||
| 948 | 949 | ||
| 949 | struct vfsmount *kern_mount_data(struct file_system_type *type, void *data) | 950 | struct vfsmount *kern_mount_data(struct file_system_type *type, void *data) |
| 950 | { | 951 | { |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index a271c87c4472..baa663e69388 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/kobject.h> | 14 | #include <linux/kobject.h> |
| 15 | #include <linux/kallsyms.h> | ||
| 15 | #include <linux/namei.h> | 16 | #include <linux/namei.h> |
| 16 | #include <linux/poll.h> | 17 | #include <linux/poll.h> |
| 17 | #include <linux/list.h> | 18 | #include <linux/list.h> |
| @@ -86,7 +87,12 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer | |||
| 86 | * The code works fine with PAGE_SIZE return but it's likely to | 87 | * The code works fine with PAGE_SIZE return but it's likely to |
| 87 | * indicate truncated result or overflow in normal use cases. | 88 | * indicate truncated result or overflow in normal use cases. |
| 88 | */ | 89 | */ |
| 89 | BUG_ON(count >= (ssize_t)PAGE_SIZE); | 90 | if (count >= (ssize_t)PAGE_SIZE) { |
| 91 | print_symbol("fill_read_buffer: %s returned bad count\n", | ||
| 92 | (unsigned long)ops->show); | ||
| 93 | /* Try to struggle along */ | ||
| 94 | count = PAGE_SIZE - 1; | ||
| 95 | } | ||
| 90 | if (count >= 0) { | 96 | if (count >= 0) { |
| 91 | buffer->needs_read_fill = 0; | 97 | buffer->needs_read_fill = 0; |
| 92 | buffer->count = count; | 98 | buffer->count = count; |
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index 1fca381f0ce2..1e7598fb9787 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
| @@ -315,8 +315,8 @@ static void ufs_change_blocknr(struct inode *inode, sector_t beg, | |||
| 315 | } | 315 | } |
| 316 | 316 | ||
| 317 | UFSD(" change from %llu to %llu, pos %u\n", | 317 | UFSD(" change from %llu to %llu, pos %u\n", |
| 318 | (unsigned long long)pos + oldb, | 318 | (unsigned long long)(pos + oldb), |
| 319 | (unsigned long long)pos + newb, pos); | 319 | (unsigned long long)(pos + newb), pos); |
| 320 | 320 | ||
| 321 | bh->b_blocknr = newb + pos; | 321 | bh->b_blocknr = newb + pos; |
| 322 | unmap_underlying_metadata(bh->b_bdev, | 322 | unmap_underlying_metadata(bh->b_bdev, |
diff --git a/fs/ufs/util.h b/fs/ufs/util.h index b26fc4dec1e7..23ceed8c8fb9 100644 --- a/fs/ufs/util.h +++ b/fs/ufs/util.h | |||
| @@ -58,7 +58,7 @@ ufs_set_fs_state(struct super_block *sb, struct ufs_super_block_first *usb1, | |||
| 58 | { | 58 | { |
| 59 | switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { | 59 | switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { |
| 60 | case UFS_ST_SUNOS: | 60 | case UFS_ST_SUNOS: |
| 61 | if (fs32_to_cpu(sb, usb3->fs_postblformat == UFS_42POSTBLFMT)) { | 61 | if (fs32_to_cpu(sb, usb3->fs_postblformat) == UFS_42POSTBLFMT) { |
| 62 | usb1->fs_u0.fs_sun.fs_state = cpu_to_fs32(sb, value); | 62 | usb1->fs_u0.fs_sun.fs_state = cpu_to_fs32(sb, value); |
| 63 | break; | 63 | break; |
| 64 | } | 64 | } |
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6 deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/fs/xfs/Makefile-linux-2.6 +++ /dev/null | |||
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index a9952e490ac9..f34bd010eb51 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
| @@ -732,7 +732,7 @@ xfs_ioctl( | |||
| 732 | * Only allow the sys admin to reserve space unless | 732 | * Only allow the sys admin to reserve space unless |
| 733 | * unwritten extents are enabled. | 733 | * unwritten extents are enabled. |
| 734 | */ | 734 | */ |
| 735 | if (!XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb) && | 735 | if (!xfs_sb_version_hasextflgbit(&mp->m_sb) && |
| 736 | !capable(CAP_SYS_ADMIN)) | 736 | !capable(CAP_SYS_ADMIN)) |
| 737 | return -EPERM; | 737 | return -EPERM; |
| 738 | 738 | ||
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 21dfc9da235e..8831d9518790 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
| @@ -171,7 +171,7 @@ xfs_parseargs( | |||
| 171 | char *this_char, *value, *eov; | 171 | char *this_char, *value, *eov; |
| 172 | int dsunit, dswidth, vol_dsunit, vol_dswidth; | 172 | int dsunit, dswidth, vol_dsunit, vol_dswidth; |
| 173 | int iosize; | 173 | int iosize; |
| 174 | int ikeep = 0; | 174 | int dmapi_implies_ikeep = 1; |
| 175 | 175 | ||
| 176 | args->flags |= XFSMNT_BARRIER; | 176 | args->flags |= XFSMNT_BARRIER; |
| 177 | args->flags2 |= XFSMNT2_COMPAT_IOSIZE; | 177 | args->flags2 |= XFSMNT2_COMPAT_IOSIZE; |
| @@ -302,10 +302,10 @@ xfs_parseargs( | |||
| 302 | } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { | 302 | } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { |
| 303 | args->flags &= ~XFSMNT_BARRIER; | 303 | args->flags &= ~XFSMNT_BARRIER; |
| 304 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { | 304 | } else if (!strcmp(this_char, MNTOPT_IKEEP)) { |
| 305 | ikeep = 1; | 305 | args->flags |= XFSMNT_IKEEP; |
| 306 | args->flags &= ~XFSMNT_IDELETE; | ||
| 307 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { | 306 | } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { |
| 308 | args->flags |= XFSMNT_IDELETE; | 307 | dmapi_implies_ikeep = 0; |
| 308 | args->flags &= ~XFSMNT_IKEEP; | ||
| 309 | } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { | 309 | } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { |
| 310 | args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE; | 310 | args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE; |
| 311 | } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { | 311 | } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { |
| @@ -410,8 +410,8 @@ xfs_parseargs( | |||
| 410 | * Note that if "ikeep" or "noikeep" mount options are | 410 | * Note that if "ikeep" or "noikeep" mount options are |
| 411 | * supplied, then they are honored. | 411 | * supplied, then they are honored. |
| 412 | */ | 412 | */ |
| 413 | if (!(args->flags & XFSMNT_DMAPI) && !ikeep) | 413 | if ((args->flags & XFSMNT_DMAPI) && dmapi_implies_ikeep) |
| 414 | args->flags |= XFSMNT_IDELETE; | 414 | args->flags |= XFSMNT_IKEEP; |
| 415 | 415 | ||
| 416 | if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { | 416 | if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { |
| 417 | if (dsunit) { | 417 | if (dsunit) { |
| @@ -446,6 +446,7 @@ xfs_showargs( | |||
| 446 | { | 446 | { |
| 447 | static struct proc_xfs_info xfs_info_set[] = { | 447 | static struct proc_xfs_info xfs_info_set[] = { |
| 448 | /* the few simple ones we can get from the mount struct */ | 448 | /* the few simple ones we can get from the mount struct */ |
| 449 | { XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP }, | ||
| 449 | { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, | 450 | { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, |
| 450 | { XFS_MOUNT_INO64, "," MNTOPT_INO64 }, | 451 | { XFS_MOUNT_INO64, "," MNTOPT_INO64 }, |
| 451 | { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, | 452 | { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, |
| @@ -461,7 +462,6 @@ xfs_showargs( | |||
| 461 | }; | 462 | }; |
| 462 | static struct proc_xfs_info xfs_info_unset[] = { | 463 | static struct proc_xfs_info xfs_info_unset[] = { |
| 463 | /* the few simple ones we can get from the mount struct */ | 464 | /* the few simple ones we can get from the mount struct */ |
| 464 | { XFS_MOUNT_IDELETE, "," MNTOPT_IKEEP }, | ||
| 465 | { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO }, | 465 | { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO }, |
| 466 | { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER }, | 466 | { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER }, |
| 467 | { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE }, | 467 | { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE }, |
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 1f3da5b8657b..8e9c5ae6504d 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
| @@ -1405,13 +1405,13 @@ xfs_qm_qino_alloc( | |||
| 1405 | #if defined(DEBUG) && defined(XFS_LOUD_RECOVERY) | 1405 | #if defined(DEBUG) && defined(XFS_LOUD_RECOVERY) |
| 1406 | unsigned oldv = mp->m_sb.sb_versionnum; | 1406 | unsigned oldv = mp->m_sb.sb_versionnum; |
| 1407 | #endif | 1407 | #endif |
| 1408 | ASSERT(!XFS_SB_VERSION_HASQUOTA(&mp->m_sb)); | 1408 | ASSERT(!xfs_sb_version_hasquota(&mp->m_sb)); |
| 1409 | ASSERT((sbfields & (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | | 1409 | ASSERT((sbfields & (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | |
| 1410 | XFS_SB_GQUOTINO | XFS_SB_QFLAGS)) == | 1410 | XFS_SB_GQUOTINO | XFS_SB_QFLAGS)) == |
| 1411 | (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | | 1411 | (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | |
| 1412 | XFS_SB_GQUOTINO | XFS_SB_QFLAGS)); | 1412 | XFS_SB_GQUOTINO | XFS_SB_QFLAGS)); |
| 1413 | 1413 | ||
| 1414 | XFS_SB_VERSION_ADDQUOTA(&mp->m_sb); | 1414 | xfs_sb_version_addquota(&mp->m_sb); |
| 1415 | mp->m_sb.sb_uquotino = NULLFSINO; | 1415 | mp->m_sb.sb_uquotino = NULLFSINO; |
| 1416 | mp->m_sb.sb_gquotino = NULLFSINO; | 1416 | mp->m_sb.sb_gquotino = NULLFSINO; |
| 1417 | 1417 | ||
| @@ -1954,7 +1954,7 @@ xfs_qm_init_quotainos( | |||
| 1954 | /* | 1954 | /* |
| 1955 | * Get the uquota and gquota inodes | 1955 | * Get the uquota and gquota inodes |
| 1956 | */ | 1956 | */ |
| 1957 | if (XFS_SB_VERSION_HASQUOTA(&mp->m_sb)) { | 1957 | if (xfs_sb_version_hasquota(&mp->m_sb)) { |
| 1958 | if (XFS_IS_UQUOTA_ON(mp) && | 1958 | if (XFS_IS_UQUOTA_ON(mp) && |
| 1959 | mp->m_sb.sb_uquotino != NULLFSINO) { | 1959 | mp->m_sb.sb_uquotino != NULLFSINO) { |
| 1960 | ASSERT(mp->m_sb.sb_uquotino > 0); | 1960 | ASSERT(mp->m_sb.sb_uquotino > 0); |
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index 97bb32937585..f4f6c4c861d7 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c | |||
| @@ -118,7 +118,7 @@ xfs_qm_newmount( | |||
| 118 | *quotaflags = 0; | 118 | *quotaflags = 0; |
| 119 | *needquotamount = B_FALSE; | 119 | *needquotamount = B_FALSE; |
| 120 | 120 | ||
| 121 | quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && | 121 | quotaondisk = xfs_sb_version_hasquota(&mp->m_sb) && |
| 122 | (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT); | 122 | (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT); |
| 123 | 123 | ||
| 124 | if (quotaondisk) { | 124 | if (quotaondisk) { |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 2cc5886cfe85..d2b8be7e75f9 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
| @@ -377,7 +377,7 @@ xfs_qm_scall_trunc_qfiles( | |||
| 377 | if (!capable(CAP_SYS_ADMIN)) | 377 | if (!capable(CAP_SYS_ADMIN)) |
| 378 | return XFS_ERROR(EPERM); | 378 | return XFS_ERROR(EPERM); |
| 379 | error = 0; | 379 | error = 0; |
| 380 | if (!XFS_SB_VERSION_HASQUOTA(&mp->m_sb) || flags == 0) { | 380 | if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) { |
| 381 | qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags); | 381 | qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags); |
| 382 | return XFS_ERROR(EINVAL); | 382 | return XFS_ERROR(EINVAL); |
| 383 | } | 383 | } |
| @@ -522,7 +522,7 @@ xfs_qm_scall_getqstat( | |||
| 522 | memset(out, 0, sizeof(fs_quota_stat_t)); | 522 | memset(out, 0, sizeof(fs_quota_stat_t)); |
| 523 | 523 | ||
| 524 | out->qs_version = FS_QSTAT_VERSION; | 524 | out->qs_version = FS_QSTAT_VERSION; |
| 525 | if (! XFS_SB_VERSION_HASQUOTA(&mp->m_sb)) { | 525 | if (!xfs_sb_version_hasquota(&mp->m_sb)) { |
| 526 | out->qs_uquota.qfs_ino = NULLFSINO; | 526 | out->qs_uquota.qfs_ino = NULLFSINO; |
| 527 | out->qs_gquota.qfs_ino = NULLFSINO; | 527 | out->qs_gquota.qfs_ino = NULLFSINO; |
| 528 | return (0); | 528 | return (0); |
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index b08e2a2a8add..96ba6aa4ed8c 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c | |||
| @@ -227,10 +227,10 @@ STATIC void | |||
| 227 | xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) | 227 | xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) |
| 228 | { | 228 | { |
| 229 | if ((mp->m_flags & XFS_MOUNT_ATTR2) && | 229 | if ((mp->m_flags & XFS_MOUNT_ATTR2) && |
| 230 | !(XFS_SB_VERSION_HASATTR2(&mp->m_sb))) { | 230 | !(xfs_sb_version_hasattr2(&mp->m_sb))) { |
| 231 | spin_lock(&mp->m_sb_lock); | 231 | spin_lock(&mp->m_sb_lock); |
| 232 | if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) { | 232 | if (!xfs_sb_version_hasattr2(&mp->m_sb)) { |
| 233 | XFS_SB_VERSION_ADDATTR2(&mp->m_sb); | 233 | xfs_sb_version_addattr2(&mp->m_sb); |
| 234 | spin_unlock(&mp->m_sb_lock); | 234 | spin_unlock(&mp->m_sb_lock); |
| 235 | xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); | 235 | xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); |
| 236 | } else | 236 | } else |
diff --git a/fs/xfs/xfs_bit.c b/fs/xfs/xfs_bit.c index 48228848f5ae..fab0b6d5a41b 100644 --- a/fs/xfs/xfs_bit.c +++ b/fs/xfs/xfs_bit.c | |||
| @@ -25,6 +25,109 @@ | |||
| 25 | * XFS bit manipulation routines, used in non-realtime code. | 25 | * XFS bit manipulation routines, used in non-realtime code. |
| 26 | */ | 26 | */ |
| 27 | 27 | ||
| 28 | #ifndef HAVE_ARCH_HIGHBIT | ||
| 29 | /* | ||
| 30 | * Index of high bit number in byte, -1 for none set, 0..7 otherwise. | ||
| 31 | */ | ||
| 32 | static const char xfs_highbit[256] = { | ||
| 33 | -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */ | ||
| 34 | 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */ | ||
| 35 | 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */ | ||
| 36 | 4, 4, 4, 4, 4, 4, 4, 4, /* 18 .. 1f */ | ||
| 37 | 5, 5, 5, 5, 5, 5, 5, 5, /* 20 .. 27 */ | ||
| 38 | 5, 5, 5, 5, 5, 5, 5, 5, /* 28 .. 2f */ | ||
| 39 | 5, 5, 5, 5, 5, 5, 5, 5, /* 30 .. 37 */ | ||
| 40 | 5, 5, 5, 5, 5, 5, 5, 5, /* 38 .. 3f */ | ||
| 41 | 6, 6, 6, 6, 6, 6, 6, 6, /* 40 .. 47 */ | ||
| 42 | 6, 6, 6, 6, 6, 6, 6, 6, /* 48 .. 4f */ | ||
| 43 | 6, 6, 6, 6, 6, 6, 6, 6, /* 50 .. 57 */ | ||
| 44 | 6, 6, 6, 6, 6, 6, 6, 6, /* 58 .. 5f */ | ||
| 45 | 6, 6, 6, 6, 6, 6, 6, 6, /* 60 .. 67 */ | ||
| 46 | 6, 6, 6, 6, 6, 6, 6, 6, /* 68 .. 6f */ | ||
| 47 | 6, 6, 6, 6, 6, 6, 6, 6, /* 70 .. 77 */ | ||
| 48 | 6, 6, 6, 6, 6, 6, 6, 6, /* 78 .. 7f */ | ||
| 49 | 7, 7, 7, 7, 7, 7, 7, 7, /* 80 .. 87 */ | ||
| 50 | 7, 7, 7, 7, 7, 7, 7, 7, /* 88 .. 8f */ | ||
| 51 | 7, 7, 7, 7, 7, 7, 7, 7, /* 90 .. 97 */ | ||
| 52 | 7, 7, 7, 7, 7, 7, 7, 7, /* 98 .. 9f */ | ||
| 53 | 7, 7, 7, 7, 7, 7, 7, 7, /* a0 .. a7 */ | ||
| 54 | 7, 7, 7, 7, 7, 7, 7, 7, /* a8 .. af */ | ||
| 55 | 7, 7, 7, 7, 7, 7, 7, 7, /* b0 .. b7 */ | ||
| 56 | 7, 7, 7, 7, 7, 7, 7, 7, /* b8 .. bf */ | ||
| 57 | 7, 7, 7, 7, 7, 7, 7, 7, /* c0 .. c7 */ | ||
| 58 | 7, 7, 7, 7, 7, 7, 7, 7, /* c8 .. cf */ | ||
| 59 | 7, 7, 7, 7, 7, 7, 7, 7, /* d0 .. d7 */ | ||
| 60 | 7, 7, 7, 7, 7, 7, 7, 7, /* d8 .. df */ | ||
| 61 | 7, 7, 7, 7, 7, 7, 7, 7, /* e0 .. e7 */ | ||
| 62 | 7, 7, 7, 7, 7, 7, 7, 7, /* e8 .. ef */ | ||
| 63 | 7, 7, 7, 7, 7, 7, 7, 7, /* f0 .. f7 */ | ||
| 64 | 7, 7, 7, 7, 7, 7, 7, 7, /* f8 .. ff */ | ||
| 65 | }; | ||
| 66 | #endif | ||
| 67 | |||
| 68 | /* | ||
| 69 | * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set. | ||
| 70 | */ | ||
| 71 | inline int | ||
| 72 | xfs_highbit32( | ||
| 73 | __uint32_t v) | ||
| 74 | { | ||
| 75 | #ifdef HAVE_ARCH_HIGHBIT | ||
| 76 | return highbit32(v); | ||
| 77 | #else | ||
| 78 | int i; | ||
| 79 | |||
| 80 | if (v & 0xffff0000) | ||
| 81 | if (v & 0xff000000) | ||
| 82 | i = 24; | ||
| 83 | else | ||
| 84 | i = 16; | ||
| 85 | else if (v & 0x0000ffff) | ||
| 86 | if (v & 0x0000ff00) | ||
| 87 | i = 8; | ||
| 88 | else | ||
| 89 | i = 0; | ||
| 90 | else | ||
| 91 | return -1; | ||
| 92 | return i + xfs_highbit[(v >> i) & 0xff]; | ||
| 93 | #endif | ||
| 94 | } | ||
| 95 | |||
| 96 | /* | ||
| 97 | * xfs_lowbit64: get low bit set out of 64-bit argument, -1 if none set. | ||
| 98 | */ | ||
| 99 | int | ||
| 100 | xfs_lowbit64( | ||
| 101 | __uint64_t v) | ||
| 102 | { | ||
| 103 | __uint32_t w = (__uint32_t)v; | ||
| 104 | int n = 0; | ||
| 105 | |||
| 106 | if (w) { /* lower bits */ | ||
| 107 | n = ffs(w); | ||
| 108 | } else { /* upper bits */ | ||
| 109 | w = (__uint32_t)(v >> 32); | ||
| 110 | if (w && (n = ffs(w))) | ||
| 111 | n += 32; | ||
| 112 | } | ||
| 113 | return n - 1; | ||
| 114 | } | ||
| 115 | |||
| 116 | /* | ||
| 117 | * xfs_highbit64: get high bit set out of 64-bit argument, -1 if none set. | ||
| 118 | */ | ||
| 119 | int | ||
| 120 | xfs_highbit64( | ||
| 121 | __uint64_t v) | ||
| 122 | { | ||
| 123 | __uint32_t h = (__uint32_t)(v >> 32); | ||
| 124 | |||
| 125 | if (h) | ||
| 126 | return xfs_highbit32(h) + 32; | ||
| 127 | return xfs_highbit32((__uint32_t)v); | ||
| 128 | } | ||
| 129 | |||
| 130 | |||
| 28 | /* | 131 | /* |
| 29 | * Return whether bitmap is empty. | 132 | * Return whether bitmap is empty. |
| 30 | * Size is number of words in the bitmap, which is padded to word boundary | 133 | * Size is number of words in the bitmap, which is padded to word boundary |
diff --git a/fs/xfs/xfs_bit.h b/fs/xfs/xfs_bit.h index 325a007dec91..082641a9782c 100644 --- a/fs/xfs/xfs_bit.h +++ b/fs/xfs/xfs_bit.h | |||
| @@ -47,30 +47,13 @@ static inline __uint64_t xfs_mask64lo(int n) | |||
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | /* Get high bit set out of 32-bit argument, -1 if none set */ | 49 | /* Get high bit set out of 32-bit argument, -1 if none set */ |
| 50 | static inline int xfs_highbit32(__uint32_t v) | 50 | extern int xfs_highbit32(__uint32_t v); |
| 51 | { | ||
| 52 | return fls(v) - 1; | ||
| 53 | } | ||
| 54 | |||
| 55 | /* Get high bit set out of 64-bit argument, -1 if none set */ | ||
| 56 | static inline int xfs_highbit64(__uint64_t v) | ||
| 57 | { | ||
| 58 | return fls64(v) - 1; | ||
| 59 | } | ||
| 60 | |||
| 61 | /* Get low bit set out of 32-bit argument, -1 if none set */ | ||
| 62 | static inline int xfs_lowbit32(__uint32_t v) | ||
| 63 | { | ||
| 64 | __uint32_t t = v; | ||
| 65 | return (t) ? find_first_bit((unsigned long *)&t, 32) : -1; | ||
| 66 | } | ||
| 67 | 51 | ||
| 68 | /* Get low bit set out of 64-bit argument, -1 if none set */ | 52 | /* Get low bit set out of 64-bit argument, -1 if none set */ |
| 69 | static inline int xfs_lowbit64(__uint64_t v) | 53 | extern int xfs_lowbit64(__uint64_t v); |
| 70 | { | 54 | |
| 71 | __uint64_t t = v; | 55 | /* Get high bit set out of 64-bit argument, -1 if none set */ |
| 72 | return (t) ? find_first_bit((unsigned long *)&t, 64) : -1; | 56 | extern int xfs_highbit64(__uint64_t); |
| 73 | } | ||
| 74 | 57 | ||
| 75 | /* Return whether bitmap is empty (1 == empty) */ | 58 | /* Return whether bitmap is empty (1 == empty) */ |
| 76 | extern int xfs_bitmap_empty(uint *map, uint size); | 59 | extern int xfs_bitmap_empty(uint *map, uint size); |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 1c0a5a585a82..2def273855a2 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
| @@ -4047,17 +4047,17 @@ xfs_bmap_add_attrfork( | |||
| 4047 | xfs_trans_log_inode(tp, ip, logflags); | 4047 | xfs_trans_log_inode(tp, ip, logflags); |
| 4048 | if (error) | 4048 | if (error) |
| 4049 | goto error2; | 4049 | goto error2; |
| 4050 | if (!XFS_SB_VERSION_HASATTR(&mp->m_sb) || | 4050 | if (!xfs_sb_version_hasattr(&mp->m_sb) || |
| 4051 | (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2)) { | 4051 | (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) { |
| 4052 | __int64_t sbfields = 0; | 4052 | __int64_t sbfields = 0; |
| 4053 | 4053 | ||
| 4054 | spin_lock(&mp->m_sb_lock); | 4054 | spin_lock(&mp->m_sb_lock); |
| 4055 | if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) { | 4055 | if (!xfs_sb_version_hasattr(&mp->m_sb)) { |
| 4056 | XFS_SB_VERSION_ADDATTR(&mp->m_sb); | 4056 | xfs_sb_version_addattr(&mp->m_sb); |
| 4057 | sbfields |= XFS_SB_VERSIONNUM; | 4057 | sbfields |= XFS_SB_VERSIONNUM; |
| 4058 | } | 4058 | } |
| 4059 | if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2) { | 4059 | if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) { |
| 4060 | XFS_SB_VERSION_ADDATTR2(&mp->m_sb); | 4060 | xfs_sb_version_addattr2(&mp->m_sb); |
| 4061 | sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); | 4061 | sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); |
| 4062 | } | 4062 | } |
| 4063 | if (sbfields) { | 4063 | if (sbfields) { |
| @@ -5043,7 +5043,7 @@ xfs_bmapi( | |||
| 5043 | * A wasdelay extent has been initialized, so | 5043 | * A wasdelay extent has been initialized, so |
| 5044 | * shouldn't be flagged as unwritten. | 5044 | * shouldn't be flagged as unwritten. |
| 5045 | */ | 5045 | */ |
| 5046 | if (wr && XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { | 5046 | if (wr && xfs_sb_version_hasextflgbit(&mp->m_sb)) { |
| 5047 | if (!wasdelay && (flags & XFS_BMAPI_PREALLOC)) | 5047 | if (!wasdelay && (flags & XFS_BMAPI_PREALLOC)) |
| 5048 | got.br_state = XFS_EXT_UNWRITTEN; | 5048 | got.br_state = XFS_EXT_UNWRITTEN; |
| 5049 | } | 5049 | } |
| @@ -5483,7 +5483,7 @@ xfs_bunmapi( | |||
| 5483 | * get rid of part of a realtime extent. | 5483 | * get rid of part of a realtime extent. |
| 5484 | */ | 5484 | */ |
| 5485 | if (del.br_state == XFS_EXT_UNWRITTEN || | 5485 | if (del.br_state == XFS_EXT_UNWRITTEN || |
| 5486 | !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { | 5486 | !xfs_sb_version_hasextflgbit(&mp->m_sb)) { |
| 5487 | /* | 5487 | /* |
| 5488 | * This piece is unwritten, or we're not | 5488 | * This piece is unwritten, or we're not |
| 5489 | * using unwritten extents. Skip over it. | 5489 | * using unwritten extents. Skip over it. |
| @@ -5535,7 +5535,7 @@ xfs_bunmapi( | |||
| 5535 | } else if ((del.br_startoff == start && | 5535 | } else if ((del.br_startoff == start && |
| 5536 | (del.br_state == XFS_EXT_UNWRITTEN || | 5536 | (del.br_state == XFS_EXT_UNWRITTEN || |
| 5537 | xfs_trans_get_block_res(tp) == 0)) || | 5537 | xfs_trans_get_block_res(tp) == 0)) || |
| 5538 | !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { | 5538 | !xfs_sb_version_hasextflgbit(&mp->m_sb)) { |
| 5539 | /* | 5539 | /* |
| 5540 | * Can't make it unwritten. There isn't | 5540 | * Can't make it unwritten. There isn't |
| 5541 | * a full extent here so just skip it. | 5541 | * a full extent here so just skip it. |
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h index 2d950e975918..cd0d4b4bb816 100644 --- a/fs/xfs/xfs_bmap_btree.h +++ b/fs/xfs/xfs_bmap_btree.h | |||
| @@ -120,7 +120,7 @@ typedef enum { | |||
| 120 | * Extent state and extent format macros. | 120 | * Extent state and extent format macros. |
| 121 | */ | 121 | */ |
| 122 | #define XFS_EXTFMT_INODE(x) \ | 122 | #define XFS_EXTFMT_INODE(x) \ |
| 123 | (XFS_SB_VERSION_HASEXTFLGBIT(&((x)->i_mount->m_sb)) ? \ | 123 | (xfs_sb_version_hasextflgbit(&((x)->i_mount->m_sb)) ? \ |
| 124 | XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE) | 124 | XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE) |
| 125 | #define ISUNWRITTEN(x) ((x)->br_state == XFS_EXT_UNWRITTEN) | 125 | #define ISUNWRITTEN(x) ((x)->br_state == XFS_EXT_UNWRITTEN) |
| 126 | 126 | ||
diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h index d16c1b971074..d5d1e60ee224 100644 --- a/fs/xfs/xfs_clnt.h +++ b/fs/xfs/xfs_clnt.h | |||
| @@ -86,7 +86,7 @@ struct xfs_mount_args { | |||
| 86 | #define XFSMNT_NOUUID 0x01000000 /* Ignore fs uuid */ | 86 | #define XFSMNT_NOUUID 0x01000000 /* Ignore fs uuid */ |
| 87 | #define XFSMNT_DMAPI 0x02000000 /* enable dmapi/xdsm */ | 87 | #define XFSMNT_DMAPI 0x02000000 /* enable dmapi/xdsm */ |
| 88 | #define XFSMNT_BARRIER 0x04000000 /* use write barriers */ | 88 | #define XFSMNT_BARRIER 0x04000000 /* use write barriers */ |
| 89 | #define XFSMNT_IDELETE 0x08000000 /* inode cluster delete */ | 89 | #define XFSMNT_IKEEP 0x08000000 /* inode cluster delete */ |
| 90 | #define XFSMNT_SWALLOC 0x10000000 /* turn on stripe width | 90 | #define XFSMNT_SWALLOC 0x10000000 /* turn on stripe width |
| 91 | * allocation */ | 91 | * allocation */ |
| 92 | #define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename | 92 | #define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename |
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c index be7c4251fa61..e92e73f0e6af 100644 --- a/fs/xfs/xfs_dir2.c +++ b/fs/xfs/xfs_dir2.c | |||
| @@ -49,7 +49,7 @@ void | |||
| 49 | xfs_dir_mount( | 49 | xfs_dir_mount( |
| 50 | xfs_mount_t *mp) | 50 | xfs_mount_t *mp) |
| 51 | { | 51 | { |
| 52 | ASSERT(XFS_SB_VERSION_HASDIRV2(&mp->m_sb)); | 52 | ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb)); |
| 53 | ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <= | 53 | ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <= |
| 54 | XFS_MAX_BLOCKSIZE); | 54 | XFS_MAX_BLOCKSIZE); |
| 55 | mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); | 55 | mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); |
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index eadc1591c795..d3a0f538d6a6 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
| @@ -77,36 +77,36 @@ xfs_fs_geometry( | |||
| 77 | if (new_version >= 3) { | 77 | if (new_version >= 3) { |
| 78 | geo->version = XFS_FSOP_GEOM_VERSION; | 78 | geo->version = XFS_FSOP_GEOM_VERSION; |
| 79 | geo->flags = | 79 | geo->flags = |
| 80 | (XFS_SB_VERSION_HASATTR(&mp->m_sb) ? | 80 | (xfs_sb_version_hasattr(&mp->m_sb) ? |
| 81 | XFS_FSOP_GEOM_FLAGS_ATTR : 0) | | 81 | XFS_FSOP_GEOM_FLAGS_ATTR : 0) | |
| 82 | (XFS_SB_VERSION_HASNLINK(&mp->m_sb) ? | 82 | (xfs_sb_version_hasnlink(&mp->m_sb) ? |
| 83 | XFS_FSOP_GEOM_FLAGS_NLINK : 0) | | 83 | XFS_FSOP_GEOM_FLAGS_NLINK : 0) | |
| 84 | (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) ? | 84 | (xfs_sb_version_hasquota(&mp->m_sb) ? |
| 85 | XFS_FSOP_GEOM_FLAGS_QUOTA : 0) | | 85 | XFS_FSOP_GEOM_FLAGS_QUOTA : 0) | |
| 86 | (XFS_SB_VERSION_HASALIGN(&mp->m_sb) ? | 86 | (xfs_sb_version_hasalign(&mp->m_sb) ? |
| 87 | XFS_FSOP_GEOM_FLAGS_IALIGN : 0) | | 87 | XFS_FSOP_GEOM_FLAGS_IALIGN : 0) | |
| 88 | (XFS_SB_VERSION_HASDALIGN(&mp->m_sb) ? | 88 | (xfs_sb_version_hasdalign(&mp->m_sb) ? |
| 89 | XFS_FSOP_GEOM_FLAGS_DALIGN : 0) | | 89 | XFS_FSOP_GEOM_FLAGS_DALIGN : 0) | |
| 90 | (XFS_SB_VERSION_HASSHARED(&mp->m_sb) ? | 90 | (xfs_sb_version_hasshared(&mp->m_sb) ? |
| 91 | XFS_FSOP_GEOM_FLAGS_SHARED : 0) | | 91 | XFS_FSOP_GEOM_FLAGS_SHARED : 0) | |
| 92 | (XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb) ? | 92 | (xfs_sb_version_hasextflgbit(&mp->m_sb) ? |
| 93 | XFS_FSOP_GEOM_FLAGS_EXTFLG : 0) | | 93 | XFS_FSOP_GEOM_FLAGS_EXTFLG : 0) | |
| 94 | (XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ? | 94 | (xfs_sb_version_hasdirv2(&mp->m_sb) ? |
| 95 | XFS_FSOP_GEOM_FLAGS_DIRV2 : 0) | | 95 | XFS_FSOP_GEOM_FLAGS_DIRV2 : 0) | |
| 96 | (XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ? | 96 | (xfs_sb_version_hassector(&mp->m_sb) ? |
| 97 | XFS_FSOP_GEOM_FLAGS_SECTOR : 0) | | 97 | XFS_FSOP_GEOM_FLAGS_SECTOR : 0) | |
| 98 | (xfs_sb_version_haslazysbcount(&mp->m_sb) ? | 98 | (xfs_sb_version_haslazysbcount(&mp->m_sb) ? |
| 99 | XFS_FSOP_GEOM_FLAGS_LAZYSB : 0) | | 99 | XFS_FSOP_GEOM_FLAGS_LAZYSB : 0) | |
| 100 | (XFS_SB_VERSION_HASATTR2(&mp->m_sb) ? | 100 | (xfs_sb_version_hasattr2(&mp->m_sb) ? |
| 101 | XFS_FSOP_GEOM_FLAGS_ATTR2 : 0); | 101 | XFS_FSOP_GEOM_FLAGS_ATTR2 : 0); |
| 102 | geo->logsectsize = XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ? | 102 | geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ? |
| 103 | mp->m_sb.sb_logsectsize : BBSIZE; | 103 | mp->m_sb.sb_logsectsize : BBSIZE; |
| 104 | geo->rtsectsize = mp->m_sb.sb_blocksize; | 104 | geo->rtsectsize = mp->m_sb.sb_blocksize; |
| 105 | geo->dirblocksize = mp->m_dirblksize; | 105 | geo->dirblocksize = mp->m_dirblksize; |
| 106 | } | 106 | } |
| 107 | if (new_version >= 4) { | 107 | if (new_version >= 4) { |
| 108 | geo->flags |= | 108 | geo->flags |= |
| 109 | (XFS_SB_VERSION_HASLOGV2(&mp->m_sb) ? | 109 | (xfs_sb_version_haslogv2(&mp->m_sb) ? |
| 110 | XFS_FSOP_GEOM_FLAGS_LOGV2 : 0); | 110 | XFS_FSOP_GEOM_FLAGS_LOGV2 : 0); |
| 111 | geo->logsunit = mp->m_sb.sb_logsunit; | 111 | geo->logsunit = mp->m_sb.sb_logsunit; |
| 112 | } | 112 | } |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index c5836b951d0c..5a146cb22980 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
| @@ -191,7 +191,7 @@ xfs_ialloc_ag_alloc( | |||
| 191 | ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN)); | 191 | ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN)); |
| 192 | args.alignment = args.mp->m_dalign; | 192 | args.alignment = args.mp->m_dalign; |
| 193 | isaligned = 1; | 193 | isaligned = 1; |
| 194 | } else if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) && | 194 | } else if (xfs_sb_version_hasalign(&args.mp->m_sb) && |
| 195 | args.mp->m_sb.sb_inoalignmt >= | 195 | args.mp->m_sb.sb_inoalignmt >= |
| 196 | XFS_B_TO_FSBT(args.mp, | 196 | XFS_B_TO_FSBT(args.mp, |
| 197 | XFS_INODE_CLUSTER_SIZE(args.mp))) | 197 | XFS_INODE_CLUSTER_SIZE(args.mp))) |
| @@ -230,7 +230,7 @@ xfs_ialloc_ag_alloc( | |||
| 230 | args.agbno = be32_to_cpu(agi->agi_root); | 230 | args.agbno = be32_to_cpu(agi->agi_root); |
| 231 | args.fsbno = XFS_AGB_TO_FSB(args.mp, | 231 | args.fsbno = XFS_AGB_TO_FSB(args.mp, |
| 232 | be32_to_cpu(agi->agi_seqno), args.agbno); | 232 | be32_to_cpu(agi->agi_seqno), args.agbno); |
| 233 | if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) && | 233 | if (xfs_sb_version_hasalign(&args.mp->m_sb) && |
| 234 | args.mp->m_sb.sb_inoalignmt >= | 234 | args.mp->m_sb.sb_inoalignmt >= |
| 235 | XFS_B_TO_FSBT(args.mp, XFS_INODE_CLUSTER_SIZE(args.mp))) | 235 | XFS_B_TO_FSBT(args.mp, XFS_INODE_CLUSTER_SIZE(args.mp))) |
| 236 | args.alignment = args.mp->m_sb.sb_inoalignmt; | 236 | args.alignment = args.mp->m_sb.sb_inoalignmt; |
| @@ -271,7 +271,7 @@ xfs_ialloc_ag_alloc( | |||
| 271 | * use the old version so that old kernels will continue to be | 271 | * use the old version so that old kernels will continue to be |
| 272 | * able to use the file system. | 272 | * able to use the file system. |
| 273 | */ | 273 | */ |
| 274 | if (XFS_SB_VERSION_HASNLINK(&args.mp->m_sb)) | 274 | if (xfs_sb_version_hasnlink(&args.mp->m_sb)) |
| 275 | version = XFS_DINODE_VERSION_2; | 275 | version = XFS_DINODE_VERSION_2; |
| 276 | else | 276 | else |
| 277 | version = XFS_DINODE_VERSION_1; | 277 | version = XFS_DINODE_VERSION_1; |
| @@ -1053,7 +1053,7 @@ xfs_difree( | |||
| 1053 | /* | 1053 | /* |
| 1054 | * When an inode cluster is free, it becomes eligible for removal | 1054 | * When an inode cluster is free, it becomes eligible for removal |
| 1055 | */ | 1055 | */ |
| 1056 | if ((mp->m_flags & XFS_MOUNT_IDELETE) && | 1056 | if (!(mp->m_flags & XFS_MOUNT_IKEEP) && |
| 1057 | (rec.ir_freecount == XFS_IALLOC_INODES(mp))) { | 1057 | (rec.ir_freecount == XFS_IALLOC_INODES(mp))) { |
| 1058 | 1058 | ||
| 1059 | *delete = 1; | 1059 | *delete = 1; |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index f01b07687faf..8e09b71f4104 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
| @@ -235,6 +235,7 @@ finish_inode: | |||
| 235 | */ | 235 | */ |
| 236 | new_icl = kmem_zone_alloc(xfs_icluster_zone, KM_SLEEP); | 236 | new_icl = kmem_zone_alloc(xfs_icluster_zone, KM_SLEEP); |
| 237 | if (radix_tree_preload(GFP_KERNEL)) { | 237 | if (radix_tree_preload(GFP_KERNEL)) { |
| 238 | xfs_idestroy(ip); | ||
| 238 | delay(1); | 239 | delay(1); |
| 239 | goto again; | 240 | goto again; |
| 240 | } | 241 | } |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index a550546a7083..f43a6e01d68f 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
| @@ -1147,7 +1147,7 @@ xfs_ialloc( | |||
| 1147 | * the inode version number now. This way we only do the conversion | 1147 | * the inode version number now. This way we only do the conversion |
| 1148 | * here rather than here and in the flush/logging code. | 1148 | * here rather than here and in the flush/logging code. |
| 1149 | */ | 1149 | */ |
| 1150 | if (XFS_SB_VERSION_HASNLINK(&tp->t_mountp->m_sb) && | 1150 | if (xfs_sb_version_hasnlink(&tp->t_mountp->m_sb) && |
| 1151 | ip->i_d.di_version == XFS_DINODE_VERSION_1) { | 1151 | ip->i_d.di_version == XFS_DINODE_VERSION_1) { |
| 1152 | ip->i_d.di_version = XFS_DINODE_VERSION_2; | 1152 | ip->i_d.di_version = XFS_DINODE_VERSION_2; |
| 1153 | /* | 1153 | /* |
| @@ -3434,9 +3434,9 @@ xfs_iflush_int( | |||
| 3434 | * has been updated, then make the conversion permanent. | 3434 | * has been updated, then make the conversion permanent. |
| 3435 | */ | 3435 | */ |
| 3436 | ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1 || | 3436 | ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1 || |
| 3437 | XFS_SB_VERSION_HASNLINK(&mp->m_sb)); | 3437 | xfs_sb_version_hasnlink(&mp->m_sb)); |
| 3438 | if (ip->i_d.di_version == XFS_DINODE_VERSION_1) { | 3438 | if (ip->i_d.di_version == XFS_DINODE_VERSION_1) { |
| 3439 | if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) { | 3439 | if (!xfs_sb_version_hasnlink(&mp->m_sb)) { |
| 3440 | /* | 3440 | /* |
| 3441 | * Convert it back. | 3441 | * Convert it back. |
| 3442 | */ | 3442 | */ |
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 034ca7202295..2c775b4ae9e6 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
| @@ -296,9 +296,9 @@ xfs_inode_item_format( | |||
| 296 | */ | 296 | */ |
| 297 | mp = ip->i_mount; | 297 | mp = ip->i_mount; |
| 298 | ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1 || | 298 | ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1 || |
| 299 | XFS_SB_VERSION_HASNLINK(&mp->m_sb)); | 299 | xfs_sb_version_hasnlink(&mp->m_sb)); |
| 300 | if (ip->i_d.di_version == XFS_DINODE_VERSION_1) { | 300 | if (ip->i_d.di_version == XFS_DINODE_VERSION_1) { |
| 301 | if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) { | 301 | if (!xfs_sb_version_hasnlink(&mp->m_sb)) { |
| 302 | /* | 302 | /* |
| 303 | * Convert it back. | 303 | * Convert it back. |
| 304 | */ | 304 | */ |
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 658aab6b1bbf..f615e04364f4 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
| @@ -45,7 +45,7 @@ xfs_internal_inum( | |||
| 45 | xfs_ino_t ino) | 45 | xfs_ino_t ino) |
| 46 | { | 46 | { |
| 47 | return (ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino || | 47 | return (ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino || |
| 48 | (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && | 48 | (xfs_sb_version_hasquota(&mp->m_sb) && |
| 49 | (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))); | 49 | (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))); |
| 50 | } | 50 | } |
| 51 | 51 | ||
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index a75edca1860f..31f2b04f2c97 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
| @@ -1090,7 +1090,7 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp, | |||
| 1090 | size >>= 1; | 1090 | size >>= 1; |
| 1091 | } | 1091 | } |
| 1092 | 1092 | ||
| 1093 | if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) { | 1093 | if (xfs_sb_version_haslogv2(&mp->m_sb)) { |
| 1094 | /* # headers = size / 32K | 1094 | /* # headers = size / 32K |
| 1095 | * one header holds cycles from 32K of data | 1095 | * one header holds cycles from 32K of data |
| 1096 | */ | 1096 | */ |
| @@ -1186,13 +1186,13 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
| 1186 | log->l_grant_reserve_cycle = 1; | 1186 | log->l_grant_reserve_cycle = 1; |
| 1187 | log->l_grant_write_cycle = 1; | 1187 | log->l_grant_write_cycle = 1; |
| 1188 | 1188 | ||
| 1189 | if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb)) { | 1189 | if (xfs_sb_version_hassector(&mp->m_sb)) { |
| 1190 | log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; | 1190 | log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; |
| 1191 | ASSERT(log->l_sectbb_log <= mp->m_sectbb_log); | 1191 | ASSERT(log->l_sectbb_log <= mp->m_sectbb_log); |
| 1192 | /* for larger sector sizes, must have v2 or external log */ | 1192 | /* for larger sector sizes, must have v2 or external log */ |
| 1193 | ASSERT(log->l_sectbb_log == 0 || | 1193 | ASSERT(log->l_sectbb_log == 0 || |
| 1194 | log->l_logBBstart == 0 || | 1194 | log->l_logBBstart == 0 || |
| 1195 | XFS_SB_VERSION_HASLOGV2(&mp->m_sb)); | 1195 | xfs_sb_version_haslogv2(&mp->m_sb)); |
| 1196 | ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT); | 1196 | ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT); |
| 1197 | } | 1197 | } |
| 1198 | log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1; | 1198 | log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1; |
| @@ -1247,7 +1247,7 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
| 1247 | memset(head, 0, sizeof(xlog_rec_header_t)); | 1247 | memset(head, 0, sizeof(xlog_rec_header_t)); |
| 1248 | head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); | 1248 | head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); |
| 1249 | head->h_version = cpu_to_be32( | 1249 | head->h_version = cpu_to_be32( |
| 1250 | XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1); | 1250 | xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? 2 : 1); |
| 1251 | head->h_size = cpu_to_be32(log->l_iclog_size); | 1251 | head->h_size = cpu_to_be32(log->l_iclog_size); |
| 1252 | /* new fields */ | 1252 | /* new fields */ |
| 1253 | head->h_fmt = cpu_to_be32(XLOG_FMT); | 1253 | head->h_fmt = cpu_to_be32(XLOG_FMT); |
| @@ -1402,7 +1402,7 @@ xlog_sync(xlog_t *log, | |||
| 1402 | int roundoff; /* roundoff to BB or stripe */ | 1402 | int roundoff; /* roundoff to BB or stripe */ |
| 1403 | int split = 0; /* split write into two regions */ | 1403 | int split = 0; /* split write into two regions */ |
| 1404 | int error; | 1404 | int error; |
| 1405 | int v2 = XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb); | 1405 | int v2 = xfs_sb_version_haslogv2(&log->l_mp->m_sb); |
| 1406 | 1406 | ||
| 1407 | XFS_STATS_INC(xs_log_writes); | 1407 | XFS_STATS_INC(xs_log_writes); |
| 1408 | ASSERT(iclog->ic_refcnt == 0); | 1408 | ASSERT(iclog->ic_refcnt == 0); |
| @@ -2881,7 +2881,7 @@ xlog_state_switch_iclogs(xlog_t *log, | |||
| 2881 | log->l_curr_block += BTOBB(eventual_size)+BTOBB(log->l_iclog_hsize); | 2881 | log->l_curr_block += BTOBB(eventual_size)+BTOBB(log->l_iclog_hsize); |
| 2882 | 2882 | ||
| 2883 | /* Round up to next log-sunit */ | 2883 | /* Round up to next log-sunit */ |
| 2884 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) && | 2884 | if (xfs_sb_version_haslogv2(&log->l_mp->m_sb) && |
| 2885 | log->l_mp->m_sb.sb_logsunit > 1) { | 2885 | log->l_mp->m_sb.sb_logsunit > 1) { |
| 2886 | __uint32_t sunit_bb = BTOBB(log->l_mp->m_sb.sb_logsunit); | 2886 | __uint32_t sunit_bb = BTOBB(log->l_mp->m_sb.sb_logsunit); |
| 2887 | log->l_curr_block = roundup(log->l_curr_block, sunit_bb); | 2887 | log->l_curr_block = roundup(log->l_curr_block, sunit_bb); |
| @@ -3334,7 +3334,7 @@ xlog_ticket_get(xlog_t *log, | |||
| 3334 | unit_bytes += sizeof(xlog_op_header_t) * num_headers; | 3334 | unit_bytes += sizeof(xlog_op_header_t) * num_headers; |
| 3335 | 3335 | ||
| 3336 | /* for roundoff padding for transaction data and one for commit record */ | 3336 | /* for roundoff padding for transaction data and one for commit record */ |
| 3337 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) && | 3337 | if (xfs_sb_version_haslogv2(&log->l_mp->m_sb) && |
| 3338 | log->l_mp->m_sb.sb_logsunit > 1) { | 3338 | log->l_mp->m_sb.sb_logsunit > 1) { |
| 3339 | /* log su roundoff */ | 3339 | /* log su roundoff */ |
| 3340 | unit_bytes += 2*log->l_mp->m_sb.sb_logsunit; | 3340 | unit_bytes += 2*log->l_mp->m_sb.sb_logsunit; |
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index e008233ee249..c6244cc733c0 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
| @@ -49,10 +49,10 @@ struct xfs_mount; | |||
| 49 | #define XLOG_HEADER_SIZE 512 | 49 | #define XLOG_HEADER_SIZE 512 |
| 50 | 50 | ||
| 51 | #define XLOG_REC_SHIFT(log) \ | 51 | #define XLOG_REC_SHIFT(log) \ |
| 52 | BTOBB(1 << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \ | 52 | BTOBB(1 << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \ |
| 53 | XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) | 53 | XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) |
| 54 | #define XLOG_TOTAL_REC_SHIFT(log) \ | 54 | #define XLOG_TOTAL_REC_SHIFT(log) \ |
| 55 | BTOBB(XLOG_MAX_ICLOGS << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \ | 55 | BTOBB(XLOG_MAX_ICLOGS << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \ |
| 56 | XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) | 56 | XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) |
| 57 | 57 | ||
| 58 | 58 | ||
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index b82d5d4d2462..b2b70eba282c 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
| @@ -478,7 +478,7 @@ xlog_find_verify_log_record( | |||
| 478 | * reset last_blk. Only when last_blk points in the middle of a log | 478 | * reset last_blk. Only when last_blk points in the middle of a log |
| 479 | * record do we update last_blk. | 479 | * record do we update last_blk. |
| 480 | */ | 480 | */ |
| 481 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 481 | if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { |
| 482 | uint h_size = be32_to_cpu(head->h_size); | 482 | uint h_size = be32_to_cpu(head->h_size); |
| 483 | 483 | ||
| 484 | xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE; | 484 | xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE; |
| @@ -888,7 +888,7 @@ xlog_find_tail( | |||
| 888 | * unmount record if there is one, so we pass the lsn of the | 888 | * unmount record if there is one, so we pass the lsn of the |
| 889 | * unmount record rather than the block after it. | 889 | * unmount record rather than the block after it. |
| 890 | */ | 890 | */ |
| 891 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 891 | if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { |
| 892 | int h_size = be32_to_cpu(rhead->h_size); | 892 | int h_size = be32_to_cpu(rhead->h_size); |
| 893 | int h_version = be32_to_cpu(rhead->h_version); | 893 | int h_version = be32_to_cpu(rhead->h_version); |
| 894 | 894 | ||
| @@ -1101,7 +1101,7 @@ xlog_add_record( | |||
| 1101 | recp->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); | 1101 | recp->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); |
| 1102 | recp->h_cycle = cpu_to_be32(cycle); | 1102 | recp->h_cycle = cpu_to_be32(cycle); |
| 1103 | recp->h_version = cpu_to_be32( | 1103 | recp->h_version = cpu_to_be32( |
| 1104 | XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1); | 1104 | xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? 2 : 1); |
| 1105 | recp->h_lsn = cpu_to_be64(xlog_assign_lsn(cycle, block)); | 1105 | recp->h_lsn = cpu_to_be64(xlog_assign_lsn(cycle, block)); |
| 1106 | recp->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(tail_cycle, tail_block)); | 1106 | recp->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(tail_cycle, tail_block)); |
| 1107 | recp->h_fmt = cpu_to_be32(XLOG_FMT); | 1107 | recp->h_fmt = cpu_to_be32(XLOG_FMT); |
| @@ -3348,7 +3348,7 @@ xlog_pack_data( | |||
| 3348 | dp += BBSIZE; | 3348 | dp += BBSIZE; |
| 3349 | } | 3349 | } |
| 3350 | 3350 | ||
| 3351 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 3351 | if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { |
| 3352 | xhdr = (xlog_in_core_2_t *)&iclog->ic_header; | 3352 | xhdr = (xlog_in_core_2_t *)&iclog->ic_header; |
| 3353 | for ( ; i < BTOBB(size); i++) { | 3353 | for ( ; i < BTOBB(size); i++) { |
| 3354 | j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); | 3354 | j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); |
| @@ -3388,7 +3388,7 @@ xlog_unpack_data_checksum( | |||
| 3388 | be32_to_cpu(rhead->h_chksum), chksum); | 3388 | be32_to_cpu(rhead->h_chksum), chksum); |
| 3389 | cmn_err(CE_DEBUG, | 3389 | cmn_err(CE_DEBUG, |
| 3390 | "XFS: Disregard message if filesystem was created with non-DEBUG kernel"); | 3390 | "XFS: Disregard message if filesystem was created with non-DEBUG kernel"); |
| 3391 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 3391 | if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { |
| 3392 | cmn_err(CE_DEBUG, | 3392 | cmn_err(CE_DEBUG, |
| 3393 | "XFS: LogR this is a LogV2 filesystem\n"); | 3393 | "XFS: LogR this is a LogV2 filesystem\n"); |
| 3394 | } | 3394 | } |
| @@ -3415,7 +3415,7 @@ xlog_unpack_data( | |||
| 3415 | dp += BBSIZE; | 3415 | dp += BBSIZE; |
| 3416 | } | 3416 | } |
| 3417 | 3417 | ||
| 3418 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 3418 | if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { |
| 3419 | xhdr = (xlog_in_core_2_t *)rhead; | 3419 | xhdr = (xlog_in_core_2_t *)rhead; |
| 3420 | for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) { | 3420 | for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) { |
| 3421 | j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); | 3421 | j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); |
| @@ -3494,7 +3494,7 @@ xlog_do_recovery_pass( | |||
| 3494 | * Read the header of the tail block and get the iclog buffer size from | 3494 | * Read the header of the tail block and get the iclog buffer size from |
| 3495 | * h_size. Use this to tell how many sectors make up the log header. | 3495 | * h_size. Use this to tell how many sectors make up the log header. |
| 3496 | */ | 3496 | */ |
| 3497 | if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) { | 3497 | if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { |
| 3498 | /* | 3498 | /* |
| 3499 | * When using variable length iclogs, read first sector of | 3499 | * When using variable length iclogs, read first sector of |
| 3500 | * iclog header and extract the header size from it. Get a | 3500 | * iclog header and extract the header size from it. Get a |
| @@ -3838,7 +3838,7 @@ xlog_do_recover( | |||
| 3838 | sbp = &log->l_mp->m_sb; | 3838 | sbp = &log->l_mp->m_sb; |
| 3839 | xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp)); | 3839 | xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp)); |
| 3840 | ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC); | 3840 | ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC); |
| 3841 | ASSERT(XFS_SB_GOOD_VERSION(sbp)); | 3841 | ASSERT(xfs_sb_good_version(sbp)); |
| 3842 | xfs_buf_relse(bp); | 3842 | xfs_buf_relse(bp); |
| 3843 | 3843 | ||
| 3844 | /* We've re-read the superblock so re-initialize per-cpu counters */ | 3844 | /* We've re-read the superblock so re-initialize per-cpu counters */ |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 6409b3762995..8ed164eb9544 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
| @@ -44,7 +44,7 @@ | |||
| 44 | #include "xfs_quota.h" | 44 | #include "xfs_quota.h" |
| 45 | #include "xfs_fsops.h" | 45 | #include "xfs_fsops.h" |
| 46 | 46 | ||
| 47 | STATIC void xfs_mount_log_sbunit(xfs_mount_t *, __int64_t); | 47 | STATIC void xfs_mount_log_sb(xfs_mount_t *, __int64_t); |
| 48 | STATIC int xfs_uuid_mount(xfs_mount_t *); | 48 | STATIC int xfs_uuid_mount(xfs_mount_t *); |
| 49 | STATIC void xfs_uuid_unmount(xfs_mount_t *mp); | 49 | STATIC void xfs_uuid_unmount(xfs_mount_t *mp); |
| 50 | STATIC void xfs_unmountfs_wait(xfs_mount_t *); | 50 | STATIC void xfs_unmountfs_wait(xfs_mount_t *); |
| @@ -119,6 +119,7 @@ static const struct { | |||
| 119 | { offsetof(xfs_sb_t, sb_logsectsize),0 }, | 119 | { offsetof(xfs_sb_t, sb_logsectsize),0 }, |
| 120 | { offsetof(xfs_sb_t, sb_logsunit), 0 }, | 120 | { offsetof(xfs_sb_t, sb_logsunit), 0 }, |
| 121 | { offsetof(xfs_sb_t, sb_features2), 0 }, | 121 | { offsetof(xfs_sb_t, sb_features2), 0 }, |
| 122 | { offsetof(xfs_sb_t, sb_bad_features2), 0 }, | ||
| 122 | { sizeof(xfs_sb_t), 0 } | 123 | { sizeof(xfs_sb_t), 0 } |
| 123 | }; | 124 | }; |
| 124 | 125 | ||
| @@ -225,7 +226,7 @@ xfs_mount_validate_sb( | |||
| 225 | return XFS_ERROR(EWRONGFS); | 226 | return XFS_ERROR(EWRONGFS); |
| 226 | } | 227 | } |
| 227 | 228 | ||
| 228 | if (!XFS_SB_GOOD_VERSION(sbp)) { | 229 | if (!xfs_sb_good_version(sbp)) { |
| 229 | xfs_fs_mount_cmn_err(flags, "bad version"); | 230 | xfs_fs_mount_cmn_err(flags, "bad version"); |
| 230 | return XFS_ERROR(EWRONGFS); | 231 | return XFS_ERROR(EWRONGFS); |
| 231 | } | 232 | } |
| @@ -300,7 +301,7 @@ xfs_mount_validate_sb( | |||
| 300 | /* | 301 | /* |
| 301 | * Version 1 directory format has never worked on Linux. | 302 | * Version 1 directory format has never worked on Linux. |
| 302 | */ | 303 | */ |
| 303 | if (unlikely(!XFS_SB_VERSION_HASDIRV2(sbp))) { | 304 | if (unlikely(!xfs_sb_version_hasdirv2(sbp))) { |
| 304 | xfs_fs_mount_cmn_err(flags, | 305 | xfs_fs_mount_cmn_err(flags, |
| 305 | "file system using version 1 directory format"); | 306 | "file system using version 1 directory format"); |
| 306 | return XFS_ERROR(ENOSYS); | 307 | return XFS_ERROR(ENOSYS); |
| @@ -449,6 +450,7 @@ xfs_sb_from_disk( | |||
| 449 | to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize); | 450 | to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize); |
| 450 | to->sb_logsunit = be32_to_cpu(from->sb_logsunit); | 451 | to->sb_logsunit = be32_to_cpu(from->sb_logsunit); |
| 451 | to->sb_features2 = be32_to_cpu(from->sb_features2); | 452 | to->sb_features2 = be32_to_cpu(from->sb_features2); |
| 453 | to->sb_bad_features2 = be32_to_cpu(from->sb_bad_features2); | ||
| 452 | } | 454 | } |
| 453 | 455 | ||
| 454 | /* | 456 | /* |
| @@ -781,7 +783,7 @@ xfs_update_alignment(xfs_mount_t *mp, int mfsi_flags, __uint64_t *update_flags) | |||
| 781 | * Update superblock with new values | 783 | * Update superblock with new values |
| 782 | * and log changes | 784 | * and log changes |
| 783 | */ | 785 | */ |
| 784 | if (XFS_SB_VERSION_HASDALIGN(sbp)) { | 786 | if (xfs_sb_version_hasdalign(sbp)) { |
| 785 | if (sbp->sb_unit != mp->m_dalign) { | 787 | if (sbp->sb_unit != mp->m_dalign) { |
| 786 | sbp->sb_unit = mp->m_dalign; | 788 | sbp->sb_unit = mp->m_dalign; |
| 787 | *update_flags |= XFS_SB_UNIT; | 789 | *update_flags |= XFS_SB_UNIT; |
| @@ -792,7 +794,7 @@ xfs_update_alignment(xfs_mount_t *mp, int mfsi_flags, __uint64_t *update_flags) | |||
| 792 | } | 794 | } |
| 793 | } | 795 | } |
| 794 | } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN && | 796 | } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN && |
| 795 | XFS_SB_VERSION_HASDALIGN(&mp->m_sb)) { | 797 | xfs_sb_version_hasdalign(&mp->m_sb)) { |
| 796 | mp->m_dalign = sbp->sb_unit; | 798 | mp->m_dalign = sbp->sb_unit; |
| 797 | mp->m_swidth = sbp->sb_width; | 799 | mp->m_swidth = sbp->sb_width; |
| 798 | } | 800 | } |
| @@ -869,7 +871,7 @@ xfs_set_rw_sizes(xfs_mount_t *mp) | |||
| 869 | STATIC void | 871 | STATIC void |
| 870 | xfs_set_inoalignment(xfs_mount_t *mp) | 872 | xfs_set_inoalignment(xfs_mount_t *mp) |
| 871 | { | 873 | { |
| 872 | if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) && | 874 | if (xfs_sb_version_hasalign(&mp->m_sb) && |
| 873 | mp->m_sb.sb_inoalignmt >= | 875 | mp->m_sb.sb_inoalignmt >= |
| 874 | XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size)) | 876 | XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size)) |
| 875 | mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1; | 877 | mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1; |
| @@ -970,6 +972,38 @@ xfs_mountfs( | |||
| 970 | xfs_mount_common(mp, sbp); | 972 | xfs_mount_common(mp, sbp); |
| 971 | 973 | ||
| 972 | /* | 974 | /* |
| 975 | * Check for a mismatched features2 values. Older kernels | ||
| 976 | * read & wrote into the wrong sb offset for sb_features2 | ||
| 977 | * on some platforms due to xfs_sb_t not being 64bit size aligned | ||
| 978 | * when sb_features2 was added, which made older superblock | ||
| 979 | * reading/writing routines swap it as a 64-bit value. | ||
| 980 | * | ||
| 981 | * For backwards compatibility, we make both slots equal. | ||
| 982 | * | ||
| 983 | * If we detect a mismatched field, we OR the set bits into the | ||
| 984 | * existing features2 field in case it has already been modified; we | ||
| 985 | * don't want to lose any features. We then update the bad location | ||
| 986 | * with the ORed value so that older kernels will see any features2 | ||
| 987 | * flags, and mark the two fields as needing updates once the | ||
| 988 | * transaction subsystem is online. | ||
| 989 | */ | ||
| 990 | if (xfs_sb_has_mismatched_features2(sbp)) { | ||
| 991 | cmn_err(CE_WARN, | ||
| 992 | "XFS: correcting sb_features alignment problem"); | ||
| 993 | sbp->sb_features2 |= sbp->sb_bad_features2; | ||
| 994 | sbp->sb_bad_features2 = sbp->sb_features2; | ||
| 995 | update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2; | ||
| 996 | |||
| 997 | /* | ||
| 998 | * Re-check for ATTR2 in case it was found in bad_features2 | ||
| 999 | * slot. | ||
| 1000 | */ | ||
| 1001 | if (xfs_sb_version_hasattr2(&mp->m_sb)) | ||
| 1002 | mp->m_flags |= XFS_MOUNT_ATTR2; | ||
| 1003 | |||
| 1004 | } | ||
| 1005 | |||
| 1006 | /* | ||
| 973 | * Check if sb_agblocks is aligned at stripe boundary | 1007 | * Check if sb_agblocks is aligned at stripe boundary |
| 974 | * If sb_agblocks is NOT aligned turn off m_dalign since | 1008 | * If sb_agblocks is NOT aligned turn off m_dalign since |
| 975 | * allocator alignment is within an ag, therefore ag has | 1009 | * allocator alignment is within an ag, therefore ag has |
| @@ -1159,11 +1193,10 @@ xfs_mountfs( | |||
| 1159 | } | 1193 | } |
| 1160 | 1194 | ||
| 1161 | /* | 1195 | /* |
| 1162 | * If fs is not mounted readonly, then update the superblock | 1196 | * If fs is not mounted readonly, then update the superblock changes. |
| 1163 | * unit and width changes. | ||
| 1164 | */ | 1197 | */ |
| 1165 | if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) | 1198 | if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) |
| 1166 | xfs_mount_log_sbunit(mp, update_flags); | 1199 | xfs_mount_log_sb(mp, update_flags); |
| 1167 | 1200 | ||
| 1168 | /* | 1201 | /* |
| 1169 | * Initialise the XFS quota management subsystem for this mount | 1202 | * Initialise the XFS quota management subsystem for this mount |
| @@ -1875,16 +1908,18 @@ xfs_uuid_unmount( | |||
| 1875 | 1908 | ||
| 1876 | /* | 1909 | /* |
| 1877 | * Used to log changes to the superblock unit and width fields which could | 1910 | * Used to log changes to the superblock unit and width fields which could |
| 1878 | * be altered by the mount options. Only the first superblock is updated. | 1911 | * be altered by the mount options, as well as any potential sb_features2 |
| 1912 | * fixup. Only the first superblock is updated. | ||
| 1879 | */ | 1913 | */ |
| 1880 | STATIC void | 1914 | STATIC void |
| 1881 | xfs_mount_log_sbunit( | 1915 | xfs_mount_log_sb( |
| 1882 | xfs_mount_t *mp, | 1916 | xfs_mount_t *mp, |
| 1883 | __int64_t fields) | 1917 | __int64_t fields) |
| 1884 | { | 1918 | { |
| 1885 | xfs_trans_t *tp; | 1919 | xfs_trans_t *tp; |
| 1886 | 1920 | ||
| 1887 | ASSERT(fields & (XFS_SB_UNIT|XFS_SB_WIDTH|XFS_SB_UUID)); | 1921 | ASSERT(fields & (XFS_SB_UNIT | XFS_SB_WIDTH | XFS_SB_UUID | |
| 1922 | XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2)); | ||
| 1888 | 1923 | ||
| 1889 | tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT); | 1924 | tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT); |
| 1890 | if (xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, | 1925 | if (xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index f7c620ec6e69..1d8a4728d847 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
| @@ -366,7 +366,7 @@ typedef struct xfs_mount { | |||
| 366 | #define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */ | 366 | #define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */ |
| 367 | #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ | 367 | #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ |
| 368 | #define XFS_MOUNT_BARRIER (1ULL << 17) | 368 | #define XFS_MOUNT_BARRIER (1ULL << 17) |
| 369 | #define XFS_MOUNT_IDELETE (1ULL << 18) /* delete empty inode clusters*/ | 369 | #define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/ |
| 370 | #define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width | 370 | #define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width |
| 371 | * allocation */ | 371 | * allocation */ |
| 372 | #define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */ | 372 | #define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */ |
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index ca83ddf72af4..47082c01872d 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c | |||
| @@ -73,6 +73,18 @@ STATIC int xfs_rtmodify_summary(xfs_mount_t *, xfs_trans_t *, int, | |||
| 73 | */ | 73 | */ |
| 74 | 74 | ||
| 75 | /* | 75 | /* |
| 76 | * xfs_lowbit32: get low bit set out of 32-bit argument, -1 if none set. | ||
| 77 | */ | ||
| 78 | STATIC int | ||
| 79 | xfs_lowbit32( | ||
| 80 | __uint32_t v) | ||
| 81 | { | ||
| 82 | if (v) | ||
| 83 | return ffs(v) - 1; | ||
| 84 | return -1; | ||
| 85 | } | ||
| 86 | |||
| 87 | /* | ||
| 76 | * Allocate space to the bitmap or summary file, and zero it, for growfs. | 88 | * Allocate space to the bitmap or summary file, and zero it, for growfs. |
| 77 | */ | 89 | */ |
| 78 | STATIC int /* error */ | 90 | STATIC int /* error */ |
| @@ -432,7 +444,6 @@ xfs_rtallocate_extent_near( | |||
| 432 | } | 444 | } |
| 433 | bbno = XFS_BITTOBLOCK(mp, bno); | 445 | bbno = XFS_BITTOBLOCK(mp, bno); |
| 434 | i = 0; | 446 | i = 0; |
| 435 | ASSERT(minlen != 0); | ||
| 436 | log2len = xfs_highbit32(minlen); | 447 | log2len = xfs_highbit32(minlen); |
| 437 | /* | 448 | /* |
| 438 | * Loop over all bitmap blocks (bbno + i is current block). | 449 | * Loop over all bitmap blocks (bbno + i is current block). |
| @@ -601,8 +612,6 @@ xfs_rtallocate_extent_size( | |||
| 601 | xfs_suminfo_t sum; /* summary information for extents */ | 612 | xfs_suminfo_t sum; /* summary information for extents */ |
| 602 | 613 | ||
| 603 | ASSERT(minlen % prod == 0 && maxlen % prod == 0); | 614 | ASSERT(minlen % prod == 0 && maxlen % prod == 0); |
| 604 | ASSERT(maxlen != 0); | ||
| 605 | |||
| 606 | /* | 615 | /* |
| 607 | * Loop over all the levels starting with maxlen. | 616 | * Loop over all the levels starting with maxlen. |
| 608 | * At each level, look at all the bitmap blocks, to see if there | 617 | * At each level, look at all the bitmap blocks, to see if there |
| @@ -660,9 +669,6 @@ xfs_rtallocate_extent_size( | |||
| 660 | *rtblock = NULLRTBLOCK; | 669 | *rtblock = NULLRTBLOCK; |
| 661 | return 0; | 670 | return 0; |
| 662 | } | 671 | } |
| 663 | ASSERT(minlen != 0); | ||
| 664 | ASSERT(maxlen != 0); | ||
| 665 | |||
| 666 | /* | 672 | /* |
| 667 | * Loop over sizes, from maxlen down to minlen. | 673 | * Loop over sizes, from maxlen down to minlen. |
| 668 | * This time, when we do the allocations, allow smaller ones | 674 | * This time, when we do the allocations, allow smaller ones |
| @@ -1948,7 +1954,6 @@ xfs_growfs_rt( | |||
| 1948 | nsbp->sb_blocksize * nsbp->sb_rextsize); | 1954 | nsbp->sb_blocksize * nsbp->sb_rextsize); |
| 1949 | nsbp->sb_rextents = nsbp->sb_rblocks; | 1955 | nsbp->sb_rextents = nsbp->sb_rblocks; |
| 1950 | do_div(nsbp->sb_rextents, nsbp->sb_rextsize); | 1956 | do_div(nsbp->sb_rextents, nsbp->sb_rextsize); |
| 1951 | ASSERT(nsbp->sb_rextents != 0); | ||
| 1952 | nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents); | 1957 | nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents); |
| 1953 | nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1; | 1958 | nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1; |
| 1954 | nrsumsize = | 1959 | nrsumsize = |
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h index 94660b1a6ccc..d904efe7f871 100644 --- a/fs/xfs/xfs_sb.h +++ b/fs/xfs/xfs_sb.h | |||
| @@ -89,6 +89,7 @@ struct xfs_mount; | |||
| 89 | 89 | ||
| 90 | /* | 90 | /* |
| 91 | * Superblock - in core version. Must match the ondisk version below. | 91 | * Superblock - in core version. Must match the ondisk version below. |
| 92 | * Must be padded to 64 bit alignment. | ||
| 92 | */ | 93 | */ |
| 93 | typedef struct xfs_sb { | 94 | typedef struct xfs_sb { |
| 94 | __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ | 95 | __uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */ |
| @@ -145,10 +146,21 @@ typedef struct xfs_sb { | |||
| 145 | __uint16_t sb_logsectsize; /* sector size for the log, bytes */ | 146 | __uint16_t sb_logsectsize; /* sector size for the log, bytes */ |
| 146 | __uint32_t sb_logsunit; /* stripe unit size for the log */ | 147 | __uint32_t sb_logsunit; /* stripe unit size for the log */ |
| 147 | __uint32_t sb_features2; /* additional feature bits */ | 148 | __uint32_t sb_features2; /* additional feature bits */ |
| 149 | |||
| 150 | /* | ||
| 151 | * bad features2 field as a result of failing to pad the sb | ||
| 152 | * structure to 64 bits. Some machines will be using this field | ||
| 153 | * for features2 bits. Easiest just to mark it bad and not use | ||
| 154 | * it for anything else. | ||
| 155 | */ | ||
| 156 | __uint32_t sb_bad_features2; | ||
| 157 | |||
| 158 | /* must be padded to 64 bit alignment */ | ||
| 148 | } xfs_sb_t; | 159 | } xfs_sb_t; |
| 149 | 160 | ||
| 150 | /* | 161 | /* |
| 151 | * Superblock - on disk version. Must match the in core version below. | 162 | * Superblock - on disk version. Must match the in core version above. |
| 163 | * Must be padded to 64 bit alignment. | ||
| 152 | */ | 164 | */ |
| 153 | typedef struct xfs_dsb { | 165 | typedef struct xfs_dsb { |
| 154 | __be32 sb_magicnum; /* magic number == XFS_SB_MAGIC */ | 166 | __be32 sb_magicnum; /* magic number == XFS_SB_MAGIC */ |
| @@ -205,6 +217,15 @@ typedef struct xfs_dsb { | |||
| 205 | __be16 sb_logsectsize; /* sector size for the log, bytes */ | 217 | __be16 sb_logsectsize; /* sector size for the log, bytes */ |
| 206 | __be32 sb_logsunit; /* stripe unit size for the log */ | 218 | __be32 sb_logsunit; /* stripe unit size for the log */ |
| 207 | __be32 sb_features2; /* additional feature bits */ | 219 | __be32 sb_features2; /* additional feature bits */ |
| 220 | /* | ||
| 221 | * bad features2 field as a result of failing to pad the sb | ||
| 222 | * structure to 64 bits. Some machines will be using this field | ||
| 223 | * for features2 bits. Easiest just to mark it bad and not use | ||
| 224 | * it for anything else. | ||
| 225 | */ | ||
| 226 | __be32 sb_bad_features2; | ||
| 227 | |||
| 228 | /* must be padded to 64 bit alignment */ | ||
| 208 | } xfs_dsb_t; | 229 | } xfs_dsb_t; |
| 209 | 230 | ||
| 210 | /* | 231 | /* |
| @@ -223,7 +244,7 @@ typedef enum { | |||
| 223 | XFS_SBS_GQUOTINO, XFS_SBS_QFLAGS, XFS_SBS_FLAGS, XFS_SBS_SHARED_VN, | 244 | XFS_SBS_GQUOTINO, XFS_SBS_QFLAGS, XFS_SBS_FLAGS, XFS_SBS_SHARED_VN, |
| 224 | XFS_SBS_INOALIGNMT, XFS_SBS_UNIT, XFS_SBS_WIDTH, XFS_SBS_DIRBLKLOG, | 245 | XFS_SBS_INOALIGNMT, XFS_SBS_UNIT, XFS_SBS_WIDTH, XFS_SBS_DIRBLKLOG, |
| 225 | XFS_SBS_LOGSECTLOG, XFS_SBS_LOGSECTSIZE, XFS_SBS_LOGSUNIT, | 246 | XFS_SBS_LOGSECTLOG, XFS_SBS_LOGSECTSIZE, XFS_SBS_LOGSUNIT, |
| 226 | XFS_SBS_FEATURES2, | 247 | XFS_SBS_FEATURES2, XFS_SBS_BAD_FEATURES2, |
| 227 | XFS_SBS_FIELDCOUNT | 248 | XFS_SBS_FIELDCOUNT |
| 228 | } xfs_sb_field_t; | 249 | } xfs_sb_field_t; |
| 229 | 250 | ||
| @@ -248,13 +269,15 @@ typedef enum { | |||
| 248 | #define XFS_SB_IFREE XFS_SB_MVAL(IFREE) | 269 | #define XFS_SB_IFREE XFS_SB_MVAL(IFREE) |
| 249 | #define XFS_SB_FDBLOCKS XFS_SB_MVAL(FDBLOCKS) | 270 | #define XFS_SB_FDBLOCKS XFS_SB_MVAL(FDBLOCKS) |
| 250 | #define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2) | 271 | #define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2) |
| 272 | #define XFS_SB_BAD_FEATURES2 XFS_SB_MVAL(BAD_FEATURES2) | ||
| 251 | #define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT) | 273 | #define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT) |
| 252 | #define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1) | 274 | #define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1) |
| 253 | #define XFS_SB_MOD_BITS \ | 275 | #define XFS_SB_MOD_BITS \ |
| 254 | (XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \ | 276 | (XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \ |
| 255 | XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \ | 277 | XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \ |
| 256 | XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \ | 278 | XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \ |
| 257 | XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2) | 279 | XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2 | \ |
| 280 | XFS_SB_BAD_FEATURES2) | ||
| 258 | 281 | ||
| 259 | 282 | ||
| 260 | /* | 283 | /* |
| @@ -271,7 +294,6 @@ typedef enum { | |||
| 271 | 294 | ||
| 272 | #define XFS_SB_VERSION_NUM(sbp) ((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS) | 295 | #define XFS_SB_VERSION_NUM(sbp) ((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS) |
| 273 | 296 | ||
| 274 | #define XFS_SB_GOOD_VERSION(sbp) xfs_sb_good_version(sbp) | ||
| 275 | #ifdef __KERNEL__ | 297 | #ifdef __KERNEL__ |
| 276 | static inline int xfs_sb_good_version(xfs_sb_t *sbp) | 298 | static inline int xfs_sb_good_version(xfs_sb_t *sbp) |
| 277 | { | 299 | { |
| @@ -297,7 +319,15 @@ static inline int xfs_sb_good_version(xfs_sb_t *sbp) | |||
| 297 | } | 319 | } |
| 298 | #endif /* __KERNEL__ */ | 320 | #endif /* __KERNEL__ */ |
| 299 | 321 | ||
| 300 | #define XFS_SB_VERSION_TONEW(v) xfs_sb_version_tonew(v) | 322 | /* |
| 323 | * Detect a mismatched features2 field. Older kernels read/wrote | ||
| 324 | * this into the wrong slot, so to be safe we keep them in sync. | ||
| 325 | */ | ||
| 326 | static inline int xfs_sb_has_mismatched_features2(xfs_sb_t *sbp) | ||
| 327 | { | ||
| 328 | return (sbp->sb_bad_features2 != sbp->sb_features2); | ||
| 329 | } | ||
| 330 | |||
| 301 | static inline unsigned xfs_sb_version_tonew(unsigned v) | 331 | static inline unsigned xfs_sb_version_tonew(unsigned v) |
| 302 | { | 332 | { |
| 303 | return ((((v) == XFS_SB_VERSION_1) ? \ | 333 | return ((((v) == XFS_SB_VERSION_1) ? \ |
| @@ -308,7 +338,6 @@ static inline unsigned xfs_sb_version_tonew(unsigned v) | |||
| 308 | XFS_SB_VERSION_4); | 338 | XFS_SB_VERSION_4); |
| 309 | } | 339 | } |
| 310 | 340 | ||
| 311 | #define XFS_SB_VERSION_TOOLD(v) xfs_sb_version_toold(v) | ||
| 312 | static inline unsigned xfs_sb_version_toold(unsigned v) | 341 | static inline unsigned xfs_sb_version_toold(unsigned v) |
| 313 | { | 342 | { |
| 314 | return (((v) & (XFS_SB_VERSION_QUOTABIT | XFS_SB_VERSION_ALIGNBIT)) ? \ | 343 | return (((v) & (XFS_SB_VERSION_QUOTABIT | XFS_SB_VERSION_ALIGNBIT)) ? \ |
| @@ -320,7 +349,6 @@ static inline unsigned xfs_sb_version_toold(unsigned v) | |||
| 320 | XFS_SB_VERSION_1))); | 349 | XFS_SB_VERSION_1))); |
| 321 | } | 350 | } |
| 322 | 351 | ||
| 323 | #define XFS_SB_VERSION_HASATTR(sbp) xfs_sb_version_hasattr(sbp) | ||
| 324 | static inline int xfs_sb_version_hasattr(xfs_sb_t *sbp) | 352 | static inline int xfs_sb_version_hasattr(xfs_sb_t *sbp) |
| 325 | { | 353 | { |
| 326 | return ((sbp)->sb_versionnum == XFS_SB_VERSION_2) || \ | 354 | return ((sbp)->sb_versionnum == XFS_SB_VERSION_2) || \ |
| @@ -329,7 +357,6 @@ static inline int xfs_sb_version_hasattr(xfs_sb_t *sbp) | |||
| 329 | ((sbp)->sb_versionnum & XFS_SB_VERSION_ATTRBIT)); | 357 | ((sbp)->sb_versionnum & XFS_SB_VERSION_ATTRBIT)); |
| 330 | } | 358 | } |
| 331 | 359 | ||
| 332 | #define XFS_SB_VERSION_ADDATTR(sbp) xfs_sb_version_addattr(sbp) | ||
| 333 | static inline void xfs_sb_version_addattr(xfs_sb_t *sbp) | 360 | static inline void xfs_sb_version_addattr(xfs_sb_t *sbp) |
| 334 | { | 361 | { |
| 335 | (sbp)->sb_versionnum = (((sbp)->sb_versionnum == XFS_SB_VERSION_1) ? \ | 362 | (sbp)->sb_versionnum = (((sbp)->sb_versionnum == XFS_SB_VERSION_1) ? \ |
| @@ -339,7 +366,6 @@ static inline void xfs_sb_version_addattr(xfs_sb_t *sbp) | |||
| 339 | (XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT))); | 366 | (XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT))); |
| 340 | } | 367 | } |
| 341 | 368 | ||
| 342 | #define XFS_SB_VERSION_HASNLINK(sbp) xfs_sb_version_hasnlink(sbp) | ||
| 343 | static inline int xfs_sb_version_hasnlink(xfs_sb_t *sbp) | 369 | static inline int xfs_sb_version_hasnlink(xfs_sb_t *sbp) |
| 344 | { | 370 | { |
| 345 | return ((sbp)->sb_versionnum == XFS_SB_VERSION_3) || \ | 371 | return ((sbp)->sb_versionnum == XFS_SB_VERSION_3) || \ |
| @@ -347,7 +373,6 @@ static inline int xfs_sb_version_hasnlink(xfs_sb_t *sbp) | |||
| 347 | ((sbp)->sb_versionnum & XFS_SB_VERSION_NLINKBIT)); | 373 | ((sbp)->sb_versionnum & XFS_SB_VERSION_NLINKBIT)); |
| 348 | } | 374 | } |
| 349 | 375 | ||
| 350 | #define XFS_SB_VERSION_ADDNLINK(sbp) xfs_sb_version_addnlink(sbp) | ||
| 351 | static inline void xfs_sb_version_addnlink(xfs_sb_t *sbp) | 376 | static inline void xfs_sb_version_addnlink(xfs_sb_t *sbp) |
| 352 | { | 377 | { |
| 353 | (sbp)->sb_versionnum = ((sbp)->sb_versionnum <= XFS_SB_VERSION_2 ? \ | 378 | (sbp)->sb_versionnum = ((sbp)->sb_versionnum <= XFS_SB_VERSION_2 ? \ |
| @@ -355,115 +380,63 @@ static inline void xfs_sb_version_addnlink(xfs_sb_t *sbp) | |||
| 355 | ((sbp)->sb_versionnum | XFS_SB_VERSION_NLINKBIT)); | 380 | ((sbp)->sb_versionnum | XFS_SB_VERSION_NLINKBIT)); |
| 356 | } | 381 | } |
| 357 | 382 | ||
| 358 | #define XFS_SB_VERSION_HASQUOTA(sbp) xfs_sb_version_hasquota(sbp) | ||
| 359 | static inline int xfs_sb_version_hasquota(xfs_sb_t *sbp) | 383 | static inline int xfs_sb_version_hasquota(xfs_sb_t *sbp) |
| 360 | { | 384 | { |
| 361 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ | 385 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ |
| 362 | ((sbp)->sb_versionnum & XFS_SB_VERSION_QUOTABIT); | 386 | ((sbp)->sb_versionnum & XFS_SB_VERSION_QUOTABIT); |
| 363 | } | 387 | } |
| 364 | 388 | ||
| 365 | #define XFS_SB_VERSION_ADDQUOTA(sbp) xfs_sb_version_addquota(sbp) | ||
| 366 | static inline void xfs_sb_version_addquota(xfs_sb_t *sbp) | 389 | static inline void xfs_sb_version_addquota(xfs_sb_t *sbp) |
| 367 | { | 390 | { |
| 368 | (sbp)->sb_versionnum = \ | 391 | (sbp)->sb_versionnum = \ |
| 369 | (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 ? \ | 392 | (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 ? \ |
| 370 | ((sbp)->sb_versionnum | XFS_SB_VERSION_QUOTABIT) : \ | 393 | ((sbp)->sb_versionnum | XFS_SB_VERSION_QUOTABIT) : \ |
| 371 | (XFS_SB_VERSION_TONEW((sbp)->sb_versionnum) | \ | 394 | (xfs_sb_version_tonew((sbp)->sb_versionnum) | \ |
| 372 | XFS_SB_VERSION_QUOTABIT)); | 395 | XFS_SB_VERSION_QUOTABIT)); |
| 373 | } | 396 | } |
| 374 | 397 | ||
| 375 | #define XFS_SB_VERSION_HASALIGN(sbp) xfs_sb_version_hasalign(sbp) | ||
| 376 | static inline int xfs_sb_version_hasalign(xfs_sb_t *sbp) | 398 | static inline int xfs_sb_version_hasalign(xfs_sb_t *sbp) |
| 377 | { | 399 | { |
| 378 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ | 400 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ |
| 379 | ((sbp)->sb_versionnum & XFS_SB_VERSION_ALIGNBIT); | 401 | ((sbp)->sb_versionnum & XFS_SB_VERSION_ALIGNBIT); |
| 380 | } | 402 | } |
| 381 | 403 | ||
| 382 | #define XFS_SB_VERSION_SUBALIGN(sbp) xfs_sb_version_subalign(sbp) | ||
| 383 | static inline void xfs_sb_version_subalign(xfs_sb_t *sbp) | ||
| 384 | { | ||
| 385 | (sbp)->sb_versionnum = \ | ||
| 386 | XFS_SB_VERSION_TOOLD((sbp)->sb_versionnum & ~XFS_SB_VERSION_ALIGNBIT); | ||
| 387 | } | ||
| 388 | |||
| 389 | #define XFS_SB_VERSION_HASDALIGN(sbp) xfs_sb_version_hasdalign(sbp) | ||
| 390 | static inline int xfs_sb_version_hasdalign(xfs_sb_t *sbp) | 404 | static inline int xfs_sb_version_hasdalign(xfs_sb_t *sbp) |
| 391 | { | 405 | { |
| 392 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ | 406 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ |
| 393 | ((sbp)->sb_versionnum & XFS_SB_VERSION_DALIGNBIT); | 407 | ((sbp)->sb_versionnum & XFS_SB_VERSION_DALIGNBIT); |
| 394 | } | 408 | } |
| 395 | 409 | ||
| 396 | #define XFS_SB_VERSION_ADDDALIGN(sbp) xfs_sb_version_adddalign(sbp) | ||
| 397 | static inline int xfs_sb_version_adddalign(xfs_sb_t *sbp) | ||
| 398 | { | ||
| 399 | return (sbp)->sb_versionnum = \ | ||
| 400 | ((sbp)->sb_versionnum | XFS_SB_VERSION_DALIGNBIT); | ||
| 401 | } | ||
| 402 | |||
| 403 | #define XFS_SB_VERSION_HASSHARED(sbp) xfs_sb_version_hasshared(sbp) | ||
| 404 | static inline int xfs_sb_version_hasshared(xfs_sb_t *sbp) | 410 | static inline int xfs_sb_version_hasshared(xfs_sb_t *sbp) |
| 405 | { | 411 | { |
| 406 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ | 412 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ |
| 407 | ((sbp)->sb_versionnum & XFS_SB_VERSION_SHAREDBIT); | 413 | ((sbp)->sb_versionnum & XFS_SB_VERSION_SHAREDBIT); |
| 408 | } | 414 | } |
| 409 | 415 | ||
| 410 | #define XFS_SB_VERSION_ADDSHARED(sbp) xfs_sb_version_addshared(sbp) | ||
| 411 | static inline int xfs_sb_version_addshared(xfs_sb_t *sbp) | ||
| 412 | { | ||
| 413 | return (sbp)->sb_versionnum = \ | ||
| 414 | ((sbp)->sb_versionnum | XFS_SB_VERSION_SHAREDBIT); | ||
| 415 | } | ||
| 416 | |||
| 417 | #define XFS_SB_VERSION_SUBSHARED(sbp) xfs_sb_version_subshared(sbp) | ||
| 418 | static inline int xfs_sb_version_subshared(xfs_sb_t *sbp) | ||
| 419 | { | ||
| 420 | return (sbp)->sb_versionnum = \ | ||
| 421 | ((sbp)->sb_versionnum & ~XFS_SB_VERSION_SHAREDBIT); | ||
| 422 | } | ||
| 423 | |||
| 424 | #define XFS_SB_VERSION_HASDIRV2(sbp) xfs_sb_version_hasdirv2(sbp) | ||
| 425 | static inline int xfs_sb_version_hasdirv2(xfs_sb_t *sbp) | 416 | static inline int xfs_sb_version_hasdirv2(xfs_sb_t *sbp) |
| 426 | { | 417 | { |
| 427 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ | 418 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ |
| 428 | ((sbp)->sb_versionnum & XFS_SB_VERSION_DIRV2BIT); | 419 | ((sbp)->sb_versionnum & XFS_SB_VERSION_DIRV2BIT); |
| 429 | } | 420 | } |
| 430 | 421 | ||
| 431 | #define XFS_SB_VERSION_HASLOGV2(sbp) xfs_sb_version_haslogv2(sbp) | ||
| 432 | static inline int xfs_sb_version_haslogv2(xfs_sb_t *sbp) | 422 | static inline int xfs_sb_version_haslogv2(xfs_sb_t *sbp) |
| 433 | { | 423 | { |
| 434 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ | 424 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ |
| 435 | ((sbp)->sb_versionnum & XFS_SB_VERSION_LOGV2BIT); | 425 | ((sbp)->sb_versionnum & XFS_SB_VERSION_LOGV2BIT); |
| 436 | } | 426 | } |
| 437 | 427 | ||
| 438 | #define XFS_SB_VERSION_HASEXTFLGBIT(sbp) xfs_sb_version_hasextflgbit(sbp) | ||
| 439 | static inline int xfs_sb_version_hasextflgbit(xfs_sb_t *sbp) | 428 | static inline int xfs_sb_version_hasextflgbit(xfs_sb_t *sbp) |
| 440 | { | 429 | { |
| 441 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ | 430 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ |
| 442 | ((sbp)->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT); | 431 | ((sbp)->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT); |
| 443 | } | 432 | } |
| 444 | 433 | ||
| 445 | #define XFS_SB_VERSION_ADDEXTFLGBIT(sbp) xfs_sb_version_addextflgbit(sbp) | ||
| 446 | static inline int xfs_sb_version_addextflgbit(xfs_sb_t *sbp) | ||
| 447 | { | ||
| 448 | return (sbp)->sb_versionnum = \ | ||
| 449 | ((sbp)->sb_versionnum | XFS_SB_VERSION_EXTFLGBIT); | ||
| 450 | } | ||
| 451 | |||
| 452 | #define XFS_SB_VERSION_SUBEXTFLGBIT(sbp) xfs_sb_version_subextflgbit(sbp) | ||
| 453 | static inline int xfs_sb_version_subextflgbit(xfs_sb_t *sbp) | ||
| 454 | { | ||
| 455 | return (sbp)->sb_versionnum = \ | ||
| 456 | ((sbp)->sb_versionnum & ~XFS_SB_VERSION_EXTFLGBIT); | ||
| 457 | } | ||
| 458 | |||
| 459 | #define XFS_SB_VERSION_HASSECTOR(sbp) xfs_sb_version_hassector(sbp) | ||
| 460 | static inline int xfs_sb_version_hassector(xfs_sb_t *sbp) | 434 | static inline int xfs_sb_version_hassector(xfs_sb_t *sbp) |
| 461 | { | 435 | { |
| 462 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ | 436 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ |
| 463 | ((sbp)->sb_versionnum & XFS_SB_VERSION_SECTORBIT); | 437 | ((sbp)->sb_versionnum & XFS_SB_VERSION_SECTORBIT); |
| 464 | } | 438 | } |
| 465 | 439 | ||
| 466 | #define XFS_SB_VERSION_HASMOREBITS(sbp) xfs_sb_version_hasmorebits(sbp) | ||
| 467 | static inline int xfs_sb_version_hasmorebits(xfs_sb_t *sbp) | 440 | static inline int xfs_sb_version_hasmorebits(xfs_sb_t *sbp) |
| 468 | { | 441 | { |
| 469 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ | 442 | return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \ |
| @@ -476,24 +449,22 @@ static inline int xfs_sb_version_hasmorebits(xfs_sb_t *sbp) | |||
| 476 | * For example, for a bit defined as XFS_SB_VERSION2_FUNBIT, has a macro: | 449 | * For example, for a bit defined as XFS_SB_VERSION2_FUNBIT, has a macro: |
| 477 | * | 450 | * |
| 478 | * SB_VERSION_HASFUNBIT(xfs_sb_t *sbp) | 451 | * SB_VERSION_HASFUNBIT(xfs_sb_t *sbp) |
| 479 | * ((XFS_SB_VERSION_HASMOREBITS(sbp) && | 452 | * ((xfs_sb_version_hasmorebits(sbp) && |
| 480 | * ((sbp)->sb_features2 & XFS_SB_VERSION2_FUNBIT) | 453 | * ((sbp)->sb_features2 & XFS_SB_VERSION2_FUNBIT) |
| 481 | */ | 454 | */ |
| 482 | 455 | ||
| 483 | static inline int xfs_sb_version_haslazysbcount(xfs_sb_t *sbp) | 456 | static inline int xfs_sb_version_haslazysbcount(xfs_sb_t *sbp) |
| 484 | { | 457 | { |
| 485 | return (XFS_SB_VERSION_HASMOREBITS(sbp) && \ | 458 | return (xfs_sb_version_hasmorebits(sbp) && \ |
| 486 | ((sbp)->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT)); | 459 | ((sbp)->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT)); |
| 487 | } | 460 | } |
| 488 | 461 | ||
| 489 | #define XFS_SB_VERSION_HASATTR2(sbp) xfs_sb_version_hasattr2(sbp) | ||
| 490 | static inline int xfs_sb_version_hasattr2(xfs_sb_t *sbp) | 462 | static inline int xfs_sb_version_hasattr2(xfs_sb_t *sbp) |
| 491 | { | 463 | { |
| 492 | return (XFS_SB_VERSION_HASMOREBITS(sbp)) && \ | 464 | return (xfs_sb_version_hasmorebits(sbp)) && \ |
| 493 | ((sbp)->sb_features2 & XFS_SB_VERSION2_ATTR2BIT); | 465 | ((sbp)->sb_features2 & XFS_SB_VERSION2_ATTR2BIT); |
| 494 | } | 466 | } |
| 495 | 467 | ||
| 496 | #define XFS_SB_VERSION_ADDATTR2(sbp) xfs_sb_version_addattr2(sbp) | ||
| 497 | static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp) | 468 | static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp) |
| 498 | { | 469 | { |
| 499 | ((sbp)->sb_versionnum = \ | 470 | ((sbp)->sb_versionnum = \ |
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 4d6330eddc8d..76d470d8a1e6 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c | |||
| @@ -261,16 +261,19 @@ xfsaild_push( | |||
| 261 | xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE); | 261 | xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE); |
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | /* | 264 | if (!count) { |
| 265 | * We reached the target so wait a bit longer for I/O to complete and | 265 | /* We're past our target or empty, so idle */ |
| 266 | * remove pushed items from the AIL before we start the next scan from | 266 | tout = 1000; |
| 267 | * the start of the AIL. | 267 | } else if (XFS_LSN_CMP(lsn, target) >= 0) { |
| 268 | */ | 268 | /* |
| 269 | if ((XFS_LSN_CMP(lsn, target) >= 0)) { | 269 | * We reached the target so wait a bit longer for I/O to |
| 270 | * complete and remove pushed items from the AIL before we | ||
| 271 | * start the next scan from the start of the AIL. | ||
| 272 | */ | ||
| 270 | tout += 20; | 273 | tout += 20; |
| 271 | last_pushed_lsn = 0; | 274 | last_pushed_lsn = 0; |
| 272 | } else if ((restarts > XFS_TRANS_PUSH_AIL_RESTARTS) || | 275 | } else if ((restarts > XFS_TRANS_PUSH_AIL_RESTARTS) || |
| 273 | (count && ((stuck * 100) / count > 90))) { | 276 | ((stuck * 100) / count > 90)) { |
| 274 | /* | 277 | /* |
| 275 | * Either there is a lot of contention on the AIL or we | 278 | * Either there is a lot of contention on the AIL or we |
| 276 | * are stuck due to operations in progress. "Stuck" in this | 279 | * are stuck due to operations in progress. "Stuck" in this |
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index 45d740df53b7..18a85e746680 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c | |||
| @@ -339,10 +339,10 @@ xfs_bump_ino_vers2( | |||
| 339 | ip->i_d.di_onlink = 0; | 339 | ip->i_d.di_onlink = 0; |
| 340 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); | 340 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); |
| 341 | mp = tp->t_mountp; | 341 | mp = tp->t_mountp; |
| 342 | if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) { | 342 | if (!xfs_sb_version_hasnlink(&mp->m_sb)) { |
| 343 | spin_lock(&mp->m_sb_lock); | 343 | spin_lock(&mp->m_sb_lock); |
| 344 | if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) { | 344 | if (!xfs_sb_version_hasnlink(&mp->m_sb)) { |
| 345 | XFS_SB_VERSION_ADDNLINK(&mp->m_sb); | 345 | xfs_sb_version_addnlink(&mp->m_sb); |
| 346 | spin_unlock(&mp->m_sb_lock); | 346 | spin_unlock(&mp->m_sb_lock); |
| 347 | xfs_mod_sb(tp, XFS_SB_VERSIONNUM); | 347 | xfs_mod_sb(tp, XFS_SB_VERSIONNUM); |
| 348 | } else { | 348 | } else { |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 413587f02155..7094caff13cf 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
| @@ -281,8 +281,8 @@ xfs_start_flags( | |||
| 281 | mp->m_readio_log = mp->m_writeio_log = ap->iosizelog; | 281 | mp->m_readio_log = mp->m_writeio_log = ap->iosizelog; |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | if (ap->flags & XFSMNT_IDELETE) | 284 | if (ap->flags & XFSMNT_IKEEP) |
| 285 | mp->m_flags |= XFS_MOUNT_IDELETE; | 285 | mp->m_flags |= XFS_MOUNT_IKEEP; |
| 286 | if (ap->flags & XFSMNT_DIRSYNC) | 286 | if (ap->flags & XFSMNT_DIRSYNC) |
| 287 | mp->m_flags |= XFS_MOUNT_DIRSYNC; | 287 | mp->m_flags |= XFS_MOUNT_DIRSYNC; |
| 288 | if (ap->flags & XFSMNT_ATTR2) | 288 | if (ap->flags & XFSMNT_ATTR2) |
| @@ -330,7 +330,7 @@ xfs_finish_flags( | |||
| 330 | int ronly = (mp->m_flags & XFS_MOUNT_RDONLY); | 330 | int ronly = (mp->m_flags & XFS_MOUNT_RDONLY); |
| 331 | 331 | ||
| 332 | /* Fail a mount where the logbuf is smaller then the log stripe */ | 332 | /* Fail a mount where the logbuf is smaller then the log stripe */ |
| 333 | if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) { | 333 | if (xfs_sb_version_haslogv2(&mp->m_sb)) { |
| 334 | if ((ap->logbufsize <= 0) && | 334 | if ((ap->logbufsize <= 0) && |
| 335 | (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) { | 335 | (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) { |
| 336 | mp->m_logbsize = mp->m_sb.sb_logsunit; | 336 | mp->m_logbsize = mp->m_sb.sb_logsunit; |
| @@ -349,9 +349,8 @@ xfs_finish_flags( | |||
| 349 | } | 349 | } |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | if (XFS_SB_VERSION_HASATTR2(&mp->m_sb)) { | 352 | if (xfs_sb_version_hasattr2(&mp->m_sb)) |
| 353 | mp->m_flags |= XFS_MOUNT_ATTR2; | 353 | mp->m_flags |= XFS_MOUNT_ATTR2; |
| 354 | } | ||
| 355 | 354 | ||
| 356 | /* | 355 | /* |
| 357 | * prohibit r/w mounts of read-only filesystems | 356 | * prohibit r/w mounts of read-only filesystems |
| @@ -366,7 +365,7 @@ xfs_finish_flags( | |||
| 366 | * check for shared mount. | 365 | * check for shared mount. |
| 367 | */ | 366 | */ |
| 368 | if (ap->flags & XFSMNT_SHARED) { | 367 | if (ap->flags & XFSMNT_SHARED) { |
| 369 | if (!XFS_SB_VERSION_HASSHARED(&mp->m_sb)) | 368 | if (!xfs_sb_version_hasshared(&mp->m_sb)) |
| 370 | return XFS_ERROR(EINVAL); | 369 | return XFS_ERROR(EINVAL); |
| 371 | 370 | ||
| 372 | /* | 371 | /* |
| @@ -512,7 +511,7 @@ xfs_mount( | |||
| 512 | if (!error && logdev && logdev != ddev) { | 511 | if (!error && logdev && logdev != ddev) { |
| 513 | unsigned int log_sector_size = BBSIZE; | 512 | unsigned int log_sector_size = BBSIZE; |
| 514 | 513 | ||
| 515 | if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb)) | 514 | if (xfs_sb_version_hassector(&mp->m_sb)) |
| 516 | log_sector_size = mp->m_sb.sb_logsectsize; | 515 | log_sector_size = mp->m_sb.sb_logsectsize; |
| 517 | error = xfs_setsize_buftarg(mp->m_logdev_targp, | 516 | error = xfs_setsize_buftarg(mp->m_logdev_targp, |
| 518 | mp->m_sb.sb_blocksize, | 517 | mp->m_sb.sb_blocksize, |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 51305242ff8c..64c5953feca4 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
| @@ -4132,7 +4132,7 @@ xfs_free_file_space( | |||
| 4132 | * actually need to zero the extent edges. Otherwise xfs_bunmapi | 4132 | * actually need to zero the extent edges. Otherwise xfs_bunmapi |
| 4133 | * will take care of it for us. | 4133 | * will take care of it for us. |
| 4134 | */ | 4134 | */ |
| 4135 | if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) { | 4135 | if (rt && !xfs_sb_version_hasextflgbit(&mp->m_sb)) { |
| 4136 | nimap = 1; | 4136 | nimap = 1; |
| 4137 | error = xfs_bmapi(NULL, ip, startoffset_fsb, | 4137 | error = xfs_bmapi(NULL, ip, startoffset_fsb, |
| 4138 | 1, 0, NULL, 0, &imap, &nimap, NULL, NULL); | 4138 | 1, 0, NULL, 0, &imap, &nimap, NULL, NULL); |
