Commit d43cc793 authored by Steve French's avatar Steve French

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
...@@ -731,29 +731,21 @@ smb2_sync_write(const unsigned int xid, struct cifsFileInfo *cfile, ...@@ -731,29 +731,21 @@ smb2_sync_write(const unsigned int xid, struct cifsFileInfo *cfile,
return SMB2_write(xid, parms, written, iov, nr_segs); return SMB2_write(xid, parms, written, iov, nr_segs);
} }
static int /* Set or clear the SPARSE_FILE attribute based on value passed in setsparse */
smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon, static bool smb2_set_sparse(const unsigned int xid, struct cifs_tcon *tcon,
struct cifsFileInfo *cfile, __u64 size, bool set_alloc) 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; struct cifsInodeInfo *cifsi;
__u8 set_sparse = 1;
int rc; int rc;
cifsi = CIFS_I(inode); cifsi = CIFS_I(inode);
/* if file already sparse or no server support don't bother */ /* if file already sparse don't bother setting sparse again */
if (cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) if ((cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) && setsparse)
goto smb2_set_eof; 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 * 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, ...@@ -766,19 +758,45 @@ smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
* if the file is repeatedly extended. * if the file is repeatedly extended.
*/ */
if (tcon->broken_sparse_sup) if (tcon->broken_sparse_sup)
goto smb2_set_eof; return false;
rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid, rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
cfile->fid.volatile_fid, FSCTL_SET_SPARSE, cfile->fid.volatile_fid, FSCTL_SET_SPARSE,
true /* is_fctl */, &set_sparse, 1, NULL, NULL); true /* is_fctl */, &setsparse, 1, NULL, NULL);
if (rc) { if (rc) {
tcon->broken_sparse_sup = true; tcon->broken_sparse_sup = true;
cifs_dbg(FYI, "set sparse rc = %d\n", rc); cifs_dbg(FYI, "set sparse rc = %d\n", rc);
} else return false;
}
if (setsparse)
cifsi->cifsAttrs |= FILE_ATTRIBUTE_SPARSE_FILE; 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, return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
cfile->fid.volatile_fid, cfile->pid, &eof, false); cfile->fid.volatile_fid, cfile->pid, &eof, false);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment