|
@@ -428,11 +428,11 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|
|
if (ret)
|
|
|
goto out_unlock;
|
|
|
|
|
|
- ret = gfs2_quota_lock_check(ip);
|
|
|
- if (ret)
|
|
|
- goto out_unlock;
|
|
|
gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks);
|
|
|
ap.target = data_blocks + ind_blocks;
|
|
|
+ ret = gfs2_quota_lock_check(ip, &ap);
|
|
|
+ if (ret)
|
|
|
+ goto out_unlock;
|
|
|
ret = gfs2_inplace_reserve(ip, &ap);
|
|
|
if (ret)
|
|
|
goto out_quota_unlock;
|
|
@@ -764,22 +764,30 @@ out:
|
|
|
brelse(dibh);
|
|
|
return error;
|
|
|
}
|
|
|
-
|
|
|
-static void calc_max_reserv(struct gfs2_inode *ip, loff_t max, loff_t *len,
|
|
|
- unsigned int *data_blocks, unsigned int *ind_blocks)
|
|
|
+/**
|
|
|
+ * calc_max_reserv() - Reverse of write_calc_reserv. Given a number of
|
|
|
+ * blocks, determine how many bytes can be written.
|
|
|
+ * @ip: The inode in question.
|
|
|
+ * @len: Max cap of bytes. What we return in *len must be <= this.
|
|
|
+ * @data_blocks: Compute and return the number of data blocks needed
|
|
|
+ * @ind_blocks: Compute and return the number of indirect blocks needed
|
|
|
+ * @max_blocks: The total blocks available to work with.
|
|
|
+ *
|
|
|
+ * Returns: void, but @len, @data_blocks and @ind_blocks are filled in.
|
|
|
+ */
|
|
|
+static void calc_max_reserv(struct gfs2_inode *ip, loff_t *len,
|
|
|
+ unsigned int *data_blocks, unsigned int *ind_blocks,
|
|
|
+ unsigned int max_blocks)
|
|
|
{
|
|
|
+ loff_t max = *len;
|
|
|
const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
|
|
- unsigned int max_blocks = ip->i_rgd->rd_free_clone;
|
|
|
unsigned int tmp, max_data = max_blocks - 3 * (sdp->sd_max_height - 1);
|
|
|
|
|
|
for (tmp = max_data; tmp > sdp->sd_diptrs;) {
|
|
|
tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs);
|
|
|
max_data -= tmp;
|
|
|
}
|
|
|
- /* This calculation isn't the exact reverse of gfs2_write_calc_reserve,
|
|
|
- so it might end up with fewer data blocks */
|
|
|
- if (max_data <= *data_blocks)
|
|
|
- return;
|
|
|
+
|
|
|
*data_blocks = max_data;
|
|
|
*ind_blocks = max_blocks - max_data;
|
|
|
*len = ((loff_t)max_data - 3) << sdp->sd_sb.sb_bsize_shift;
|
|
@@ -796,7 +804,7 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t
|
|
|
struct gfs2_inode *ip = GFS2_I(inode);
|
|
|
struct gfs2_alloc_parms ap = { .aflags = 0, };
|
|
|
unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
|
|
|
- loff_t bytes, max_bytes;
|
|
|
+ loff_t bytes, max_bytes, max_blks = UINT_MAX;
|
|
|
int error;
|
|
|
const loff_t pos = offset;
|
|
|
const loff_t count = len;
|
|
@@ -818,6 +826,9 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t
|
|
|
|
|
|
gfs2_size_hint(file, offset, len);
|
|
|
|
|
|
+ gfs2_write_calc_reserv(ip, PAGE_SIZE, &data_blocks, &ind_blocks);
|
|
|
+ ap.min_target = data_blocks + ind_blocks;
|
|
|
+
|
|
|
while (len > 0) {
|
|
|
if (len < bytes)
|
|
|
bytes = len;
|
|
@@ -826,27 +837,41 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t
|
|
|
offset += bytes;
|
|
|
continue;
|
|
|
}
|
|
|
- error = gfs2_quota_lock_check(ip);
|
|
|
+
|
|
|
+ /* We need to determine how many bytes we can actually
|
|
|
+ * fallocate without exceeding quota or going over the
|
|
|
+ * end of the fs. We start off optimistically by assuming
|
|
|
+ * we can write max_bytes */
|
|
|
+ max_bytes = (len > max_chunk_size) ? max_chunk_size : len;
|
|
|
+
|
|
|
+ /* Since max_bytes is most likely a theoretical max, we
|
|
|
+ * calculate a more realistic 'bytes' to serve as a good
|
|
|
+ * starting point for the number of bytes we may be able
|
|
|
+ * to write */
|
|
|
+ gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks);
|
|
|
+ ap.target = data_blocks + ind_blocks;
|
|
|
+
|
|
|
+ error = gfs2_quota_lock_check(ip, &ap);
|
|
|
if (error)
|
|
|
return error;
|
|
|
-retry:
|
|
|
- gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks);
|
|
|
+ /* ap.allowed tells us how many blocks quota will allow
|
|
|
+ * us to write. Check if this reduces max_blks */
|
|
|
+ if (ap.allowed && ap.allowed < max_blks)
|
|
|
+ max_blks = ap.allowed;
|
|
|
|
|
|
- ap.target = data_blocks + ind_blocks;
|
|
|
error = gfs2_inplace_reserve(ip, &ap);
|
|
|
- if (error) {
|
|
|
- if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) {
|
|
|
- bytes >>= 1;
|
|
|
- bytes &= bsize_mask;
|
|
|
- if (bytes == 0)
|
|
|
- bytes = sdp->sd_sb.sb_bsize;
|
|
|
- goto retry;
|
|
|
- }
|
|
|
+ if (error)
|
|
|
goto out_qunlock;
|
|
|
- }
|
|
|
- max_bytes = bytes;
|
|
|
- calc_max_reserv(ip, (len > max_chunk_size)? max_chunk_size: len,
|
|
|
- &max_bytes, &data_blocks, &ind_blocks);
|
|
|
+
|
|
|
+ /* check if the selected rgrp limits our max_blks further */
|
|
|
+ if (ap.allowed && ap.allowed < max_blks)
|
|
|
+ max_blks = ap.allowed;
|
|
|
+
|
|
|
+ /* Almost done. Calculate bytes that can be written using
|
|
|
+ * max_blks. We also recompute max_bytes, data_blocks and
|
|
|
+ * ind_blocks */
|
|
|
+ calc_max_reserv(ip, &max_bytes, &data_blocks,
|
|
|
+ &ind_blocks, max_blks);
|
|
|
|
|
|
rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA +
|
|
|
RES_RG_HDR + gfs2_rg_blocks(ip, data_blocks + ind_blocks);
|
|
@@ -930,6 +955,22 @@ out_uninit:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static ssize_t gfs2_file_splice_write(struct pipe_inode_info *pipe,
|
|
|
+ struct file *out, loff_t *ppos,
|
|
|
+ size_t len, unsigned int flags)
|
|
|
+{
|
|
|
+ int error;
|
|
|
+ struct gfs2_inode *ip = GFS2_I(out->f_mapping->host);
|
|
|
+
|
|
|
+ error = gfs2_rs_alloc(ip);
|
|
|
+ if (error)
|
|
|
+ return (ssize_t)error;
|
|
|
+
|
|
|
+ gfs2_size_hint(out, *ppos, len);
|
|
|
+
|
|
|
+ return iter_file_splice_write(pipe, out, ppos, len, flags);
|
|
|
+}
|
|
|
+
|
|
|
#ifdef CONFIG_GFS2_FS_LOCKING_DLM
|
|
|
|
|
|
/**
|
|
@@ -1076,7 +1117,7 @@ const struct file_operations gfs2_file_fops = {
|
|
|
.lock = gfs2_lock,
|
|
|
.flock = gfs2_flock,
|
|
|
.splice_read = generic_file_splice_read,
|
|
|
- .splice_write = iter_file_splice_write,
|
|
|
+ .splice_write = gfs2_file_splice_write,
|
|
|
.setlease = simple_nosetlease,
|
|
|
.fallocate = gfs2_fallocate,
|
|
|
};
|
|
@@ -1106,7 +1147,7 @@ const struct file_operations gfs2_file_fops_nolock = {
|
|
|
.release = gfs2_release,
|
|
|
.fsync = gfs2_fsync,
|
|
|
.splice_read = generic_file_splice_read,
|
|
|
- .splice_write = iter_file_splice_write,
|
|
|
+ .splice_write = gfs2_file_splice_write,
|
|
|
.setlease = generic_setlease,
|
|
|
.fallocate = gfs2_fallocate,
|
|
|
};
|