fs/nfsd/nfs4proc.c

Source file repositories/reference/linux-study-clean/fs/nfsd/nfs4proc.c

File Facts

System
Linux kernel
Corpus path
fs/nfsd/nfs4proc.c
Extension
.c
Size
114405 bytes
Lines
4118
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 (open->op_dpacl || open->op_pacl) {
			status = nfserr_inval;
			goto out;
		}
		if (is_create_with_attrs(open)) {
			status = nfsd4_acl_to_attr(NF4REG, open->op_acl,
						   &attrs);
			if (status)
				goto out;
		}
	} else if (is_create_with_attrs(open)) {
		/* The dpacl and pacl will get released by nfsd_attrs_free(). */
		attrs.na_dpacl = open->op_dpacl;
		attrs.na_pacl = open->op_pacl;
		open->op_dpacl = NULL;
		open->op_pacl = NULL;
	}

	child = start_creating(&nop_mnt_idmap, parent,
			       &QSTR_LEN(open->op_fname, open->op_fnamelen));
	if (IS_ERR(child)) {
		status = nfserrno(PTR_ERR(child));
		goto out;
	}

	if (d_really_is_negative(child)) {
		status = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE);
		if (status != nfs_ok)
			goto out;
	}

	status = fh_compose(resfhp, fhp->fh_export, child, fhp);
	if (status != nfs_ok)
		goto out;

	v_mtime = 0;
	v_atime = 0;
	if (nfsd4_create_is_exclusive(open->op_createmode)) {
		u32 *verifier = (u32 *)open->op_verf.data;

		/*
		 * Solaris 7 gets confused (bugid 4218508) if these have
		 * the high bit set, as do xfs filesystems without the
		 * "bigtime" feature. So just clear the high bits. If this
		 * is ever changed to use different attrs for storing the
		 * verifier, then do_open_lookup() will also need to be
		 * fixed accordingly.
		 */
		v_mtime = verifier[0] & 0x7fffffff;
		v_atime = verifier[1] & 0x7fffffff;
	}

	if (d_really_is_positive(child)) {
		/* NFSv4 protocol requires change attributes even though
		 * no change happened.
		 */
		status = fh_fill_both_attrs(fhp);
		if (status != nfs_ok)
			goto out;

		switch (open->op_createmode) {
		case NFS4_CREATE_UNCHECKED:
			if (!d_is_reg(child))
				break;

			/*
			 * In NFSv4, we don't want to truncate the file
			 * now. This would be wrong if the OPEN fails for
			 * some other reason. Furthermore, if the size is
			 * nonzero, we should ignore it according to spec!
			 */
			open->op_truncate = (iap->ia_valid & ATTR_SIZE) &&
						!iap->ia_size;
			break;
		case NFS4_CREATE_GUARDED:
			status = nfserr_exist;
			break;
		case NFS4_CREATE_EXCLUSIVE:
			if (inode_get_mtime_sec(d_inode(child)) == v_mtime &&
			    inode_get_atime_sec(d_inode(child)) == v_atime &&
			    d_inode(child)->i_size == 0) {
				open->op_created = true;
				break;		/* subtle */
			}
			status = nfserr_exist;
			break;
		case NFS4_CREATE_EXCLUSIVE4_1:
			if (inode_get_mtime_sec(d_inode(child)) == v_mtime &&
			    inode_get_atime_sec(d_inode(child)) == v_atime &&
			    d_inode(child)->i_size == 0) {

Annotation

Implementation Notes