aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorSteve French <smfrench@gmail.com>2014-08-13 18:16:29 -0400
committerSteve French <smfrench@gmail.com>2014-08-16 00:01:00 -0400
commitd43cc79343dfabf9f168531d3f5cff313205c8fb (patch)
tree7f17f1c5b8f8ce58ecb9d4faad57b38387be3533 /fs/cifs
parent3d1a3745d8ca7ccdf00905b01fd5ab42ff523a94 (diff)
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>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/smb2ops.c80
1 files changed, 49 insertions, 31 deletions
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 74634369c21e..85be34ad8d76 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -731,6 +731,52 @@ smb2_sync_write(const unsigned int xid, struct cifsFileInfo *cfile,
731 return SMB2_write(xid, parms, written, iov, nr_segs); 731 return SMB2_write(xid, parms, written, iov, nr_segs);
732} 732}
733 733
734/* Set or clear the SPARSE_FILE attribute based on value passed in setsparse */
735static bool smb2_set_sparse(const unsigned int xid, struct cifs_tcon *tcon,
736 struct cifsFileInfo *cfile, struct inode *inode, __u8 setsparse)
737{
738 struct cifsInodeInfo *cifsi;
739 int rc;
740
741 cifsi = CIFS_I(inode);
742
743 /* if file already sparse don't bother setting sparse again */
744 if ((cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) && setsparse)
745 return true; /* already sparse */
746
747 if (!(cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) && !setsparse)
748 return true; /* already not sparse */
749
750 /*
751 * Can't check for sparse support on share the usual way via the
752 * FS attribute info (FILE_SUPPORTS_SPARSE_FILES) on the share
753 * since Samba server doesn't set the flag on the share, yet
754 * supports the set sparse FSCTL and returns sparse correctly
755 * in the file attributes. If we fail setting sparse though we
756 * mark that server does not support sparse files for this share
757 * to avoid repeatedly sending the unsupported fsctl to server
758 * if the file is repeatedly extended.
759 */
760 if (tcon->broken_sparse_sup)
761 return false;
762
763 rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
764 cfile->fid.volatile_fid, FSCTL_SET_SPARSE,
765 true /* is_fctl */, &setsparse, 1, NULL, NULL);
766 if (rc) {
767 tcon->broken_sparse_sup = true;
768 cifs_dbg(FYI, "set sparse rc = %d\n", rc);
769 return false;
770 }
771
772 if (setsparse)
773 cifsi->cifsAttrs |= FILE_ATTRIBUTE_SPARSE_FILE;
774 else
775 cifsi->cifsAttrs &= (~FILE_ATTRIBUTE_SPARSE_FILE);
776
777 return true;
778}
779
734static int 780static int
735smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon, 781smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
736 struct cifsFileInfo *cfile, __u64 size, bool set_alloc) 782 struct cifsFileInfo *cfile, __u64 size, bool set_alloc)
@@ -745,40 +791,12 @@ smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
745 inode = cfile->dentry->d_inode; 791 inode = cfile->dentry->d_inode;
746 792
747 if (!set_alloc && (size > inode->i_size + 8192)) { 793 if (!set_alloc && (size > inode->i_size + 8192)) {
748 struct cifsInodeInfo *cifsi;
749 __u8 set_sparse = 1; 794 __u8 set_sparse = 1;
750 int rc; 795
751 796 /* whether set sparse succeeds or not, extend the file */
752 cifsi = CIFS_I(inode); 797 smb2_set_sparse(xid, tcon, cfile, inode, set_sparse);
753
754 /* if file already sparse or no server support don't bother */
755 if (cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE)
756 goto smb2_set_eof;
757
758 /*
759 * Can't check for sparse support on share the usual way via the
760 * FS attribute info (FILE_SUPPORTS_SPARSE_FILES) on the share
761 * since Samba server doesn't set the flag on the share, yet
762 * supports the set sparse FSCTL and returns sparse correctly
763 * in the file attributes. If we fail setting sparse though we
764 * mark that server does not support sparse files for this share
765 * to avoid repeatedly sending the unsupported fsctl to server
766 * if the file is repeatedly extended.
767 */
768 if (tcon->broken_sparse_sup)
769 goto smb2_set_eof;
770
771 rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
772 cfile->fid.volatile_fid, FSCTL_SET_SPARSE,
773 true /* is_fctl */, &set_sparse, 1, NULL, NULL);
774 if (rc) {
775 tcon->broken_sparse_sup = true;
776 cifs_dbg(FYI, "set sparse rc = %d\n", rc);
777 } else
778 cifsi->cifsAttrs |= FILE_ATTRIBUTE_SPARSE_FILE;
779 } 798 }
780 799
781smb2_set_eof:
782 return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid, 800 return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
783 cfile->fid.volatile_fid, cfile->pid, &eof, false); 801 cfile->fid.volatile_fid, cfile->pid, &eof, false);
784} 802}