fs/smb/client/link.c

Source file repositories/reference/linux-study-clean/fs/smb/client/link.c

File Facts

System
Linux kernel
Corpus path
fs/smb/client/link.c
Extension
.c
Size
15763 bytes
Lines
652
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 (!server->ops->create_hardlink) {
			rc = -ENOSYS;
			goto cifs_hl_exit;
		}
		rc = server->ops->create_hardlink(xid, tcon, old_file,
						  from_name, to_name, cifs_sb);
		if ((rc == -EIO) || (rc == -EINVAL))
			rc = -EOPNOTSUPP;
	}

	d_drop(direntry);	/* force new lookup from server of target */

	/*
	 * if source file is cached (oplocked) revalidate will not go to server
	 * until the file is closed or oplock broken so update nlinks locally
	 */
	if (d_really_is_positive(old_file)) {
		cifsInode = CIFS_I(d_inode(old_file));
		if (rc == 0) {
			clear_bit(CIFS_INO_TMPFILE, &cifsInode->flags);
			spin_lock(&d_inode(old_file)->i_lock);
			inc_nlink(d_inode(old_file));
			spin_unlock(&d_inode(old_file)->i_lock);

			/*
			 * parent dir timestamps will update from srv within a
			 * second, would it really be worth it to set the parent
			 * dir cifs inode time to zero to force revalidate
			 * (faster) for it too?
			 */
		}
		/*
		 * if not oplocked will force revalidate to get info on source
		 * file from srv.  Note Samba server prior to 4.2 has bug -
		 * not updating src file ctime on hardlinks but Windows servers
		 * handle it properly
		 */
		cifsInode->time = 0;

		/*
		 * Will update parent dir timestamps from srv within a second.
		 * Would it really be worth it to set the parent dir (cifs
		 * inode) time field to zero to force revalidate on parent
		 * directory faster ie
		 *
		 * CIFS_I(inode)->time = 0;
		 */
	}

cifs_hl_exit:
	free_dentry_path(page1);
	free_dentry_path(page2);
	free_xid(xid);
	cifs_put_tlink(tlink);
	return rc;
}

int
cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
	     struct dentry *direntry, const char *symname)
{
	struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
	struct inode *newinode = NULL;
	struct tcon_link *tlink;
	struct cifs_tcon *pTcon;
	const char *full_path;
	int rc = -EOPNOTSUPP;
	unsigned int sbflags;
	unsigned int xid;
	void *page;

	if (unlikely(cifs_forced_shutdown(cifs_sb)))
		return smb_EIO(smb_eio_trace_forced_shutdown);

	page = alloc_dentry_path();
	if (!page)
		return -ENOMEM;

	xid = get_xid();

	tlink = cifs_sb_tlink(cifs_sb);
	if (IS_ERR(tlink)) {
		rc = PTR_ERR(tlink);
		/* BB could be clearer if skipped put_tlink on error here, but harmless */
		goto symlink_exit;
	}
	pTcon = tlink_tcon(tlink);

	full_path = build_path_from_dentry(direntry, page);
	if (IS_ERR(full_path)) {

Annotation

Implementation Notes