Skip to content

Commit

Permalink
Cleanup sparse file support by creating worker function for it
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Steve French committed Aug 16, 2014
1 parent 3d1a374 commit d43cc79
Showing 1 changed file with 49 additions and 31 deletions.
80 changes: 49 additions & 31 deletions fs/cifs/smb2ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,52 @@ smb2_sync_write(const unsigned int xid, struct cifsFileInfo *cfile,
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
smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
struct cifsFileInfo *cfile, __u64 size, bool set_alloc)
Expand All @@ -745,40 +791,12 @@ smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
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;

/*
* 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;

/* 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);
}
Expand Down

0 comments on commit d43cc79

Please sign in to comment.