|
@@ -1728,7 +1728,6 @@ static long ceph_fallocate(struct file *file, int mode,
|
|
struct ceph_file_info *fi = file->private_data;
|
|
struct ceph_file_info *fi = file->private_data;
|
|
struct inode *inode = file_inode(file);
|
|
struct inode *inode = file_inode(file);
|
|
struct ceph_inode_info *ci = ceph_inode(inode);
|
|
struct ceph_inode_info *ci = ceph_inode(inode);
|
|
- struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
|
|
|
|
struct ceph_cap_flush *prealloc_cf;
|
|
struct ceph_cap_flush *prealloc_cf;
|
|
int want, got = 0;
|
|
int want, got = 0;
|
|
int dirty;
|
|
int dirty;
|
|
@@ -1736,10 +1735,7 @@ static long ceph_fallocate(struct file *file, int mode,
|
|
loff_t endoff = 0;
|
|
loff_t endoff = 0;
|
|
loff_t size;
|
|
loff_t size;
|
|
|
|
|
|
- if ((offset + length) > max(i_size_read(inode), fsc->max_file_size))
|
|
|
|
- return -EFBIG;
|
|
|
|
-
|
|
|
|
- if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
|
|
|
|
|
|
+ if (mode != (FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
|
|
return -EOPNOTSUPP;
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
if (!S_ISREG(inode->i_mode))
|
|
if (!S_ISREG(inode->i_mode))
|
|
@@ -1756,18 +1752,6 @@ static long ceph_fallocate(struct file *file, int mode,
|
|
goto unlock;
|
|
goto unlock;
|
|
}
|
|
}
|
|
|
|
|
|
- if (!(mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE)) &&
|
|
|
|
- ceph_quota_is_max_bytes_exceeded(inode, offset + length)) {
|
|
|
|
- ret = -EDQUOT;
|
|
|
|
- goto unlock;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (ceph_osdmap_flag(&fsc->client->osdc, CEPH_OSDMAP_FULL) &&
|
|
|
|
- !(mode & FALLOC_FL_PUNCH_HOLE)) {
|
|
|
|
- ret = -ENOSPC;
|
|
|
|
- goto unlock;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (ci->i_inline_version != CEPH_INLINE_NONE) {
|
|
if (ci->i_inline_version != CEPH_INLINE_NONE) {
|
|
ret = ceph_uninline_data(file, NULL);
|
|
ret = ceph_uninline_data(file, NULL);
|
|
if (ret < 0)
|
|
if (ret < 0)
|
|
@@ -1775,12 +1759,12 @@ static long ceph_fallocate(struct file *file, int mode,
|
|
}
|
|
}
|
|
|
|
|
|
size = i_size_read(inode);
|
|
size = i_size_read(inode);
|
|
- if (!(mode & FALLOC_FL_KEEP_SIZE)) {
|
|
|
|
- endoff = offset + length;
|
|
|
|
- ret = inode_newsize_ok(inode, endoff);
|
|
|
|
- if (ret)
|
|
|
|
- goto unlock;
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ /* Are we punching a hole beyond EOF? */
|
|
|
|
+ if (offset >= size)
|
|
|
|
+ goto unlock;
|
|
|
|
+ if ((offset + length) > size)
|
|
|
|
+ length = size - offset;
|
|
|
|
|
|
if (fi->fmode & CEPH_FILE_MODE_LAZY)
|
|
if (fi->fmode & CEPH_FILE_MODE_LAZY)
|
|
want = CEPH_CAP_FILE_BUFFER | CEPH_CAP_FILE_LAZYIO;
|
|
want = CEPH_CAP_FILE_BUFFER | CEPH_CAP_FILE_LAZYIO;
|
|
@@ -1791,16 +1775,8 @@ static long ceph_fallocate(struct file *file, int mode,
|
|
if (ret < 0)
|
|
if (ret < 0)
|
|
goto unlock;
|
|
goto unlock;
|
|
|
|
|
|
- if (mode & FALLOC_FL_PUNCH_HOLE) {
|
|
|
|
- if (offset < size)
|
|
|
|
- ceph_zero_pagecache_range(inode, offset, length);
|
|
|
|
- ret = ceph_zero_objects(inode, offset, length);
|
|
|
|
- } else if (endoff > size) {
|
|
|
|
- truncate_pagecache_range(inode, size, -1);
|
|
|
|
- if (ceph_inode_set_size(inode, endoff))
|
|
|
|
- ceph_check_caps(ceph_inode(inode),
|
|
|
|
- CHECK_CAPS_AUTHONLY, NULL);
|
|
|
|
- }
|
|
|
|
|
|
+ ceph_zero_pagecache_range(inode, offset, length);
|
|
|
|
+ ret = ceph_zero_objects(inode, offset, length);
|
|
|
|
|
|
if (!ret) {
|
|
if (!ret) {
|
|
spin_lock(&ci->i_ceph_lock);
|
|
spin_lock(&ci->i_ceph_lock);
|
|
@@ -1810,9 +1786,6 @@ static long ceph_fallocate(struct file *file, int mode,
|
|
spin_unlock(&ci->i_ceph_lock);
|
|
spin_unlock(&ci->i_ceph_lock);
|
|
if (dirty)
|
|
if (dirty)
|
|
__mark_inode_dirty(inode, dirty);
|
|
__mark_inode_dirty(inode, dirty);
|
|
- if ((endoff > size) &&
|
|
|
|
- ceph_quota_is_max_bytes_approaching(inode, endoff))
|
|
|
|
- ceph_check_caps(ci, CHECK_CAPS_NODELAY, NULL);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
ceph_put_cap_refs(ci, got);
|
|
ceph_put_cap_refs(ci, got);
|