diff options
42 files changed, 650 insertions, 280 deletions
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index 345a4b1fe144..675879b65ce6 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c | |||
@@ -640,8 +640,8 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
640 | /* Skip cs, ip, orig_ax and gs. */ \ | 640 | /* Skip cs, ip, orig_ax and gs. */ \ |
641 | " subl $16, %esp\n" \ | 641 | " subl $16, %esp\n" \ |
642 | " pushl %fs\n" \ | 642 | " pushl %fs\n" \ |
643 | " pushl %ds\n" \ | ||
644 | " pushl %es\n" \ | 643 | " pushl %es\n" \ |
644 | " pushl %ds\n" \ | ||
645 | " pushl %eax\n" \ | 645 | " pushl %eax\n" \ |
646 | " pushl %ebp\n" \ | 646 | " pushl %ebp\n" \ |
647 | " pushl %edi\n" \ | 647 | " pushl %edi\n" \ |
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 6fdb3ec30c31..55253095be84 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
@@ -184,6 +184,7 @@ static void __init pcibios_allocate_resources(int pass) | |||
184 | idx, r, disabled, pass); | 184 | idx, r, disabled, pass); |
185 | if (pci_claim_resource(dev, idx) < 0) { | 185 | if (pci_claim_resource(dev, idx) < 0) { |
186 | /* We'll assign a new address later */ | 186 | /* We'll assign a new address later */ |
187 | dev->fw_addr[idx] = r->start; | ||
187 | r->end -= r->start; | 188 | r->end -= r->start; |
188 | r->start = 0; | 189 | r->start = 0; |
189 | } | 190 | } |
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c index 98a66103f4f2..a854df2a5a4b 100644 --- a/crypto/ablkcipher.c +++ b/crypto/ablkcipher.c | |||
@@ -165,7 +165,7 @@ static inline int ablkcipher_next_slow(struct ablkcipher_request *req, | |||
165 | 165 | ||
166 | p = kmalloc(n, GFP_ATOMIC); | 166 | p = kmalloc(n, GFP_ATOMIC); |
167 | if (!p) | 167 | if (!p) |
168 | ablkcipher_walk_done(req, walk, -ENOMEM); | 168 | return ablkcipher_walk_done(req, walk, -ENOMEM); |
169 | 169 | ||
170 | base = p + 1; | 170 | base = p + 1; |
171 | 171 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 074385882ccf..8757ecf6e96b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2241,6 +2241,7 @@ i915_gem_object_get_pages(struct drm_gem_object *obj, | |||
2241 | page = read_cache_page_gfp(mapping, i, | 2241 | page = read_cache_page_gfp(mapping, i, |
2242 | GFP_HIGHUSER | | 2242 | GFP_HIGHUSER | |
2243 | __GFP_COLD | | 2243 | __GFP_COLD | |
2244 | __GFP_RECLAIMABLE | | ||
2244 | gfpmask); | 2245 | gfpmask); |
2245 | if (IS_ERR(page)) | 2246 | if (IS_ERR(page)) |
2246 | goto err_pages; | 2247 | goto err_pages; |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 40cea334ad13..9ba9c4a17e15 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -206,6 +206,7 @@ static int synaptics_resolution(struct psmouse *psmouse) | |||
206 | unsigned char max[3]; | 206 | unsigned char max[3]; |
207 | 207 | ||
208 | if (SYN_ID_MAJOR(priv->identity) < 4) | 208 | if (SYN_ID_MAJOR(priv->identity) < 4) |
209 | return 0; | ||
209 | 210 | ||
210 | if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res) == 0) { | 211 | if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res) == 0) { |
211 | if (res[0] != 0 && (res[1] & 0x80) && res[2] != 0) { | 212 | if (res[0] != 0 && (res[1] & 0x80) && res[2] != 0) { |
diff --git a/drivers/input/touchscreen/w90p910_ts.c b/drivers/input/touchscreen/w90p910_ts.c index cc18265be1a8..7a45d68c3516 100644 --- a/drivers/input/touchscreen/w90p910_ts.c +++ b/drivers/input/touchscreen/w90p910_ts.c | |||
@@ -233,7 +233,7 @@ static int __devinit w90x900ts_probe(struct platform_device *pdev) | |||
233 | w90p910_ts->state = TS_IDLE; | 233 | w90p910_ts->state = TS_IDLE; |
234 | spin_lock_init(&w90p910_ts->lock); | 234 | spin_lock_init(&w90p910_ts->lock); |
235 | setup_timer(&w90p910_ts->timer, w90p910_check_pen_up, | 235 | setup_timer(&w90p910_ts->timer, w90p910_check_pen_up, |
236 | (unsigned long)&w90p910_ts); | 236 | (unsigned long)w90p910_ts); |
237 | 237 | ||
238 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 238 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
239 | if (!res) { | 239 | if (!res) { |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 92379e2d37e7..2aaa13150de3 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -156,6 +156,38 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | |||
156 | pcibios_align_resource, dev); | 156 | pcibios_align_resource, dev); |
157 | } | 157 | } |
158 | 158 | ||
159 | if (ret < 0 && dev->fw_addr[resno]) { | ||
160 | struct resource *root, *conflict; | ||
161 | resource_size_t start, end; | ||
162 | |||
163 | /* | ||
164 | * If we failed to assign anything, let's try the address | ||
165 | * where firmware left it. That at least has a chance of | ||
166 | * working, which is better than just leaving it disabled. | ||
167 | */ | ||
168 | |||
169 | if (res->flags & IORESOURCE_IO) | ||
170 | root = &ioport_resource; | ||
171 | else | ||
172 | root = &iomem_resource; | ||
173 | |||
174 | start = res->start; | ||
175 | end = res->end; | ||
176 | res->start = dev->fw_addr[resno]; | ||
177 | res->end = res->start + size - 1; | ||
178 | dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n", | ||
179 | resno, res); | ||
180 | conflict = request_resource_conflict(root, res); | ||
181 | if (conflict) { | ||
182 | dev_info(&dev->dev, | ||
183 | "BAR %d: %pR conflicts with %s %pR\n", resno, | ||
184 | res, conflict->name, conflict); | ||
185 | res->start = start; | ||
186 | res->end = end; | ||
187 | } else | ||
188 | ret = 0; | ||
189 | } | ||
190 | |||
159 | if (!ret) { | 191 | if (!ret) { |
160 | res->flags &= ~IORESOURCE_STARTALIGN; | 192 | res->flags &= ~IORESOURCE_STARTALIGN; |
161 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | 193 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); |
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 40658e3385b4..bb2f1fba637b 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c | |||
@@ -489,7 +489,7 @@ int intel_scu_ipc_simple_command(int cmd, int sub) | |||
489 | mutex_unlock(&ipclock); | 489 | mutex_unlock(&ipclock); |
490 | return -ENODEV; | 490 | return -ENODEV; |
491 | } | 491 | } |
492 | ipc_command(cmd << 12 | sub); | 492 | ipc_command(sub << 12 | cmd); |
493 | err = busy_loop(); | 493 | err = busy_loop(); |
494 | mutex_unlock(&ipclock); | 494 | mutex_unlock(&ipclock); |
495 | return err; | 495 | return err; |
@@ -501,9 +501,9 @@ EXPORT_SYMBOL(intel_scu_ipc_simple_command); | |||
501 | * @cmd: command | 501 | * @cmd: command |
502 | * @sub: sub type | 502 | * @sub: sub type |
503 | * @in: input data | 503 | * @in: input data |
504 | * @inlen: input length | 504 | * @inlen: input length in dwords |
505 | * @out: output data | 505 | * @out: output data |
506 | * @outlein: output length | 506 | * @outlein: output length in dwords |
507 | * | 507 | * |
508 | * Issue a command to the SCU which involves data transfers. Do the | 508 | * Issue a command to the SCU which involves data transfers. Do the |
509 | * data copies under the lock but leave it for the caller to interpret | 509 | * data copies under the lock but leave it for the caller to interpret |
@@ -524,7 +524,7 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, | |||
524 | for (i = 0; i < inlen; i++) | 524 | for (i = 0; i < inlen; i++) |
525 | ipc_data_writel(*in++, 4 * i); | 525 | ipc_data_writel(*in++, 4 * i); |
526 | 526 | ||
527 | ipc_command((cmd << 12) | sub | (inlen << 18)); | 527 | ipc_command((sub << 12) | cmd | (inlen << 18)); |
528 | err = busy_loop(); | 528 | err = busy_loop(); |
529 | 529 | ||
530 | for (i = 0; i < outlen; i++) | 530 | for (i = 0; i < outlen; i++) |
@@ -556,6 +556,10 @@ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data) | |||
556 | u32 cmd = 0; | 556 | u32 cmd = 0; |
557 | 557 | ||
558 | mutex_lock(&ipclock); | 558 | mutex_lock(&ipclock); |
559 | if (ipcdev.pdev == NULL) { | ||
560 | mutex_unlock(&ipclock); | ||
561 | return -ENODEV; | ||
562 | } | ||
559 | cmd = (addr >> 24) & 0xFF; | 563 | cmd = (addr >> 24) & 0xFF; |
560 | if (cmd == IPC_I2C_READ) { | 564 | if (cmd == IPC_I2C_READ) { |
561 | writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); | 565 | writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); |
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 34d51dd4c539..bed7b4634ccd 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
@@ -948,8 +948,10 @@ static ssize_t dasd_alias_show(struct device *dev, | |||
948 | if (device->discipline && device->discipline->get_uid && | 948 | if (device->discipline && device->discipline->get_uid && |
949 | !device->discipline->get_uid(device, &uid)) { | 949 | !device->discipline->get_uid(device, &uid)) { |
950 | if (uid.type == UA_BASE_PAV_ALIAS || | 950 | if (uid.type == UA_BASE_PAV_ALIAS || |
951 | uid.type == UA_HYPER_PAV_ALIAS) | 951 | uid.type == UA_HYPER_PAV_ALIAS) { |
952 | dasd_put_device(device); | ||
952 | return sprintf(buf, "1\n"); | 953 | return sprintf(buf, "1\n"); |
954 | } | ||
953 | } | 955 | } |
954 | dasd_put_device(device); | 956 | dasd_put_device(device); |
955 | 957 | ||
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index ce7cb87479fe..407d0e9adfaf 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -713,7 +713,7 @@ int chsc_determine_base_channel_path_desc(struct chp_id chpid, | |||
713 | ret = chsc_determine_channel_path_desc(chpid, 0, 0, 0, 0, chsc_resp); | 713 | ret = chsc_determine_channel_path_desc(chpid, 0, 0, 0, 0, chsc_resp); |
714 | if (ret) | 714 | if (ret) |
715 | goto out_free; | 715 | goto out_free; |
716 | memcpy(desc, &chsc_resp->data, chsc_resp->length); | 716 | memcpy(desc, &chsc_resp->data, sizeof(*desc)); |
717 | out_free: | 717 | out_free: |
718 | kfree(chsc_resp); | 718 | kfree(chsc_resp); |
719 | return ret; | 719 | return ret; |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 4a48c0f4b402..84da64b551b2 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -1041,6 +1041,7 @@ static int trunc_start(struct gfs2_inode *ip, u64 size) | |||
1041 | 1041 | ||
1042 | if (gfs2_is_stuffed(ip)) { | 1042 | if (gfs2_is_stuffed(ip)) { |
1043 | u64 dsize = size + sizeof(struct gfs2_inode); | 1043 | u64 dsize = size + sizeof(struct gfs2_inode); |
1044 | ip->i_disksize = size; | ||
1044 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; | 1045 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
1045 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1046 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1046 | gfs2_dinode_out(ip, dibh->b_data); | 1047 | gfs2_dinode_out(ip, dibh->b_data); |
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 8295c5b5d4a9..26ca3361a8bc 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -392,7 +392,7 @@ static int gfs2_dirent_find_space(const struct gfs2_dirent *dent, | |||
392 | unsigned totlen = be16_to_cpu(dent->de_rec_len); | 392 | unsigned totlen = be16_to_cpu(dent->de_rec_len); |
393 | 393 | ||
394 | if (gfs2_dirent_sentinel(dent)) | 394 | if (gfs2_dirent_sentinel(dent)) |
395 | actual = GFS2_DIRENT_SIZE(0); | 395 | actual = 0; |
396 | if (totlen - actual >= required) | 396 | if (totlen - actual >= required) |
397 | return 1; | 397 | return 1; |
398 | return 0; | 398 | return 0; |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index ddcdbf493536..dbab3fdc2582 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -706,8 +706,18 @@ static void glock_work_func(struct work_struct *work) | |||
706 | { | 706 | { |
707 | unsigned long delay = 0; | 707 | unsigned long delay = 0; |
708 | struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_work.work); | 708 | struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_work.work); |
709 | struct gfs2_holder *gh; | ||
709 | int drop_ref = 0; | 710 | int drop_ref = 0; |
710 | 711 | ||
712 | if (unlikely(test_bit(GLF_FROZEN, &gl->gl_flags))) { | ||
713 | spin_lock(&gl->gl_spin); | ||
714 | gh = find_first_waiter(gl); | ||
715 | if (gh && (gh->gh_flags & LM_FLAG_NOEXP) && | ||
716 | test_and_clear_bit(GLF_FROZEN, &gl->gl_flags)) | ||
717 | set_bit(GLF_REPLY_PENDING, &gl->gl_flags); | ||
718 | spin_unlock(&gl->gl_spin); | ||
719 | } | ||
720 | |||
711 | if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags)) { | 721 | if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags)) { |
712 | finish_xmote(gl, gl->gl_reply); | 722 | finish_xmote(gl, gl->gl_reply); |
713 | drop_ref = 1; | 723 | drop_ref = 1; |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index b5612cbb62a5..f03afd9c44bc 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -169,7 +169,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, | |||
169 | { | 169 | { |
170 | struct inode *inode; | 170 | struct inode *inode; |
171 | struct gfs2_inode *ip; | 171 | struct gfs2_inode *ip; |
172 | struct gfs2_glock *io_gl; | 172 | struct gfs2_glock *io_gl = NULL; |
173 | int error; | 173 | int error; |
174 | 174 | ||
175 | inode = gfs2_iget(sb, no_addr); | 175 | inode = gfs2_iget(sb, no_addr); |
@@ -198,6 +198,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, | |||
198 | ip->i_iopen_gh.gh_gl->gl_object = ip; | 198 | ip->i_iopen_gh.gh_gl->gl_object = ip; |
199 | 199 | ||
200 | gfs2_glock_put(io_gl); | 200 | gfs2_glock_put(io_gl); |
201 | io_gl = NULL; | ||
201 | 202 | ||
202 | if ((type == DT_UNKNOWN) && (no_formal_ino == 0)) | 203 | if ((type == DT_UNKNOWN) && (no_formal_ino == 0)) |
203 | goto gfs2_nfsbypass; | 204 | goto gfs2_nfsbypass; |
@@ -228,7 +229,8 @@ gfs2_nfsbypass: | |||
228 | fail_glock: | 229 | fail_glock: |
229 | gfs2_glock_dq(&ip->i_iopen_gh); | 230 | gfs2_glock_dq(&ip->i_iopen_gh); |
230 | fail_iopen: | 231 | fail_iopen: |
231 | gfs2_glock_put(io_gl); | 232 | if (io_gl) |
233 | gfs2_glock_put(io_gl); | ||
232 | fail_put: | 234 | fail_put: |
233 | if (inode->i_state & I_NEW) | 235 | if (inode->i_state & I_NEW) |
234 | ip->i_gl->gl_object = NULL; | 236 | ip->i_gl->gl_object = NULL; |
@@ -256,7 +258,7 @@ void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr) | |||
256 | { | 258 | { |
257 | struct gfs2_sbd *sdp; | 259 | struct gfs2_sbd *sdp; |
258 | struct gfs2_inode *ip; | 260 | struct gfs2_inode *ip; |
259 | struct gfs2_glock *io_gl; | 261 | struct gfs2_glock *io_gl = NULL; |
260 | int error; | 262 | int error; |
261 | struct gfs2_holder gh; | 263 | struct gfs2_holder gh; |
262 | struct inode *inode; | 264 | struct inode *inode; |
@@ -293,6 +295,7 @@ void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr) | |||
293 | 295 | ||
294 | ip->i_iopen_gh.gh_gl->gl_object = ip; | 296 | ip->i_iopen_gh.gh_gl->gl_object = ip; |
295 | gfs2_glock_put(io_gl); | 297 | gfs2_glock_put(io_gl); |
298 | io_gl = NULL; | ||
296 | 299 | ||
297 | inode->i_mode = DT2IF(DT_UNKNOWN); | 300 | inode->i_mode = DT2IF(DT_UNKNOWN); |
298 | 301 | ||
@@ -319,7 +322,8 @@ void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr) | |||
319 | fail_glock: | 322 | fail_glock: |
320 | gfs2_glock_dq(&ip->i_iopen_gh); | 323 | gfs2_glock_dq(&ip->i_iopen_gh); |
321 | fail_iopen: | 324 | fail_iopen: |
322 | gfs2_glock_put(io_gl); | 325 | if (io_gl) |
326 | gfs2_glock_put(io_gl); | ||
323 | fail_put: | 327 | fail_put: |
324 | ip->i_gl->gl_object = NULL; | 328 | ip->i_gl->gl_object = NULL; |
325 | gfs2_glock_put(ip->i_gl); | 329 | gfs2_glock_put(ip->i_gl); |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 49667d68769e..b256d6f24288 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -694,10 +694,8 @@ get_a_page: | |||
694 | if (!buffer_mapped(bh)) | 694 | if (!buffer_mapped(bh)) |
695 | goto unlock_out; | 695 | goto unlock_out; |
696 | /* If it's a newly allocated disk block for quota, zero it */ | 696 | /* If it's a newly allocated disk block for quota, zero it */ |
697 | if (buffer_new(bh)) { | 697 | if (buffer_new(bh)) |
698 | memset(bh->b_data, 0, bh->b_size); | 698 | zero_user(page, pos - blocksize, bh->b_size); |
699 | set_buffer_uptodate(bh); | ||
700 | } | ||
701 | } | 699 | } |
702 | 700 | ||
703 | if (PageUptodate(page)) | 701 | if (PageUptodate(page)) |
@@ -723,7 +721,7 @@ get_a_page: | |||
723 | 721 | ||
724 | /* If quota straddles page boundary, we need to update the rest of the | 722 | /* If quota straddles page boundary, we need to update the rest of the |
725 | * quota at the beginning of the next page */ | 723 | * quota at the beginning of the next page */ |
726 | if (offset != 0) { /* first page, offset is closer to PAGE_CACHE_SIZE */ | 724 | if ((offset + sizeof(struct gfs2_quota)) > PAGE_CACHE_SIZE) { |
727 | ptr = ptr + nbytes; | 725 | ptr = ptr + nbytes; |
728 | nbytes = sizeof(struct gfs2_quota) - nbytes; | 726 | nbytes = sizeof(struct gfs2_quota) - nbytes; |
729 | offset = 0; | 727 | offset = 0; |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index bc2ff5932769..036880895bfc 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -297,7 +297,6 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, | |||
297 | struct page *new_page; | 297 | struct page *new_page; |
298 | unsigned int new_offset; | 298 | unsigned int new_offset; |
299 | struct buffer_head *bh_in = jh2bh(jh_in); | 299 | struct buffer_head *bh_in = jh2bh(jh_in); |
300 | struct jbd2_buffer_trigger_type *triggers; | ||
301 | journal_t *journal = transaction->t_journal; | 300 | journal_t *journal = transaction->t_journal; |
302 | 301 | ||
303 | /* | 302 | /* |
@@ -328,21 +327,21 @@ repeat: | |||
328 | done_copy_out = 1; | 327 | done_copy_out = 1; |
329 | new_page = virt_to_page(jh_in->b_frozen_data); | 328 | new_page = virt_to_page(jh_in->b_frozen_data); |
330 | new_offset = offset_in_page(jh_in->b_frozen_data); | 329 | new_offset = offset_in_page(jh_in->b_frozen_data); |
331 | triggers = jh_in->b_frozen_triggers; | ||
332 | } else { | 330 | } else { |
333 | new_page = jh2bh(jh_in)->b_page; | 331 | new_page = jh2bh(jh_in)->b_page; |
334 | new_offset = offset_in_page(jh2bh(jh_in)->b_data); | 332 | new_offset = offset_in_page(jh2bh(jh_in)->b_data); |
335 | triggers = jh_in->b_triggers; | ||
336 | } | 333 | } |
337 | 334 | ||
338 | mapped_data = kmap_atomic(new_page, KM_USER0); | 335 | mapped_data = kmap_atomic(new_page, KM_USER0); |
339 | /* | 336 | /* |
340 | * Fire any commit trigger. Do this before checking for escaping, | 337 | * Fire data frozen trigger if data already wasn't frozen. Do this |
341 | * as the trigger may modify the magic offset. If a copy-out | 338 | * before checking for escaping, as the trigger may modify the magic |
342 | * happens afterwards, it will have the correct data in the buffer. | 339 | * offset. If a copy-out happens afterwards, it will have the correct |
340 | * data in the buffer. | ||
343 | */ | 341 | */ |
344 | jbd2_buffer_commit_trigger(jh_in, mapped_data + new_offset, | 342 | if (!done_copy_out) |
345 | triggers); | 343 | jbd2_buffer_frozen_trigger(jh_in, mapped_data + new_offset, |
344 | jh_in->b_triggers); | ||
346 | 345 | ||
347 | /* | 346 | /* |
348 | * Check for escaping | 347 | * Check for escaping |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index e214d68620ac..b8e0806681bb 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -725,6 +725,9 @@ done: | |||
725 | page = jh2bh(jh)->b_page; | 725 | page = jh2bh(jh)->b_page; |
726 | offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK; | 726 | offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK; |
727 | source = kmap_atomic(page, KM_USER0); | 727 | source = kmap_atomic(page, KM_USER0); |
728 | /* Fire data frozen trigger just before we copy the data */ | ||
729 | jbd2_buffer_frozen_trigger(jh, source + offset, | ||
730 | jh->b_triggers); | ||
728 | memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size); | 731 | memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size); |
729 | kunmap_atomic(source, KM_USER0); | 732 | kunmap_atomic(source, KM_USER0); |
730 | 733 | ||
@@ -963,15 +966,15 @@ void jbd2_journal_set_triggers(struct buffer_head *bh, | |||
963 | jh->b_triggers = type; | 966 | jh->b_triggers = type; |
964 | } | 967 | } |
965 | 968 | ||
966 | void jbd2_buffer_commit_trigger(struct journal_head *jh, void *mapped_data, | 969 | void jbd2_buffer_frozen_trigger(struct journal_head *jh, void *mapped_data, |
967 | struct jbd2_buffer_trigger_type *triggers) | 970 | struct jbd2_buffer_trigger_type *triggers) |
968 | { | 971 | { |
969 | struct buffer_head *bh = jh2bh(jh); | 972 | struct buffer_head *bh = jh2bh(jh); |
970 | 973 | ||
971 | if (!triggers || !triggers->t_commit) | 974 | if (!triggers || !triggers->t_frozen) |
972 | return; | 975 | return; |
973 | 976 | ||
974 | triggers->t_commit(triggers, bh, mapped_data, bh->b_size); | 977 | triggers->t_frozen(triggers, bh, mapped_data, bh->b_size); |
975 | } | 978 | } |
976 | 979 | ||
977 | void jbd2_buffer_abort_trigger(struct journal_head *jh, | 980 | void jbd2_buffer_abort_trigger(struct journal_head *jh, |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 3623ca20cc18..356e976772bf 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -196,15 +196,14 @@ int ocfs2_get_block(struct inode *inode, sector_t iblock, | |||
196 | dump_stack(); | 196 | dump_stack(); |
197 | goto bail; | 197 | goto bail; |
198 | } | 198 | } |
199 | |||
200 | past_eof = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode)); | ||
201 | mlog(0, "Inode %lu, past_eof = %llu\n", inode->i_ino, | ||
202 | (unsigned long long)past_eof); | ||
203 | |||
204 | if (create && (iblock >= past_eof)) | ||
205 | set_buffer_new(bh_result); | ||
206 | } | 199 | } |
207 | 200 | ||
201 | past_eof = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode)); | ||
202 | mlog(0, "Inode %lu, past_eof = %llu\n", inode->i_ino, | ||
203 | (unsigned long long)past_eof); | ||
204 | if (create && (iblock >= past_eof)) | ||
205 | set_buffer_new(bh_result); | ||
206 | |||
208 | bail: | 207 | bail: |
209 | if (err < 0) | 208 | if (err < 0) |
210 | err = -EIO; | 209 | err = -EIO; |
@@ -459,36 +458,6 @@ int walk_page_buffers( handle_t *handle, | |||
459 | return ret; | 458 | return ret; |
460 | } | 459 | } |
461 | 460 | ||
462 | handle_t *ocfs2_start_walk_page_trans(struct inode *inode, | ||
463 | struct page *page, | ||
464 | unsigned from, | ||
465 | unsigned to) | ||
466 | { | ||
467 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
468 | handle_t *handle; | ||
469 | int ret = 0; | ||
470 | |||
471 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | ||
472 | if (IS_ERR(handle)) { | ||
473 | ret = -ENOMEM; | ||
474 | mlog_errno(ret); | ||
475 | goto out; | ||
476 | } | ||
477 | |||
478 | if (ocfs2_should_order_data(inode)) { | ||
479 | ret = ocfs2_jbd2_file_inode(handle, inode); | ||
480 | if (ret < 0) | ||
481 | mlog_errno(ret); | ||
482 | } | ||
483 | out: | ||
484 | if (ret) { | ||
485 | if (!IS_ERR(handle)) | ||
486 | ocfs2_commit_trans(osb, handle); | ||
487 | handle = ERR_PTR(ret); | ||
488 | } | ||
489 | return handle; | ||
490 | } | ||
491 | |||
492 | static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block) | 461 | static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block) |
493 | { | 462 | { |
494 | sector_t status; | 463 | sector_t status; |
@@ -1131,23 +1100,37 @@ out: | |||
1131 | */ | 1100 | */ |
1132 | static int ocfs2_grab_pages_for_write(struct address_space *mapping, | 1101 | static int ocfs2_grab_pages_for_write(struct address_space *mapping, |
1133 | struct ocfs2_write_ctxt *wc, | 1102 | struct ocfs2_write_ctxt *wc, |
1134 | u32 cpos, loff_t user_pos, int new, | 1103 | u32 cpos, loff_t user_pos, |
1104 | unsigned user_len, int new, | ||
1135 | struct page *mmap_page) | 1105 | struct page *mmap_page) |
1136 | { | 1106 | { |
1137 | int ret = 0, i; | 1107 | int ret = 0, i; |
1138 | unsigned long start, target_index, index; | 1108 | unsigned long start, target_index, end_index, index; |
1139 | struct inode *inode = mapping->host; | 1109 | struct inode *inode = mapping->host; |
1110 | loff_t last_byte; | ||
1140 | 1111 | ||
1141 | target_index = user_pos >> PAGE_CACHE_SHIFT; | 1112 | target_index = user_pos >> PAGE_CACHE_SHIFT; |
1142 | 1113 | ||
1143 | /* | 1114 | /* |
1144 | * Figure out how many pages we'll be manipulating here. For | 1115 | * Figure out how many pages we'll be manipulating here. For |
1145 | * non allocating write, we just change the one | 1116 | * non allocating write, we just change the one |
1146 | * page. Otherwise, we'll need a whole clusters worth. | 1117 | * page. Otherwise, we'll need a whole clusters worth. If we're |
1118 | * writing past i_size, we only need enough pages to cover the | ||
1119 | * last page of the write. | ||
1147 | */ | 1120 | */ |
1148 | if (new) { | 1121 | if (new) { |
1149 | wc->w_num_pages = ocfs2_pages_per_cluster(inode->i_sb); | 1122 | wc->w_num_pages = ocfs2_pages_per_cluster(inode->i_sb); |
1150 | start = ocfs2_align_clusters_to_page_index(inode->i_sb, cpos); | 1123 | start = ocfs2_align_clusters_to_page_index(inode->i_sb, cpos); |
1124 | /* | ||
1125 | * We need the index *past* the last page we could possibly | ||
1126 | * touch. This is the page past the end of the write or | ||
1127 | * i_size, whichever is greater. | ||
1128 | */ | ||
1129 | last_byte = max(user_pos + user_len, i_size_read(inode)); | ||
1130 | BUG_ON(last_byte < 1); | ||
1131 | end_index = ((last_byte - 1) >> PAGE_CACHE_SHIFT) + 1; | ||
1132 | if ((start + wc->w_num_pages) > end_index) | ||
1133 | wc->w_num_pages = end_index - start; | ||
1151 | } else { | 1134 | } else { |
1152 | wc->w_num_pages = 1; | 1135 | wc->w_num_pages = 1; |
1153 | start = target_index; | 1136 | start = target_index; |
@@ -1620,21 +1603,20 @@ out: | |||
1620 | * write path can treat it as an non-allocating write, which has no | 1603 | * write path can treat it as an non-allocating write, which has no |
1621 | * special case code for sparse/nonsparse files. | 1604 | * special case code for sparse/nonsparse files. |
1622 | */ | 1605 | */ |
1623 | static int ocfs2_expand_nonsparse_inode(struct inode *inode, loff_t pos, | 1606 | static int ocfs2_expand_nonsparse_inode(struct inode *inode, |
1624 | unsigned len, | 1607 | struct buffer_head *di_bh, |
1608 | loff_t pos, unsigned len, | ||
1625 | struct ocfs2_write_ctxt *wc) | 1609 | struct ocfs2_write_ctxt *wc) |
1626 | { | 1610 | { |
1627 | int ret; | 1611 | int ret; |
1628 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
1629 | loff_t newsize = pos + len; | 1612 | loff_t newsize = pos + len; |
1630 | 1613 | ||
1631 | if (ocfs2_sparse_alloc(osb)) | 1614 | BUG_ON(ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))); |
1632 | return 0; | ||
1633 | 1615 | ||
1634 | if (newsize <= i_size_read(inode)) | 1616 | if (newsize <= i_size_read(inode)) |
1635 | return 0; | 1617 | return 0; |
1636 | 1618 | ||
1637 | ret = ocfs2_extend_no_holes(inode, newsize, pos); | 1619 | ret = ocfs2_extend_no_holes(inode, di_bh, newsize, pos); |
1638 | if (ret) | 1620 | if (ret) |
1639 | mlog_errno(ret); | 1621 | mlog_errno(ret); |
1640 | 1622 | ||
@@ -1644,6 +1626,18 @@ static int ocfs2_expand_nonsparse_inode(struct inode *inode, loff_t pos, | |||
1644 | return ret; | 1626 | return ret; |
1645 | } | 1627 | } |
1646 | 1628 | ||
1629 | static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh, | ||
1630 | loff_t pos) | ||
1631 | { | ||
1632 | int ret = 0; | ||
1633 | |||
1634 | BUG_ON(!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))); | ||
1635 | if (pos > i_size_read(inode)) | ||
1636 | ret = ocfs2_zero_extend(inode, di_bh, pos); | ||
1637 | |||
1638 | return ret; | ||
1639 | } | ||
1640 | |||
1647 | int ocfs2_write_begin_nolock(struct address_space *mapping, | 1641 | int ocfs2_write_begin_nolock(struct address_space *mapping, |
1648 | loff_t pos, unsigned len, unsigned flags, | 1642 | loff_t pos, unsigned len, unsigned flags, |
1649 | struct page **pagep, void **fsdata, | 1643 | struct page **pagep, void **fsdata, |
@@ -1679,7 +1673,11 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
1679 | } | 1673 | } |
1680 | } | 1674 | } |
1681 | 1675 | ||
1682 | ret = ocfs2_expand_nonsparse_inode(inode, pos, len, wc); | 1676 | if (ocfs2_sparse_alloc(osb)) |
1677 | ret = ocfs2_zero_tail(inode, di_bh, pos); | ||
1678 | else | ||
1679 | ret = ocfs2_expand_nonsparse_inode(inode, di_bh, pos, len, | ||
1680 | wc); | ||
1683 | if (ret) { | 1681 | if (ret) { |
1684 | mlog_errno(ret); | 1682 | mlog_errno(ret); |
1685 | goto out; | 1683 | goto out; |
@@ -1789,7 +1787,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, | |||
1789 | * that we can zero and flush if we error after adding the | 1787 | * that we can zero and flush if we error after adding the |
1790 | * extent. | 1788 | * extent. |
1791 | */ | 1789 | */ |
1792 | ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, | 1790 | ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len, |
1793 | cluster_of_pages, mmap_page); | 1791 | cluster_of_pages, mmap_page); |
1794 | if (ret) { | 1792 | if (ret) { |
1795 | mlog_errno(ret); | 1793 | mlog_errno(ret); |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 6b5a492e1749..153abb5abef0 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
@@ -1671,7 +1671,7 @@ struct dlm_ctxt * dlm_register_domain(const char *domain, | |||
1671 | struct dlm_ctxt *dlm = NULL; | 1671 | struct dlm_ctxt *dlm = NULL; |
1672 | struct dlm_ctxt *new_ctxt = NULL; | 1672 | struct dlm_ctxt *new_ctxt = NULL; |
1673 | 1673 | ||
1674 | if (strlen(domain) > O2NM_MAX_NAME_LEN) { | 1674 | if (strlen(domain) >= O2NM_MAX_NAME_LEN) { |
1675 | ret = -ENAMETOOLONG; | 1675 | ret = -ENAMETOOLONG; |
1676 | mlog(ML_ERROR, "domain name length too long\n"); | 1676 | mlog(ML_ERROR, "domain name length too long\n"); |
1677 | goto leave; | 1677 | goto leave; |
@@ -1709,6 +1709,7 @@ retry: | |||
1709 | } | 1709 | } |
1710 | 1710 | ||
1711 | if (dlm_protocol_compare(&dlm->fs_locking_proto, fs_proto)) { | 1711 | if (dlm_protocol_compare(&dlm->fs_locking_proto, fs_proto)) { |
1712 | spin_unlock(&dlm_domain_lock); | ||
1712 | mlog(ML_ERROR, | 1713 | mlog(ML_ERROR, |
1713 | "Requested locking protocol version is not " | 1714 | "Requested locking protocol version is not " |
1714 | "compatible with already registered domain " | 1715 | "compatible with already registered domain " |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 4a7506a4e314..94b97fc6a88e 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -2808,14 +2808,8 @@ again: | |||
2808 | mlog(0, "trying again...\n"); | 2808 | mlog(0, "trying again...\n"); |
2809 | goto again; | 2809 | goto again; |
2810 | } | 2810 | } |
2811 | /* now that we are sure the MIGRATING state is there, drop | ||
2812 | * the unneded state which blocked threads trying to DIRTY */ | ||
2813 | spin_lock(&res->spinlock); | ||
2814 | BUG_ON(!(res->state & DLM_LOCK_RES_BLOCK_DIRTY)); | ||
2815 | BUG_ON(!(res->state & DLM_LOCK_RES_MIGRATING)); | ||
2816 | res->state &= ~DLM_LOCK_RES_BLOCK_DIRTY; | ||
2817 | spin_unlock(&res->spinlock); | ||
2818 | 2811 | ||
2812 | ret = 0; | ||
2819 | /* did the target go down or die? */ | 2813 | /* did the target go down or die? */ |
2820 | spin_lock(&dlm->spinlock); | 2814 | spin_lock(&dlm->spinlock); |
2821 | if (!test_bit(target, dlm->domain_map)) { | 2815 | if (!test_bit(target, dlm->domain_map)) { |
@@ -2826,9 +2820,21 @@ again: | |||
2826 | spin_unlock(&dlm->spinlock); | 2820 | spin_unlock(&dlm->spinlock); |
2827 | 2821 | ||
2828 | /* | 2822 | /* |
2823 | * if target is down, we need to clear DLM_LOCK_RES_BLOCK_DIRTY for | ||
2824 | * another try; otherwise, we are sure the MIGRATING state is there, | ||
2825 | * drop the unneded state which blocked threads trying to DIRTY | ||
2826 | */ | ||
2827 | spin_lock(&res->spinlock); | ||
2828 | BUG_ON(!(res->state & DLM_LOCK_RES_BLOCK_DIRTY)); | ||
2829 | res->state &= ~DLM_LOCK_RES_BLOCK_DIRTY; | ||
2830 | if (!ret) | ||
2831 | BUG_ON(!(res->state & DLM_LOCK_RES_MIGRATING)); | ||
2832 | spin_unlock(&res->spinlock); | ||
2833 | |||
2834 | /* | ||
2829 | * at this point: | 2835 | * at this point: |
2830 | * | 2836 | * |
2831 | * o the DLM_LOCK_RES_MIGRATING flag is set | 2837 | * o the DLM_LOCK_RES_MIGRATING flag is set if target not down |
2832 | * o there are no pending asts on this lockres | 2838 | * o there are no pending asts on this lockres |
2833 | * o all processes trying to reserve an ast on this | 2839 | * o all processes trying to reserve an ast on this |
2834 | * lockres must wait for the MIGRATING flag to clear | 2840 | * lockres must wait for the MIGRATING flag to clear |
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index f8b75ce4be70..9dfaac73b36d 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
@@ -463,7 +463,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) | |||
463 | if (dlm->reco.dead_node == O2NM_INVALID_NODE_NUM) { | 463 | if (dlm->reco.dead_node == O2NM_INVALID_NODE_NUM) { |
464 | int bit; | 464 | int bit; |
465 | 465 | ||
466 | bit = find_next_bit (dlm->recovery_map, O2NM_MAX_NODES+1, 0); | 466 | bit = find_next_bit (dlm->recovery_map, O2NM_MAX_NODES, 0); |
467 | if (bit >= O2NM_MAX_NODES || bit < 0) | 467 | if (bit >= O2NM_MAX_NODES || bit < 0) |
468 | dlm_set_reco_dead_node(dlm, O2NM_INVALID_NODE_NUM); | 468 | dlm_set_reco_dead_node(dlm, O2NM_INVALID_NODE_NUM); |
469 | else | 469 | else |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 6a13ea64c447..2b10b36d1577 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -724,28 +724,55 @@ leave: | |||
724 | return status; | 724 | return status; |
725 | } | 725 | } |
726 | 726 | ||
727 | /* | ||
728 | * While a write will already be ordering the data, a truncate will not. | ||
729 | * Thus, we need to explicitly order the zeroed pages. | ||
730 | */ | ||
731 | static handle_t *ocfs2_zero_start_ordered_transaction(struct inode *inode) | ||
732 | { | ||
733 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
734 | handle_t *handle = NULL; | ||
735 | int ret = 0; | ||
736 | |||
737 | if (!ocfs2_should_order_data(inode)) | ||
738 | goto out; | ||
739 | |||
740 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | ||
741 | if (IS_ERR(handle)) { | ||
742 | ret = -ENOMEM; | ||
743 | mlog_errno(ret); | ||
744 | goto out; | ||
745 | } | ||
746 | |||
747 | ret = ocfs2_jbd2_file_inode(handle, inode); | ||
748 | if (ret < 0) | ||
749 | mlog_errno(ret); | ||
750 | |||
751 | out: | ||
752 | if (ret) { | ||
753 | if (!IS_ERR(handle)) | ||
754 | ocfs2_commit_trans(osb, handle); | ||
755 | handle = ERR_PTR(ret); | ||
756 | } | ||
757 | return handle; | ||
758 | } | ||
759 | |||
727 | /* Some parts of this taken from generic_cont_expand, which turned out | 760 | /* Some parts of this taken from generic_cont_expand, which turned out |
728 | * to be too fragile to do exactly what we need without us having to | 761 | * to be too fragile to do exactly what we need without us having to |
729 | * worry about recursive locking in ->write_begin() and ->write_end(). */ | 762 | * worry about recursive locking in ->write_begin() and ->write_end(). */ |
730 | static int ocfs2_write_zero_page(struct inode *inode, | 763 | static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, |
731 | u64 size) | 764 | u64 abs_to) |
732 | { | 765 | { |
733 | struct address_space *mapping = inode->i_mapping; | 766 | struct address_space *mapping = inode->i_mapping; |
734 | struct page *page; | 767 | struct page *page; |
735 | unsigned long index; | 768 | unsigned long index = abs_from >> PAGE_CACHE_SHIFT; |
736 | unsigned int offset; | ||
737 | handle_t *handle = NULL; | 769 | handle_t *handle = NULL; |
738 | int ret; | 770 | int ret = 0; |
771 | unsigned zero_from, zero_to, block_start, block_end; | ||
739 | 772 | ||
740 | offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */ | 773 | BUG_ON(abs_from >= abs_to); |
741 | /* ugh. in prepare/commit_write, if from==to==start of block, we | 774 | BUG_ON(abs_to > (((u64)index + 1) << PAGE_CACHE_SHIFT)); |
742 | ** skip the prepare. make sure we never send an offset for the start | 775 | BUG_ON(abs_from & (inode->i_blkbits - 1)); |
743 | ** of a block | ||
744 | */ | ||
745 | if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) { | ||
746 | offset++; | ||
747 | } | ||
748 | index = size >> PAGE_CACHE_SHIFT; | ||
749 | 776 | ||
750 | page = grab_cache_page(mapping, index); | 777 | page = grab_cache_page(mapping, index); |
751 | if (!page) { | 778 | if (!page) { |
@@ -754,31 +781,56 @@ static int ocfs2_write_zero_page(struct inode *inode, | |||
754 | goto out; | 781 | goto out; |
755 | } | 782 | } |
756 | 783 | ||
757 | ret = ocfs2_prepare_write_nolock(inode, page, offset, offset); | 784 | /* Get the offsets within the page that we want to zero */ |
758 | if (ret < 0) { | 785 | zero_from = abs_from & (PAGE_CACHE_SIZE - 1); |
759 | mlog_errno(ret); | 786 | zero_to = abs_to & (PAGE_CACHE_SIZE - 1); |
760 | goto out_unlock; | 787 | if (!zero_to) |
761 | } | 788 | zero_to = PAGE_CACHE_SIZE; |
762 | 789 | ||
763 | if (ocfs2_should_order_data(inode)) { | 790 | mlog(0, |
764 | handle = ocfs2_start_walk_page_trans(inode, page, offset, | 791 | "abs_from = %llu, abs_to = %llu, index = %lu, zero_from = %u, zero_to = %u\n", |
765 | offset); | 792 | (unsigned long long)abs_from, (unsigned long long)abs_to, |
766 | if (IS_ERR(handle)) { | 793 | index, zero_from, zero_to); |
767 | ret = PTR_ERR(handle); | 794 | |
768 | handle = NULL; | 795 | /* We know that zero_from is block aligned */ |
796 | for (block_start = zero_from; block_start < zero_to; | ||
797 | block_start = block_end) { | ||
798 | block_end = block_start + (1 << inode->i_blkbits); | ||
799 | |||
800 | /* | ||
801 | * block_start is block-aligned. Bump it by one to | ||
802 | * force ocfs2_{prepare,commit}_write() to zero the | ||
803 | * whole block. | ||
804 | */ | ||
805 | ret = ocfs2_prepare_write_nolock(inode, page, | ||
806 | block_start + 1, | ||
807 | block_start + 1); | ||
808 | if (ret < 0) { | ||
809 | mlog_errno(ret); | ||
769 | goto out_unlock; | 810 | goto out_unlock; |
770 | } | 811 | } |
771 | } | ||
772 | 812 | ||
773 | /* must not update i_size! */ | 813 | if (!handle) { |
774 | ret = block_commit_write(page, offset, offset); | 814 | handle = ocfs2_zero_start_ordered_transaction(inode); |
775 | if (ret < 0) | 815 | if (IS_ERR(handle)) { |
776 | mlog_errno(ret); | 816 | ret = PTR_ERR(handle); |
777 | else | 817 | handle = NULL; |
778 | ret = 0; | 818 | break; |
819 | } | ||
820 | } | ||
821 | |||
822 | /* must not update i_size! */ | ||
823 | ret = block_commit_write(page, block_start + 1, | ||
824 | block_start + 1); | ||
825 | if (ret < 0) | ||
826 | mlog_errno(ret); | ||
827 | else | ||
828 | ret = 0; | ||
829 | } | ||
779 | 830 | ||
780 | if (handle) | 831 | if (handle) |
781 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | 832 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
833 | |||
782 | out_unlock: | 834 | out_unlock: |
783 | unlock_page(page); | 835 | unlock_page(page); |
784 | page_cache_release(page); | 836 | page_cache_release(page); |
@@ -786,22 +838,114 @@ out: | |||
786 | return ret; | 838 | return ret; |
787 | } | 839 | } |
788 | 840 | ||
789 | static int ocfs2_zero_extend(struct inode *inode, | 841 | /* |
790 | u64 zero_to_size) | 842 | * Find the next range to zero. We do this in terms of bytes because |
843 | * that's what ocfs2_zero_extend() wants, and it is dealing with the | ||
844 | * pagecache. We may return multiple extents. | ||
845 | * | ||
846 | * zero_start and zero_end are ocfs2_zero_extend()s current idea of what | ||
847 | * needs to be zeroed. range_start and range_end return the next zeroing | ||
848 | * range. A subsequent call should pass the previous range_end as its | ||
849 | * zero_start. If range_end is 0, there's nothing to do. | ||
850 | * | ||
851 | * Unwritten extents are skipped over. Refcounted extents are CoWd. | ||
852 | */ | ||
853 | static int ocfs2_zero_extend_get_range(struct inode *inode, | ||
854 | struct buffer_head *di_bh, | ||
855 | u64 zero_start, u64 zero_end, | ||
856 | u64 *range_start, u64 *range_end) | ||
791 | { | 857 | { |
792 | int ret = 0; | 858 | int rc = 0, needs_cow = 0; |
793 | u64 start_off; | 859 | u32 p_cpos, zero_clusters = 0; |
794 | struct super_block *sb = inode->i_sb; | 860 | u32 zero_cpos = |
861 | zero_start >> OCFS2_SB(inode->i_sb)->s_clustersize_bits; | ||
862 | u32 last_cpos = ocfs2_clusters_for_bytes(inode->i_sb, zero_end); | ||
863 | unsigned int num_clusters = 0; | ||
864 | unsigned int ext_flags = 0; | ||
795 | 865 | ||
796 | start_off = ocfs2_align_bytes_to_blocks(sb, i_size_read(inode)); | 866 | while (zero_cpos < last_cpos) { |
797 | while (start_off < zero_to_size) { | 867 | rc = ocfs2_get_clusters(inode, zero_cpos, &p_cpos, |
798 | ret = ocfs2_write_zero_page(inode, start_off); | 868 | &num_clusters, &ext_flags); |
799 | if (ret < 0) { | 869 | if (rc) { |
800 | mlog_errno(ret); | 870 | mlog_errno(rc); |
871 | goto out; | ||
872 | } | ||
873 | |||
874 | if (p_cpos && !(ext_flags & OCFS2_EXT_UNWRITTEN)) { | ||
875 | zero_clusters = num_clusters; | ||
876 | if (ext_flags & OCFS2_EXT_REFCOUNTED) | ||
877 | needs_cow = 1; | ||
878 | break; | ||
879 | } | ||
880 | |||
881 | zero_cpos += num_clusters; | ||
882 | } | ||
883 | if (!zero_clusters) { | ||
884 | *range_end = 0; | ||
885 | goto out; | ||
886 | } | ||
887 | |||
888 | while ((zero_cpos + zero_clusters) < last_cpos) { | ||
889 | rc = ocfs2_get_clusters(inode, zero_cpos + zero_clusters, | ||
890 | &p_cpos, &num_clusters, | ||
891 | &ext_flags); | ||
892 | if (rc) { | ||
893 | mlog_errno(rc); | ||
801 | goto out; | 894 | goto out; |
802 | } | 895 | } |
803 | 896 | ||
804 | start_off += sb->s_blocksize; | 897 | if (!p_cpos || (ext_flags & OCFS2_EXT_UNWRITTEN)) |
898 | break; | ||
899 | if (ext_flags & OCFS2_EXT_REFCOUNTED) | ||
900 | needs_cow = 1; | ||
901 | zero_clusters += num_clusters; | ||
902 | } | ||
903 | if ((zero_cpos + zero_clusters) > last_cpos) | ||
904 | zero_clusters = last_cpos - zero_cpos; | ||
905 | |||
906 | if (needs_cow) { | ||
907 | rc = ocfs2_refcount_cow(inode, di_bh, zero_cpos, zero_clusters, | ||
908 | UINT_MAX); | ||
909 | if (rc) { | ||
910 | mlog_errno(rc); | ||
911 | goto out; | ||
912 | } | ||
913 | } | ||
914 | |||
915 | *range_start = ocfs2_clusters_to_bytes(inode->i_sb, zero_cpos); | ||
916 | *range_end = ocfs2_clusters_to_bytes(inode->i_sb, | ||
917 | zero_cpos + zero_clusters); | ||
918 | |||
919 | out: | ||
920 | return rc; | ||
921 | } | ||
922 | |||
923 | /* | ||
924 | * Zero one range returned from ocfs2_zero_extend_get_range(). The caller | ||
925 | * has made sure that the entire range needs zeroing. | ||
926 | */ | ||
927 | static int ocfs2_zero_extend_range(struct inode *inode, u64 range_start, | ||
928 | u64 range_end) | ||
929 | { | ||
930 | int rc = 0; | ||
931 | u64 next_pos; | ||
932 | u64 zero_pos = range_start; | ||
933 | |||
934 | mlog(0, "range_start = %llu, range_end = %llu\n", | ||
935 | (unsigned long long)range_start, | ||
936 | (unsigned long long)range_end); | ||
937 | BUG_ON(range_start >= range_end); | ||
938 | |||
939 | while (zero_pos < range_end) { | ||
940 | next_pos = (zero_pos & PAGE_CACHE_MASK) + PAGE_CACHE_SIZE; | ||
941 | if (next_pos > range_end) | ||
942 | next_pos = range_end; | ||
943 | rc = ocfs2_write_zero_page(inode, zero_pos, next_pos); | ||
944 | if (rc < 0) { | ||
945 | mlog_errno(rc); | ||
946 | break; | ||
947 | } | ||
948 | zero_pos = next_pos; | ||
805 | 949 | ||
806 | /* | 950 | /* |
807 | * Very large extends have the potential to lock up | 951 | * Very large extends have the potential to lock up |
@@ -810,16 +954,63 @@ static int ocfs2_zero_extend(struct inode *inode, | |||
810 | cond_resched(); | 954 | cond_resched(); |
811 | } | 955 | } |
812 | 956 | ||
813 | out: | 957 | return rc; |
958 | } | ||
959 | |||
960 | int ocfs2_zero_extend(struct inode *inode, struct buffer_head *di_bh, | ||
961 | loff_t zero_to_size) | ||
962 | { | ||
963 | int ret = 0; | ||
964 | u64 zero_start, range_start = 0, range_end = 0; | ||
965 | struct super_block *sb = inode->i_sb; | ||
966 | |||
967 | zero_start = ocfs2_align_bytes_to_blocks(sb, i_size_read(inode)); | ||
968 | mlog(0, "zero_start %llu for i_size %llu\n", | ||
969 | (unsigned long long)zero_start, | ||
970 | (unsigned long long)i_size_read(inode)); | ||
971 | while (zero_start < zero_to_size) { | ||
972 | ret = ocfs2_zero_extend_get_range(inode, di_bh, zero_start, | ||
973 | zero_to_size, | ||
974 | &range_start, | ||
975 | &range_end); | ||
976 | if (ret) { | ||
977 | mlog_errno(ret); | ||
978 | break; | ||
979 | } | ||
980 | if (!range_end) | ||
981 | break; | ||
982 | /* Trim the ends */ | ||
983 | if (range_start < zero_start) | ||
984 | range_start = zero_start; | ||
985 | if (range_end > zero_to_size) | ||
986 | range_end = zero_to_size; | ||
987 | |||
988 | ret = ocfs2_zero_extend_range(inode, range_start, | ||
989 | range_end); | ||
990 | if (ret) { | ||
991 | mlog_errno(ret); | ||
992 | break; | ||
993 | } | ||
994 | zero_start = range_end; | ||
995 | } | ||
996 | |||
814 | return ret; | 997 | return ret; |
815 | } | 998 | } |
816 | 999 | ||
817 | int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size, u64 zero_to) | 1000 | int ocfs2_extend_no_holes(struct inode *inode, struct buffer_head *di_bh, |
1001 | u64 new_i_size, u64 zero_to) | ||
818 | { | 1002 | { |
819 | int ret; | 1003 | int ret; |
820 | u32 clusters_to_add; | 1004 | u32 clusters_to_add; |
821 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 1005 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
822 | 1006 | ||
1007 | /* | ||
1008 | * Only quota files call this without a bh, and they can't be | ||
1009 | * refcounted. | ||
1010 | */ | ||
1011 | BUG_ON(!di_bh && (oi->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL)); | ||
1012 | BUG_ON(!di_bh && !(oi->ip_flags & OCFS2_INODE_SYSTEM_FILE)); | ||
1013 | |||
823 | clusters_to_add = ocfs2_clusters_for_bytes(inode->i_sb, new_i_size); | 1014 | clusters_to_add = ocfs2_clusters_for_bytes(inode->i_sb, new_i_size); |
824 | if (clusters_to_add < oi->ip_clusters) | 1015 | if (clusters_to_add < oi->ip_clusters) |
825 | clusters_to_add = 0; | 1016 | clusters_to_add = 0; |
@@ -840,7 +1031,7 @@ int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size, u64 zero_to) | |||
840 | * still need to zero the area between the old i_size and the | 1031 | * still need to zero the area between the old i_size and the |
841 | * new i_size. | 1032 | * new i_size. |
842 | */ | 1033 | */ |
843 | ret = ocfs2_zero_extend(inode, zero_to); | 1034 | ret = ocfs2_zero_extend(inode, di_bh, zero_to); |
844 | if (ret < 0) | 1035 | if (ret < 0) |
845 | mlog_errno(ret); | 1036 | mlog_errno(ret); |
846 | 1037 | ||
@@ -862,27 +1053,15 @@ static int ocfs2_extend_file(struct inode *inode, | |||
862 | goto out; | 1053 | goto out; |
863 | 1054 | ||
864 | if (i_size_read(inode) == new_i_size) | 1055 | if (i_size_read(inode) == new_i_size) |
865 | goto out; | 1056 | goto out; |
866 | BUG_ON(new_i_size < i_size_read(inode)); | 1057 | BUG_ON(new_i_size < i_size_read(inode)); |
867 | 1058 | ||
868 | /* | 1059 | /* |
869 | * Fall through for converting inline data, even if the fs | ||
870 | * supports sparse files. | ||
871 | * | ||
872 | * The check for inline data here is legal - nobody can add | ||
873 | * the feature since we have i_mutex. We must check it again | ||
874 | * after acquiring ip_alloc_sem though, as paths like mmap | ||
875 | * might have raced us to converting the inode to extents. | ||
876 | */ | ||
877 | if (!(oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) | ||
878 | && ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) | ||
879 | goto out_update_size; | ||
880 | |||
881 | /* | ||
882 | * The alloc sem blocks people in read/write from reading our | 1060 | * The alloc sem blocks people in read/write from reading our |
883 | * allocation until we're done changing it. We depend on | 1061 | * allocation until we're done changing it. We depend on |
884 | * i_mutex to block other extend/truncate calls while we're | 1062 | * i_mutex to block other extend/truncate calls while we're |
885 | * here. | 1063 | * here. We even have to hold it for sparse files because there |
1064 | * might be some tail zeroing. | ||
886 | */ | 1065 | */ |
887 | down_write(&oi->ip_alloc_sem); | 1066 | down_write(&oi->ip_alloc_sem); |
888 | 1067 | ||
@@ -899,14 +1078,16 @@ static int ocfs2_extend_file(struct inode *inode, | |||
899 | ret = ocfs2_convert_inline_data_to_extents(inode, di_bh); | 1078 | ret = ocfs2_convert_inline_data_to_extents(inode, di_bh); |
900 | if (ret) { | 1079 | if (ret) { |
901 | up_write(&oi->ip_alloc_sem); | 1080 | up_write(&oi->ip_alloc_sem); |
902 | |||
903 | mlog_errno(ret); | 1081 | mlog_errno(ret); |
904 | goto out; | 1082 | goto out; |
905 | } | 1083 | } |
906 | } | 1084 | } |
907 | 1085 | ||
908 | if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) | 1086 | if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) |
909 | ret = ocfs2_extend_no_holes(inode, new_i_size, new_i_size); | 1087 | ret = ocfs2_zero_extend(inode, di_bh, new_i_size); |
1088 | else | ||
1089 | ret = ocfs2_extend_no_holes(inode, di_bh, new_i_size, | ||
1090 | new_i_size); | ||
910 | 1091 | ||
911 | up_write(&oi->ip_alloc_sem); | 1092 | up_write(&oi->ip_alloc_sem); |
912 | 1093 | ||
diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h index d66cf4f7c70e..97bf761c9e7c 100644 --- a/fs/ocfs2/file.h +++ b/fs/ocfs2/file.h | |||
@@ -54,8 +54,10 @@ int ocfs2_add_inode_data(struct ocfs2_super *osb, | |||
54 | int ocfs2_simple_size_update(struct inode *inode, | 54 | int ocfs2_simple_size_update(struct inode *inode, |
55 | struct buffer_head *di_bh, | 55 | struct buffer_head *di_bh, |
56 | u64 new_i_size); | 56 | u64 new_i_size); |
57 | int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size, | 57 | int ocfs2_extend_no_holes(struct inode *inode, struct buffer_head *di_bh, |
58 | u64 zero_to); | 58 | u64 new_i_size, u64 zero_to); |
59 | int ocfs2_zero_extend(struct inode *inode, struct buffer_head *di_bh, | ||
60 | loff_t zero_to); | ||
59 | int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); | 61 | int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); |
60 | int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, | 62 | int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, |
61 | struct kstat *stat); | 63 | struct kstat *stat); |
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 47878cf16418..625de9d7088c 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c | |||
@@ -472,7 +472,7 @@ static inline struct ocfs2_triggers *to_ocfs2_trigger(struct jbd2_buffer_trigger | |||
472 | return container_of(triggers, struct ocfs2_triggers, ot_triggers); | 472 | return container_of(triggers, struct ocfs2_triggers, ot_triggers); |
473 | } | 473 | } |
474 | 474 | ||
475 | static void ocfs2_commit_trigger(struct jbd2_buffer_trigger_type *triggers, | 475 | static void ocfs2_frozen_trigger(struct jbd2_buffer_trigger_type *triggers, |
476 | struct buffer_head *bh, | 476 | struct buffer_head *bh, |
477 | void *data, size_t size) | 477 | void *data, size_t size) |
478 | { | 478 | { |
@@ -491,7 +491,7 @@ static void ocfs2_commit_trigger(struct jbd2_buffer_trigger_type *triggers, | |||
491 | * Quota blocks have their own trigger because the struct ocfs2_block_check | 491 | * Quota blocks have their own trigger because the struct ocfs2_block_check |
492 | * offset depends on the blocksize. | 492 | * offset depends on the blocksize. |
493 | */ | 493 | */ |
494 | static void ocfs2_dq_commit_trigger(struct jbd2_buffer_trigger_type *triggers, | 494 | static void ocfs2_dq_frozen_trigger(struct jbd2_buffer_trigger_type *triggers, |
495 | struct buffer_head *bh, | 495 | struct buffer_head *bh, |
496 | void *data, size_t size) | 496 | void *data, size_t size) |
497 | { | 497 | { |
@@ -511,7 +511,7 @@ static void ocfs2_dq_commit_trigger(struct jbd2_buffer_trigger_type *triggers, | |||
511 | * Directory blocks also have their own trigger because the | 511 | * Directory blocks also have their own trigger because the |
512 | * struct ocfs2_block_check offset depends on the blocksize. | 512 | * struct ocfs2_block_check offset depends on the blocksize. |
513 | */ | 513 | */ |
514 | static void ocfs2_db_commit_trigger(struct jbd2_buffer_trigger_type *triggers, | 514 | static void ocfs2_db_frozen_trigger(struct jbd2_buffer_trigger_type *triggers, |
515 | struct buffer_head *bh, | 515 | struct buffer_head *bh, |
516 | void *data, size_t size) | 516 | void *data, size_t size) |
517 | { | 517 | { |
@@ -544,7 +544,7 @@ static void ocfs2_abort_trigger(struct jbd2_buffer_trigger_type *triggers, | |||
544 | 544 | ||
545 | static struct ocfs2_triggers di_triggers = { | 545 | static struct ocfs2_triggers di_triggers = { |
546 | .ot_triggers = { | 546 | .ot_triggers = { |
547 | .t_commit = ocfs2_commit_trigger, | 547 | .t_frozen = ocfs2_frozen_trigger, |
548 | .t_abort = ocfs2_abort_trigger, | 548 | .t_abort = ocfs2_abort_trigger, |
549 | }, | 549 | }, |
550 | .ot_offset = offsetof(struct ocfs2_dinode, i_check), | 550 | .ot_offset = offsetof(struct ocfs2_dinode, i_check), |
@@ -552,7 +552,7 @@ static struct ocfs2_triggers di_triggers = { | |||
552 | 552 | ||
553 | static struct ocfs2_triggers eb_triggers = { | 553 | static struct ocfs2_triggers eb_triggers = { |
554 | .ot_triggers = { | 554 | .ot_triggers = { |
555 | .t_commit = ocfs2_commit_trigger, | 555 | .t_frozen = ocfs2_frozen_trigger, |
556 | .t_abort = ocfs2_abort_trigger, | 556 | .t_abort = ocfs2_abort_trigger, |
557 | }, | 557 | }, |
558 | .ot_offset = offsetof(struct ocfs2_extent_block, h_check), | 558 | .ot_offset = offsetof(struct ocfs2_extent_block, h_check), |
@@ -560,7 +560,7 @@ static struct ocfs2_triggers eb_triggers = { | |||
560 | 560 | ||
561 | static struct ocfs2_triggers rb_triggers = { | 561 | static struct ocfs2_triggers rb_triggers = { |
562 | .ot_triggers = { | 562 | .ot_triggers = { |
563 | .t_commit = ocfs2_commit_trigger, | 563 | .t_frozen = ocfs2_frozen_trigger, |
564 | .t_abort = ocfs2_abort_trigger, | 564 | .t_abort = ocfs2_abort_trigger, |
565 | }, | 565 | }, |
566 | .ot_offset = offsetof(struct ocfs2_refcount_block, rf_check), | 566 | .ot_offset = offsetof(struct ocfs2_refcount_block, rf_check), |
@@ -568,7 +568,7 @@ static struct ocfs2_triggers rb_triggers = { | |||
568 | 568 | ||
569 | static struct ocfs2_triggers gd_triggers = { | 569 | static struct ocfs2_triggers gd_triggers = { |
570 | .ot_triggers = { | 570 | .ot_triggers = { |
571 | .t_commit = ocfs2_commit_trigger, | 571 | .t_frozen = ocfs2_frozen_trigger, |
572 | .t_abort = ocfs2_abort_trigger, | 572 | .t_abort = ocfs2_abort_trigger, |
573 | }, | 573 | }, |
574 | .ot_offset = offsetof(struct ocfs2_group_desc, bg_check), | 574 | .ot_offset = offsetof(struct ocfs2_group_desc, bg_check), |
@@ -576,14 +576,14 @@ static struct ocfs2_triggers gd_triggers = { | |||
576 | 576 | ||
577 | static struct ocfs2_triggers db_triggers = { | 577 | static struct ocfs2_triggers db_triggers = { |
578 | .ot_triggers = { | 578 | .ot_triggers = { |
579 | .t_commit = ocfs2_db_commit_trigger, | 579 | .t_frozen = ocfs2_db_frozen_trigger, |
580 | .t_abort = ocfs2_abort_trigger, | 580 | .t_abort = ocfs2_abort_trigger, |
581 | }, | 581 | }, |
582 | }; | 582 | }; |
583 | 583 | ||
584 | static struct ocfs2_triggers xb_triggers = { | 584 | static struct ocfs2_triggers xb_triggers = { |
585 | .ot_triggers = { | 585 | .ot_triggers = { |
586 | .t_commit = ocfs2_commit_trigger, | 586 | .t_frozen = ocfs2_frozen_trigger, |
587 | .t_abort = ocfs2_abort_trigger, | 587 | .t_abort = ocfs2_abort_trigger, |
588 | }, | 588 | }, |
589 | .ot_offset = offsetof(struct ocfs2_xattr_block, xb_check), | 589 | .ot_offset = offsetof(struct ocfs2_xattr_block, xb_check), |
@@ -591,14 +591,14 @@ static struct ocfs2_triggers xb_triggers = { | |||
591 | 591 | ||
592 | static struct ocfs2_triggers dq_triggers = { | 592 | static struct ocfs2_triggers dq_triggers = { |
593 | .ot_triggers = { | 593 | .ot_triggers = { |
594 | .t_commit = ocfs2_dq_commit_trigger, | 594 | .t_frozen = ocfs2_dq_frozen_trigger, |
595 | .t_abort = ocfs2_abort_trigger, | 595 | .t_abort = ocfs2_abort_trigger, |
596 | }, | 596 | }, |
597 | }; | 597 | }; |
598 | 598 | ||
599 | static struct ocfs2_triggers dr_triggers = { | 599 | static struct ocfs2_triggers dr_triggers = { |
600 | .ot_triggers = { | 600 | .ot_triggers = { |
601 | .t_commit = ocfs2_commit_trigger, | 601 | .t_frozen = ocfs2_frozen_trigger, |
602 | .t_abort = ocfs2_abort_trigger, | 602 | .t_abort = ocfs2_abort_trigger, |
603 | }, | 603 | }, |
604 | .ot_offset = offsetof(struct ocfs2_dx_root_block, dr_check), | 604 | .ot_offset = offsetof(struct ocfs2_dx_root_block, dr_check), |
@@ -606,7 +606,7 @@ static struct ocfs2_triggers dr_triggers = { | |||
606 | 606 | ||
607 | static struct ocfs2_triggers dl_triggers = { | 607 | static struct ocfs2_triggers dl_triggers = { |
608 | .ot_triggers = { | 608 | .ot_triggers = { |
609 | .t_commit = ocfs2_commit_trigger, | 609 | .t_frozen = ocfs2_frozen_trigger, |
610 | .t_abort = ocfs2_abort_trigger, | 610 | .t_abort = ocfs2_abort_trigger, |
611 | }, | 611 | }, |
612 | .ot_offset = offsetof(struct ocfs2_dx_leaf, dl_check), | 612 | .ot_offset = offsetof(struct ocfs2_dx_leaf, dl_check), |
@@ -1936,7 +1936,7 @@ void ocfs2_orphan_scan_work(struct work_struct *work) | |||
1936 | mutex_lock(&os->os_lock); | 1936 | mutex_lock(&os->os_lock); |
1937 | ocfs2_queue_orphan_scan(osb); | 1937 | ocfs2_queue_orphan_scan(osb); |
1938 | if (atomic_read(&os->os_state) == ORPHAN_SCAN_ACTIVE) | 1938 | if (atomic_read(&os->os_state) == ORPHAN_SCAN_ACTIVE) |
1939 | schedule_delayed_work(&os->os_orphan_scan_work, | 1939 | queue_delayed_work(ocfs2_wq, &os->os_orphan_scan_work, |
1940 | ocfs2_orphan_scan_timeout()); | 1940 | ocfs2_orphan_scan_timeout()); |
1941 | mutex_unlock(&os->os_lock); | 1941 | mutex_unlock(&os->os_lock); |
1942 | } | 1942 | } |
@@ -1976,8 +1976,8 @@ void ocfs2_orphan_scan_start(struct ocfs2_super *osb) | |||
1976 | atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE); | 1976 | atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE); |
1977 | else { | 1977 | else { |
1978 | atomic_set(&os->os_state, ORPHAN_SCAN_ACTIVE); | 1978 | atomic_set(&os->os_state, ORPHAN_SCAN_ACTIVE); |
1979 | schedule_delayed_work(&os->os_orphan_scan_work, | 1979 | queue_delayed_work(ocfs2_wq, &os->os_orphan_scan_work, |
1980 | ocfs2_orphan_scan_timeout()); | 1980 | ocfs2_orphan_scan_timeout()); |
1981 | } | 1981 | } |
1982 | } | 1982 | } |
1983 | 1983 | ||
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index 3d7419682dc0..ec6adbf8f551 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c | |||
@@ -118,6 +118,7 @@ unsigned int ocfs2_la_default_mb(struct ocfs2_super *osb) | |||
118 | { | 118 | { |
119 | unsigned int la_mb; | 119 | unsigned int la_mb; |
120 | unsigned int gd_mb; | 120 | unsigned int gd_mb; |
121 | unsigned int la_max_mb; | ||
121 | unsigned int megs_per_slot; | 122 | unsigned int megs_per_slot; |
122 | struct super_block *sb = osb->sb; | 123 | struct super_block *sb = osb->sb; |
123 | 124 | ||
@@ -182,6 +183,12 @@ unsigned int ocfs2_la_default_mb(struct ocfs2_super *osb) | |||
182 | if (megs_per_slot < la_mb) | 183 | if (megs_per_slot < la_mb) |
183 | la_mb = megs_per_slot; | 184 | la_mb = megs_per_slot; |
184 | 185 | ||
186 | /* We can't store more bits than we can in a block. */ | ||
187 | la_max_mb = ocfs2_clusters_to_megabytes(osb->sb, | ||
188 | ocfs2_local_alloc_size(sb) * 8); | ||
189 | if (la_mb > la_max_mb) | ||
190 | la_mb = la_max_mb; | ||
191 | |||
185 | return la_mb; | 192 | return la_mb; |
186 | } | 193 | } |
187 | 194 | ||
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index 2bb35fe00511..4607923eb24c 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c | |||
@@ -775,7 +775,7 @@ static int ocfs2_acquire_dquot(struct dquot *dquot) | |||
775 | * locking allocators ranks above a transaction start | 775 | * locking allocators ranks above a transaction start |
776 | */ | 776 | */ |
777 | WARN_ON(journal_current_handle()); | 777 | WARN_ON(journal_current_handle()); |
778 | status = ocfs2_extend_no_holes(gqinode, | 778 | status = ocfs2_extend_no_holes(gqinode, NULL, |
779 | gqinode->i_size + (need_alloc << sb->s_blocksize_bits), | 779 | gqinode->i_size + (need_alloc << sb->s_blocksize_bits), |
780 | gqinode->i_size); | 780 | gqinode->i_size); |
781 | if (status < 0) | 781 | if (status < 0) |
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c index 8bd70d4d184d..dc78764ccc4c 100644 --- a/fs/ocfs2/quota_local.c +++ b/fs/ocfs2/quota_local.c | |||
@@ -971,7 +971,7 @@ static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk( | |||
971 | u64 p_blkno; | 971 | u64 p_blkno; |
972 | 972 | ||
973 | /* We are protected by dqio_sem so no locking needed */ | 973 | /* We are protected by dqio_sem so no locking needed */ |
974 | status = ocfs2_extend_no_holes(lqinode, | 974 | status = ocfs2_extend_no_holes(lqinode, NULL, |
975 | lqinode->i_size + 2 * sb->s_blocksize, | 975 | lqinode->i_size + 2 * sb->s_blocksize, |
976 | lqinode->i_size); | 976 | lqinode->i_size); |
977 | if (status < 0) { | 977 | if (status < 0) { |
@@ -1114,7 +1114,7 @@ static struct ocfs2_quota_chunk *ocfs2_extend_local_quota_file( | |||
1114 | return ocfs2_local_quota_add_chunk(sb, type, offset); | 1114 | return ocfs2_local_quota_add_chunk(sb, type, offset); |
1115 | 1115 | ||
1116 | /* We are protected by dqio_sem so no locking needed */ | 1116 | /* We are protected by dqio_sem so no locking needed */ |
1117 | status = ocfs2_extend_no_holes(lqinode, | 1117 | status = ocfs2_extend_no_holes(lqinode, NULL, |
1118 | lqinode->i_size + sb->s_blocksize, | 1118 | lqinode->i_size + sb->s_blocksize, |
1119 | lqinode->i_size); | 1119 | lqinode->i_size); |
1120 | if (status < 0) { | 1120 | if (status < 0) { |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 4793f36f6518..3ac5aa733e9c 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
@@ -2931,6 +2931,12 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle, | |||
2931 | 2931 | ||
2932 | offset = ((loff_t)cpos) << OCFS2_SB(sb)->s_clustersize_bits; | 2932 | offset = ((loff_t)cpos) << OCFS2_SB(sb)->s_clustersize_bits; |
2933 | end = offset + (new_len << OCFS2_SB(sb)->s_clustersize_bits); | 2933 | end = offset + (new_len << OCFS2_SB(sb)->s_clustersize_bits); |
2934 | /* | ||
2935 | * We only duplicate pages until we reach the page contains i_size - 1. | ||
2936 | * So trim 'end' to i_size. | ||
2937 | */ | ||
2938 | if (end > i_size_read(context->inode)) | ||
2939 | end = i_size_read(context->inode); | ||
2934 | 2940 | ||
2935 | while (offset < end) { | 2941 | while (offset < end) { |
2936 | page_index = offset >> PAGE_CACHE_SHIFT; | 2942 | page_index = offset >> PAGE_CACHE_SHIFT; |
@@ -4166,6 +4172,12 @@ static int __ocfs2_reflink(struct dentry *old_dentry, | |||
4166 | struct inode *inode = old_dentry->d_inode; | 4172 | struct inode *inode = old_dentry->d_inode; |
4167 | struct buffer_head *new_bh = NULL; | 4173 | struct buffer_head *new_bh = NULL; |
4168 | 4174 | ||
4175 | if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE) { | ||
4176 | ret = -EINVAL; | ||
4177 | mlog_errno(ret); | ||
4178 | goto out; | ||
4179 | } | ||
4180 | |||
4169 | ret = filemap_fdatawrite(inode->i_mapping); | 4181 | ret = filemap_fdatawrite(inode->i_mapping); |
4170 | if (ret) { | 4182 | if (ret) { |
4171 | mlog_errno(ret); | 4183 | mlog_errno(ret); |
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index f4c2a9eb8c4d..a8e6a95a353f 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -741,7 +741,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
741 | le16_to_cpu(bg->bg_free_bits_count)); | 741 | le16_to_cpu(bg->bg_free_bits_count)); |
742 | le32_add_cpu(&cl->cl_recs[alloc_rec].c_total, | 742 | le32_add_cpu(&cl->cl_recs[alloc_rec].c_total, |
743 | le16_to_cpu(bg->bg_bits)); | 743 | le16_to_cpu(bg->bg_bits)); |
744 | cl->cl_recs[alloc_rec].c_blkno = cpu_to_le64(bg->bg_blkno); | 744 | cl->cl_recs[alloc_rec].c_blkno = bg->bg_blkno; |
745 | if (le16_to_cpu(cl->cl_next_free_rec) < le16_to_cpu(cl->cl_count)) | 745 | if (le16_to_cpu(cl->cl_next_free_rec) < le16_to_cpu(cl->cl_count)) |
746 | le16_add_cpu(&cl->cl_next_free_rec, 1); | 746 | le16_add_cpu(&cl->cl_next_free_rec, 1); |
747 | 747 | ||
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index e97b34842cfe..d03469f61801 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -709,7 +709,7 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode, | |||
709 | struct ocfs2_xattr_value_buf *vb, | 709 | struct ocfs2_xattr_value_buf *vb, |
710 | struct ocfs2_xattr_set_ctxt *ctxt) | 710 | struct ocfs2_xattr_set_ctxt *ctxt) |
711 | { | 711 | { |
712 | int status = 0; | 712 | int status = 0, credits; |
713 | handle_t *handle = ctxt->handle; | 713 | handle_t *handle = ctxt->handle; |
714 | enum ocfs2_alloc_restarted why; | 714 | enum ocfs2_alloc_restarted why; |
715 | u32 prev_clusters, logical_start = le32_to_cpu(vb->vb_xv->xr_clusters); | 715 | u32 prev_clusters, logical_start = le32_to_cpu(vb->vb_xv->xr_clusters); |
@@ -719,38 +719,54 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode, | |||
719 | 719 | ||
720 | ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb); | 720 | ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb); |
721 | 721 | ||
722 | status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh, | 722 | while (clusters_to_add) { |
723 | OCFS2_JOURNAL_ACCESS_WRITE); | 723 | status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh, |
724 | if (status < 0) { | 724 | OCFS2_JOURNAL_ACCESS_WRITE); |
725 | mlog_errno(status); | 725 | if (status < 0) { |
726 | goto leave; | 726 | mlog_errno(status); |
727 | } | 727 | break; |
728 | } | ||
728 | 729 | ||
729 | prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters); | 730 | prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters); |
730 | status = ocfs2_add_clusters_in_btree(handle, | 731 | status = ocfs2_add_clusters_in_btree(handle, |
731 | &et, | 732 | &et, |
732 | &logical_start, | 733 | &logical_start, |
733 | clusters_to_add, | 734 | clusters_to_add, |
734 | 0, | 735 | 0, |
735 | ctxt->data_ac, | 736 | ctxt->data_ac, |
736 | ctxt->meta_ac, | 737 | ctxt->meta_ac, |
737 | &why); | 738 | &why); |
738 | if (status < 0) { | 739 | if ((status < 0) && (status != -EAGAIN)) { |
739 | mlog_errno(status); | 740 | if (status != -ENOSPC) |
740 | goto leave; | 741 | mlog_errno(status); |
741 | } | 742 | break; |
743 | } | ||
742 | 744 | ||
743 | ocfs2_journal_dirty(handle, vb->vb_bh); | 745 | ocfs2_journal_dirty(handle, vb->vb_bh); |
744 | 746 | ||
745 | clusters_to_add -= le32_to_cpu(vb->vb_xv->xr_clusters) - prev_clusters; | 747 | clusters_to_add -= le32_to_cpu(vb->vb_xv->xr_clusters) - |
748 | prev_clusters; | ||
746 | 749 | ||
747 | /* | 750 | if (why != RESTART_NONE && clusters_to_add) { |
748 | * We should have already allocated enough space before the transaction, | 751 | /* |
749 | * so no need to restart. | 752 | * We can only fail in case the alloc file doesn't give |
750 | */ | 753 | * up enough clusters. |
751 | BUG_ON(why != RESTART_NONE || clusters_to_add); | 754 | */ |
752 | 755 | BUG_ON(why == RESTART_META); | |
753 | leave: | 756 | |
757 | mlog(0, "restarting xattr value extension for %u" | ||
758 | " clusters,.\n", clusters_to_add); | ||
759 | credits = ocfs2_calc_extend_credits(inode->i_sb, | ||
760 | &vb->vb_xv->xr_list, | ||
761 | clusters_to_add); | ||
762 | status = ocfs2_extend_trans(handle, credits); | ||
763 | if (status < 0) { | ||
764 | status = -ENOMEM; | ||
765 | mlog_errno(status); | ||
766 | break; | ||
767 | } | ||
768 | } | ||
769 | } | ||
754 | 770 | ||
755 | return status; | 771 | return status; |
756 | } | 772 | } |
@@ -6788,16 +6804,15 @@ out: | |||
6788 | return ret; | 6804 | return ret; |
6789 | } | 6805 | } |
6790 | 6806 | ||
6791 | static int ocfs2_reflink_xattr_buckets(handle_t *handle, | 6807 | static int ocfs2_reflink_xattr_bucket(handle_t *handle, |
6792 | u64 blkno, u64 new_blkno, u32 clusters, | 6808 | u64 blkno, u64 new_blkno, u32 clusters, |
6809 | u32 *cpos, int num_buckets, | ||
6793 | struct ocfs2_alloc_context *meta_ac, | 6810 | struct ocfs2_alloc_context *meta_ac, |
6794 | struct ocfs2_alloc_context *data_ac, | 6811 | struct ocfs2_alloc_context *data_ac, |
6795 | struct ocfs2_reflink_xattr_tree_args *args) | 6812 | struct ocfs2_reflink_xattr_tree_args *args) |
6796 | { | 6813 | { |
6797 | int i, j, ret = 0; | 6814 | int i, j, ret = 0; |
6798 | struct super_block *sb = args->reflink->old_inode->i_sb; | 6815 | struct super_block *sb = args->reflink->old_inode->i_sb; |
6799 | u32 bpc = ocfs2_xattr_buckets_per_cluster(OCFS2_SB(sb)); | ||
6800 | u32 num_buckets = clusters * bpc; | ||
6801 | int bpb = args->old_bucket->bu_blocks; | 6816 | int bpb = args->old_bucket->bu_blocks; |
6802 | struct ocfs2_xattr_value_buf vb = { | 6817 | struct ocfs2_xattr_value_buf vb = { |
6803 | .vb_access = ocfs2_journal_access, | 6818 | .vb_access = ocfs2_journal_access, |
@@ -6816,14 +6831,6 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle, | |||
6816 | break; | 6831 | break; |
6817 | } | 6832 | } |
6818 | 6833 | ||
6819 | /* | ||
6820 | * The real bucket num in this series of blocks is stored | ||
6821 | * in the 1st bucket. | ||
6822 | */ | ||
6823 | if (i == 0) | ||
6824 | num_buckets = le16_to_cpu( | ||
6825 | bucket_xh(args->old_bucket)->xh_num_buckets); | ||
6826 | |||
6827 | ret = ocfs2_xattr_bucket_journal_access(handle, | 6834 | ret = ocfs2_xattr_bucket_journal_access(handle, |
6828 | args->new_bucket, | 6835 | args->new_bucket, |
6829 | OCFS2_JOURNAL_ACCESS_CREATE); | 6836 | OCFS2_JOURNAL_ACCESS_CREATE); |
@@ -6837,6 +6844,18 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle, | |||
6837 | bucket_block(args->old_bucket, j), | 6844 | bucket_block(args->old_bucket, j), |
6838 | sb->s_blocksize); | 6845 | sb->s_blocksize); |
6839 | 6846 | ||
6847 | /* | ||
6848 | * Record the start cpos so that we can use it to initialize | ||
6849 | * our xattr tree we also set the xh_num_bucket for the new | ||
6850 | * bucket. | ||
6851 | */ | ||
6852 | if (i == 0) { | ||
6853 | *cpos = le32_to_cpu(bucket_xh(args->new_bucket)-> | ||
6854 | xh_entries[0].xe_name_hash); | ||
6855 | bucket_xh(args->new_bucket)->xh_num_buckets = | ||
6856 | cpu_to_le16(num_buckets); | ||
6857 | } | ||
6858 | |||
6840 | ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); | 6859 | ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); |
6841 | 6860 | ||
6842 | ret = ocfs2_reflink_xattr_header(handle, args->reflink, | 6861 | ret = ocfs2_reflink_xattr_header(handle, args->reflink, |
@@ -6866,6 +6885,7 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle, | |||
6866 | } | 6885 | } |
6867 | 6886 | ||
6868 | ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); | 6887 | ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); |
6888 | |||
6869 | ocfs2_xattr_bucket_relse(args->old_bucket); | 6889 | ocfs2_xattr_bucket_relse(args->old_bucket); |
6870 | ocfs2_xattr_bucket_relse(args->new_bucket); | 6890 | ocfs2_xattr_bucket_relse(args->new_bucket); |
6871 | } | 6891 | } |
@@ -6874,6 +6894,75 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle, | |||
6874 | ocfs2_xattr_bucket_relse(args->new_bucket); | 6894 | ocfs2_xattr_bucket_relse(args->new_bucket); |
6875 | return ret; | 6895 | return ret; |
6876 | } | 6896 | } |
6897 | |||
6898 | static int ocfs2_reflink_xattr_buckets(handle_t *handle, | ||
6899 | struct inode *inode, | ||
6900 | struct ocfs2_reflink_xattr_tree_args *args, | ||
6901 | struct ocfs2_extent_tree *et, | ||
6902 | struct ocfs2_alloc_context *meta_ac, | ||
6903 | struct ocfs2_alloc_context *data_ac, | ||
6904 | u64 blkno, u32 cpos, u32 len) | ||
6905 | { | ||
6906 | int ret, first_inserted = 0; | ||
6907 | u32 p_cluster, num_clusters, reflink_cpos = 0; | ||
6908 | u64 new_blkno; | ||
6909 | unsigned int num_buckets, reflink_buckets; | ||
6910 | unsigned int bpc = | ||
6911 | ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb)); | ||
6912 | |||
6913 | ret = ocfs2_read_xattr_bucket(args->old_bucket, blkno); | ||
6914 | if (ret) { | ||
6915 | mlog_errno(ret); | ||
6916 | goto out; | ||
6917 | } | ||
6918 | num_buckets = le16_to_cpu(bucket_xh(args->old_bucket)->xh_num_buckets); | ||
6919 | ocfs2_xattr_bucket_relse(args->old_bucket); | ||
6920 | |||
6921 | while (len && num_buckets) { | ||
6922 | ret = ocfs2_claim_clusters(handle, data_ac, | ||
6923 | 1, &p_cluster, &num_clusters); | ||
6924 | if (ret) { | ||
6925 | mlog_errno(ret); | ||
6926 | goto out; | ||
6927 | } | ||
6928 | |||
6929 | new_blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster); | ||
6930 | reflink_buckets = min(num_buckets, bpc * num_clusters); | ||
6931 | |||
6932 | ret = ocfs2_reflink_xattr_bucket(handle, blkno, | ||
6933 | new_blkno, num_clusters, | ||
6934 | &reflink_cpos, reflink_buckets, | ||
6935 | meta_ac, data_ac, args); | ||
6936 | if (ret) { | ||
6937 | mlog_errno(ret); | ||
6938 | goto out; | ||
6939 | } | ||
6940 | |||
6941 | /* | ||
6942 | * For the 1st allocated cluster, we make it use the same cpos | ||
6943 | * so that the xattr tree looks the same as the original one | ||
6944 | * in the most case. | ||
6945 | */ | ||
6946 | if (!first_inserted) { | ||
6947 | reflink_cpos = cpos; | ||
6948 | first_inserted = 1; | ||
6949 | } | ||
6950 | ret = ocfs2_insert_extent(handle, et, reflink_cpos, new_blkno, | ||
6951 | num_clusters, 0, meta_ac); | ||
6952 | if (ret) | ||
6953 | mlog_errno(ret); | ||
6954 | |||
6955 | mlog(0, "insert new xattr extent rec start %llu len %u to %u\n", | ||
6956 | (unsigned long long)new_blkno, num_clusters, reflink_cpos); | ||
6957 | |||
6958 | len -= num_clusters; | ||
6959 | blkno += ocfs2_clusters_to_blocks(inode->i_sb, num_clusters); | ||
6960 | num_buckets -= reflink_buckets; | ||
6961 | } | ||
6962 | out: | ||
6963 | return ret; | ||
6964 | } | ||
6965 | |||
6877 | /* | 6966 | /* |
6878 | * Create the same xattr extent record in the new inode's xattr tree. | 6967 | * Create the same xattr extent record in the new inode's xattr tree. |
6879 | */ | 6968 | */ |
@@ -6885,8 +6974,6 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode, | |||
6885 | void *para) | 6974 | void *para) |
6886 | { | 6975 | { |
6887 | int ret, credits = 0; | 6976 | int ret, credits = 0; |
6888 | u32 p_cluster, num_clusters; | ||
6889 | u64 new_blkno; | ||
6890 | handle_t *handle; | 6977 | handle_t *handle; |
6891 | struct ocfs2_reflink_xattr_tree_args *args = | 6978 | struct ocfs2_reflink_xattr_tree_args *args = |
6892 | (struct ocfs2_reflink_xattr_tree_args *)para; | 6979 | (struct ocfs2_reflink_xattr_tree_args *)para; |
@@ -6895,6 +6982,9 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode, | |||
6895 | struct ocfs2_alloc_context *data_ac = NULL; | 6982 | struct ocfs2_alloc_context *data_ac = NULL; |
6896 | struct ocfs2_extent_tree et; | 6983 | struct ocfs2_extent_tree et; |
6897 | 6984 | ||
6985 | mlog(0, "reflink xattr buckets %llu len %u\n", | ||
6986 | (unsigned long long)blkno, len); | ||
6987 | |||
6898 | ocfs2_init_xattr_tree_extent_tree(&et, | 6988 | ocfs2_init_xattr_tree_extent_tree(&et, |
6899 | INODE_CACHE(args->reflink->new_inode), | 6989 | INODE_CACHE(args->reflink->new_inode), |
6900 | args->new_blk_bh); | 6990 | args->new_blk_bh); |
@@ -6914,32 +7004,12 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode, | |||
6914 | goto out; | 7004 | goto out; |
6915 | } | 7005 | } |
6916 | 7006 | ||
6917 | ret = ocfs2_claim_clusters(handle, data_ac, | 7007 | ret = ocfs2_reflink_xattr_buckets(handle, inode, args, &et, |
6918 | len, &p_cluster, &num_clusters); | 7008 | meta_ac, data_ac, |
6919 | if (ret) { | 7009 | blkno, cpos, len); |
6920 | mlog_errno(ret); | ||
6921 | goto out_commit; | ||
6922 | } | ||
6923 | |||
6924 | new_blkno = ocfs2_clusters_to_blocks(osb->sb, p_cluster); | ||
6925 | |||
6926 | mlog(0, "reflink xattr buckets %llu to %llu, len %u\n", | ||
6927 | (unsigned long long)blkno, (unsigned long long)new_blkno, len); | ||
6928 | ret = ocfs2_reflink_xattr_buckets(handle, blkno, new_blkno, len, | ||
6929 | meta_ac, data_ac, args); | ||
6930 | if (ret) { | ||
6931 | mlog_errno(ret); | ||
6932 | goto out_commit; | ||
6933 | } | ||
6934 | |||
6935 | mlog(0, "insert new xattr extent rec start %llu len %u to %u\n", | ||
6936 | (unsigned long long)new_blkno, len, cpos); | ||
6937 | ret = ocfs2_insert_extent(handle, &et, cpos, new_blkno, | ||
6938 | len, 0, meta_ac); | ||
6939 | if (ret) | 7010 | if (ret) |
6940 | mlog_errno(ret); | 7011 | mlog_errno(ret); |
6941 | 7012 | ||
6942 | out_commit: | ||
6943 | ocfs2_commit_trans(osb, handle); | 7013 | ocfs2_commit_trans(osb, handle); |
6944 | 7014 | ||
6945 | out: | 7015 | out: |
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c index 3e73de5967ff..fc8497643fd0 100644 --- a/fs/partitions/ibm.c +++ b/fs/partitions/ibm.c | |||
@@ -74,6 +74,7 @@ int ibm_partition(struct parsed_partitions *state) | |||
74 | } *label; | 74 | } *label; |
75 | unsigned char *data; | 75 | unsigned char *data; |
76 | Sector sect; | 76 | Sector sect; |
77 | sector_t labelsect; | ||
77 | 78 | ||
78 | res = 0; | 79 | res = 0; |
79 | blocksize = bdev_logical_block_size(bdev); | 80 | blocksize = bdev_logical_block_size(bdev); |
@@ -98,10 +99,19 @@ int ibm_partition(struct parsed_partitions *state) | |||
98 | goto out_freeall; | 99 | goto out_freeall; |
99 | 100 | ||
100 | /* | 101 | /* |
102 | * Special case for FBA disks: label sector does not depend on | ||
103 | * blocksize. | ||
104 | */ | ||
105 | if ((info->cu_type == 0x6310 && info->dev_type == 0x9336) || | ||
106 | (info->cu_type == 0x3880 && info->dev_type == 0x3370)) | ||
107 | labelsect = info->label_block; | ||
108 | else | ||
109 | labelsect = info->label_block * (blocksize >> 9); | ||
110 | |||
111 | /* | ||
101 | * Get volume label, extract name and type. | 112 | * Get volume label, extract name and type. |
102 | */ | 113 | */ |
103 | data = read_part_sector(state, info->label_block*(blocksize/512), | 114 | data = read_part_sector(state, labelsect, §); |
104 | §); | ||
105 | if (data == NULL) | 115 | if (data == NULL) |
106 | goto out_readerr; | 116 | goto out_readerr; |
107 | 117 | ||
diff --git a/include/linux/i8042.h b/include/linux/i8042.h index 9bf6870ee5f4..a986ff588944 100644 --- a/include/linux/i8042.h +++ b/include/linux/i8042.h | |||
@@ -46,31 +46,31 @@ int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str, | |||
46 | 46 | ||
47 | #else | 47 | #else |
48 | 48 | ||
49 | void i8042_lock_chip(void) | 49 | static inline void i8042_lock_chip(void) |
50 | { | 50 | { |
51 | } | 51 | } |
52 | 52 | ||
53 | void i8042_unlock_chip(void) | 53 | static inline void i8042_unlock_chip(void) |
54 | { | 54 | { |
55 | } | 55 | } |
56 | 56 | ||
57 | int i8042_command(unsigned char *param, int command) | 57 | static inline int i8042_command(unsigned char *param, int command) |
58 | { | 58 | { |
59 | return -ENODEV; | 59 | return -ENODEV; |
60 | } | 60 | } |
61 | 61 | ||
62 | bool i8042_check_port_owner(const struct serio *serio) | 62 | static inline bool i8042_check_port_owner(const struct serio *serio) |
63 | { | 63 | { |
64 | return false; | 64 | return false; |
65 | } | 65 | } |
66 | 66 | ||
67 | int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str, | 67 | static inline int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str, |
68 | struct serio *serio)) | 68 | struct serio *serio)) |
69 | { | 69 | { |
70 | return -ENODEV; | 70 | return -ENODEV; |
71 | } | 71 | } |
72 | 72 | ||
73 | int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str, | 73 | static inline int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str, |
74 | struct serio *serio)) | 74 | struct serio *serio)) |
75 | { | 75 | { |
76 | return -ENODEV; | 76 | return -ENODEV; |
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index a4d2e9f7088a..adf832dec3f3 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h | |||
@@ -1026,11 +1026,12 @@ void __jbd2_journal_insert_checkpoint(struct journal_head *, transaction_t *); | |||
1026 | 1026 | ||
1027 | struct jbd2_buffer_trigger_type { | 1027 | struct jbd2_buffer_trigger_type { |
1028 | /* | 1028 | /* |
1029 | * Fired just before a buffer is written to the journal. | 1029 | * Fired a the moment data to write to the journal are known to be |
1030 | * mapped_data is a mapped buffer that is the frozen data for | 1030 | * stable - so either at the moment b_frozen_data is created or just |
1031 | * commit. | 1031 | * before a buffer is written to the journal. mapped_data is a mapped |
1032 | * buffer that is the frozen data for commit. | ||
1032 | */ | 1033 | */ |
1033 | void (*t_commit)(struct jbd2_buffer_trigger_type *type, | 1034 | void (*t_frozen)(struct jbd2_buffer_trigger_type *type, |
1034 | struct buffer_head *bh, void *mapped_data, | 1035 | struct buffer_head *bh, void *mapped_data, |
1035 | size_t size); | 1036 | size_t size); |
1036 | 1037 | ||
@@ -1042,7 +1043,7 @@ struct jbd2_buffer_trigger_type { | |||
1042 | struct buffer_head *bh); | 1043 | struct buffer_head *bh); |
1043 | }; | 1044 | }; |
1044 | 1045 | ||
1045 | extern void jbd2_buffer_commit_trigger(struct journal_head *jh, | 1046 | extern void jbd2_buffer_frozen_trigger(struct journal_head *jh, |
1046 | void *mapped_data, | 1047 | void *mapped_data, |
1047 | struct jbd2_buffer_trigger_type *triggers); | 1048 | struct jbd2_buffer_trigger_type *triggers); |
1048 | extern void jbd2_buffer_abort_trigger(struct journal_head *jh, | 1049 | extern void jbd2_buffer_abort_trigger(struct journal_head *jh, |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 7cb00845f150..f26fda76b87f 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -288,6 +288,7 @@ struct pci_dev { | |||
288 | */ | 288 | */ |
289 | unsigned int irq; | 289 | unsigned int irq; |
290 | struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ | 290 | struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ |
291 | resource_size_t fw_addr[DEVICE_COUNT_RESOURCE]; /* FW-assigned addr */ | ||
291 | 292 | ||
292 | /* These fields are used by common fixups */ | 293 | /* These fields are used by common fixups */ |
293 | unsigned int transparent:1; /* Transparent PCI bridge */ | 294 | unsigned int transparent:1; /* Transparent PCI bridge */ |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 7f614ce274a9..13ebb5413a79 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -124,7 +124,8 @@ extern struct trace_event_functions enter_syscall_print_funcs; | |||
124 | extern struct trace_event_functions exit_syscall_print_funcs; | 124 | extern struct trace_event_functions exit_syscall_print_funcs; |
125 | 125 | ||
126 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ | 126 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ |
127 | static struct syscall_metadata __syscall_meta_##sname; \ | 127 | static struct syscall_metadata \ |
128 | __attribute__((__aligned__(4))) __syscall_meta_##sname; \ | ||
128 | static struct ftrace_event_call \ | 129 | static struct ftrace_event_call \ |
129 | __attribute__((__aligned__(4))) event_enter_##sname; \ | 130 | __attribute__((__aligned__(4))) event_enter_##sname; \ |
130 | static struct ftrace_event_call __used \ | 131 | static struct ftrace_event_call __used \ |
@@ -138,7 +139,8 @@ extern struct trace_event_functions exit_syscall_print_funcs; | |||
138 | } | 139 | } |
139 | 140 | ||
140 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ | 141 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ |
141 | static struct syscall_metadata __syscall_meta_##sname; \ | 142 | static struct syscall_metadata \ |
143 | __attribute__((__aligned__(4))) __syscall_meta_##sname; \ | ||
142 | static struct ftrace_event_call \ | 144 | static struct ftrace_event_call \ |
143 | __attribute__((__aligned__(4))) event_exit_##sname; \ | 145 | __attribute__((__aligned__(4))) event_exit_##sname; \ |
144 | static struct ftrace_event_call __used \ | 146 | static struct ftrace_event_call __used \ |
diff --git a/kernel/early_res.c b/kernel/early_res.c index 31aa9332ef3f..7bfae887f211 100644 --- a/kernel/early_res.c +++ b/kernel/early_res.c | |||
@@ -7,6 +7,8 @@ | |||
7 | #include <linux/bootmem.h> | 7 | #include <linux/bootmem.h> |
8 | #include <linux/mm.h> | 8 | #include <linux/mm.h> |
9 | #include <linux/early_res.h> | 9 | #include <linux/early_res.h> |
10 | #include <linux/slab.h> | ||
11 | #include <linux/kmemleak.h> | ||
10 | 12 | ||
11 | /* | 13 | /* |
12 | * Early reserved memory areas. | 14 | * Early reserved memory areas. |
@@ -319,6 +321,8 @@ void __init free_early(u64 start, u64 end) | |||
319 | struct early_res *r; | 321 | struct early_res *r; |
320 | int i; | 322 | int i; |
321 | 323 | ||
324 | kmemleak_free_part(__va(start), end - start); | ||
325 | |||
322 | i = find_overlapped_early(start, end); | 326 | i = find_overlapped_early(start, end); |
323 | r = &early_res[i]; | 327 | r = &early_res[i]; |
324 | if (i >= max_early_res || r->end != end || r->start != start) | 328 | if (i >= max_early_res || r->end != end || r->start != start) |
@@ -333,6 +337,8 @@ void __init free_early_partial(u64 start, u64 end) | |||
333 | struct early_res *r; | 337 | struct early_res *r; |
334 | int i; | 338 | int i; |
335 | 339 | ||
340 | kmemleak_free_part(__va(start), end - start); | ||
341 | |||
336 | if (start == end) | 342 | if (start == end) |
337 | return; | 343 | return; |
338 | 344 | ||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 431214b941ac..68319dd20bed 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -3659,6 +3659,11 @@ void * __init __alloc_memory_core_early(int nid, u64 size, u64 align, | |||
3659 | ptr = phys_to_virt(addr); | 3659 | ptr = phys_to_virt(addr); |
3660 | memset(ptr, 0, size); | 3660 | memset(ptr, 0, size); |
3661 | reserve_early_without_check(addr, addr + size, "BOOTMEM"); | 3661 | reserve_early_without_check(addr, addr + size, "BOOTMEM"); |
3662 | /* | ||
3663 | * The min_count is set to 0 so that bootmem allocated blocks | ||
3664 | * are never reported as leaks. | ||
3665 | */ | ||
3666 | kmemleak_alloc(ptr, size, 0, 0); | ||
3662 | return ptr; | 3667 | return ptr; |
3663 | } | 3668 | } |
3664 | 3669 | ||
diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c index 6c0081441a32..5bffada7cde1 100644 --- a/mm/page_cgroup.c +++ b/mm/page_cgroup.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/vmalloc.h> | 9 | #include <linux/vmalloc.h> |
10 | #include <linux/cgroup.h> | 10 | #include <linux/cgroup.h> |
11 | #include <linux/swapops.h> | 11 | #include <linux/swapops.h> |
12 | #include <linux/kmemleak.h> | ||
12 | 13 | ||
13 | static void __meminit | 14 | static void __meminit |
14 | __init_page_cgroup(struct page_cgroup *pc, unsigned long pfn) | 15 | __init_page_cgroup(struct page_cgroup *pc, unsigned long pfn) |
@@ -126,6 +127,12 @@ static int __init_refok init_section_page_cgroup(unsigned long pfn) | |||
126 | if (!base) | 127 | if (!base) |
127 | base = vmalloc(table_size); | 128 | base = vmalloc(table_size); |
128 | } | 129 | } |
130 | /* | ||
131 | * The value stored in section->page_cgroup is (base - pfn) | ||
132 | * and it does not point to the memory block allocated above, | ||
133 | * causing kmemleak false positives. | ||
134 | */ | ||
135 | kmemleak_not_leak(base); | ||
129 | } else { | 136 | } else { |
130 | /* | 137 | /* |
131 | * We don't have to allocate page_cgroup again, but | 138 | * We don't have to allocate page_cgroup again, but |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 359205782964..fd7407c7205c 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -107,7 +107,7 @@ static int perf_session__add_hist_entry(struct perf_session *self, | |||
107 | goto out_free_syms; | 107 | goto out_free_syms; |
108 | err = 0; | 108 | err = 0; |
109 | if (symbol_conf.use_callchain) { | 109 | if (symbol_conf.use_callchain) { |
110 | err = append_chain(he->callchain, data->callchain, syms); | 110 | err = append_chain(he->callchain, data->callchain, syms, data->period); |
111 | if (err) | 111 | if (err) |
112 | goto out_free_syms; | 112 | goto out_free_syms; |
113 | } | 113 | } |
diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN index 49ece7921914..97d76562a1a0 100755 --- a/tools/perf/util/PERF-VERSION-GEN +++ b/tools/perf/util/PERF-VERSION-GEN | |||
@@ -5,17 +5,13 @@ if [ $# -eq 1 ] ; then | |||
5 | fi | 5 | fi |
6 | 6 | ||
7 | GVF=${OUTPUT}PERF-VERSION-FILE | 7 | GVF=${OUTPUT}PERF-VERSION-FILE |
8 | DEF_VER=v0.0.2.PERF | ||
9 | 8 | ||
10 | LF=' | 9 | LF=' |
11 | ' | 10 | ' |
12 | 11 | ||
13 | # First see if there is a version file (included in release tarballs), | 12 | # First check if there is a .git to get the version from git describe |
14 | # then try git-describe, then default. | 13 | # otherwise try to get the version from the kernel makefile |
15 | if test -f version | 14 | if test -d ../../.git -o -f ../../.git && |
16 | then | ||
17 | VN=$(cat version) || VN="$DEF_VER" | ||
18 | elif test -d .git -o -f .git && | ||
19 | VN=$(git describe --abbrev=4 HEAD 2>/dev/null) && | 15 | VN=$(git describe --abbrev=4 HEAD 2>/dev/null) && |
20 | case "$VN" in | 16 | case "$VN" in |
21 | *$LF*) (exit 1) ;; | 17 | *$LF*) (exit 1) ;; |
@@ -27,7 +23,12 @@ elif test -d .git -o -f .git && | |||
27 | then | 23 | then |
28 | VN=$(echo "$VN" | sed -e 's/-/./g'); | 24 | VN=$(echo "$VN" | sed -e 's/-/./g'); |
29 | else | 25 | else |
30 | VN="$DEF_VER" | 26 | eval `grep '^VERSION\s*=' ../../Makefile|tr -d ' '` |
27 | eval `grep '^PATCHLEVEL\s*=' ../../Makefile|tr -d ' '` | ||
28 | eval `grep '^SUBLEVEL\s*=' ../../Makefile|tr -d ' '` | ||
29 | eval `grep '^EXTRAVERSION\s*=' ../../Makefile|tr -d ' '` | ||
30 | |||
31 | VN="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}" | ||
31 | fi | 32 | fi |
32 | 33 | ||
33 | VN=$(expr "$VN" : v*'\(.*\)') | 34 | VN=$(expr "$VN" : v*'\(.*\)') |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 62b69ad4aa73..52c777e451ed 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -230,7 +230,7 @@ fill_node(struct callchain_node *node, struct resolved_chain *chain, int start) | |||
230 | 230 | ||
231 | static void | 231 | static void |
232 | add_child(struct callchain_node *parent, struct resolved_chain *chain, | 232 | add_child(struct callchain_node *parent, struct resolved_chain *chain, |
233 | int start) | 233 | int start, u64 period) |
234 | { | 234 | { |
235 | struct callchain_node *new; | 235 | struct callchain_node *new; |
236 | 236 | ||
@@ -238,7 +238,7 @@ add_child(struct callchain_node *parent, struct resolved_chain *chain, | |||
238 | fill_node(new, chain, start); | 238 | fill_node(new, chain, start); |
239 | 239 | ||
240 | new->children_hit = 0; | 240 | new->children_hit = 0; |
241 | new->hit = 1; | 241 | new->hit = period; |
242 | } | 242 | } |
243 | 243 | ||
244 | /* | 244 | /* |
@@ -248,7 +248,8 @@ add_child(struct callchain_node *parent, struct resolved_chain *chain, | |||
248 | */ | 248 | */ |
249 | static void | 249 | static void |
250 | split_add_child(struct callchain_node *parent, struct resolved_chain *chain, | 250 | split_add_child(struct callchain_node *parent, struct resolved_chain *chain, |
251 | struct callchain_list *to_split, int idx_parents, int idx_local) | 251 | struct callchain_list *to_split, int idx_parents, int idx_local, |
252 | u64 period) | ||
252 | { | 253 | { |
253 | struct callchain_node *new; | 254 | struct callchain_node *new; |
254 | struct list_head *old_tail; | 255 | struct list_head *old_tail; |
@@ -275,41 +276,41 @@ split_add_child(struct callchain_node *parent, struct resolved_chain *chain, | |||
275 | /* create a new child for the new branch if any */ | 276 | /* create a new child for the new branch if any */ |
276 | if (idx_total < chain->nr) { | 277 | if (idx_total < chain->nr) { |
277 | parent->hit = 0; | 278 | parent->hit = 0; |
278 | add_child(parent, chain, idx_total); | 279 | add_child(parent, chain, idx_total, period); |
279 | parent->children_hit++; | 280 | parent->children_hit += period; |
280 | } else { | 281 | } else { |
281 | parent->hit = 1; | 282 | parent->hit = period; |
282 | } | 283 | } |
283 | } | 284 | } |
284 | 285 | ||
285 | static int | 286 | static int |
286 | __append_chain(struct callchain_node *root, struct resolved_chain *chain, | 287 | __append_chain(struct callchain_node *root, struct resolved_chain *chain, |
287 | unsigned int start); | 288 | unsigned int start, u64 period); |
288 | 289 | ||
289 | static void | 290 | static void |
290 | __append_chain_children(struct callchain_node *root, | 291 | __append_chain_children(struct callchain_node *root, |
291 | struct resolved_chain *chain, | 292 | struct resolved_chain *chain, |
292 | unsigned int start) | 293 | unsigned int start, u64 period) |
293 | { | 294 | { |
294 | struct callchain_node *rnode; | 295 | struct callchain_node *rnode; |
295 | 296 | ||
296 | /* lookup in childrens */ | 297 | /* lookup in childrens */ |
297 | chain_for_each_child(rnode, root) { | 298 | chain_for_each_child(rnode, root) { |
298 | unsigned int ret = __append_chain(rnode, chain, start); | 299 | unsigned int ret = __append_chain(rnode, chain, start, period); |
299 | 300 | ||
300 | if (!ret) | 301 | if (!ret) |
301 | goto inc_children_hit; | 302 | goto inc_children_hit; |
302 | } | 303 | } |
303 | /* nothing in children, add to the current node */ | 304 | /* nothing in children, add to the current node */ |
304 | add_child(root, chain, start); | 305 | add_child(root, chain, start, period); |
305 | 306 | ||
306 | inc_children_hit: | 307 | inc_children_hit: |
307 | root->children_hit++; | 308 | root->children_hit += period; |
308 | } | 309 | } |
309 | 310 | ||
310 | static int | 311 | static int |
311 | __append_chain(struct callchain_node *root, struct resolved_chain *chain, | 312 | __append_chain(struct callchain_node *root, struct resolved_chain *chain, |
312 | unsigned int start) | 313 | unsigned int start, u64 period) |
313 | { | 314 | { |
314 | struct callchain_list *cnode; | 315 | struct callchain_list *cnode; |
315 | unsigned int i = start; | 316 | unsigned int i = start; |
@@ -345,18 +346,18 @@ __append_chain(struct callchain_node *root, struct resolved_chain *chain, | |||
345 | 346 | ||
346 | /* we match only a part of the node. Split it and add the new chain */ | 347 | /* we match only a part of the node. Split it and add the new chain */ |
347 | if (i - start < root->val_nr) { | 348 | if (i - start < root->val_nr) { |
348 | split_add_child(root, chain, cnode, start, i - start); | 349 | split_add_child(root, chain, cnode, start, i - start, period); |
349 | return 0; | 350 | return 0; |
350 | } | 351 | } |
351 | 352 | ||
352 | /* we match 100% of the path, increment the hit */ | 353 | /* we match 100% of the path, increment the hit */ |
353 | if (i - start == root->val_nr && i == chain->nr) { | 354 | if (i - start == root->val_nr && i == chain->nr) { |
354 | root->hit++; | 355 | root->hit += period; |
355 | return 0; | 356 | return 0; |
356 | } | 357 | } |
357 | 358 | ||
358 | /* We match the node and still have a part remaining */ | 359 | /* We match the node and still have a part remaining */ |
359 | __append_chain_children(root, chain, i); | 360 | __append_chain_children(root, chain, i, period); |
360 | 361 | ||
361 | return 0; | 362 | return 0; |
362 | } | 363 | } |
@@ -380,7 +381,7 @@ static void filter_context(struct ip_callchain *old, struct resolved_chain *new, | |||
380 | 381 | ||
381 | 382 | ||
382 | int append_chain(struct callchain_node *root, struct ip_callchain *chain, | 383 | int append_chain(struct callchain_node *root, struct ip_callchain *chain, |
383 | struct map_symbol *syms) | 384 | struct map_symbol *syms, u64 period) |
384 | { | 385 | { |
385 | struct resolved_chain *filtered; | 386 | struct resolved_chain *filtered; |
386 | 387 | ||
@@ -397,7 +398,7 @@ int append_chain(struct callchain_node *root, struct ip_callchain *chain, | |||
397 | if (!filtered->nr) | 398 | if (!filtered->nr) |
398 | goto end; | 399 | goto end; |
399 | 400 | ||
400 | __append_chain_children(root, filtered, 0); | 401 | __append_chain_children(root, filtered, 0, period); |
401 | end: | 402 | end: |
402 | free(filtered); | 403 | free(filtered); |
403 | 404 | ||
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 1ca73e4a2723..f2e9ee164bd8 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -49,6 +49,9 @@ static inline void callchain_init(struct callchain_node *node) | |||
49 | INIT_LIST_HEAD(&node->brothers); | 49 | INIT_LIST_HEAD(&node->brothers); |
50 | INIT_LIST_HEAD(&node->children); | 50 | INIT_LIST_HEAD(&node->children); |
51 | INIT_LIST_HEAD(&node->val); | 51 | INIT_LIST_HEAD(&node->val); |
52 | |||
53 | node->parent = NULL; | ||
54 | node->hit = 0; | ||
52 | } | 55 | } |
53 | 56 | ||
54 | static inline u64 cumul_hits(struct callchain_node *node) | 57 | static inline u64 cumul_hits(struct callchain_node *node) |
@@ -58,7 +61,7 @@ static inline u64 cumul_hits(struct callchain_node *node) | |||
58 | 61 | ||
59 | int register_callchain_param(struct callchain_param *param); | 62 | int register_callchain_param(struct callchain_param *param); |
60 | int append_chain(struct callchain_node *root, struct ip_callchain *chain, | 63 | int append_chain(struct callchain_node *root, struct ip_callchain *chain, |
61 | struct map_symbol *syms); | 64 | struct map_symbol *syms, u64 period); |
62 | 65 | ||
63 | bool ip_callchain__valid(struct ip_callchain *chain, event_t *event); | 66 | bool ip_callchain__valid(struct ip_callchain *chain, event_t *event); |
64 | #endif /* __PERF_CALLCHAIN_H */ | 67 | #endif /* __PERF_CALLCHAIN_H */ |