fs/nfs/namespace.c

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

File Facts

System
Linux kernel
Corpus path
fs/nfs/namespace.c
Extension
.c
Size
10015 bytes
Lines
387
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: exported/initcall integration point
Status
integration 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 (--buflen < 0) {
			spin_unlock(&dentry->d_lock);
			rcu_read_unlock();
			goto Elong;
		}
		*--end = '/';
	}
	*p = end;
	base = dentry->d_fsdata;
	if (!base) {
		spin_unlock(&dentry->d_lock);
		rcu_read_unlock();
		WARN_ON(1);
		return end;
	}
	namelen = strlen(base);
	if (*end == '/') {
		/* Strip off excess slashes in base string */
		while (namelen > 0 && base[namelen - 1] == '/')
			namelen--;
	}
	buflen -= namelen;
	if (buflen < 0) {
		spin_unlock(&dentry->d_lock);
		rcu_read_unlock();
		goto Elong;
	}
	end -= namelen;
	memcpy(end, base, namelen);
	spin_unlock(&dentry->d_lock);
	rcu_read_unlock();
	return end;
Elong_unlock:
	spin_unlock(&dentry->d_lock);
	rcu_read_unlock();
	if (read_seqretry(&rename_lock, seq))
		goto rename_retry;
Elong:
	return ERR_PTR(-ENAMETOOLONG);
}
EXPORT_SYMBOL_GPL(nfs_path);

/*
 * nfs_d_automount - Handle crossing a mountpoint on the server
 * @path - The mountpoint
 *
 * When we encounter a mountpoint on the server, we want to set up
 * a mountpoint on the client too, to prevent inode numbers from
 * colliding, and to allow "df" to work properly.
 * On NFSv4, we also want to allow for the fact that different
 * filesystems may be migrated to different servers in a failover
 * situation, and that different filesystems may want to use
 * different security flavours.
 */
struct vfsmount *nfs_d_automount(struct path *path)
{
	struct nfs_fs_context *ctx;
	struct fs_context *fc;
	struct vfsmount *mnt = ERR_PTR(-ENOMEM);
	struct nfs_server *server = NFS_SB(path->dentry->d_sb);
	struct nfs_client *client = server->nfs_client;
	unsigned long s_flags = path->dentry->d_sb->s_flags;
	int timeout = READ_ONCE(nfs_mountpoint_expiry_timeout);
	int ret;

	if (IS_ROOT(path->dentry))
		return ERR_PTR(-ESTALE);

	/* Open a new filesystem context, transferring parameters from the
	 * parent superblock, including the network namespace.
	 */
	fc = fs_context_for_submount(path->mnt->mnt_sb->s_type, path->dentry);
	if (IS_ERR(fc))
		return ERR_CAST(fc);

	ctx = nfs_fc2context(fc);
	ctx->clone_data.dentry	= path->dentry;
	ctx->clone_data.sb	= path->dentry->d_sb;
	ctx->clone_data.fattr	= nfs_alloc_fattr();
	if (!ctx->clone_data.fattr)
		goto out_fc;

	if (fc->cred != server->cred) {
		put_cred(fc->cred);
		fc->cred = get_cred(server->cred);
	}

	if (fc->net_ns != client->cl_net) {
		put_net(fc->net_ns);
		fc->net_ns = get_net(client->cl_net);

Annotation

Implementation Notes