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 */ |