fs/smb/server/vfs.c

Source file repositories/reference/linux-study-clean/fs/smb/server/vfs.c

File Facts

System
Linux kernel
Corpus path
fs/smb/server/vfs.c
Extension
.c
Size
48936 bytes
Lines
2030
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (err) {
			path_put(path);
			return -ENOENT;
		}

		d = start_removing_noperm(path->dentry, &last);

		if (!IS_ERR(d)) {
			dput(path->dentry);
			path->dentry = d;
			return 0;
		}
		mnt_drop_write(path->mnt);
		path_put(path);
		return -ENOENT;
	}

	d = lookup_noperm_unlocked(&last, path->dentry);
	if (!IS_ERR(d) && d_is_negative(d)) {
		dput(d);
		d = ERR_PTR(-ENOENT);
	}
	if (IS_ERR(d)) {
		path_put(path);
		return -ENOENT;
	}
	dput(path->dentry);
	path->dentry = d;

	if (test_share_config_flag(share_conf, KSMBD_SHARE_FLAG_CROSSMNT)) {
		err = follow_down(path, 0);
		if (err < 0) {
			path_put(path);
			return -ENOENT;
		}
	}
	return 0;
}

void ksmbd_vfs_query_maximal_access(struct mnt_idmap *idmap,
				   struct dentry *dentry, __le32 *daccess)
{
	*daccess = cpu_to_le32(FILE_READ_ATTRIBUTES | READ_CONTROL);

	if (!inode_permission(idmap, d_inode(dentry), MAY_OPEN | MAY_WRITE))
		*daccess |= cpu_to_le32(WRITE_DAC | WRITE_OWNER | SYNCHRONIZE |
				FILE_WRITE_DATA | FILE_APPEND_DATA |
				FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES |
				FILE_DELETE_CHILD);

	if (!inode_permission(idmap, d_inode(dentry), MAY_OPEN | MAY_READ))
		*daccess |= FILE_READ_DATA_LE | FILE_READ_EA_LE;

	if (!inode_permission(idmap, d_inode(dentry), MAY_OPEN | MAY_EXEC))
		*daccess |= FILE_EXECUTE_LE;

	if (!inode_permission(idmap, d_inode(dentry->d_parent), MAY_EXEC | MAY_WRITE))
		*daccess |= FILE_DELETE_LE;
}

/**
 * ksmbd_vfs_create() - vfs helper for smb create file
 * @work:	work
 * @name:	file name that is relative to share
 * @mode:	file create mode
 *
 * Return:	0 on success, otherwise error
 */
int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode)
{
	struct path path;
	struct dentry *dentry;
	int err;

	dentry = ksmbd_vfs_kern_path_create(work, name,
					    LOOKUP_NO_SYMLINKS, &path);
	if (IS_ERR(dentry)) {
		err = PTR_ERR(dentry);
		if (err != -ENOENT)
			pr_err("path create failed for %s, err %d\n",
			       name, err);
		return err;
	}

	mode |= S_IFREG;
	err = vfs_create(mnt_idmap(path.mnt), dentry, mode, NULL);
	if (!err) {
		ksmbd_vfs_inherit_owner(work, d_inode(path.dentry),
					d_inode(dentry));
	} else {

Annotation

Implementation Notes