* [PATCH] cifs: move some bloat out of cifsfs.c to inode.c/file.c/dir.c
@ 2022-08-01 21:36 Enzo Matsumiya
2022-08-02 4:47 ` kernel test robot
0 siblings, 1 reply; 2+ messages in thread
From: Enzo Matsumiya @ 2022-08-01 21:36 UTC (permalink / raw)
To: linux-cifs; +Cc: smfrench, pc, ronniesahlberg, nspmangalore
Leave cifsfs.c with crucial code only, while making it easier to
identify what to move/remove from dir/file/inode re: SMB1 split.
Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
---
fs/cifs/cifsfs.c | 596 +----------------------------------------------
fs/cifs/dir.c | 29 +++
fs/cifs/file.c | 406 ++++++++++++++++++++++++++++++++
fs/cifs/inode.c | 149 ++++++++++++
4 files changed, 592 insertions(+), 588 deletions(-)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index af4c5632490e..c3c2ae62d222 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -155,6 +155,14 @@ struct workqueue_struct *cifsoplockd_wq;
struct workqueue_struct *deferredclose_wq;
__u32 cifs_lock_secret;
+extern struct inode *cifs_alloc_inode(struct super_block *);
+extern void cifs_free_inode(struct inode *);
+extern void cifs_evict_inode(struct inode *);
+extern int cifs_write_inode(struct inode *, struct writeback_control *);
+extern int cifs_drop_inode(struct inode *);
+extern int cifs_init_inodecache(void) __init;
+extern void cifs_destroy_inodecache(void);
+
/*
* Bumps refcount for cifs super block.
* Note that it should be only called if a referece to VFS super block is
@@ -349,38 +357,6 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
return rc;
}
-static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len)
-{
- struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
- struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
- struct TCP_Server_Info *server = tcon->ses->server;
-
- if (server->ops->fallocate)
- return server->ops->fallocate(file, tcon, mode, off, len);
-
- return -EOPNOTSUPP;
-}
-
-static int cifs_permission(struct user_namespace *mnt_userns,
- struct inode *inode, int mask)
-{
- struct cifs_sb_info *cifs_sb;
-
- cifs_sb = CIFS_SB(inode->i_sb);
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
- if ((mask & MAY_EXEC) && !execute_ok(inode))
- return -EACCES;
- else
- return 0;
- } else /* file mode might have been restricted at mount time
- on the client (above and beyond ACL on servers) for
- servers which do not support setting and viewing mode bits,
- so allowing client to check permissions is useful */
- return generic_permission(&init_user_ns, inode, mask);
-}
-
-static struct kmem_cache *cifs_inode_cachep;
static struct kmem_cache *cifs_req_cachep;
static struct kmem_cache *cifs_mid_cachep;
static struct kmem_cache *cifs_sm_req_cachep;
@@ -388,59 +364,6 @@ mempool_t *cifs_sm_req_poolp;
mempool_t *cifs_req_poolp;
mempool_t *cifs_mid_poolp;
-static struct inode *
-cifs_alloc_inode(struct super_block *sb)
-{
- struct cifsInodeInfo *cifs_inode;
- cifs_inode = alloc_inode_sb(sb, cifs_inode_cachep, GFP_KERNEL);
- if (!cifs_inode)
- return NULL;
- cifs_inode->cifsAttrs = 0x20; /* default */
- cifs_inode->time = 0;
- /*
- * Until the file is open and we have gotten oplock info back from the
- * server, can not assume caching of file data or metadata.
- */
- cifs_set_oplock_level(cifs_inode, 0);
- cifs_inode->flags = 0;
- spin_lock_init(&cifs_inode->writers_lock);
- cifs_inode->writers = 0;
- cifs_inode->netfs.inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
- cifs_inode->server_eof = 0;
- cifs_inode->uniqueid = 0;
- cifs_inode->createtime = 0;
- cifs_inode->epoch = 0;
- spin_lock_init(&cifs_inode->open_file_lock);
- generate_random_uuid(cifs_inode->lease_key);
-
- /*
- * Can not set i_flags here - they get immediately overwritten to zero
- * by the VFS.
- */
- /* cifs_inode->netfs.inode.i_flags = S_NOATIME | S_NOCMTIME; */
- INIT_LIST_HEAD(&cifs_inode->openFileList);
- INIT_LIST_HEAD(&cifs_inode->llist);
- INIT_LIST_HEAD(&cifs_inode->deferred_closes);
- spin_lock_init(&cifs_inode->deferred_lock);
- return &cifs_inode->netfs.inode;
-}
-
-static void
-cifs_free_inode(struct inode *inode)
-{
- kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
-}
-
-static void
-cifs_evict_inode(struct inode *inode)
-{
- truncate_inode_pages_final(&inode->i_data);
- if (inode->i_state & I_PINNING_FSCACHE_WB)
- cifs_fscache_unuse_inode_cookie(inode, true);
- cifs_fscache_release_inode_cookie(inode);
- clear_inode(inode);
-}
-
static void
cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server)
{
@@ -767,21 +690,6 @@ static int cifs_show_stats(struct seq_file *s, struct dentry *root)
}
#endif
-static int cifs_write_inode(struct inode *inode, struct writeback_control *wbc)
-{
- fscache_unpin_writeback(wbc, cifs_inode_cookie(inode));
- return 0;
-}
-
-static int cifs_drop_inode(struct inode *inode)
-{
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
-
- /* no serverino => unconditional eviction */
- return !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) ||
- generic_drop_inode(inode);
-}
-
static const struct super_operations cifs_super_ops = {
.statfs = cifs_statfs,
.alloc_inode = cifs_alloc_inode,
@@ -789,12 +697,7 @@ static const struct super_operations cifs_super_ops = {
.free_inode = cifs_free_inode,
.drop_inode = cifs_drop_inode,
.evict_inode = cifs_evict_inode,
-/* .show_path = cifs_show_path, */ /* Would we ever need show path? */
.show_devname = cifs_show_devname,
-/* .delete_inode = cifs_delete_inode, */ /* Do not need above
- function unless later we add lazy close of inodes or unless the
- kernel forgets to call us with the same number of releases (closes)
- as opens */
.show_options = cifs_show_options,
.umount_begin = cifs_umount_begin,
#ifdef CONFIG_CIFS_STATS2
@@ -974,139 +877,6 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
return root;
}
-
-static ssize_t
-cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter)
-{
- ssize_t rc;
- struct inode *inode = file_inode(iocb->ki_filp);
-
- if (iocb->ki_flags & IOCB_DIRECT)
- return cifs_user_readv(iocb, iter);
-
- rc = cifs_revalidate_mapping(inode);
- if (rc)
- return rc;
-
- return generic_file_read_iter(iocb, iter);
-}
-
-static ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
-{
- struct inode *inode = file_inode(iocb->ki_filp);
- struct cifsInodeInfo *cinode = CIFS_I(inode);
- ssize_t written;
- int rc;
-
- if (iocb->ki_filp->f_flags & O_DIRECT) {
- written = cifs_user_writev(iocb, from);
- if (written > 0 && CIFS_CACHE_READ(cinode)) {
- cifs_zap_mapping(inode);
- cifs_dbg(FYI,
- "Set no oplock for inode=%p after a write operation\n",
- inode);
- cinode->oplock = 0;
- }
- return written;
- }
-
- written = cifs_get_writer(cinode);
- if (written)
- return written;
-
- written = generic_file_write_iter(iocb, from);
-
- if (CIFS_CACHE_WRITE(CIFS_I(inode)))
- goto out;
-
- rc = filemap_fdatawrite(inode->i_mapping);
- if (rc)
- cifs_dbg(FYI, "cifs_file_write_iter: %d rc on %p inode\n",
- rc, inode);
-
-out:
- cifs_put_writer(cinode);
- return written;
-}
-
-static loff_t cifs_llseek(struct file *file, loff_t offset, int whence)
-{
- struct cifsFileInfo *cfile = file->private_data;
- struct cifs_tcon *tcon;
-
- /*
- * whence == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate
- * the cached file length
- */
- if (whence != SEEK_SET && whence != SEEK_CUR) {
- int rc;
- struct inode *inode = file_inode(file);
-
- /*
- * We need to be sure that all dirty pages are written and the
- * server has the newest file length.
- */
- 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;
- }
- }
- /*
- * Some applications poll for the file length in this strange
- * way so we must seek to end on non-oplocked files by
- * setting the revalidate time to zero.
- */
- CIFS_I(inode)->time = 0;
-
- rc = cifs_revalidate_file_attr(file);
- if (rc < 0)
- return (loff_t)rc;
- }
- if (cfile && cfile->tlink) {
- tcon = tlink_tcon(cfile->tlink);
- if (tcon->ses->server->ops->llseek)
- return tcon->ses->server->ops->llseek(file, tcon,
- offset, whence);
- }
- return generic_file_llseek(file, offset, whence);
-}
-
-static int
-cifs_setlease(struct file *file, long arg, struct file_lock **lease, void **priv)
-{
- /*
- * Note that this is called by vfs setlease with i_lock held to
- * protect *lease from going away.
- */
- struct inode *inode = file_inode(file);
- struct cifsFileInfo *cfile = file->private_data;
-
- if (!(S_ISREG(inode->i_mode)))
- return -EINVAL;
-
- /* Check if file is oplocked if this is request for new lease */
- if (arg == F_UNLCK ||
- ((arg == F_RDLCK) && CIFS_CACHE_READ(CIFS_I(inode))) ||
- ((arg == F_WRLCK) && CIFS_CACHE_WRITE(CIFS_I(inode))))
- return generic_setlease(file, arg, lease, priv);
- else if (tlink_tcon(cfile->tlink)->local_lease &&
- !CIFS_CACHE_READ(CIFS_I(inode)))
- /*
- * If the server claims to support oplock on this file, then we
- * still need to check oplock even if the local_lease mount
- * option is set, but there are servers which do not support
- * oplock for which this mount option may be useful if the user
- * knows that the file won't be changed on the server by anyone
- * else.
- */
- return generic_setlease(file, arg, lease, priv);
- else
- return -EAGAIN;
-}
-
struct file_system_type cifs_fs_type = {
.owner = THIS_MODULE,
.name = "cifs",
@@ -1128,356 +898,6 @@ struct file_system_type smb3_fs_type = {
MODULE_ALIAS_FS("smb3");
MODULE_ALIAS("smb3");
-const struct inode_operations cifs_dir_inode_ops = {
- .create = cifs_create,
- .atomic_open = cifs_atomic_open,
- .lookup = cifs_lookup,
- .getattr = cifs_getattr,
- .unlink = cifs_unlink,
- .link = cifs_hardlink,
- .mkdir = cifs_mkdir,
- .rmdir = cifs_rmdir,
- .rename = cifs_rename2,
- .permission = cifs_permission,
- .setattr = cifs_setattr,
- .symlink = cifs_symlink,
- .mknod = cifs_mknod,
- .listxattr = cifs_listxattr,
-};
-
-const struct inode_operations cifs_file_inode_ops = {
- .setattr = cifs_setattr,
- .getattr = cifs_getattr,
- .permission = cifs_permission,
- .listxattr = cifs_listxattr,
- .fiemap = cifs_fiemap,
-};
-
-const struct inode_operations cifs_symlink_inode_ops = {
- .get_link = cifs_get_link,
- .permission = cifs_permission,
- .listxattr = cifs_listxattr,
-};
-
-static loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
- struct file *dst_file, loff_t destoff, loff_t len,
- unsigned int remap_flags)
-{
- struct inode *src_inode = file_inode(src_file);
- struct inode *target_inode = file_inode(dst_file);
- struct cifsFileInfo *smb_file_src = src_file->private_data;
- struct cifsFileInfo *smb_file_target;
- struct cifs_tcon *target_tcon;
- unsigned int xid;
- int rc;
-
- if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY))
- return -EINVAL;
-
- cifs_dbg(FYI, "clone range\n");
-
- xid = get_xid();
-
- if (!src_file->private_data || !dst_file->private_data) {
- rc = -EBADF;
- cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n");
- goto out;
- }
-
- smb_file_target = dst_file->private_data;
- target_tcon = tlink_tcon(smb_file_target->tlink);
-
- /*
- * Note: cifs case is easier than btrfs since server responsible for
- * checks for proper open modes and file type and if it wants
- * server could even support copy of range where source = target
- */
- lock_two_nondirectories(target_inode, src_inode);
-
- if (len == 0)
- len = src_inode->i_size - off;
-
- cifs_dbg(FYI, "about to flush pages\n");
- /* should we flush first and last page first */
- truncate_inode_pages_range(&target_inode->i_data, destoff,
- PAGE_ALIGN(destoff + len)-1);
-
- if (target_tcon->ses->server->ops->duplicate_extents)
- rc = target_tcon->ses->server->ops->duplicate_extents(xid,
- smb_file_src, smb_file_target, off, len, destoff);
- else
- rc = -EOPNOTSUPP;
-
- /* force revalidate of size and timestamps of target file now
- that target is updated on the server */
- CIFS_I(target_inode)->time = 0;
- /* although unlocking in the reverse order from locking is not
- strictly necessary here it is a little cleaner to be consistent */
- unlock_two_nondirectories(src_inode, target_inode);
-out:
- free_xid(xid);
- return rc < 0 ? rc : len;
-}
-
-ssize_t cifs_file_copychunk_range(unsigned int xid,
- struct file *src_file, loff_t off,
- struct file *dst_file, loff_t destoff,
- size_t len, unsigned int flags)
-{
- struct inode *src_inode = file_inode(src_file);
- struct inode *target_inode = file_inode(dst_file);
- struct cifsFileInfo *smb_file_src;
- struct cifsFileInfo *smb_file_target;
- struct cifs_tcon *src_tcon;
- struct cifs_tcon *target_tcon;
- ssize_t rc;
-
- cifs_dbg(FYI, "copychunk range\n");
-
- if (!src_file->private_data || !dst_file->private_data) {
- rc = -EBADF;
- cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n");
- goto out;
- }
-
- rc = -EXDEV;
- smb_file_target = dst_file->private_data;
- smb_file_src = src_file->private_data;
- src_tcon = tlink_tcon(smb_file_src->tlink);
- target_tcon = tlink_tcon(smb_file_target->tlink);
-
- if (src_tcon->ses != target_tcon->ses) {
- cifs_dbg(VFS, "source and target of copy not on same server\n");
- goto out;
- }
-
- rc = -EOPNOTSUPP;
- if (!target_tcon->ses->server->ops->copychunk_range)
- goto out;
-
- /*
- * Note: cifs case is easier than btrfs since server responsible for
- * checks for proper open modes and file type and if it wants
- * server could even support copy of range where source = target
- */
- lock_two_nondirectories(target_inode, src_inode);
-
- cifs_dbg(FYI, "about to flush pages\n");
- /* should we flush first and last page first */
- truncate_inode_pages(&target_inode->i_data, 0);
-
- rc = file_modified(dst_file);
- if (!rc)
- rc = target_tcon->ses->server->ops->copychunk_range(xid,
- smb_file_src, smb_file_target, off, len, destoff);
-
- file_accessed(src_file);
-
- /* force revalidate of size and timestamps of target file now
- * that target is updated on the server
- */
- CIFS_I(target_inode)->time = 0;
- /* although unlocking in the reverse order from locking is not
- * strictly necessary here it is a little cleaner to be consistent
- */
- unlock_two_nondirectories(src_inode, target_inode);
-
-out:
- return rc;
-}
-
-/*
- * Directory operations under CIFS/SMB2/SMB3 are synchronous, so fsync()
- * is a dummy operation.
- */
-static int cifs_dir_fsync(struct file *file, loff_t start, loff_t end, int datasync)
-{
- cifs_dbg(FYI, "Sync directory - name: %pD datasync: 0x%x\n",
- file, datasync);
-
- return 0;
-}
-
-static ssize_t cifs_copy_file_range(struct file *src_file, loff_t off,
- struct file *dst_file, loff_t destoff,
- size_t len, unsigned int flags)
-{
- unsigned int xid = get_xid();
- ssize_t rc;
- struct cifsFileInfo *cfile = dst_file->private_data;
-
- if (cfile->swapfile)
- return -EOPNOTSUPP;
-
- rc = cifs_file_copychunk_range(xid, src_file, off, dst_file, destoff,
- len, flags);
- free_xid(xid);
-
- if (rc == -EOPNOTSUPP || rc == -EXDEV)
- rc = generic_copy_file_range(src_file, off, dst_file,
- destoff, len, flags);
- return rc;
-}
-
-const struct file_operations cifs_file_ops = {
- .read_iter = cifs_loose_read_iter,
- .write_iter = cifs_file_write_iter,
- .open = cifs_open,
- .release = cifs_close,
- .lock = cifs_lock,
- .flock = cifs_flock,
- .fsync = cifs_fsync,
- .flush = cifs_flush,
- .mmap = cifs_file_mmap,
- .splice_read = generic_file_splice_read,
- .splice_write = iter_file_splice_write,
- .llseek = cifs_llseek,
- .unlocked_ioctl = cifs_ioctl,
- .copy_file_range = cifs_copy_file_range,
- .remap_file_range = cifs_remap_file_range,
- .setlease = cifs_setlease,
- .fallocate = cifs_fallocate,
-};
-
-const struct file_operations cifs_file_strict_ops = {
- .read_iter = cifs_strict_readv,
- .write_iter = cifs_strict_writev,
- .open = cifs_open,
- .release = cifs_close,
- .lock = cifs_lock,
- .flock = cifs_flock,
- .fsync = cifs_strict_fsync,
- .flush = cifs_flush,
- .mmap = cifs_file_strict_mmap,
- .splice_read = generic_file_splice_read,
- .splice_write = iter_file_splice_write,
- .llseek = cifs_llseek,
- .unlocked_ioctl = cifs_ioctl,
- .copy_file_range = cifs_copy_file_range,
- .remap_file_range = cifs_remap_file_range,
- .setlease = cifs_setlease,
- .fallocate = cifs_fallocate,
-};
-
-const struct file_operations cifs_file_direct_ops = {
- .read_iter = cifs_direct_readv,
- .write_iter = cifs_direct_writev,
- .open = cifs_open,
- .release = cifs_close,
- .lock = cifs_lock,
- .flock = cifs_flock,
- .fsync = cifs_fsync,
- .flush = cifs_flush,
- .mmap = cifs_file_mmap,
- .splice_read = generic_file_splice_read,
- .splice_write = iter_file_splice_write,
- .unlocked_ioctl = cifs_ioctl,
- .copy_file_range = cifs_copy_file_range,
- .remap_file_range = cifs_remap_file_range,
- .llseek = cifs_llseek,
- .setlease = cifs_setlease,
- .fallocate = cifs_fallocate,
-};
-
-const struct file_operations cifs_file_nobrl_ops = {
- .read_iter = cifs_loose_read_iter,
- .write_iter = cifs_file_write_iter,
- .open = cifs_open,
- .release = cifs_close,
- .fsync = cifs_fsync,
- .flush = cifs_flush,
- .mmap = cifs_file_mmap,
- .splice_read = generic_file_splice_read,
- .splice_write = iter_file_splice_write,
- .llseek = cifs_llseek,
- .unlocked_ioctl = cifs_ioctl,
- .copy_file_range = cifs_copy_file_range,
- .remap_file_range = cifs_remap_file_range,
- .setlease = cifs_setlease,
- .fallocate = cifs_fallocate,
-};
-
-const struct file_operations cifs_file_strict_nobrl_ops = {
- .read_iter = cifs_strict_readv,
- .write_iter = cifs_strict_writev,
- .open = cifs_open,
- .release = cifs_close,
- .fsync = cifs_strict_fsync,
- .flush = cifs_flush,
- .mmap = cifs_file_strict_mmap,
- .splice_read = generic_file_splice_read,
- .splice_write = iter_file_splice_write,
- .llseek = cifs_llseek,
- .unlocked_ioctl = cifs_ioctl,
- .copy_file_range = cifs_copy_file_range,
- .remap_file_range = cifs_remap_file_range,
- .setlease = cifs_setlease,
- .fallocate = cifs_fallocate,
-};
-
-const struct file_operations cifs_file_direct_nobrl_ops = {
- .read_iter = cifs_direct_readv,
- .write_iter = cifs_direct_writev,
- .open = cifs_open,
- .release = cifs_close,
- .fsync = cifs_fsync,
- .flush = cifs_flush,
- .mmap = cifs_file_mmap,
- .splice_read = generic_file_splice_read,
- .splice_write = iter_file_splice_write,
- .unlocked_ioctl = cifs_ioctl,
- .copy_file_range = cifs_copy_file_range,
- .remap_file_range = cifs_remap_file_range,
- .llseek = cifs_llseek,
- .setlease = cifs_setlease,
- .fallocate = cifs_fallocate,
-};
-
-const struct file_operations cifs_dir_ops = {
- .iterate_shared = cifs_readdir,
- .release = cifs_closedir,
- .read = generic_read_dir,
- .unlocked_ioctl = cifs_ioctl,
- .copy_file_range = cifs_copy_file_range,
- .remap_file_range = cifs_remap_file_range,
- .llseek = generic_file_llseek,
- .fsync = cifs_dir_fsync,
-};
-
-static void
-cifs_init_once(void *inode)
-{
- struct cifsInodeInfo *cifsi = inode;
-
- inode_init_once(&cifsi->netfs.inode);
- init_rwsem(&cifsi->lock_sem);
-}
-
-static int __init
-cifs_init_inodecache(void)
-{
- cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
- sizeof(struct cifsInodeInfo),
- 0, (SLAB_RECLAIM_ACCOUNT|
- SLAB_MEM_SPREAD|SLAB_ACCOUNT),
- cifs_init_once);
- if (cifs_inode_cachep == NULL)
- return -ENOMEM;
-
- return 0;
-}
-
-static void
-cifs_destroy_inodecache(void)
-{
- /*
- * Make sure all delayed rcu free inodes are flushed before we
- * destroy cache.
- */
- rcu_barrier();
- kmem_cache_destroy(cifs_inode_cachep);
-}
-
static int
cifs_init_request_bufs(void)
{
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 08f7392716e2..c95532b6ee72 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -24,6 +24,12 @@
#include "cifs_ioctl.h"
#include "fscache.h"
+
+extern ssize_t cifs_copy_file_range(struct file *, loff_t, struct file *, loff_t,
+ size_t, unsigned int);
+extern loff_t cifs_remap_file_range(struct file *, loff_t, struct file *,
+ loff_t, loff_t, unsigned int);
+
static void
renew_parental_timestamps(struct dentry *direntry)
{
@@ -870,3 +876,26 @@ const struct dentry_operations cifs_ci_dentry_ops = {
.d_compare = cifs_ci_compare,
.d_automount = cifs_dfs_d_automount,
};
+
+/*
+ * Directory operations under CIFS/SMB2/SMB3 are synchronous, so fsync()
+ * is a dummy operation.
+ */
+static int cifs_dir_fsync(struct file *file, loff_t start, loff_t end, int datasync)
+{
+ cifs_dbg(FYI, "Sync directory - name: %pD datasync: 0x%x\n",
+ file, datasync);
+
+ return 0;
+}
+
+const struct file_operations cifs_dir_ops = {
+ .iterate_shared = cifs_readdir,
+ .release = cifs_closedir,
+ .read = generic_read_dir,
+ .unlocked_ioctl = cifs_ioctl,
+ .copy_file_range = cifs_copy_file_range,
+ .remap_file_range = cifs_remap_file_range,
+ .llseek = generic_file_llseek,
+ .fsync = cifs_dir_fsync,
+};
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 85f2abcb2795..6b39ccede67d 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -5228,6 +5228,298 @@ static bool cifs_dirty_folio(struct address_space *mapping, struct folio *folio)
#define cifs_dirty_folio filemap_dirty_folio
#endif
+static ssize_t
+cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter)
+{
+ ssize_t rc;
+ struct inode *inode = file_inode(iocb->ki_filp);
+
+ if (iocb->ki_flags & IOCB_DIRECT)
+ return cifs_user_readv(iocb, iter);
+
+ rc = cifs_revalidate_mapping(inode);
+ if (rc)
+ return rc;
+
+ return generic_file_read_iter(iocb, iter);
+}
+
+static ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
+{
+ struct inode *inode = file_inode(iocb->ki_filp);
+ struct cifsInodeInfo *cinode = CIFS_I(inode);
+ ssize_t written;
+ int rc;
+
+ if (iocb->ki_filp->f_flags & O_DIRECT) {
+ written = cifs_user_writev(iocb, from);
+ if (written > 0 && CIFS_CACHE_READ(cinode)) {
+ cifs_zap_mapping(inode);
+ cifs_dbg(FYI,
+ "Set no oplock for inode=%p after a write operation\n",
+ inode);
+ cinode->oplock = 0;
+ }
+ return written;
+ }
+
+ written = cifs_get_writer(cinode);
+ if (written)
+ return written;
+
+ written = generic_file_write_iter(iocb, from);
+
+ if (CIFS_CACHE_WRITE(CIFS_I(inode)))
+ goto out;
+
+ rc = filemap_fdatawrite(inode->i_mapping);
+ if (rc)
+ cifs_dbg(FYI, "cifs_file_write_iter: %d rc on %p inode\n",
+ rc, inode);
+
+out:
+ cifs_put_writer(cinode);
+ return written;
+}
+
+static loff_t cifs_llseek(struct file *file, loff_t offset, int whence)
+{
+ struct cifsFileInfo *cfile = file->private_data;
+ struct cifs_tcon *tcon;
+
+ /*
+ * whence == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate
+ * the cached file length
+ */
+ if (whence != SEEK_SET && whence != SEEK_CUR) {
+ int rc;
+ struct inode *inode = file_inode(file);
+
+ /*
+ * We need to be sure that all dirty pages are written and the
+ * server has the newest file length.
+ */
+ 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;
+ }
+ }
+ /*
+ * Some applications poll for the file length in this strange
+ * way so we must seek to end on non-oplocked files by
+ * setting the revalidate time to zero.
+ */
+ CIFS_I(inode)->time = 0;
+
+ rc = cifs_revalidate_file_attr(file);
+ if (rc < 0)
+ return (loff_t)rc;
+ }
+ if (cfile && cfile->tlink) {
+ tcon = tlink_tcon(cfile->tlink);
+ if (tcon->ses->server->ops->llseek)
+ return tcon->ses->server->ops->llseek(file, tcon,
+ offset, whence);
+ }
+ return generic_file_llseek(file, offset, whence);
+}
+
+static int
+cifs_setlease(struct file *file, long arg, struct file_lock **lease, void **priv)
+{
+ /*
+ * Note that this is called by vfs setlease with i_lock held to
+ * protect *lease from going away.
+ */
+ struct inode *inode = file_inode(file);
+ struct cifsFileInfo *cfile = file->private_data;
+
+ if (!(S_ISREG(inode->i_mode)))
+ return -EINVAL;
+
+ /* Check if file is oplocked if this is request for new lease */
+ if (arg == F_UNLCK ||
+ ((arg == F_RDLCK) && CIFS_CACHE_READ(CIFS_I(inode))) ||
+ ((arg == F_WRLCK) && CIFS_CACHE_WRITE(CIFS_I(inode))))
+ return generic_setlease(file, arg, lease, priv);
+ else if (tlink_tcon(cfile->tlink)->local_lease &&
+ !CIFS_CACHE_READ(CIFS_I(inode)))
+ /*
+ * If the server claims to support oplock on this file, then we
+ * still need to check oplock even if the local_lease mount
+ * option is set, but there are servers which do not support
+ * oplock for which this mount option may be useful if the user
+ * knows that the file won't be changed on the server by anyone
+ * else.
+ */
+ return generic_setlease(file, arg, lease, priv);
+ else
+ return -EAGAIN;
+}
+
+static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len)
+{
+ struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+ struct TCP_Server_Info *server = tcon->ses->server;
+
+ if (server->ops->fallocate)
+ return server->ops->fallocate(file, tcon, mode, off, len);
+
+ return -EOPNOTSUPP;
+}
+
+loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
+ struct file *dst_file, loff_t destoff, loff_t len,
+ unsigned int remap_flags)
+{
+ struct inode *src_inode = file_inode(src_file);
+ struct inode *target_inode = file_inode(dst_file);
+ struct cifsFileInfo *smb_file_src = src_file->private_data;
+ struct cifsFileInfo *smb_file_target;
+ struct cifs_tcon *target_tcon;
+ unsigned int xid;
+ int rc;
+
+ if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY))
+ return -EINVAL;
+
+ cifs_dbg(FYI, "clone range\n");
+
+ xid = get_xid();
+
+ if (!src_file->private_data || !dst_file->private_data) {
+ rc = -EBADF;
+ cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n");
+ goto out;
+ }
+
+ smb_file_target = dst_file->private_data;
+ target_tcon = tlink_tcon(smb_file_target->tlink);
+
+ /*
+ * Note: cifs case is easier than btrfs since server responsible for
+ * checks for proper open modes and file type and if it wants
+ * server could even support copy of range where source = target
+ */
+ lock_two_nondirectories(target_inode, src_inode);
+
+ if (len == 0)
+ len = src_inode->i_size - off;
+
+ cifs_dbg(FYI, "about to flush pages\n");
+ /* should we flush first and last page first */
+ truncate_inode_pages_range(&target_inode->i_data, destoff,
+ PAGE_ALIGN(destoff + len)-1);
+
+ if (target_tcon->ses->server->ops->duplicate_extents)
+ rc = target_tcon->ses->server->ops->duplicate_extents(xid,
+ smb_file_src, smb_file_target, off, len, destoff);
+ else
+ rc = -EOPNOTSUPP;
+
+ /* force revalidate of size and timestamps of target file now
+ that target is updated on the server */
+ CIFS_I(target_inode)->time = 0;
+ /* although unlocking in the reverse order from locking is not
+ strictly necessary here it is a little cleaner to be consistent */
+ unlock_two_nondirectories(src_inode, target_inode);
+out:
+ free_xid(xid);
+ return rc < 0 ? rc : len;
+}
+
+ssize_t cifs_file_copychunk_range(unsigned int xid,
+ struct file *src_file, loff_t off,
+ struct file *dst_file, loff_t destoff,
+ size_t len, unsigned int flags)
+{
+ struct inode *src_inode = file_inode(src_file);
+ struct inode *target_inode = file_inode(dst_file);
+ struct cifsFileInfo *smb_file_src;
+ struct cifsFileInfo *smb_file_target;
+ struct cifs_tcon *src_tcon;
+ struct cifs_tcon *target_tcon;
+ ssize_t rc;
+
+ cifs_dbg(FYI, "copychunk range\n");
+
+ if (!src_file->private_data || !dst_file->private_data) {
+ rc = -EBADF;
+ cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n");
+ goto out;
+ }
+
+ rc = -EXDEV;
+ smb_file_target = dst_file->private_data;
+ smb_file_src = src_file->private_data;
+ src_tcon = tlink_tcon(smb_file_src->tlink);
+ target_tcon = tlink_tcon(smb_file_target->tlink);
+
+ if (src_tcon->ses != target_tcon->ses) {
+ cifs_dbg(VFS, "source and target of copy not on same server\n");
+ goto out;
+ }
+
+ rc = -EOPNOTSUPP;
+ if (!target_tcon->ses->server->ops->copychunk_range)
+ goto out;
+
+ /*
+ * Note: cifs case is easier than btrfs since server responsible for
+ * checks for proper open modes and file type and if it wants
+ * server could even support copy of range where source = target
+ */
+ lock_two_nondirectories(target_inode, src_inode);
+
+ cifs_dbg(FYI, "about to flush pages\n");
+ /* should we flush first and last page first */
+ truncate_inode_pages(&target_inode->i_data, 0);
+
+ rc = file_modified(dst_file);
+ if (!rc)
+ rc = target_tcon->ses->server->ops->copychunk_range(xid,
+ smb_file_src, smb_file_target, off, len, destoff);
+
+ file_accessed(src_file);
+
+ /* force revalidate of size and timestamps of target file now
+ * that target is updated on the server
+ */
+ CIFS_I(target_inode)->time = 0;
+ /* although unlocking in the reverse order from locking is not
+ * strictly necessary here it is a little cleaner to be consistent
+ */
+ unlock_two_nondirectories(src_inode, target_inode);
+
+out:
+ return rc;
+}
+
+ssize_t cifs_copy_file_range(struct file *src_file, loff_t off,
+ struct file *dst_file, loff_t destoff,
+ size_t len, unsigned int flags)
+{
+ unsigned int xid = get_xid();
+ ssize_t rc;
+ struct cifsFileInfo *cfile = dst_file->private_data;
+
+ if (cfile->swapfile)
+ return -EOPNOTSUPP;
+
+ rc = cifs_file_copychunk_range(xid, src_file, off, dst_file, destoff,
+ len, flags);
+ free_xid(xid);
+
+ if (rc == -EOPNOTSUPP || rc == -EXDEV)
+ rc = generic_copy_file_range(src_file, off, dst_file,
+ destoff, len, flags);
+ return rc;
+}
+
const struct address_space_operations cifs_addr_ops = {
.read_folio = cifs_read_folio,
.readahead = cifs_readahead,
@@ -5265,3 +5557,117 @@ const struct address_space_operations cifs_addr_ops_smallbuf = {
.invalidate_folio = cifs_invalidate_folio,
.launder_folio = cifs_launder_folio,
};
+
+const struct file_operations cifs_file_ops = {
+ .read_iter = cifs_loose_read_iter,
+ .write_iter = cifs_file_write_iter,
+ .open = cifs_open,
+ .release = cifs_close,
+ .lock = cifs_lock,
+ .flock = cifs_flock,
+ .fsync = cifs_fsync,
+ .flush = cifs_flush,
+ .mmap = cifs_file_mmap,
+ .splice_read = generic_file_splice_read,
+ .splice_write = iter_file_splice_write,
+ .llseek = cifs_llseek,
+ .unlocked_ioctl = cifs_ioctl,
+ .copy_file_range = cifs_copy_file_range,
+ .remap_file_range = cifs_remap_file_range,
+ .setlease = cifs_setlease,
+ .fallocate = cifs_fallocate,
+};
+
+const struct file_operations cifs_file_strict_ops = {
+ .read_iter = cifs_strict_readv,
+ .write_iter = cifs_strict_writev,
+ .open = cifs_open,
+ .release = cifs_close,
+ .lock = cifs_lock,
+ .flock = cifs_flock,
+ .fsync = cifs_strict_fsync,
+ .flush = cifs_flush,
+ .mmap = cifs_file_strict_mmap,
+ .splice_read = generic_file_splice_read,
+ .splice_write = iter_file_splice_write,
+ .llseek = cifs_llseek,
+ .unlocked_ioctl = cifs_ioctl,
+ .copy_file_range = cifs_copy_file_range,
+ .remap_file_range = cifs_remap_file_range,
+ .setlease = cifs_setlease,
+ .fallocate = cifs_fallocate,
+};
+
+const struct file_operations cifs_file_direct_ops = {
+ .read_iter = cifs_direct_readv,
+ .write_iter = cifs_direct_writev,
+ .open = cifs_open,
+ .release = cifs_close,
+ .lock = cifs_lock,
+ .flock = cifs_flock,
+ .fsync = cifs_fsync,
+ .flush = cifs_flush,
+ .mmap = cifs_file_mmap,
+ .splice_read = generic_file_splice_read,
+ .splice_write = iter_file_splice_write,
+ .unlocked_ioctl = cifs_ioctl,
+ .copy_file_range = cifs_copy_file_range,
+ .remap_file_range = cifs_remap_file_range,
+ .llseek = cifs_llseek,
+ .setlease = cifs_setlease,
+ .fallocate = cifs_fallocate,
+};
+
+const struct file_operations cifs_file_nobrl_ops = {
+ .read_iter = cifs_loose_read_iter,
+ .write_iter = cifs_file_write_iter,
+ .open = cifs_open,
+ .release = cifs_close,
+ .fsync = cifs_fsync,
+ .flush = cifs_flush,
+ .mmap = cifs_file_mmap,
+ .splice_read = generic_file_splice_read,
+ .splice_write = iter_file_splice_write,
+ .llseek = cifs_llseek,
+ .unlocked_ioctl = cifs_ioctl,
+ .copy_file_range = cifs_copy_file_range,
+ .remap_file_range = cifs_remap_file_range,
+ .setlease = cifs_setlease,
+ .fallocate = cifs_fallocate,
+};
+
+const struct file_operations cifs_file_strict_nobrl_ops = {
+ .read_iter = cifs_strict_readv,
+ .write_iter = cifs_strict_writev,
+ .open = cifs_open,
+ .release = cifs_close,
+ .fsync = cifs_strict_fsync,
+ .flush = cifs_flush,
+ .mmap = cifs_file_strict_mmap,
+ .splice_read = generic_file_splice_read,
+ .splice_write = iter_file_splice_write,
+ .llseek = cifs_llseek,
+ .unlocked_ioctl = cifs_ioctl,
+ .copy_file_range = cifs_copy_file_range,
+ .remap_file_range = cifs_remap_file_range,
+ .setlease = cifs_setlease,
+ .fallocate = cifs_fallocate,
+};
+
+const struct file_operations cifs_file_direct_nobrl_ops = {
+ .read_iter = cifs_direct_readv,
+ .write_iter = cifs_direct_writev,
+ .open = cifs_open,
+ .release = cifs_close,
+ .fsync = cifs_fsync,
+ .flush = cifs_flush,
+ .mmap = cifs_file_mmap,
+ .splice_read = generic_file_splice_read,
+ .splice_write = iter_file_splice_write,
+ .unlocked_ioctl = cifs_ioctl,
+ .copy_file_range = cifs_copy_file_range,
+ .remap_file_range = cifs_remap_file_range,
+ .llseek = cifs_llseek,
+ .setlease = cifs_setlease,
+ .fallocate = cifs_fallocate,
+};
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index eeeaba3dec05..bfa7a2561c6b 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -26,6 +26,8 @@
#include "fs_context.h"
#include "cifs_ioctl.h"
+static struct kmem_cache *cifs_inode_cachep;
+
static void cifs_set_ops(struct inode *inode)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
@@ -3036,6 +3038,25 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
return rc;
}
+static int cifs_permission(struct user_namespace *mnt_userns,
+ struct inode *inode, int mask)
+{
+ struct cifs_sb_info *cifs_sb;
+
+ cifs_sb = CIFS_SB(inode->i_sb);
+
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
+ if ((mask & MAY_EXEC) && !execute_ok(inode))
+ return -EACCES;
+ else
+ return 0;
+ } else /* file mode might have been restricted at mount time
+ on the client (above and beyond ACL on servers) for
+ servers which do not support setting and viewing mode bits,
+ so allowing client to check permissions is useful */
+ return generic_permission(&init_user_ns, inode, mask);
+}
+
int
cifs_setattr(struct user_namespace *mnt_userns, struct dentry *direntry,
struct iattr *attrs)
@@ -3062,3 +3083,131 @@ cifs_setattr(struct user_namespace *mnt_userns, struct dentry *direntry,
/* BB: add cifs_setattr_legacy for really old servers */
return rc;
}
+
+struct inode *cifs_alloc_inode(struct super_block *sb)
+{
+ struct cifsInodeInfo *cifs_inode;
+ cifs_inode = alloc_inode_sb(sb, cifs_inode_cachep, GFP_KERNEL);
+ if (!cifs_inode)
+ return NULL;
+ cifs_inode->cifsAttrs = 0x20; /* default */
+ cifs_inode->time = 0;
+ /*
+ * Until the file is open and we have gotten oplock info back from the
+ * server, can not assume caching of file data or metadata.
+ */
+ cifs_set_oplock_level(cifs_inode, 0);
+ cifs_inode->flags = 0;
+ spin_lock_init(&cifs_inode->writers_lock);
+ cifs_inode->writers = 0;
+ cifs_inode->netfs.inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
+ cifs_inode->server_eof = 0;
+ cifs_inode->uniqueid = 0;
+ cifs_inode->createtime = 0;
+ cifs_inode->epoch = 0;
+ spin_lock_init(&cifs_inode->open_file_lock);
+ generate_random_uuid(cifs_inode->lease_key);
+
+ /*
+ * Can not set i_flags here - they get immediately overwritten to zero
+ * by the VFS.
+ */
+ /* cifs_inode->netfs.inode.i_flags = S_NOATIME | S_NOCMTIME; */
+ INIT_LIST_HEAD(&cifs_inode->openFileList);
+ INIT_LIST_HEAD(&cifs_inode->llist);
+ INIT_LIST_HEAD(&cifs_inode->deferred_closes);
+ spin_lock_init(&cifs_inode->deferred_lock);
+ return &cifs_inode->netfs.inode;
+}
+
+void cifs_free_inode(struct inode *inode)
+{
+ kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
+}
+
+void cifs_evict_inode(struct inode *inode)
+{
+ truncate_inode_pages_final(&inode->i_data);
+ if (inode->i_state & I_PINNING_FSCACHE_WB)
+ cifs_fscache_unuse_inode_cookie(inode, true);
+ cifs_fscache_release_inode_cookie(inode);
+ clear_inode(inode);
+}
+
+int cifs_write_inode(struct inode *inode, struct writeback_control *wbc)
+{
+ fscache_unpin_writeback(wbc, cifs_inode_cookie(inode));
+ return 0;
+}
+
+int cifs_drop_inode(struct inode *inode)
+{
+ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+
+ /* no serverino => unconditional eviction */
+ return !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) ||
+ generic_drop_inode(inode);
+}
+
+static void
+cifs_init_once(void *inode)
+{
+ struct cifsInodeInfo *cifsi = inode;
+
+ inode_init_once(&cifsi->netfs.inode);
+ init_rwsem(&cifsi->lock_sem);
+}
+
+int __init cifs_init_inodecache(void)
+{
+ cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
+ sizeof(struct cifsInodeInfo),
+ 0, (SLAB_RECLAIM_ACCOUNT|
+ SLAB_MEM_SPREAD|SLAB_ACCOUNT),
+ cifs_init_once);
+ if (cifs_inode_cachep == NULL)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void cifs_destroy_inodecache(void)
+{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
+ kmem_cache_destroy(cifs_inode_cachep);
+}
+
+const struct inode_operations cifs_dir_inode_ops = {
+ .create = cifs_create,
+ .atomic_open = cifs_atomic_open,
+ .lookup = cifs_lookup,
+ .getattr = cifs_getattr,
+ .unlink = cifs_unlink,
+ .link = cifs_hardlink,
+ .mkdir = cifs_mkdir,
+ .rmdir = cifs_rmdir,
+ .rename = cifs_rename2,
+ .permission = cifs_permission,
+ .setattr = cifs_setattr,
+ .symlink = cifs_symlink,
+ .mknod = cifs_mknod,
+ .listxattr = cifs_listxattr,
+};
+
+const struct inode_operations cifs_file_inode_ops = {
+ .setattr = cifs_setattr,
+ .getattr = cifs_getattr,
+ .permission = cifs_permission,
+ .listxattr = cifs_listxattr,
+ .fiemap = cifs_fiemap,
+};
+
+const struct inode_operations cifs_symlink_inode_ops = {
+ .get_link = cifs_get_link,
+ .permission = cifs_permission,
+ .listxattr = cifs_listxattr,
+};
--
2.35.3
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] cifs: move some bloat out of cifsfs.c to inode.c/file.c/dir.c
2022-08-01 21:36 [PATCH] cifs: move some bloat out of cifsfs.c to inode.c/file.c/dir.c Enzo Matsumiya
@ 2022-08-02 4:47 ` kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2022-08-02 4:47 UTC (permalink / raw)
To: Enzo Matsumiya, linux-cifs
Cc: llvm, kbuild-all, smfrench, pc, ronniesahlberg, nspmangalore
Hi Enzo,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on cifs/for-next]
[also build test WARNING on linus/master v5.19 next-20220728]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Enzo-Matsumiya/cifs-move-some-bloat-out-of-cifsfs-c-to-inode-c-file-c-dir-c/20220802-053657
base: git://git.samba.org/sfrench/cifs-2.6.git for-next
config: i386-randconfig-r031-20220801 (https://download.01.org/0day-ci/archive/20220802/202208021251.F3onzjl6-lkp@intel.com/config)
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 52cd00cabf479aa7eb6dbb063b7ba41ea57bce9e)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/d7e7fe7f0c75e89b86ce07dfb26774fc11330b61
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Enzo-Matsumiya/cifs-move-some-bloat-out-of-cifsfs-c-to-inode-c-file-c-dir-c/20220802-053657
git checkout d7e7fe7f0c75e89b86ce07dfb26774fc11330b61
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash fs/cifs/
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
>> fs/cifs/file.c:5375:8: warning: no previous prototype for function 'cifs_remap_file_range' [-Wmissing-prototypes]
loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
^
fs/cifs/file.c:5375:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
^
static
>> fs/cifs/file.c:5502:9: warning: no previous prototype for function 'cifs_copy_file_range' [-Wmissing-prototypes]
ssize_t cifs_copy_file_range(struct file *src_file, loff_t off,
^
fs/cifs/file.c:5502:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
ssize_t cifs_copy_file_range(struct file *src_file, loff_t off,
^
static
2 warnings generated.
--
>> fs/cifs/inode.c:3087:15: warning: no previous prototype for function 'cifs_alloc_inode' [-Wmissing-prototypes]
struct inode *cifs_alloc_inode(struct super_block *sb)
^
fs/cifs/inode.c:3087:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
struct inode *cifs_alloc_inode(struct super_block *sb)
^
static
>> fs/cifs/inode.c:3123:6: warning: no previous prototype for function 'cifs_free_inode' [-Wmissing-prototypes]
void cifs_free_inode(struct inode *inode)
^
fs/cifs/inode.c:3123:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void cifs_free_inode(struct inode *inode)
^
static
>> fs/cifs/inode.c:3128:6: warning: no previous prototype for function 'cifs_evict_inode' [-Wmissing-prototypes]
void cifs_evict_inode(struct inode *inode)
^
fs/cifs/inode.c:3128:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void cifs_evict_inode(struct inode *inode)
^
static
>> fs/cifs/inode.c:3137:5: warning: no previous prototype for function 'cifs_write_inode' [-Wmissing-prototypes]
int cifs_write_inode(struct inode *inode, struct writeback_control *wbc)
^
fs/cifs/inode.c:3137:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int cifs_write_inode(struct inode *inode, struct writeback_control *wbc)
^
static
>> fs/cifs/inode.c:3143:5: warning: no previous prototype for function 'cifs_drop_inode' [-Wmissing-prototypes]
int cifs_drop_inode(struct inode *inode)
^
fs/cifs/inode.c:3143:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int cifs_drop_inode(struct inode *inode)
^
static
>> fs/cifs/inode.c:3161:12: warning: no previous prototype for function 'cifs_init_inodecache' [-Wmissing-prototypes]
int __init cifs_init_inodecache(void)
^
fs/cifs/inode.c:3161:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int __init cifs_init_inodecache(void)
^
static
>> fs/cifs/inode.c:3174:6: warning: no previous prototype for function 'cifs_destroy_inodecache' [-Wmissing-prototypes]
void cifs_destroy_inodecache(void)
^
fs/cifs/inode.c:3174:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void cifs_destroy_inodecache(void)
^
static
7 warnings generated.
vim +/cifs_remap_file_range +5375 fs/cifs/file.c
5374
> 5375 loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
5376 struct file *dst_file, loff_t destoff, loff_t len,
5377 unsigned int remap_flags)
5378 {
5379 struct inode *src_inode = file_inode(src_file);
5380 struct inode *target_inode = file_inode(dst_file);
5381 struct cifsFileInfo *smb_file_src = src_file->private_data;
5382 struct cifsFileInfo *smb_file_target;
5383 struct cifs_tcon *target_tcon;
5384 unsigned int xid;
5385 int rc;
5386
5387 if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY))
5388 return -EINVAL;
5389
5390 cifs_dbg(FYI, "clone range\n");
5391
5392 xid = get_xid();
5393
5394 if (!src_file->private_data || !dst_file->private_data) {
5395 rc = -EBADF;
5396 cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n");
5397 goto out;
5398 }
5399
5400 smb_file_target = dst_file->private_data;
5401 target_tcon = tlink_tcon(smb_file_target->tlink);
5402
5403 /*
5404 * Note: cifs case is easier than btrfs since server responsible for
5405 * checks for proper open modes and file type and if it wants
5406 * server could even support copy of range where source = target
5407 */
5408 lock_two_nondirectories(target_inode, src_inode);
5409
5410 if (len == 0)
5411 len = src_inode->i_size - off;
5412
5413 cifs_dbg(FYI, "about to flush pages\n");
5414 /* should we flush first and last page first */
5415 truncate_inode_pages_range(&target_inode->i_data, destoff,
5416 PAGE_ALIGN(destoff + len)-1);
5417
5418 if (target_tcon->ses->server->ops->duplicate_extents)
5419 rc = target_tcon->ses->server->ops->duplicate_extents(xid,
5420 smb_file_src, smb_file_target, off, len, destoff);
5421 else
5422 rc = -EOPNOTSUPP;
5423
5424 /* force revalidate of size and timestamps of target file now
5425 that target is updated on the server */
5426 CIFS_I(target_inode)->time = 0;
5427 /* although unlocking in the reverse order from locking is not
5428 strictly necessary here it is a little cleaner to be consistent */
5429 unlock_two_nondirectories(src_inode, target_inode);
5430 out:
5431 free_xid(xid);
5432 return rc < 0 ? rc : len;
5433 }
5434
5435 ssize_t cifs_file_copychunk_range(unsigned int xid,
5436 struct file *src_file, loff_t off,
5437 struct file *dst_file, loff_t destoff,
5438 size_t len, unsigned int flags)
5439 {
5440 struct inode *src_inode = file_inode(src_file);
5441 struct inode *target_inode = file_inode(dst_file);
5442 struct cifsFileInfo *smb_file_src;
5443 struct cifsFileInfo *smb_file_target;
5444 struct cifs_tcon *src_tcon;
5445 struct cifs_tcon *target_tcon;
5446 ssize_t rc;
5447
5448 cifs_dbg(FYI, "copychunk range\n");
5449
5450 if (!src_file->private_data || !dst_file->private_data) {
5451 rc = -EBADF;
5452 cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n");
5453 goto out;
5454 }
5455
5456 rc = -EXDEV;
5457 smb_file_target = dst_file->private_data;
5458 smb_file_src = src_file->private_data;
5459 src_tcon = tlink_tcon(smb_file_src->tlink);
5460 target_tcon = tlink_tcon(smb_file_target->tlink);
5461
5462 if (src_tcon->ses != target_tcon->ses) {
5463 cifs_dbg(VFS, "source and target of copy not on same server\n");
5464 goto out;
5465 }
5466
5467 rc = -EOPNOTSUPP;
5468 if (!target_tcon->ses->server->ops->copychunk_range)
5469 goto out;
5470
5471 /*
5472 * Note: cifs case is easier than btrfs since server responsible for
5473 * checks for proper open modes and file type and if it wants
5474 * server could even support copy of range where source = target
5475 */
5476 lock_two_nondirectories(target_inode, src_inode);
5477
5478 cifs_dbg(FYI, "about to flush pages\n");
5479 /* should we flush first and last page first */
5480 truncate_inode_pages(&target_inode->i_data, 0);
5481
5482 rc = file_modified(dst_file);
5483 if (!rc)
5484 rc = target_tcon->ses->server->ops->copychunk_range(xid,
5485 smb_file_src, smb_file_target, off, len, destoff);
5486
5487 file_accessed(src_file);
5488
5489 /* force revalidate of size and timestamps of target file now
5490 * that target is updated on the server
5491 */
5492 CIFS_I(target_inode)->time = 0;
5493 /* although unlocking in the reverse order from locking is not
5494 * strictly necessary here it is a little cleaner to be consistent
5495 */
5496 unlock_two_nondirectories(src_inode, target_inode);
5497
5498 out:
5499 return rc;
5500 }
5501
> 5502 ssize_t cifs_copy_file_range(struct file *src_file, loff_t off,
5503 struct file *dst_file, loff_t destoff,
5504 size_t len, unsigned int flags)
5505 {
5506 unsigned int xid = get_xid();
5507 ssize_t rc;
5508 struct cifsFileInfo *cfile = dst_file->private_data;
5509
5510 if (cfile->swapfile)
5511 return -EOPNOTSUPP;
5512
5513 rc = cifs_file_copychunk_range(xid, src_file, off, dst_file, destoff,
5514 len, flags);
5515 free_xid(xid);
5516
5517 if (rc == -EOPNOTSUPP || rc == -EXDEV)
5518 rc = generic_copy_file_range(src_file, off, dst_file,
5519 destoff, len, flags);
5520 return rc;
5521 }
5522
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-08-02 4:48 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-01 21:36 [PATCH] cifs: move some bloat out of cifsfs.c to inode.c/file.c/dir.c Enzo Matsumiya
2022-08-02 4:47 ` kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.