fs/nfsd/nfs3proc.c

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

File Facts

System
Linux kernel
Corpus path
fs/nfsd/nfs3proc.c
Extension
.c
Size
29530 bytes
Lines
1081
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

switch (argp->createmode) {
		case NFS3_CREATE_UNCHECKED:
			if (!d_is_reg(child))
				break;
			iap->ia_valid &= ATTR_SIZE;
			goto set_attr;
		case NFS3_CREATE_GUARDED:
			status = nfserr_exist;
			break;
		case NFS3_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) {
				break;
			}
			status = nfserr_exist;
		}
		goto out;
	}

	if (!IS_POSIXACL(inode))
		iap->ia_mode &= ~current_umask();

	status = fh_fill_pre_attrs(fhp);
	if (status != nfs_ok)
		goto out;
	host_err = vfs_create(&nop_mnt_idmap, child, iap->ia_mode, NULL);
	if (host_err < 0) {
		status = nfserrno(host_err);
		goto out;
	}
	fh_fill_post_attrs(fhp);

	/* A newly created file already has a file size of zero. */
	if ((iap->ia_valid & ATTR_SIZE) && (iap->ia_size == 0))
		iap->ia_valid &= ~ATTR_SIZE;
	if (argp->createmode == NFS3_CREATE_EXCLUSIVE) {
		iap->ia_valid = ATTR_MTIME | ATTR_ATIME |
				ATTR_MTIME_SET | ATTR_ATIME_SET;
		iap->ia_mtime.tv_sec = v_mtime;
		iap->ia_atime.tv_sec = v_atime;
		iap->ia_mtime.tv_nsec = 0;
		iap->ia_atime.tv_nsec = 0;
	}

set_attr:
	status = nfsd_create_setattr(rqstp, fhp, resfhp, &attrs);

out:
	end_creating(child);
out_write:
	fh_drop_write(fhp);
	return status;
}

static __be32
nfsd3_proc_create(struct svc_rqst *rqstp)
{
	struct nfsd3_createargs *argp = rqstp->rq_argp;
	struct nfsd3_diropres *resp = rqstp->rq_resp;
	svc_fh *dirfhp, *newfhp;

	dirfhp = fh_copy(&resp->dirfh, &argp->fh);
	newfhp = fh_init(&resp->fh, NFS3_FHSIZE);

	resp->status = nfsd3_create_file(rqstp, dirfhp, newfhp, argp);
	resp->status = nfsd3_map_status(resp->status);
	return rpc_success;
}

/*
 * Make directory. This operation is not idempotent.
 */
static __be32
nfsd3_proc_mkdir(struct svc_rqst *rqstp)
{
	struct nfsd3_createargs *argp = rqstp->rq_argp;
	struct nfsd3_diropres *resp = rqstp->rq_resp;
	struct nfsd_attrs attrs = {
		.na_iattr	= &argp->attrs,
	};

	argp->attrs.ia_valid &= ~ATTR_SIZE;
	fh_copy(&resp->dirfh, &argp->fh);
	fh_init(&resp->fh, NFS3_FHSIZE);
	resp->status = nfsd_create(rqstp, &resp->dirfh, argp->name, argp->len,
				   &attrs, S_IFDIR, 0, &resp->fh);
	resp->status = nfsd3_map_status(resp->status);
	return rpc_success;
}

Annotation

Implementation Notes