vfs.c (8d99c1131d9d03053b7b1e1245b8f6e6846d9c69) vfs.c (bf4e7080aeed29354cb156a8eb5d221ab2b6a8cc)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
4 * Copyright (C) 2018 Samsung Electronics Co., Ltd.
5 */
6
7#include <linux/kernel.h>
8#include <linux/fs.h>

--- 35 unchanged lines hidden (view full) ---

44 KSMBD_SHARE_FLAG_INHERIT_OWNER))
45 return;
46
47 i_uid_write(inode, i_uid_read(parent_inode));
48}
49
50/**
51 * ksmbd_vfs_lock_parent() - lock parent dentry if it is stable
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
4 * Copyright (C) 2018 Samsung Electronics Co., Ltd.
5 */
6
7#include <linux/kernel.h>
8#include <linux/fs.h>

--- 35 unchanged lines hidden (view full) ---

44 KSMBD_SHARE_FLAG_INHERIT_OWNER))
45 return;
46
47 i_uid_write(inode, i_uid_read(parent_inode));
48}
49
50/**
51 * ksmbd_vfs_lock_parent() - lock parent dentry if it is stable
52 * @parent: parent dentry
53 * @child: child dentry
54 *
55 * Returns: %0 on success, %-ENOENT if the parent dentry is not stable
56 */
57int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child)
58{
59 inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
60 if (child->d_parent != parent) {
61 inode_unlock(d_inode(parent));
62 return -ENOENT;
63 }

--- 295 unchanged lines hidden (view full) ---

359out:
360 spin_unlock(&ctx->flc_lock);
361 return error;
362}
363
364/**
365 * ksmbd_vfs_read() - vfs helper for smb file read
366 * @work: smb work
52 */
53int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child)
54{
55 inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
56 if (child->d_parent != parent) {
57 inode_unlock(d_inode(parent));
58 return -ENOENT;
59 }

--- 295 unchanged lines hidden (view full) ---

355out:
356 spin_unlock(&ctx->flc_lock);
357 return error;
358}
359
360/**
361 * ksmbd_vfs_read() - vfs helper for smb file read
362 * @work: smb work
367 * @fp: ksmbd file pointer
363 * @fid: file id of open file
368 * @count: read byte count
369 * @pos: file pos
370 * @rbuf: read data buffer
371 *
372 * Return: number of read bytes on success, otherwise error
373 */
374int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count,
375 loff_t *pos, char *rbuf)

--- 97 unchanged lines hidden (view full) ---

473out:
474 kvfree(stream_buf);
475 return err;
476}
477
478/**
479 * ksmbd_vfs_write() - vfs helper for smb file write
480 * @work: work
364 * @count: read byte count
365 * @pos: file pos
366 * @rbuf: read data buffer
367 *
368 * Return: number of read bytes on success, otherwise error
369 */
370int ksmbd_vfs_read(struct ksmbd_work *work, struct ksmbd_file *fp, size_t count,
371 loff_t *pos, char *rbuf)

--- 97 unchanged lines hidden (view full) ---

469out:
470 kvfree(stream_buf);
471 return err;
472}
473
474/**
475 * ksmbd_vfs_write() - vfs helper for smb file write
476 * @work: work
481 * @fp: ksmbd file pointer
477 * @fid: file id of open file
482 * @buf: buf containing data for writing
483 * @count: read byte count
484 * @pos: file pos
485 * @sync: fsync after write
486 * @written: number of bytes written
487 *
488 * Return: 0 on success, otherwise error
489 */

--- 54 unchanged lines hidden (view full) ---

544 }
545
546out:
547 return err;
548}
549
550/**
551 * ksmbd_vfs_getattr() - vfs helper for smb getattr
478 * @buf: buf containing data for writing
479 * @count: read byte count
480 * @pos: file pos
481 * @sync: fsync after write
482 * @written: number of bytes written
483 *
484 * Return: 0 on success, otherwise error
485 */

--- 54 unchanged lines hidden (view full) ---

