diff options
author | Steve French <smfrench@gmail.com> | 2014-08-13 18:16:29 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2014-08-16 00:01:00 -0400 |
commit | d43cc79343dfabf9f168531d3f5cff313205c8fb (patch) | |
tree | 7f17f1c5b8f8ce58ecb9d4faad57b38387be3533 /fs/cifs/smb2ops.c | |
parent | 3d1a3745d8ca7ccdf00905b01fd5ab42ff523a94 (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.c | 80 |
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 */ | ||
735 | static 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 | |||
734 | static int | 780 | static int |
735 | smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon, | 781 | smb2_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 | ||
781 | smb2_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 | } |