diff options
| -rw-r--r-- | fs/locks.c | 100 | ||||
| -rw-r--r-- | include/uapi/asm-generic/fcntl.h | 3 |
2 files changed, 32 insertions, 71 deletions
diff --git a/fs/locks.c b/fs/locks.c index dd309333afc9..b49e853a9c7b 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
| @@ -344,48 +344,43 @@ static int assign_type(struct file_lock *fl, long type) | |||
| 344 | return 0; | 344 | return 0; |
| 345 | } | 345 | } |
| 346 | 346 | ||
| 347 | /* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX | 347 | static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, |
| 348 | * style lock. | 348 | struct flock64 *l) |
| 349 | */ | ||
| 350 | static int flock_to_posix_lock(struct file *filp, struct file_lock *fl, | ||
| 351 | struct flock *l) | ||
| 352 | { | 349 | { |
| 353 | off_t start, end; | ||
| 354 | |||
| 355 | switch (l->l_whence) { | 350 | switch (l->l_whence) { |
| 356 | case SEEK_SET: | 351 | case SEEK_SET: |
| 357 | start = 0; | 352 | fl->fl_start = 0; |
| 358 | break; | 353 | break; |
| 359 | case SEEK_CUR: | 354 | case SEEK_CUR: |
| 360 | start = filp->f_pos; | 355 | fl->fl_start = filp->f_pos; |
| 361 | break; | 356 | break; |
| 362 | case SEEK_END: | 357 | case SEEK_END: |
| 363 | start = i_size_read(file_inode(filp)); | 358 | fl->fl_start = i_size_read(file_inode(filp)); |
| 364 | break; | 359 | break; |
| 365 | default: | 360 | default: |
| 366 | return -EINVAL; | 361 | return -EINVAL; |
| 367 | } | 362 | } |
| 363 | if (l->l_start > OFFSET_MAX - fl->fl_start) | ||
| 364 | return -EOVERFLOW; | ||
| 365 | fl->fl_start += l->l_start; | ||
| 366 | if (fl->fl_start < 0) | ||
| 367 | return -EINVAL; | ||
| 368 | 368 | ||
| 369 | /* POSIX-1996 leaves the case l->l_len < 0 undefined; | 369 | /* POSIX-1996 leaves the case l->l_len < 0 undefined; |
| 370 | POSIX-2001 defines it. */ | 370 | POSIX-2001 defines it. */ |
| 371 | start += l->l_start; | ||
| 372 | if (start < 0) | ||
| 373 | return -EINVAL; | ||
| 374 | fl->fl_end = OFFSET_MAX; | ||
| 375 | if (l->l_len > 0) { | 371 | if (l->l_len > 0) { |
| 376 | end = start + l->l_len - 1; | 372 | if (l->l_len - 1 > OFFSET_MAX - fl->fl_start) |
| 377 | fl->fl_end = end; | 373 | return -EOVERFLOW; |
| 374 | fl->fl_end = fl->fl_start + l->l_len - 1; | ||
| 375 | |||
| 378 | } else if (l->l_len < 0) { | 376 | } else if (l->l_len < 0) { |
| 379 | end = start - 1; | 377 | if (fl->fl_start + l->l_len < 0) |
| 380 | fl->fl_end = end; | ||
| 381 | start += l->l_len; | ||
| 382 | if (start < 0) | ||
| 383 | return -EINVAL; | 378 | return -EINVAL; |
| 384 | } | 379 | fl->fl_end = fl->fl_start - 1; |
| 385 | fl->fl_start = start; /* we record the absolute position */ | 380 | fl->fl_start += l->l_len; |
| 386 | if (fl->fl_end < fl->fl_start) | 381 | } else |
| 387 | return -EOVERFLOW; | 382 | fl->fl_end = OFFSET_MAX; |
| 388 | 383 | ||
| 389 | fl->fl_owner = current->files; | 384 | fl->fl_owner = current->files; |
| 390 | fl->fl_pid = current->tgid; | 385 | fl->fl_pid = current->tgid; |
| 391 | fl->fl_file = filp; | 386 | fl->fl_file = filp; |
| @@ -396,52 +391,21 @@ static int flock_to_posix_lock(struct file *filp, struct file_lock *fl, | |||
| 396 | return assign_type(fl, l->l_type); | 391 | return assign_type(fl, l->l_type); |
| 397 | } | 392 | } |
| 398 | 393 | ||
| 399 | #if BITS_PER_LONG == 32 | 394 | /* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX |
| 400 | static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, | 395 | * style lock. |
| 401 | struct flock64 *l) | 396 | */ |
| 397 | static int flock_to_posix_lock(struct file *filp, struct file_lock *fl, | ||
| 398 | struct flock *l) | ||
| 402 | { | 399 | { |
| 403 | loff_t start; | 400 | struct flock64 ll = { |
| 404 | 401 | .l_type = l->l_type, | |
| 405 | switch (l->l_whence) { | 402 | .l_whence = l->l_whence, |
| 406 | case SEEK_SET: | 403 | .l_start = l->l_start, |
| 407 | start = 0; | 404 | .l_len = l->l_len, |
| 408 | break; | 405 | }; |
| 409 | case SEEK_CUR: | ||
| 410 | start = filp->f_pos; | ||
| 411 | break; | ||
| 412 | case SEEK_END: | ||
| 413 | start = i_size_read(file_inode(filp)); | ||
| 414 | break; | ||
| 415 | default: | ||
| 416 | return -EINVAL; | ||
| 417 | } | ||
| 418 | 406 | ||
| 419 | start += l->l_start; | 407 | return flock64_to_posix_lock(filp, fl, &ll); |
| 420 | if (start < 0) | ||
| 421 | return -EINVAL; | ||
| 422 | fl->fl_end = OFFSET_MAX; | ||
| 423 | if (l->l_len > 0) { | ||
| 424 | fl->fl_end = start + l->l_len - 1; | ||
| 425 | } else if (l->l_len < 0) { | ||
| 426 | fl->fl_end = start - 1; | ||
| 427 | start += l->l_len; | ||
| 428 | if (start < 0) | ||
| 429 | return -EINVAL; | ||
| 430 | } | ||
| 431 | fl->fl_start = start; /* we record the absolute position */ | ||
| 432 | if (fl->fl_end < fl->fl_start) | ||
| 433 | return -EOVERFLOW; | ||
| 434 | |||
| 435 | fl->fl_owner = current->files; | ||
| 436 | fl->fl_pid = current->tgid; | ||
| 437 | fl->fl_file = filp; | ||
| 438 | fl->fl_flags = FL_POSIX; | ||
| 439 | fl->fl_ops = NULL; | ||
| 440 | fl->fl_lmops = NULL; | ||
| 441 | |||
| 442 | return assign_type(fl, l->l_type); | ||
| 443 | } | 408 | } |
| 444 | #endif | ||
| 445 | 409 | ||
| 446 | /* default lease lock manager operations */ | 410 | /* default lease lock manager operations */ |
| 447 | static void lease_break_callback(struct file_lock *fl) | 411 | static void lease_break_callback(struct file_lock *fl) |
diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h index 95e46c8e05f9..36025f77c6ed 100644 --- a/include/uapi/asm-generic/fcntl.h +++ b/include/uapi/asm-generic/fcntl.h | |||
| @@ -186,8 +186,6 @@ struct flock { | |||
| 186 | }; | 186 | }; |
| 187 | #endif | 187 | #endif |
| 188 | 188 | ||
| 189 | #ifndef CONFIG_64BIT | ||
| 190 | |||
| 191 | #ifndef HAVE_ARCH_STRUCT_FLOCK64 | 189 | #ifndef HAVE_ARCH_STRUCT_FLOCK64 |
| 192 | #ifndef __ARCH_FLOCK64_PAD | 190 | #ifndef __ARCH_FLOCK64_PAD |
| 193 | #define __ARCH_FLOCK64_PAD | 191 | #define __ARCH_FLOCK64_PAD |
| @@ -202,6 +200,5 @@ struct flock64 { | |||
| 202 | __ARCH_FLOCK64_PAD | 200 | __ARCH_FLOCK64_PAD |
| 203 | }; | 201 | }; |
| 204 | #endif | 202 | #endif |
| 205 | #endif /* !CONFIG_64BIT */ | ||
| 206 | 203 | ||
| 207 | #endif /* _ASM_GENERIC_FCNTL_H */ | 204 | #endif /* _ASM_GENERIC_FCNTL_H */ |
