cregit-Linux how code gets into the kernel

Release 4.10 fs/cachefiles/xattr.c

Directory: fs/cachefiles
/* CacheFiles extended attribute management
 *
 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 */

#include <linux/module.h>
#include <linux/sched.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/fsnotify.h>
#include <linux/quotaops.h>
#include <linux/xattr.h>
#include <linux/slab.h>
#include "internal.h"


static const char cachefiles_xattr_cache[] =
	XATTR_USER_PREFIX "CacheFiles.cache";

/*
 * check the type label on an object
 * - done using xattrs
 */

int cachefiles_check_object_type(struct cachefiles_object *object) { struct dentry *dentry = object->dentry; char type[3], xtype[3]; int ret; ASSERT(dentry); ASSERT(d_backing_inode(dentry)); if (!object->fscache.cookie) strcpy(type, "C3"); else snprintf(type, 3, "%02x", object->fscache.cookie->def->type); _enter("%p{%s}", object, type); /* attempt to install a type label directly */ ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2, XATTR_CREATE); if (ret == 0) { _debug("SET"); /* we succeeded */ goto error; } if (ret != -EEXIST) { pr_err("Can't set xattr on %pd [%lu] (err %d)\n", dentry, d_backing_inode(dentry)->i_ino, -ret); goto error; } /* read the current type label */ ret = vfs_getxattr(dentry, cachefiles_xattr_cache, xtype, 3); if (ret < 0) { if (ret == -ERANGE) goto bad_type_length; pr_err("Can't read xattr on %pd [%lu] (err %d)\n", dentry, d_backing_inode(dentry)->i_ino, -ret); goto error; } /* check the type is what we're expecting */ if (ret != 2) goto bad_type_length; if (xtype[0] != type[0] || xtype[1] != type[1]) goto bad_type; ret = 0; error: _leave(" = %d", ret); return ret; bad_type_length: pr_err("Cache object %lu type xattr length incorrect\n", d_backing_inode(dentry)->i_ino); ret = -EIO; goto error; bad_type: xtype[2] = 0; pr_err("Cache object %pd [%lu] type %s not %s\n", dentry, d_backing_inode(dentry)->i_ino, xtype, type); ret = -EIO; goto error; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells30597.44%240.00%
fabian frederickfabian frederick51.60%240.00%
al viroal viro30.96%120.00%
Total313100.00%5100.00%

