提交 d43cc793 编写于 作者: S 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: NSteve French <smfrench@gmail.com>
Reviewed-by: NDavid Disseldorp <ddiss@samba.org>
上级 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% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册