diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2012-09-18 19:20:34 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-09-24 22:46:30 -0400 |
commit | 6fc05c25ca35e65ee1759dd803f23576a268f5ec (patch) | |
tree | 048a8fa4bf1e8c0b486d8b037f0b7eaaf0b4c755 /fs/cifs/smb2pdu.c | |
parent | 76ec5e33846de386f44826f145cd725b92c23630 (diff) |
CIFS: Add statfs support for SMB2
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/smb2pdu.c')
-rw-r--r-- | fs/cifs/smb2pdu.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 566d86b0ad96..994c184ac9a9 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -1971,3 +1971,84 @@ SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, | |||
1971 | 1971 | ||
1972 | return rc; | 1972 | return rc; |
1973 | } | 1973 | } |
1974 | |||
1975 | static void | ||
1976 | copy_fs_info_to_kstatfs(struct smb2_fs_full_size_info *pfs_inf, | ||
1977 | struct kstatfs *kst) | ||
1978 | { | ||
1979 | kst->f_bsize = le32_to_cpu(pfs_inf->BytesPerSector) * | ||
1980 | le32_to_cpu(pfs_inf->SectorsPerAllocationUnit); | ||
1981 | kst->f_blocks = le64_to_cpu(pfs_inf->TotalAllocationUnits); | ||
1982 | kst->f_bfree = le64_to_cpu(pfs_inf->ActualAvailableAllocationUnits); | ||
1983 | kst->f_bavail = le64_to_cpu(pfs_inf->CallerAvailableAllocationUnits); | ||
1984 | return; | ||
1985 | } | ||
1986 | |||
1987 | static int | ||
1988 | build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, int level, | ||
1989 | int outbuf_len, u64 persistent_fid, u64 volatile_fid) | ||
1990 | { | ||
1991 | int rc; | ||
1992 | struct smb2_query_info_req *req; | ||
1993 | |||
1994 | cFYI(1, "Query FSInfo level %d", level); | ||
1995 | |||
1996 | if ((tcon->ses == NULL) || (tcon->ses->server == NULL)) | ||
1997 | return -EIO; | ||
1998 | |||
1999 | rc = small_smb2_init(SMB2_QUERY_INFO, tcon, (void **) &req); | ||
2000 | if (rc) | ||
2001 | return rc; | ||
2002 | |||
2003 | req->InfoType = SMB2_O_INFO_FILESYSTEM; | ||
2004 | req->FileInfoClass = level; | ||
2005 | req->PersistentFileId = persistent_fid; | ||
2006 | req->VolatileFileId = volatile_fid; | ||
2007 | /* 4 for rfc1002 length field and 1 for pad */ | ||
2008 | req->InputBufferOffset = | ||
2009 | cpu_to_le16(sizeof(struct smb2_query_info_req) - 1 - 4); | ||
2010 | req->OutputBufferLength = cpu_to_le32( | ||
2011 | outbuf_len + sizeof(struct smb2_query_info_rsp) - 1 - 4); | ||
2012 | |||
2013 | iov->iov_base = (char *)req; | ||
2014 | /* 4 for rfc1002 length field */ | ||
2015 | iov->iov_len = get_rfc1002_length(req) + 4; | ||
2016 | return 0; | ||
2017 | } | ||
2018 | |||
2019 | int | ||
2020 | SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, | ||
2021 | u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata) | ||
2022 | { | ||
2023 | struct smb2_query_info_rsp *rsp = NULL; | ||
2024 | struct kvec iov; | ||
2025 | int rc = 0; | ||
2026 | int resp_buftype; | ||
2027 | struct cifs_ses *ses = tcon->ses; | ||
2028 | struct smb2_fs_full_size_info *info = NULL; | ||
2029 | |||
2030 | rc = build_qfs_info_req(&iov, tcon, FS_FULL_SIZE_INFORMATION, | ||
2031 | sizeof(struct smb2_fs_full_size_info), | ||
2032 | persistent_fid, volatile_fid); | ||
2033 | if (rc) | ||
2034 | return rc; | ||
2035 | |||
2036 | rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, 0); | ||
2037 | if (rc) { | ||
2038 | cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); | ||
2039 | goto qinf_exit; | ||
2040 | } | ||
2041 | rsp = (struct smb2_query_info_rsp *)iov.iov_base; | ||
2042 | |||
2043 | info = (struct smb2_fs_full_size_info *)(4 /* RFC1001 len */ + | ||
2044 | le16_to_cpu(rsp->OutputBufferOffset) + (char *)&rsp->hdr); | ||
2045 | rc = validate_buf(le16_to_cpu(rsp->OutputBufferOffset), | ||
2046 | le32_to_cpu(rsp->OutputBufferLength), &rsp->hdr, | ||
2047 | sizeof(struct smb2_fs_full_size_info)); | ||
2048 | if (!rc) | ||
2049 | copy_fs_info_to_kstatfs(info, fsdata); | ||
2050 | |||
2051 | qinf_exit: | ||
2052 | free_rsp_buf(resp_buftype, iov.iov_base); | ||
2053 | return rc; | ||
2054 | } | ||