diff options
author | Ronnie Sahlberg <lsahlber@redhat.com> | 2019-04-25 16:45:29 +1000 |
---|---|---|
committer | Steve French <stfrench@microsoft.com> | 2019-05-07 23:24:55 -0500 |
commit | 2f3ebaba13cebd8badfb9aed31c0cf3cc82eb4f4 (patch) | |
tree | cd2e5193de15784d7e50ce1a42d2a55ae8727f5f /fs/cifs/inode.c | |
parent | d7bef4c4ebe4a2b1788d0214a08d69518e0de3cc (diff) | |
download | linux-stable-2f3ebaba13cebd8badfb9aed31c0cf3cc82eb4f4.tar.gz linux-stable-2f3ebaba13cebd8badfb9aed31c0cf3cc82eb4f4.tar.bz2 linux-stable-2f3ebaba13cebd8badfb9aed31c0cf3cc82eb4f4.zip |
cifs: add fiemap support
Useful for improved copy performance as well as for
applications which query allocated ranges of sparse
files.
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 538fd7d807e4..d7cc62252634 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -2116,6 +2116,43 @@ int cifs_getattr(const struct path *path, struct kstat *stat, return rc; } +int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start, + u64 len) +{ + struct cifsInodeInfo *cifs_i = CIFS_I(inode); + struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_i->vfs_inode.i_sb); + struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); + struct TCP_Server_Info *server = tcon->ses->server; + struct cifsFileInfo *cfile; + int rc; + + /* + * We need to be sure that all dirty pages are written as they + * might fill holes on the server. + */ + if (!CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping && + inode->i_mapping->nrpages != 0) { + rc = filemap_fdatawait(inode->i_mapping); + if (rc) { + mapping_set_error(inode->i_mapping, rc); + return rc; + } + } + + cfile = find_readable_file(cifs_i, false); + if (cfile == NULL) + return -EINVAL; + + if (server->ops->fiemap) { + rc = server->ops->fiemap(tcon, cfile, fei, start, len); + cifsFileInfo_put(cfile); + return rc; + } + + cifsFileInfo_put(cfile); + return -ENOTSUPP; +} + static int cifs_truncate_page(struct address_space *mapping, loff_t from) { pgoff_t index = from >> PAGE_SHIFT; |