/* * set the state xattr on a cache file */
int cachefiles_set_object_xattr(struct cachefiles_object *object, struct cachefiles_xattr *auxdata) { struct dentry *dentry = object->dentry; int ret; ASSERT(dentry); _enter("%p,#%d", object, auxdata->len); /* attempt to install the cache metadata directly */ _debug("SET #%u", auxdata->len); ret = vfs_setxattr(dentry, cachefiles_xattr_cache, &auxdata->type, auxdata->len, XATTR_CREATE); if (ret < 0 && ret != -ENOMEM) cachefiles_io_error_obj( object, "Failed to set xattr with error %d", ret); _leave(" = %d", ret); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells103100.00%2100.00%
Total103100.00%2100.00%

/* * update the state xattr on a cache file */
int cachefiles_update_object_xattr(struct cachefiles_object *object, struct cachefiles_xattr *auxdata) { struct dentry *dentry = object->dentry; int ret; ASSERT(dentry); _enter("%p,#%d", object, auxdata->len); /* attempt to install the cache metadata directly */ _debug("SET #%u", auxdata->len); ret = vfs_setxattr(dentry, cachefiles_xattr_cache, &auxdata->type, auxdata->len, XATTR_REPLACE); if (ret < 0 && ret != -ENOMEM) cachefiles_io_error_obj( object, "Failed to update xattr with error %d", ret); _leave(" = %d", ret); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells103100.00%2100.00%
Total103100.00%2100.00%

/* * check the consistency between the backing cache and the FS-Cache cookie */
int cachefiles_check_auxdata(struct cachefiles_object *object) { struct cachefiles_xattr *auxbuf; enum fscache_checkaux validity; struct dentry *dentry = object->dentry; ssize_t xlen; int ret; ASSERT(dentry); ASSERT(d_backing_inode(dentry)); ASSERT(object->fscache.cookie->def->check_aux); auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, GFP_KERNEL); if (!auxbuf) return -ENOMEM; xlen = vfs_getxattr(dentry, cachefiles_xattr_cache, &auxbuf->type, 512 + 1); ret = -ESTALE; if (xlen < 1 || auxbuf->type != object->fscache.cookie->def->type) goto error; xlen--; validity = fscache_check_aux(&object->fscache, &auxbuf->data, xlen); if (validity != FSCACHE_CHECKAUX_OKAY) goto error; ret = 0; error: kfree(auxbuf); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells13678.61%266.67%
josh boyerjosh boyer3721.39%133.33%
Total173100.00%3100.00%

/* * check the state xattr on a cache file * - return -ESTALE if the object should be deleted */
int cachefiles_check_object_xattr(struct cachefiles_object *object, struct cachefiles_xattr *auxdata) { struct cachefiles_xattr *auxbuf; struct dentry *dentry = object->dentry; int ret; _enter("%p,#%d", object, auxdata->len); ASSERT(dentry); ASSERT(d_backing_inode(dentry)); auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, cachefiles_gfp); if (!auxbuf) { _leave(" = -ENOMEM"); return -ENOMEM; } /* read the current type label */ ret = vfs_getxattr(dentry, cachefiles_xattr_cache, &auxbuf->type, 512 + 1); if (ret < 0) { if (ret == -ENODATA) goto stale; /* no attribute - power went off * mid-cull? */ if (ret == -ERANGE) goto bad_type_length; cachefiles_io_error_obj(object, "Can't read xattr on %lu (err %d)", d_backing_inode(dentry)->i_ino, -ret); goto error; } /* check the on-disk object */ if (ret < 1) goto bad_type_length; if (auxbuf->type != auxdata->type) goto stale; auxbuf->len = ret; /* consult the netfs */ if (object->fscache.cookie->def->check_aux) { enum fscache_checkaux result; unsigned int dlen; dlen = auxbuf->len - 1; _debug("checkaux %s #%u", object->fscache.cookie->def->name, dlen); result = fscache_check_aux(&object->fscache, &auxbuf->data, dlen); switch (result) { /* entry okay as is */ case FSCACHE_CHECKAUX_OKAY: goto okay; /* entry requires update */ case FSCACHE_CHECKAUX_NEEDS_UPDATE: break; /* entry requires deletion */ case FSCACHE_CHECKAUX_OBSOLETE: goto stale; default: BUG(); } /* update the current label */ ret = vfs_setxattr(dentry, cachefiles_xattr_cache, &auxdata->type, auxdata->len, XATTR_REPLACE); if (ret < 0) { cachefiles_io_error_obj(object, "Can't update xattr on %lu" " (error %d)", d_backing_inode(dentry)->i_ino, -ret); goto error; } } okay: ret = 0; error: kfree(auxbuf); _leave(" = %d", ret); return ret; bad_type_length: pr_err("Cache object %lu xattr length incorrect\n", d_backing_inode(dentry)->i_ino); ret = -EIO; goto error; stale: ret = -ESTALE; goto error; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells38199.48%360.00%
fabian frederickfabian frederick20.52%240.00%
Total383100.00%5100.00%

/* * remove the object's xattr to mark it stale */
int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, struct dentry *dentry) { int ret; ret = vfs_removexattr(dentry, cachefiles_xattr_cache); if (ret < 0) { if (ret == -ENOENT || ret == -ENODATA) ret = 0; else if (ret != -ENOMEM) cachefiles_io_error(cache, "Can't remove xattr from %lu" " (error %d)", d_backing_inode(dentry)->i_ino, -ret); } _leave(" = %d", ret); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells87100.00%2100.00%
Total87100.00%2100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
david howellsdavid howells115595.85%550.00%
josh boyerjosh boyer373.07%110.00%
fabian frederickfabian frederick70.58%220.00%
tejun heotejun heo30.25%110.00%
al viroal viro30.25%110.00%
Total1205100.00%10100.00%
Directory: fs/cachefiles
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.