diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/autofs4/dev-ioctl.c | 2 | ||||
| -rw-r--r-- | fs/dax.c | 1 | ||||
| -rw-r--r-- | fs/exec.c | 28 | ||||
| -rw-r--r-- | fs/ocfs2/dlmglue.c | 4 | ||||
| -rw-r--r-- | fs/ocfs2/xattr.c | 23 |
5 files changed, 43 insertions, 15 deletions
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index 734cbf8d9676..dd9f1bebb5a3 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c | |||
| @@ -344,7 +344,7 @@ static int autofs_dev_ioctl_fail(struct file *fp, | |||
| 344 | int status; | 344 | int status; |
| 345 | 345 | ||
| 346 | token = (autofs_wqt_t) param->fail.token; | 346 | token = (autofs_wqt_t) param->fail.token; |
| 347 | status = param->fail.status ? param->fail.status : -ENOENT; | 347 | status = param->fail.status < 0 ? param->fail.status : -ENOENT; |
| 348 | return autofs4_wait_release(sbi, token, status); | 348 | return autofs4_wait_release(sbi, token, status); |
| 349 | } | 349 | } |
| 350 | 350 | ||
| @@ -859,6 +859,7 @@ int dax_writeback_mapping_range(struct address_space *mapping, | |||
| 859 | if (ret < 0) | 859 | if (ret < 0) |
| 860 | goto out; | 860 | goto out; |
| 861 | } | 861 | } |
| 862 | start_index = indices[pvec.nr - 1] + 1; | ||
| 862 | } | 863 | } |
| 863 | out: | 864 | out: |
| 864 | put_dax(dax_dev); | 865 | put_dax(dax_dev); |
| @@ -220,8 +220,26 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | |||
| 220 | 220 | ||
| 221 | if (write) { | 221 | if (write) { |
| 222 | unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; | 222 | unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; |
| 223 | unsigned long ptr_size; | ||
| 223 | struct rlimit *rlim; | 224 | struct rlimit *rlim; |
| 224 | 225 | ||
| 226 | /* | ||
| 227 | * Since the stack will hold pointers to the strings, we | ||
| 228 | * must account for them as well. | ||
| 229 | * | ||
| 230 | * The size calculation is the entire vma while each arg page is | ||
| 231 | * built, so each time we get here it's calculating how far it | ||
| 232 | * is currently (rather than each call being just the newly | ||
| 233 | * added size from the arg page). As a result, we need to | ||
| 234 | * always add the entire size of the pointers, so that on the | ||
| 235 | * last call to get_arg_page() we'll actually have the entire | ||
| 236 | * correct size. | ||
| 237 | */ | ||
| 238 | ptr_size = (bprm->argc + bprm->envc) * sizeof(void *); | ||
| 239 | if (ptr_size > ULONG_MAX - size) | ||
| 240 | goto fail; | ||
| 241 | size += ptr_size; | ||
| 242 | |||
| 225 | acct_arg_size(bprm, size / PAGE_SIZE); | 243 | acct_arg_size(bprm, size / PAGE_SIZE); |
| 226 | 244 | ||
| 227 | /* | 245 | /* |
| @@ -239,13 +257,15 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | |||
| 239 | * to work from. | 257 | * to work from. |
| 240 | */ | 258 | */ |
| 241 | rlim = current->signal->rlim; | 259 | rlim = current->signal->rlim; |
| 242 | if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) { | 260 | if (size > READ_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) |
| 243 | put_page(page); | 261 | goto fail; |
| 244 | return NULL; | ||
| 245 | } | ||
| 246 | } | 262 | } |
| 247 | 263 | ||
| 248 | return page; | 264 | return page; |
| 265 | |||
| 266 | fail: | ||
| 267 | put_page(page); | ||
| 268 | return NULL; | ||
| 249 | } | 269 | } |
| 250 | 270 | ||
| 251 | static void put_arg_page(struct page *page) | 271 | static void put_arg_page(struct page *page) |
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 3b7c937a36b5..4689940a953c 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
| @@ -2591,6 +2591,10 @@ void ocfs2_inode_unlock_tracker(struct inode *inode, | |||
| 2591 | struct ocfs2_lock_res *lockres; | 2591 | struct ocfs2_lock_res *lockres; |
| 2592 | 2592 | ||
| 2593 | lockres = &OCFS2_I(inode)->ip_inode_lockres; | 2593 | lockres = &OCFS2_I(inode)->ip_inode_lockres; |
| 2594 | /* had_lock means that the currect process already takes the cluster | ||
| 2595 | * lock previously. If had_lock is 1, we have nothing to do here, and | ||
| 2596 | * it will get unlocked where we got the lock. | ||
| 2597 | */ | ||
| 2594 | if (!had_lock) { | 2598 | if (!had_lock) { |
| 2595 | ocfs2_remove_holder(lockres, oh); | 2599 | ocfs2_remove_holder(lockres, oh); |
| 2596 | ocfs2_inode_unlock(inode, ex); | 2600 | ocfs2_inode_unlock(inode, ex); |
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 3c5384d9b3a5..f70c3778d600 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
| @@ -1328,20 +1328,21 @@ static int ocfs2_xattr_get(struct inode *inode, | |||
| 1328 | void *buffer, | 1328 | void *buffer, |
| 1329 | size_t buffer_size) | 1329 | size_t buffer_size) |
| 1330 | { | 1330 | { |
| 1331 | int ret; | 1331 | int ret, had_lock; |
| 1332 | struct buffer_head *di_bh = NULL; | 1332 | struct buffer_head *di_bh = NULL; |
| 1333 | struct ocfs2_lock_holder oh; | ||
| 1333 | 1334 | ||
| 1334 | ret = ocfs2_inode_lock(inode, &di_bh, 0); | 1335 | had_lock = ocfs2_inode_lock_tracker(inode, &di_bh, 0, &oh); |
| 1335 | if (ret < 0) { | 1336 | if (had_lock < 0) { |
| 1336 | mlog_errno(ret); | 1337 | mlog_errno(had_lock); |
| 1337 | return ret; | 1338 | return had_lock; |
| 1338 | } | 1339 | } |
| 1339 | down_read(&OCFS2_I(inode)->ip_xattr_sem); | 1340 | down_read(&OCFS2_I(inode)->ip_xattr_sem); |
| 1340 | ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index, | 1341 | ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index, |
| 1341 | name, buffer, buffer_size); | 1342 | name, buffer, buffer_size); |
| 1342 | up_read(&OCFS2_I(inode)->ip_xattr_sem); | 1343 | up_read(&OCFS2_I(inode)->ip_xattr_sem); |
| 1343 | 1344 | ||
| 1344 | ocfs2_inode_unlock(inode, 0); | 1345 | ocfs2_inode_unlock_tracker(inode, 0, &oh, had_lock); |
| 1345 | 1346 | ||
| 1346 | brelse(di_bh); | 1347 | brelse(di_bh); |
| 1347 | 1348 | ||
| @@ -3537,11 +3538,12 @@ int ocfs2_xattr_set(struct inode *inode, | |||
| 3537 | { | 3538 | { |
| 3538 | struct buffer_head *di_bh = NULL; | 3539 | struct buffer_head *di_bh = NULL; |
| 3539 | struct ocfs2_dinode *di; | 3540 | struct ocfs2_dinode *di; |
| 3540 | int ret, credits, ref_meta = 0, ref_credits = 0; | 3541 | int ret, credits, had_lock, ref_meta = 0, ref_credits = 0; |
| 3541 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 3542 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 3542 | struct inode *tl_inode = osb->osb_tl_inode; | 3543 | struct inode *tl_inode = osb->osb_tl_inode; |
| 3543 | struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, NULL, }; | 3544 | struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, NULL, }; |
| 3544 | struct ocfs2_refcount_tree *ref_tree = NULL; | 3545 | struct ocfs2_refcount_tree *ref_tree = NULL; |
| 3546 | struct ocfs2_lock_holder oh; | ||
| 3545 | 3547 | ||
| 3546 | struct ocfs2_xattr_info xi = { | 3548 | struct ocfs2_xattr_info xi = { |
| 3547 | .xi_name_index = name_index, | 3549 | .xi_name_index = name_index, |
| @@ -3572,8 +3574,9 @@ int ocfs2_xattr_set(struct inode *inode, | |||
| 3572 | return -ENOMEM; | 3574 | return -ENOMEM; |
| 3573 | } | 3575 | } |
| 3574 | 3576 | ||
| 3575 | ret = ocfs2_inode_lock(inode, &di_bh, 1); | 3577 | had_lock = ocfs2_inode_lock_tracker(inode, &di_bh, 1, &oh); |
| 3576 | if (ret < 0) { | 3578 | if (had_lock < 0) { |
| 3579 | ret = had_lock; | ||
| 3577 | mlog_errno(ret); | 3580 | mlog_errno(ret); |
| 3578 | goto cleanup_nolock; | 3581 | goto cleanup_nolock; |
| 3579 | } | 3582 | } |
| @@ -3670,7 +3673,7 @@ cleanup: | |||
| 3670 | if (ret) | 3673 | if (ret) |
| 3671 | mlog_errno(ret); | 3674 | mlog_errno(ret); |
| 3672 | } | 3675 | } |
| 3673 | ocfs2_inode_unlock(inode, 1); | 3676 | ocfs2_inode_unlock_tracker(inode, 1, &oh, had_lock); |
| 3674 | cleanup_nolock: | 3677 | cleanup_nolock: |
| 3675 | brelse(di_bh); | 3678 | brelse(di_bh); |
| 3676 | brelse(xbs.xattr_bh); | 3679 | brelse(xbs.xattr_bh); |
