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: Steve French <smfrench@gmail.com> Reviewed-by: David Disseldorp <ddiss@samba.org>
This commit is contained in:
Родитель
3d1a3745d8
Коммит
d43cc79343
|
@ -731,6 +731,52 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
struct cifsInodeInfo *cifsi;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
cifsi = CIFS_I(inode);
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
* FS attribute info (FILE_SUPPORTS_SPARSE_FILES) on the share
|
||||||
|
* since Samba server doesn't set the flag on the share, yet
|
||||||
|
* supports the set sparse FSCTL and returns sparse correctly
|
||||||
|
* in the file attributes. If we fail setting sparse though we
|
||||||
|
* mark that server does not support sparse files for this share
|
||||||
|
* to avoid repeatedly sending the unsupported fsctl to server
|
||||||
|
* if the file is repeatedly extended.
|
||||||
|
*/
|
||||||
|
if (tcon->broken_sparse_sup)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
|
||||||
|
cfile->fid.volatile_fid, FSCTL_SET_SPARSE,
|
||||||
|
true /* is_fctl */, &setsparse, 1, NULL, NULL);
|
||||||
|
if (rc) {
|
||||||
|
tcon->broken_sparse_sup = true;
|
||||||
|
cifs_dbg(FYI, "set sparse rc = %d\n", rc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setsparse)
|
||||||
|
cifsi->cifsAttrs |= FILE_ATTRIBUTE_SPARSE_FILE;
|
||||||
|
else
|
||||||
|
cifsi->cifsAttrs &= (~FILE_ATTRIBUTE_SPARSE_FILE);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
|
smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
struct cifsFileInfo *cfile, __u64 size, bool set_alloc)
|
struct cifsFileInfo *cfile, __u64 size, bool set_alloc)
|
||||||
|
@ -745,40 +791,12 @@ smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
|
||||||
inode = cfile->dentry->d_inode;
|
inode = cfile->dentry->d_inode;
|
||||||
|
|
||||||
if (!set_alloc && (size > inode->i_size + 8192)) {
|
if (!set_alloc && (size > inode->i_size + 8192)) {
|
||||||
struct cifsInodeInfo *cifsi;
|
|
||||||
__u8 set_sparse = 1;
|
__u8 set_sparse = 1;
|
||||||
int rc;
|
|
||||||
|
|
||||||
cifsi = CIFS_I(inode);
|
/* whether set sparse succeeds or not, extend the file */
|
||||||
|
smb2_set_sparse(xid, tcon, cfile, inode, set_sparse);
|
||||||
/* if file already sparse or no server support don't bother */
|
|
||||||
if (cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE)
|
|
||||||
goto smb2_set_eof;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Can't check for sparse support on share the usual way via the
|
|
||||||
* FS attribute info (FILE_SUPPORTS_SPARSE_FILES) on the share
|
|
||||||
* since Samba server doesn't set the flag on the share, yet
|
|
||||||
* supports the set sparse FSCTL and returns sparse correctly
|
|
||||||
* in the file attributes. If we fail setting sparse though we
|
|
||||||
* mark that server does not support sparse files for this share
|
|
||||||
* to avoid repeatedly sending the unsupported fsctl to server
|
|
||||||
* if the file is repeatedly extended.
|
|
||||||
*/
|
|
||||||
if (tcon->broken_sparse_sup)
|
|
||||||
goto smb2_set_eof;
|
|
||||||
|
|
||||||
rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
|
|
||||||
cfile->fid.volatile_fid, FSCTL_SET_SPARSE,
|
|
||||||
true /* is_fctl */, &set_sparse, 1, NULL, NULL);
|
|
||||||
if (rc) {
|
|
||||||
tcon->broken_sparse_sup = true;
|
|
||||||
cifs_dbg(FYI, "set sparse rc = %d\n", rc);
|
|
||||||
} else
|
|
||||||
cifsi->cifsAttrs |= FILE_ATTRIBUTE_SPARSE_FILE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче