fs/smb/client/namespace.c

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

File Facts

System
Linux kernel
Corpus path
fs/smb/client/namespace.c
Extension
.c
Size
7074 bytes
Lines
299
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

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *   Contains mounting routines used for handling traversal via SMB junctions.
 *
 *   Copyright (c) 2007 Igor Mammedov
 *   Copyright (C) International Business Machines  Corp., 2008
 *   Author(s): Igor Mammedov (niallain@gmail.com)
 *		Steve French (sfrench@us.ibm.com)
 *   Copyright (c) 2023 Paulo Alcantara <palcantara@suse.de>
 */

#include <linux/dcache.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/slab.h>
#include <linux/vfs.h>
#include <linux/fs.h>
#include <linux/inet.h>
#include "cifsglob.h"
#include "cifsproto.h"
#include "cifsfs.h"
#include "cifs_debug.h"
#include "fs_context.h"

static LIST_HEAD(cifs_automount_list);

static void cifs_expire_automounts(struct work_struct *work);
static DECLARE_DELAYED_WORK(cifs_automount_task,
			    cifs_expire_automounts);
static int cifs_mountpoint_expiry_timeout = 500 * HZ;

static void cifs_expire_automounts(struct work_struct *work)
{
	struct list_head *list = &cifs_automount_list;

	mark_mounts_for_expiry(list);
	if (!list_empty(list))
		schedule_delayed_work(&cifs_automount_task,
				      cifs_mountpoint_expiry_timeout);
}

void cifs_release_automount_timer(void)
{
	if (WARN_ON(!list_empty(&cifs_automount_list)))
		return;
	cancel_delayed_work_sync(&cifs_automount_task);
}

/**
 * cifs_build_devname - build a devicename from a UNC and optional prepath
 * @nodename:	pointer to UNC string
 * @prepath:	pointer to prefixpath (or NULL if there isn't one)
 *
 * Build a new cifs devicename after chasing a DFS referral. Allocate a buffer
 * big enough to hold the final thing. Copy the UNC from the nodename, and
 * concatenate the prepath onto the end of it if there is one.
 *
 * Returns pointer to the built string, or a ERR_PTR. Caller is responsible
 * for freeing the returned string.
 */
char *
cifs_build_devname(char *nodename, const char *prepath)
{
	size_t pplen;
	size_t unclen;
	char *dev;
	char *pos;

	/* skip over any preceding delimiters */
	nodename += strspn(nodename, "\\");
	if (!*nodename)
		return ERR_PTR(-EINVAL);

	/* get length of UNC and set pos to last char */
	unclen = strlen(nodename);
	pos = nodename + unclen - 1;

	/* trim off any trailing delimiters */
	while (*pos == '\\') {
		--pos;
		--unclen;
	}

	/* allocate a buffer:
	 * +2 for preceding "//"
	 * +1 for delimiter between UNC and prepath
	 * +1 for trailing NULL
	 */
	pplen = prepath ? strlen(prepath) : 0;
	dev = kmalloc(2 + unclen + 1 + pplen + 1, GFP_KERNEL);

Annotation

Implementation Notes