diff options
Diffstat (limited to 'fs/ceph/file.c')
-rw-r--r-- | fs/ceph/file.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 905986dd4c3c..d533075a823d 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -275,10 +275,10 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, | |||
275 | err = ceph_mdsc_do_request(mdsc, | 275 | err = ceph_mdsc_do_request(mdsc, |
276 | (flags & (O_CREAT|O_TRUNC)) ? dir : NULL, | 276 | (flags & (O_CREAT|O_TRUNC)) ? dir : NULL, |
277 | req); | 277 | req); |
278 | err = ceph_handle_snapdir(req, dentry, err); | ||
278 | if (err) | 279 | if (err) |
279 | goto out_req; | 280 | goto out_req; |
280 | 281 | ||
281 | err = ceph_handle_snapdir(req, dentry, err); | ||
282 | if (err == 0 && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry) | 282 | if (err == 0 && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry) |
283 | err = ceph_handle_notrace_create(dir, dentry); | 283 | err = ceph_handle_notrace_create(dir, dentry); |
284 | 284 | ||
@@ -292,7 +292,7 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, | |||
292 | } | 292 | } |
293 | if (err) | 293 | if (err) |
294 | goto out_req; | 294 | goto out_req; |
295 | if (dn || dentry->d_inode == NULL || S_ISLNK(dentry->d_inode->i_mode)) { | 295 | if (dn || dentry->d_inode == NULL || d_is_symlink(dentry)) { |
296 | /* make vfs retry on splice, ENOENT, or symlink */ | 296 | /* make vfs retry on splice, ENOENT, or symlink */ |
297 | dout("atomic_open finish_no_open on dn %p\n", dn); | 297 | dout("atomic_open finish_no_open on dn %p\n", dn); |
298 | err = finish_no_open(file, dn); | 298 | err = finish_no_open(file, dn); |
@@ -392,13 +392,14 @@ more: | |||
392 | if (ret >= 0) { | 392 | if (ret >= 0) { |
393 | int didpages; | 393 | int didpages; |
394 | if (was_short && (pos + ret < inode->i_size)) { | 394 | if (was_short && (pos + ret < inode->i_size)) { |
395 | u64 tmp = min(this_len - ret, | 395 | int zlen = min(this_len - ret, |
396 | inode->i_size - pos - ret); | 396 | inode->i_size - pos - ret); |
397 | int zoff = (o_direct ? buf_align : io_align) + | ||
398 | read + ret; | ||
397 | dout(" zero gap %llu to %llu\n", | 399 | dout(" zero gap %llu to %llu\n", |
398 | pos + ret, pos + ret + tmp); | 400 | pos + ret, pos + ret + zlen); |
399 | ceph_zero_page_vector_range(page_align + read + ret, | 401 | ceph_zero_page_vector_range(zoff, zlen, pages); |
400 | tmp, pages); | 402 | ret += zlen; |
401 | ret += tmp; | ||
402 | } | 403 | } |
403 | 404 | ||
404 | didpages = (page_align + ret) >> PAGE_CACHE_SHIFT; | 405 | didpages = (page_align + ret) >> PAGE_CACHE_SHIFT; |
@@ -878,28 +879,34 @@ again: | |||
878 | 879 | ||
879 | i_size = i_size_read(inode); | 880 | i_size = i_size_read(inode); |
880 | if (retry_op == READ_INLINE) { | 881 | if (retry_op == READ_INLINE) { |
881 | /* does not support inline data > PAGE_SIZE */ | 882 | BUG_ON(ret > 0 || read > 0); |
882 | if (i_size > PAGE_CACHE_SIZE) { | 883 | if (iocb->ki_pos < i_size && |
883 | ret = -EIO; | 884 | iocb->ki_pos < PAGE_CACHE_SIZE) { |
884 | } else if (iocb->ki_pos < i_size) { | ||
885 | loff_t end = min_t(loff_t, i_size, | 885 | loff_t end = min_t(loff_t, i_size, |
886 | iocb->ki_pos + len); | 886 | iocb->ki_pos + len); |
887 | end = min_t(loff_t, end, PAGE_CACHE_SIZE); | ||
887 | if (statret < end) | 888 | if (statret < end) |
888 | zero_user_segment(page, statret, end); | 889 | zero_user_segment(page, statret, end); |
889 | ret = copy_page_to_iter(page, | 890 | ret = copy_page_to_iter(page, |
890 | iocb->ki_pos & ~PAGE_MASK, | 891 | iocb->ki_pos & ~PAGE_MASK, |
891 | end - iocb->ki_pos, to); | 892 | end - iocb->ki_pos, to); |
892 | iocb->ki_pos += ret; | 893 | iocb->ki_pos += ret; |
893 | } else { | 894 | read += ret; |
894 | ret = 0; | 895 | } |
896 | if (iocb->ki_pos < i_size && read < len) { | ||
897 | size_t zlen = min_t(size_t, len - read, | ||
898 | i_size - iocb->ki_pos); | ||
899 | ret = iov_iter_zero(zlen, to); | ||
900 | iocb->ki_pos += ret; | ||
901 | read += ret; | ||
895 | } | 902 | } |
896 | __free_pages(page, 0); | 903 | __free_pages(page, 0); |
897 | return ret; | 904 | return read; |
898 | } | 905 | } |
899 | 906 | ||
900 | /* hit EOF or hole? */ | 907 | /* hit EOF or hole? */ |
901 | if (retry_op == CHECK_EOF && iocb->ki_pos < i_size && | 908 | if (retry_op == CHECK_EOF && iocb->ki_pos < i_size && |
902 | ret < len) { | 909 | ret < len) { |
903 | dout("sync_read hit hole, ppos %lld < size %lld" | 910 | dout("sync_read hit hole, ppos %lld < size %lld" |
904 | ", reading more\n", iocb->ki_pos, | 911 | ", reading more\n", iocb->ki_pos, |
905 | inode->i_size); | 912 | inode->i_size); |