Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d43cc793 authored by Steve French's avatar Steve French
Browse files

Cleanup sparse file support by creating worker function for it



Simply move code to new function (for clarity). Function sets or clears
the sparse file attribute flag.

Signed-off-by: default avatarSteve French <smfrench@gmail.com>
Reviewed-by: default avatarDavid Disseldorp <ddiss@samba.org>
parent 3d1a3745
Loading
Loading
Loading
Loading
+49 −31
Original line number Diff line number Diff line
@@ -731,29 +731,21 @@ smb2_sync_write(const unsigned int xid, struct cifsFileInfo *cfile,
	return SMB2_write(xid, parms, written, iov, nr_segs);
}

static int
smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
		   struct cifsFileInfo *cfile, __u64 size, bool set_alloc)
/* Set or clear the SPARSE_FILE attribute based on value passed in setsparse */
static bool smb2_set_sparse(const unsigned int xid, struct cifs_tcon *tcon,
		struct cifsFileInfo *cfile, struct inode *inode, __u8 setsparse)
{
	__le64 eof = cpu_to_le64(size);
	struct inode *inode;

	/*
	 * If extending file more than one page make sparse. Many Linux fs
	 * make files sparse by default when extending via ftruncate
	 */
	inode = cfile->dentry->d_inode;

	if (!set_alloc && (size > inode->i_size + 8192)) {
	struct cifsInodeInfo *cifsi;
		__u8 set_sparse = 1;
	int rc;

	cifsi = CIFS_I(inode);

		/* if file already sparse or no server support don't bother */
		if (cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE)
			goto smb2_set_eof;
	/* if file already sparse don't bother setting sparse again */
	if ((cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) && setsparse)
		return true; /* already sparse */

	if (!(cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) && !setsparse)
		return true; /* already not sparse */

	/*
	 * Can't check for sparse support on share the usual way via the
@@ -766,19 +758,45 @@ smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
	 * if the file is repeatedly extended.
	 */
	if (tcon->broken_sparse_sup)
			goto smb2_set_eof;
		return false;

	rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
			cfile->fid.volatile_fid, FSCTL_SET_SPARSE,
				true /* is_fctl */, &set_sparse, 1, NULL, NULL);
			true /* is_fctl */, &setsparse, 1, NULL, NULL);
	if (rc) {
		tcon->broken_sparse_sup = true;
		cifs_dbg(FYI, "set sparse rc = %d\n", rc);
		} else
		return false;
	}

	if (setsparse)
		cifsi->cifsAttrs |= FILE_ATTRIBUTE_SPARSE_FILE;
	else
		cifsi->cifsAttrs &= (~FILE_ATTRIBUTE_SPARSE_FILE);

	return true;
}

static int
smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
		   struct cifsFileInfo *cfile, __u64 size, bool set_alloc)
{
	__le64 eof = cpu_to_le64(size);
	struct inode *inode;

	/*
	 * If extending file more than one page make sparse. Many Linux fs
	 * make files sparse by default when extending via ftruncate
	 */
	inode = cfile->dentry->d_inode;

	if (!set_alloc && (size > inode->i_size + 8192)) {
		__u8 set_sparse = 1;

		/* whether set sparse succeeds or not, extend the file */
		smb2_set_sparse(xid, tcon, cfile, inode, set_sparse);
	}

smb2_set_eof:
	return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
			    cfile->fid.volatile_fid, cfile->pid, &eof, false);
}