aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/smb2ops.c
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/smb2ops.c
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/smb2ops.c')
-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}