fs/orangefs/xattr.c

Source file repositories/reference/linux-study-clean/fs/orangefs/xattr.c

File Facts

System
Linux kernel
Corpus path
fs/orangefs/xattr.c
Extension
.c
Size
15208 bytes
Lines
567
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 (cx->length == -1) {
			ret = -ENODATA;
			goto out_unlock;
		} else {
			if (size == 0) {
				ret = cx->length;
				goto out_unlock;
			}
			if (cx->length > size) {
				ret = -ERANGE;
				goto out_unlock;
			}
			memcpy(buffer, cx->val, cx->length);
			memset(buffer + cx->length, 0, size - cx->length);
			ret = cx->length;
			goto out_unlock;
		}
	}

	new_op = op_alloc(ORANGEFS_VFS_OP_GETXATTR);
	if (!new_op)
		goto out_unlock;

	new_op->upcall.req.getxattr.refn = orangefs_inode->refn;
	strscpy(new_op->upcall.req.getxattr.key, name);

	/*
	 * NOTE: Although keys are meant to be NULL terminated textual
	 * strings, I am going to explicitly pass the length just in case
	 * we change this later on...
	 */
	new_op->upcall.req.getxattr.key_sz = strlen(name) + 1;

	ret = service_operation(new_op, "orangefs_inode_getxattr",
				get_interruptible_flag(inode));
	if (ret != 0) {
		if (ret == -ENOENT) {
			ret = -ENODATA;
			gossip_debug(GOSSIP_XATTR_DEBUG,
				     "orangefs_inode_getxattr: inode %pU key %s"
				     " does not exist!\n",
				     get_khandle_from_ino(inode),
				     (char *)new_op->upcall.req.getxattr.key);
			cx = kmalloc_obj(*cx);
			if (cx) {
				strscpy(cx->key, name);
				cx->length = -1;
				cx->timeout = jiffies +
				    orangefs_getattr_timeout_msecs*HZ/1000;
				hlist_add_head( &cx->node,
                                   &orangefs_inode->xattr_cache[xattr_key(cx->key)]);
			}
		}
		goto out_release_op;
	}

	/*
	 * Length returned includes null terminator.
	 */
	length = new_op->downcall.resp.getxattr.val_sz;
	if (length < 0 || length > ORANGEFS_MAX_XATTR_VALUELEN) {
		ret = -EIO;
		goto out_release_op;
	}

	/*
	 * Just return the length of the queried attribute.
	 */
	if (size == 0) {
		ret = length;
		goto out_release_op;
	}

	/*
	 * Check to see if key length is > provided buffer size.
	 */
	if (length > size) {
		ret = -ERANGE;
		goto out_release_op;
	}

	memcpy(buffer, new_op->downcall.resp.getxattr.val, length);
	memset(buffer + length, 0, size - length);
	gossip_debug(GOSSIP_XATTR_DEBUG,
	     "orangefs_inode_getxattr: inode %pU "
	     "key %s key_sz %d, val_len %d\n",
	     get_khandle_from_ino(inode),
	     (char *)new_op->
		upcall.req.getxattr.key,
		     (int)new_op->

Annotation

Implementation Notes