diff options
author | David S. Miller <davem@davemloft.net> | 2011-01-24 16:17:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-24 16:17:06 -0500 |
commit | e92427b289d252cfbd4cb5282d92f4ce1a5bb1fb (patch) | |
tree | 6d30e5e7b7f8e9aaa51d43b7128ac56860fa03bb /fs/ntfs/file.c | |
parent | c506653d35249bb4738bb139c24362e1ae724bc1 (diff) | |
parent | ec30f343d61391ab23705e50a525da1d55395780 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'fs/ntfs/file.c')
-rw-r--r-- | fs/ntfs/file.c | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 113ebd9f25a4..f4b1057abdd2 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * file.c - NTFS kernel file operations. Part of the Linux-NTFS project. | 2 | * file.c - NTFS kernel file operations. Part of the Linux-NTFS project. |
3 | * | 3 | * |
4 | * Copyright (c) 2001-2007 Anton Altaparmakov | 4 | * Copyright (c) 2001-2011 Anton Altaparmakov and Tuxera Inc. |
5 | * | 5 | * |
6 | * This program/include file is free software; you can redistribute it and/or | 6 | * This program/include file is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License as published | 7 | * modify it under the terms of the GNU General Public License as published |
@@ -1380,15 +1380,14 @@ static inline void ntfs_set_next_iovec(const struct iovec **iovp, | |||
1380 | * pages (out to offset + bytes), to emulate ntfs_copy_from_user()'s | 1380 | * pages (out to offset + bytes), to emulate ntfs_copy_from_user()'s |
1381 | * single-segment behaviour. | 1381 | * single-segment behaviour. |
1382 | * | 1382 | * |
1383 | * We call the same helper (__ntfs_copy_from_user_iovec_inatomic()) both | 1383 | * We call the same helper (__ntfs_copy_from_user_iovec_inatomic()) both when |
1384 | * when atomic and when not atomic. This is ok because | 1384 | * atomic and when not atomic. This is ok because it calls |
1385 | * __ntfs_copy_from_user_iovec_inatomic() calls __copy_from_user_inatomic() | 1385 | * __copy_from_user_inatomic() and it is ok to call this when non-atomic. In |
1386 | * and it is ok to call this when non-atomic. | 1386 | * fact, the only difference between __copy_from_user_inatomic() and |
1387 | * Infact, the only difference between __copy_from_user_inatomic() and | ||
1388 | * __copy_from_user() is that the latter calls might_sleep() and the former | 1387 | * __copy_from_user() is that the latter calls might_sleep() and the former |
1389 | * should not zero the tail of the buffer on error. And on many | 1388 | * should not zero the tail of the buffer on error. And on many architectures |
1390 | * architectures __copy_from_user_inatomic() is just defined to | 1389 | * __copy_from_user_inatomic() is just defined to __copy_from_user() so it |
1391 | * __copy_from_user() so it makes no difference at all on those architectures. | 1390 | * makes no difference at all on those architectures. |
1392 | */ | 1391 | */ |
1393 | static inline size_t ntfs_copy_from_user_iovec(struct page **pages, | 1392 | static inline size_t ntfs_copy_from_user_iovec(struct page **pages, |
1394 | unsigned nr_pages, unsigned ofs, const struct iovec **iov, | 1393 | unsigned nr_pages, unsigned ofs, const struct iovec **iov, |
@@ -1409,28 +1408,28 @@ static inline size_t ntfs_copy_from_user_iovec(struct page **pages, | |||
1409 | if (unlikely(copied != len)) { | 1408 | if (unlikely(copied != len)) { |
1410 | /* Do it the slow way. */ | 1409 | /* Do it the slow way. */ |
1411 | addr = kmap(*pages); | 1410 | addr = kmap(*pages); |
1412 | copied = __ntfs_copy_from_user_iovec_inatomic(addr + ofs, | 1411 | copied = __ntfs_copy_from_user_iovec_inatomic(addr + |
1413 | *iov, *iov_ofs, len); | 1412 | ofs, *iov, *iov_ofs, len); |
1414 | /* | ||
1415 | * Zero the rest of the target like __copy_from_user(). | ||
1416 | */ | ||
1417 | memset(addr + ofs + copied, 0, len - copied); | ||
1418 | kunmap(*pages); | ||
1419 | if (unlikely(copied != len)) | 1413 | if (unlikely(copied != len)) |
1420 | goto err_out; | 1414 | goto err_out; |
1415 | kunmap(*pages); | ||
1421 | } | 1416 | } |
1422 | total += len; | 1417 | total += len; |
1418 | ntfs_set_next_iovec(iov, iov_ofs, len); | ||
1423 | bytes -= len; | 1419 | bytes -= len; |
1424 | if (!bytes) | 1420 | if (!bytes) |
1425 | break; | 1421 | break; |
1426 | ntfs_set_next_iovec(iov, iov_ofs, len); | ||
1427 | ofs = 0; | 1422 | ofs = 0; |
1428 | } while (++pages < last_page); | 1423 | } while (++pages < last_page); |
1429 | out: | 1424 | out: |
1430 | return total; | 1425 | return total; |
1431 | err_out: | 1426 | err_out: |
1432 | total += copied; | 1427 | BUG_ON(copied > len); |
1433 | /* Zero the rest of the target like __copy_from_user(). */ | 1428 | /* Zero the rest of the target like __copy_from_user(). */ |
1429 | memset(addr + ofs + copied, 0, len - copied); | ||
1430 | kunmap(*pages); | ||
1431 | total += copied; | ||
1432 | ntfs_set_next_iovec(iov, iov_ofs, copied); | ||
1434 | while (++pages < last_page) { | 1433 | while (++pages < last_page) { |
1435 | bytes -= len; | 1434 | bytes -= len; |
1436 | if (!bytes) | 1435 | if (!bytes) |