Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro:
- more ->d_init() stuff (work.dcache)
- pathname resolution cleanups (work.namei)
- a few missing iov_iter primitives - copy_from_iter_full() and
friends. Either copy the full requested amount, advance the iterator
and return true, or fail, return false and do _not_ advance the
iterator. Quite a few open-coded callers converted (and became more
readable and harder to fuck up that way) (work.iov_iter)
- several assorted patches, the big one being logfs removal
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
logfs: remove from tree
vfs: fix put_compat_statfs64() does not handle errors
namei: fold should_follow_link() with the step into not-followed link
namei: pass both WALK_GET and WALK_MORE to should_follow_link()
namei: invert WALK_PUT logics
namei: shift interpretation of LOOKUP_FOLLOW inside should_follow_link()
namei: saner calling conventions for mountpoint_last()
namei.c: get rid of user_path_parent()
switch getfrag callbacks to ..._full() primitives
make skb_add_data,{_nocache}() and skb_copy_to_page_nocache() advance only on success
[iov_iter] new primitives - copy_from_iter_full() and friends
don't open-code file_inode()
ceph: switch to use of ->d_init()
ceph: unify dentry_operations instances
lustre: switch to use of ->d_init()
This commit is contained in:
@@ -569,6 +569,31 @@ size_t copy_from_iter(void *addr, size_t bytes, struct iov_iter *i)
|
||||
}
|
||||
EXPORT_SYMBOL(copy_from_iter);
|
||||
|
||||
bool copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i)
|
||||
{
|
||||
char *to = addr;
|
||||
if (unlikely(i->type & ITER_PIPE)) {
|
||||
WARN_ON(1);
|
||||
return false;
|
||||
}
|
||||
if (unlikely(i->count < bytes)) \
|
||||
return false;
|
||||
|
||||
iterate_all_kinds(i, bytes, v, ({
|
||||
if (__copy_from_user((to += v.iov_len) - v.iov_len,
|
||||
v.iov_base, v.iov_len))
|
||||
return false;
|
||||
0;}),
|
||||
memcpy_from_page((to += v.bv_len) - v.bv_len, v.bv_page,
|
||||
v.bv_offset, v.bv_len),
|
||||
memcpy((to += v.iov_len) - v.iov_len, v.iov_base, v.iov_len)
|
||||
)
|
||||
|
||||
iov_iter_advance(i, bytes);
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(copy_from_iter_full);
|
||||
|
||||
size_t copy_from_iter_nocache(void *addr, size_t bytes, struct iov_iter *i)
|
||||
{
|
||||
char *to = addr;
|
||||
@@ -588,6 +613,30 @@ size_t copy_from_iter_nocache(void *addr, size_t bytes, struct iov_iter *i)
|
||||
}
|
||||
EXPORT_SYMBOL(copy_from_iter_nocache);
|
||||
|
||||
bool copy_from_iter_full_nocache(void *addr, size_t bytes, struct iov_iter *i)
|
||||
{
|
||||
char *to = addr;
|
||||
if (unlikely(i->type & ITER_PIPE)) {
|
||||
WARN_ON(1);
|
||||
return false;
|
||||
}
|
||||
if (unlikely(i->count < bytes)) \
|
||||
return false;
|
||||
iterate_all_kinds(i, bytes, v, ({
|
||||
if (__copy_from_user_nocache((to += v.iov_len) - v.iov_len,
|
||||
v.iov_base, v.iov_len))
|
||||
return false;
|
||||
0;}),
|
||||
memcpy_from_page((to += v.bv_len) - v.bv_len, v.bv_page,
|
||||
v.bv_offset, v.bv_len),
|
||||
memcpy((to += v.iov_len) - v.iov_len, v.iov_base, v.iov_len)
|
||||
)
|
||||
|
||||
iov_iter_advance(i, bytes);
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(copy_from_iter_full_nocache);
|
||||
|
||||
size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
|
||||
struct iov_iter *i)
|
||||
{
|
||||
@@ -1009,7 +1058,7 @@ size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum,
|
||||
}
|
||||
iterate_and_advance(i, bytes, v, ({
|
||||
int err = 0;
|
||||
next = csum_and_copy_from_user(v.iov_base,
|
||||
next = csum_and_copy_from_user(v.iov_base,
|
||||
(to += v.iov_len) - v.iov_len,
|
||||
v.iov_len, 0, &err);
|
||||
if (!err) {
|
||||
@@ -1038,6 +1087,51 @@ size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum,
|
||||
}
|
||||
EXPORT_SYMBOL(csum_and_copy_from_iter);
|
||||
|
||||
bool csum_and_copy_from_iter_full(void *addr, size_t bytes, __wsum *csum,
|
||||
struct iov_iter *i)
|
||||
{
|
||||
char *to = addr;
|
||||
__wsum sum, next;
|
||||
size_t off = 0;
|
||||
sum = *csum;
|
||||
if (unlikely(i->type & ITER_PIPE)) {
|
||||
WARN_ON(1);
|
||||
return false;
|
||||
}
|
||||
if (unlikely(i->count < bytes))
|
||||
return false;
|
||||
iterate_all_kinds(i, bytes, v, ({
|
||||
int err = 0;
|
||||
next = csum_and_copy_from_user(v.iov_base,
|
||||
(to += v.iov_len) - v.iov_len,
|
||||
v.iov_len, 0, &err);
|
||||
if (err)
|
||||
return false;
|
||||
sum = csum_block_add(sum, next, off);
|
||||
off += v.iov_len;
|
||||
0;
|
||||
}), ({
|
||||
char *p = kmap_atomic(v.bv_page);
|
||||
next = csum_partial_copy_nocheck(p + v.bv_offset,
|
||||
(to += v.bv_len) - v.bv_len,
|
||||
v.bv_len, 0);
|
||||
kunmap_atomic(p);
|
||||
sum = csum_block_add(sum, next, off);
|
||||
off += v.bv_len;
|
||||
}),({
|
||||
next = csum_partial_copy_nocheck(v.iov_base,
|
||||
(to += v.iov_len) - v.iov_len,
|
||||
v.iov_len, 0);
|
||||
sum = csum_block_add(sum, next, off);
|
||||
off += v.iov_len;
|
||||
})
|
||||
)
|
||||
*csum = sum;
|
||||
iov_iter_advance(i, bytes);
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(csum_and_copy_from_iter_full);
|
||||
|
||||
size_t csum_and_copy_to_iter(const void *addr, size_t bytes, __wsum *csum,
|
||||
struct iov_iter *i)
|
||||
{
|
||||
@@ -1052,7 +1146,7 @@ size_t csum_and_copy_to_iter(const void *addr, size_t bytes, __wsum *csum,
|
||||
iterate_and_advance(i, bytes, v, ({
|
||||
int err = 0;
|
||||
next = csum_and_copy_to_user((from += v.iov_len) - v.iov_len,
|
||||
v.iov_base,
|
||||
v.iov_base,
|
||||
v.iov_len, 0, &err);
|
||||
if (!err) {
|
||||
sum = csum_block_add(sum, next, off);
|
||||
|
||||
Reference in New Issue
Block a user