diff options
| -rw-r--r-- | fs/cifs/cifsfs.c | 11 | ||||
| -rw-r--r-- | fs/cifs/cifspdu.h | 16 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 14 |
3 files changed, 33 insertions, 8 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 850738ed1eaf..dec4d9149d35 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -170,7 +170,7 @@ cifs_put_super(struct super_block *sb) static int cifs_statfs(struct super_block *sb, struct kstatfs *buf) { - int xid, rc; + int xid, rc = 0; struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; @@ -189,6 +189,15 @@ cifs_statfs(struct super_block *sb, struct kstatfs *buf) buf->f_files = 0; /* undefined */ buf->f_ffree = 0; /* unlimited */ +#ifdef CONFIG_CIFS_EXPERIMENTAL +/* BB we could add a second check for a QFS Unix capability bit */ + if (pTcon->ses->capabilities & CAP_UNIX) + rc = CIFSSMBQFSPosixInfo(xid, pTcon, buf, cifs_sb->local_nls); + + /* Only need to call the old QFSInfo if failed + on newer one */ + if(rc) +#endif /* CIFS_EXPERIMENTAL */ rc = CIFSSMBQFSInfo(xid, pTcon, buf, cifs_sb->local_nls); /* diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index d176d966047c..c5b7a560902e 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -1509,12 +1509,20 @@ typedef struct { #define CIFS_UNIX_XATTR_CAP 0x00000004 /*support for new namespace*/ typedef struct { - /* For undefined values return -1 in that field */ + /* For undefined recommended transfer size return -1 in that field */ __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */ __le32 BlockSize; - __le64 TotalBlocks; /* redundant but easy to return */ - __le64 BlocksAvail; /* redundant but easy to return */ - __le64 UserBlocksAvail; /* bavail */ + /* The next three fields are in terms of the block size. + (above). If block size is unknown, 4096 would be a + reasonable block size for a server to report. + Note that returning the blocks/blocksavail removes need + to make a second call (to QFSInfo level 0x103 to get this info. + UserBlockAvail is typically less than or equal to BlocksAvail, + if no distinction is made return the same value in each */ + __le64 TotalBlocks; + __le64 BlocksAvail; /* bfree */ + __le64 UserBlocksAvail; /* bavail */ + /* For undefined Node fields or FSID return -1 */ __le64 TotalFileNodes; __le64 FreeFileNodes; __le64 FileSysIdentifier; /* fsid */ diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index c47ad1a96587..8a06dba05abb 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -3159,15 +3159,23 @@ QFSPosixRetry: (FILE_SYSTEM_POSIX_INFO *) (((char *) &pSMBr->hdr.Protocol) + data_offset); + FSData->f_bsize = + le32_to_cpu(response_data->BlockSize); FSData->f_blocks = le64_to_cpu(response_data->TotalBlocks); FSData->f_bfree = le64_to_cpu(response_data->BlocksAvail); - FSData->f_bavail = + if(response_data->UserBlocksAvail == -1) { + FSData->f_bavail = FSData->f_bfree; + } else { + FSData->f_bavail = le64_to_cpu(response_data->UserBlocksAvail); - FSData->f_files = + } + if(response_data->TotalFileNodes != -1) + FSData->f_files = le64_to_cpu(response_data->TotalFileNodes); - FSData->f_ffree = + if(response_data->FreeFileNodes != -1) + FSData->f_ffree = le64_to_cpu(response_data->FreeFileNodes); } } |