540 }
541
542out:
543 return err;
544}
545
546/**
547 * ksmbd_vfs_getattr() - vfs helper for smb getattr
552 * @path: path of dentry
553 * @stat: pointer to returned kernel stat structure
548 * @work: work
549 * @fid: file id of open file
550 * @attrs: inode attributes
551 *
554 * Return: 0 on success, otherwise error
555 */
556int ksmbd_vfs_getattr(const struct path *path, struct kstat *stat)
557{
558 int err;
559
560 err = vfs_getattr(path, stat, STATX_BTIME, AT_STATX_SYNC_AS_STAT);
561 if (err)
562 pr_err("getattr failed, err %d\n", err);
563 return err;
564}
565
566/**
567 * ksmbd_vfs_fsync() - vfs helper for smb fsync
568 * @work: work
569 * @fid: file id of open file
552 * Return: 0 on success, otherwise error
553 */
554int ksmbd_vfs_getattr(const struct path *path, struct kstat *stat)
555{
556 int err;
557
558 err = vfs_getattr(path, stat, STATX_BTIME, AT_STATX_SYNC_AS_STAT);
559 if (err)
560 pr_err("getattr failed, err %d\n", err);
561 return err;
562}
563
564/**
565 * ksmbd_vfs_fsync() - vfs helper for smb fsync
566 * @work: work
567 * @fid: file id of open file
570 * @p_id: persistent file id
571 *
572 * Return: 0 on success, otherwise error
573 */
574int ksmbd_vfs_fsync(struct ksmbd_work *work, u64 fid, u64 p_id)
575{
576 struct ksmbd_file *fp;
577 int err;
578

--- 6 unchanged lines hidden (view full) ---

585 if (err < 0)
586 pr_err("smb fsync failed, err = %d\n", err);
587 ksmbd_fd_put(work, fp);
588 return err;
589}
590
591/**
592 * ksmbd_vfs_remove_file() - vfs helper for smb rmdir or unlink
568 *
569 * Return: 0 on success, otherwise error
570 */
571int ksmbd_vfs_fsync(struct ksmbd_work *work, u64 fid, u64 p_id)
572{
573 struct ksmbd_file *fp;
574 int err;
575

--- 6 unchanged lines hidden (view full) ---

582 if (err < 0)
583 pr_err("smb fsync failed, err = %d\n", err);
584 ksmbd_fd_put(work, fp);
585 return err;
586}
587
588/**
589 * ksmbd_vfs_remove_file() - vfs helper for smb rmdir or unlink
593 * @work: work
594 * @path: path of dentry
590 * @name: directory or file name that is relative to share
595 *
596 * Return: 0 on success, otherwise error
597 */
598int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path)
599{
600 struct mnt_idmap *idmap;
601 struct dentry *parent = path->dentry->d_parent;
602 int err;

--- 19 unchanged lines hidden (view full) ---

622
623out_err:
624 ksmbd_revert_fsids(work);
625 return err;
626}
627
628/**
629 * ksmbd_vfs_link() - vfs helper for creating smb hardlink
591 *
592 * Return: 0 on success, otherwise error
593 */
594int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path)
595{
596 struct mnt_idmap *idmap;
597 struct dentry *parent = path->dentry->d_parent;
598 int err;

--- 19 unchanged lines hidden (view full) ---

618
619out_err:
620 ksmbd_revert_fsids(work);
621 return err;
622}
623
624/**
625 * ksmbd_vfs_link() - vfs helper for creating smb hardlink
630 * @work: work
631 * @oldname: source file name
632 * @newname: hardlink name that is relative to share
633 *
634 * Return: 0 on success, otherwise error
635 */
636int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
637 const char *newname)
638{

--- 76 unchanged lines hidden (view full) ---

715 goto out2;
716 }
717
718 err = mnt_want_write(old_path->mnt);
719 if (err)
720 goto out2;
721
722 trap = lock_rename_child(old_child, new_path.dentry);
626 * @oldname: source file name
627 * @newname: hardlink name that is relative to share
628 *
629 * Return: 0 on success, otherwise error
630 */
631int ksmbd_vfs_link(struct ksmbd_work *work, const char *oldname,
632 const char *newname)
633{

--- 76 unchanged lines hidden (view full) ---

710 goto out2;
711 }
712
713 err = mnt_want_write(old_path->mnt);
714 if (err)
715 goto out2;
716
717 trap = lock_rename_child(old_child, new_path.dentry);
718 if (IS_ERR(trap)) {
719 err = PTR_ERR(trap);
720 goto out_drop_write;
721 }
723
724 old_parent = dget(old_child->d_parent);
725 if (d_unhashed(old_child)) {
726 err = -EINVAL;
727 goto out3;
728 }
729
730 parent_fp = ksmbd_lookup_fd_inode(old_child->d_parent);

--- 46 unchanged lines hidden (view full) ---

777 if (err)
778 ksmbd_debug(VFS, "vfs_rename failed err %d\n", err);
779
780out4:
781 dput(new_dentry);
782out3:
783 dput(old_parent);
784 unlock_rename(old_parent, new_path.dentry);
722
723 old_parent = dget(old_child->d_parent);
724 if (d_unhashed(old_child)) {
725 err = -EINVAL;
726 goto out3;
727 }
728
729 parent_fp = ksmbd_lookup_fd_inode(old_child->d_parent);

--- 46 unchanged lines hidden (view full) ---

776 if (err)
777 ksmbd_debug(VFS, "vfs_rename failed err %d\n", err);
778
779out4:
780 dput(new_dentry);
781out3:
782 dput(old_parent);
783 unlock_rename(old_parent, new_path.dentry);
784out_drop_write:
785 mnt_drop_write(old_path->mnt);
786out2:
787 path_put(&new_path);
788
789 if (retry_estale(err, lookup_flags)) {
790 lookup_flags |= LOOKUP_REVAL;
791 goto retry;
792 }
793out1:
794 putname(to);
795revert_fsids:
796 ksmbd_revert_fsids(work);
797 return err;
798}
799
800/**
801 * ksmbd_vfs_truncate() - vfs helper for smb file truncate
802 * @work: work
785 mnt_drop_write(old_path->mnt);
786out2:
787 path_put(&new_path);
788
789 if (retry_estale(err, lookup_flags)) {
790 lookup_flags |= LOOKUP_REVAL;
791 goto retry;
792 }
793out1:
794 putname(to);
795revert_fsids:
796 ksmbd_revert_fsids(work);
797 return err;
798}
799
800/**
801 * ksmbd_vfs_truncate() - vfs helper for smb file truncate
802 * @work: work
803 * @fp: ksmbd file pointer
803 * @fid: file id of old file
804 * @size: truncate to given size
805 *
806 * Return: 0 on success, otherwise error
807 */
808int ksmbd_vfs_truncate(struct ksmbd_work *work,
809 struct ksmbd_file *fp, loff_t size)
810{
811 int err = 0;

--- 26 unchanged lines hidden (view full) ---

838 pr_err("truncate failed, err %d\n", err);
839 return err;
840}
841
842/**
843 * ksmbd_vfs_listxattr() - vfs helper for smb list extended attributes
844 * @dentry: dentry of file for listing xattrs
845 * @list: destination buffer
804 * @size: truncate to given size
805 *
806 * Return: 0 on success, otherwise error
807 */
808int ksmbd_vfs_truncate(struct ksmbd_work *work,
809 struct ksmbd_file *fp, loff_t size)
810{
811 int err = 0;

--- 26 unchanged lines hidden (view full) ---

838 pr_err("truncate failed, err %d\n", err);
839 return err;
840}
841
842/**
843 * ksmbd_vfs_listxattr() - vfs helper for smb list extended attributes
844 * @dentry: dentry of file for listing xattrs
845 * @list: destination buffer
846 * @size: destination buffer length
846 *
847 * Return: xattr list length on success, otherwise error
848 */
849ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list)
850{
851 ssize_t size;
852 char *vlist = NULL;
853

--- 92 unchanged lines hidden (view full) ---

946 if (get_write == true)
947 mnt_drop_write(path->mnt);
948 return err;
949}
950
951/**
952 * ksmbd_vfs_set_fadvise() - convert smb IO caching options to linux options
953 * @filp: file pointer for IO
847 *
848 * Return: xattr list length on success, otherwise error
849 */
850ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list)
851{
852 ssize_t size;
853 char *vlist = NULL;
854

--- 92 unchanged lines hidden (view full) ---

947 if (get_write == true)
948 mnt_drop_write(path->mnt);
949 return err;
950}
951
952/**
953 * ksmbd_vfs_set_fadvise() - convert smb IO caching options to linux options
954 * @filp: file pointer for IO
954 * @option: smb IO options
955 * @options: smb IO options
955 */
956void ksmbd_vfs_set_fadvise(struct file *filp, __le32 option)
957{
958 struct address_space *mapping;
959
960 mapping = filp->f_mapping;
961
962 if (!option || !mapping)

--- 195 unchanged lines hidden (view full) ---

1158 return true;
1159}
1160
1161/**
1162 * ksmbd_vfs_lookup_in_dir() - lookup a file in a directory
1163 * @dir: path info
1164 * @name: filename to lookup
1165 * @namelen: filename length
956 */
957void ksmbd_vfs_set_fadvise(struct file *filp, __le32 option)
958{
959 struct address_space *mapping;
960
961 mapping = filp->f_mapping;
962
963 if (!option || !mapping)

--- 195 unchanged lines hidden (view full) ---

1159 return true;
1160}
1161
1162/**
1163 * ksmbd_vfs_lookup_in_dir() - lookup a file in a directory
1164 * @dir: path info
1165 * @name: filename to lookup
1166 * @namelen: filename length
1166 * @um: &struct unicode_map to use
1167 *
1168 * Return: 0 on success, otherwise error
1169 */
1170static int ksmbd_vfs_lookup_in_dir(const struct path *dir, char *name,
1171 size_t namelen, struct unicode_map *um)
1172{
1173 int ret;
1174 struct file *dfilp;

--- 14 unchanged lines hidden (view full) ---

1189 if (readdir_data.dirent_count > 0)
1190 ret = 0;
1191 fput(dfilp);
1192 return ret;
1193}
1194
1195/**
1196 * ksmbd_vfs_kern_path_locked() - lookup a file and get path info
1167 *
1168 * Return: 0 on success, otherwise error
1169 */
1170static int ksmbd_vfs_lookup_in_dir(const struct path *dir, char *name,
1171 size_t namelen, struct unicode_map *um)
1172{
1173 int ret;
1174 struct file *dfilp;

--- 14 unchanged lines hidden (view full) ---

1189 if (readdir_data.dirent_count > 0)
1190 ret = 0;
1191 fput(dfilp);
1192 return ret;
1193}
1194
1195/**
1196 * ksmbd_vfs_kern_path_locked() - lookup a file and get path info
1197 * @work: work
1198 * @name: file path that is relative to share
1199 * @flags: lookup flags
1200 * @parent_path: if lookup succeed, return parent_path info
1201 * @path: if lookup succeed, return path info
1202 * @caseless: caseless filename lookup
1203 *
1204 * Return: 0 on success, otherwise error
1205 */

--- 431 unchanged lines hidden (view full) ---

1637
1638 return err;
1639}
1640
1641/**
1642 * ksmbd_vfs_init_kstat() - convert unix stat information to smb stat format
1643 * @p: destination buffer
1644 * @ksmbd_kstat: ksmbd kstat wrapper
1197 * @name: file path that is relative to share
1198 * @flags: lookup flags
1199 * @parent_path: if lookup succeed, return parent_path info
1200 * @path: if lookup succeed, return path info
1201 * @caseless: caseless filename lookup
1202 *
1203 * Return: 0 on success, otherwise error
1204 */

--- 431 unchanged lines hidden (view full) ---

1636
1637 return err;
1638}
1639
1640/**
1641 * ksmbd_vfs_init_kstat() - convert unix stat information to smb stat format
1642 * @p: destination buffer
1643 * @ksmbd_kstat: ksmbd kstat wrapper
1645 *
1646 * Returns: pointer to the converted &struct file_directory_info
1647 */
1648void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat)
1649{
1650 struct file_directory_info *info = (struct file_directory_info *)(*p);
1651 struct kstat *kstat = ksmbd_kstat->kstat;
1652 u64 time;
1653
1654 info->FileIndex = 0;

--- 287 unchanged lines hidden ---
1644 */
1645void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat)
1646{
1647 struct file_directory_info *info = (struct file_directory_info *)(*p);
1648 struct kstat *kstat = ksmbd_kstat->kstat;
1649 u64 time;
1650
1651 info->FileIndex = 0;

--- 287 unchanged lines hidden ---