summaryrefslogtreecommitdiffstats
path: root/fs/stat.c
AgeCommit message (Expand)Author
2015-04-15VFS: assorted d_backing_inode() annotationsDavid Howells
2015-04-11switch security_inode_getattr() to struct path *Al Viro
2013-11-09vfs: split out vfs_getattr_nosecJ. Bruce Fields
2013-08-17quota: provide interface for readding allocated space into reserved spaceJan Kara
2013-02-26switch vfs_getattr() to struct pathAl Viro
2012-12-20vfs: fix readlinkat to retry on ESTALEJeff Layton
2012-12-20vfs: make fstatat retry on ESTALE errors from getattr callJeff Layton
2012-10-02Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/vir...Linus Torvalds
2012-10-01Merge tag 'arm64-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/...Linus Torvalds
2012-09-26switch simple cases of fget_light to fdgetAl Viro
2012-09-14vfs: make O_PATH file descriptors usable for 'fstat()'Linus Torvalds
2012-09-14fs: Build sys_stat64() and friends if __ARCH_WANT_COMPAT_STAT64Catalin Marinas
2012-05-23Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebi...Linus Torvalds
2012-05-21Merge branch 'vfs-cleanups' (random vfs cleanups)Linus Torvalds
2012-05-15userns: Convert stat to return values mapped from kuids and kgidsEric W. Biederman
2012-05-06vfs: don't force a big memset of stat data just to clear padding fieldsLinus Torvalds
2012-05-06vfs: de-crapify "cp_new_stat()" functionLinus Torvalds
2012-04-28VFS: make vfs_fstat() use f[get|put]_light()Linus Torvalds
2012-03-24Merge tag 'module-for-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/p...Linus Torvalds
2012-03-20switch touch_atime to struct pathAl Viro
2012-02-28fs: reduce the use of module.h wherever possiblePaul Gortmaker
2011-11-02readlinkat: ensure we return ENOENT for the empty pathname for normal lookupsAndy Whitcroft
2011-09-27vfs: remove LOOKUP_NO_AUTOMOUNT flagLinus Torvalds
2011-08-06vfs: optimize inode cache access patternsLinus Torvalds
2011-03-15readlinkat(), fchownat() and fstatat() with empty relative pathnamesAl Viro
2011-01-15Add an AT_NO_AUTOMOUNT flag to suppress terminal automountDavid Howells
2010-08-13Mark arguments to certain syscalls as being constDavid Howells
2009-12-23Add unlocked version of inode_add_bytes() functionDmitry Monakhov
2009-04-20kill vfs_stat_fd / vfs_lstat_fdChristoph Hellwig
2009-04-20Separate out common fstatat code into vfs_fstatatOleg Drokin
2009-01-14[CVE-2009-0029] System call wrappers part 30Heiko Carstens
2009-01-14[CVE-2009-0029] System call wrappers part 16Heiko Carstens
2009-01-14[CVE-2009-0029] System call wrappers part 11Heiko Carstens
2009-01-14[CVE-2009-0029] System call wrappers part 10Heiko Carstens
2009-01-05inode->i_op is never NULLAl Viro
2008-07-26[PATCH] sanitize __user_walk_fd() et.al.Al Viro
2008-02-14Introduce path_put()Jan Blunck
2008-02-14Embed a struct path into struct nameidata instead of nd->{dentry,mnt}Jan Blunck
2007-05-08header cleaning: don't include smp_lock.h when not usedRandy Dunlap
2006-12-08[PATCH] VFS: change struct file to use struct pathJosef "Jeff" Sipek
2006-12-07[PATCH] vfs_getattr(): remove dead codeAndrew Morton
2006-10-03[PATCH] VFS: Make filldir_t and struct kstat deal in 64-bit inode numbersDavid Howells
2006-09-27[PATCH] inode-diet: Eliminate i_blksize from the inode structureTheodore Ts'o
2006-06-30Remove obsolete #include <linux/config.h>Jörn Engel
2006-04-28[PATCH] powerpc: Wire up *at syscallsAndreas Schwab
2006-02-11[PATCH] fstatat64 supportUlrich Drepper
2006-01-18[PATCH] vfs: *at functions: coreUlrich Drepper
2005-04-16Linux-2.6.12-rc2Linus Torvalds
555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/*
 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
 *
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 *                                                                   USA
 */

#include "dtc.h"

void data_free(struct data d)
{
	struct marker *m, *nm;

	m = d.markers;
	while (m) {
		nm = m->next;
		free(m->ref);
		free(m);
		m = nm;
	}

	if (d.val)
		free(d.val);
}

struct data data_grow_for(struct data d, int xlen)
{
	struct data nd;
	int newsize;

	if (xlen == 0)
		return d;

	nd = d;

	newsize = xlen;

	while ((d.len + xlen) > newsize)
		newsize *= 2;

	nd.val = xrealloc(d.val, newsize);

	return nd;
}

struct data data_copy_mem(const char *mem, int len)
{
	struct data d;

	d = data_grow_for(empty_data, len);

	d.len = len;
	memcpy(d.val, mem, len);

	return d;
}

struct data data_copy_escape_string(const char *s, int len)
{
	int i = 0;
	struct data d;
	char *q;

	d = data_grow_for(empty_data, len + 1);

	q = d.val;
	while (i < len) {
		char c = s[i++];

		if (c == '\\')
			c = get_escape_char(s, &i);

		q[d.len++] = c;
	}

	q[d.len++] = '\0';
	return d;
}

struct data data_copy_file(FILE *f, size_t maxlen)
{
	struct data d = empty_data;

	while (!feof(f) && (d.len < maxlen)) {
		size_t chunksize, ret;

		if (maxlen == -1)
			chunksize = 4096;
		else
			chunksize = maxlen - d.len;

		d = data_grow_for(d, chunksize);
		ret = fread(d.val + d.len, 1, chunksize, f);

		if (ferror(f))
			die("Error reading file into data: %s", strerror(errno));

		if (d.len + ret < d.len)
			die("Overflow reading file into data\n");

		d.len += ret;
	}

	return d;
}

struct data data_append_data(struct data d, const void *p, int len)
{
	d = data_grow_for(d, len);
	memcpy(d.val + d.len, p, len);
	d.len += len;
	return d;
}

struct data data_insert_at_marker(struct data d, struct marker *m,
				  const void *p, int len)
{
	d = data_grow_for(d, len);
	memmove(d.val + m->offset + len, d.val + m->offset, d.len - m->offset);
	memcpy(d.val + m->offset, p, len);
	d.len += len;

	/* Adjust all markers after the one we're inserting at */
	m = m->next;
	for_each_marker(m)
		m->offset += len;
	return d;
}

static struct data data_append_markers(struct data d, struct marker *m)
{
	struct marker **mp = &d.markers;

	/* Find the end of the markerlist */
	while (*mp)
		mp = &((*mp)->next);
	*mp = m;
	return d;
}

struct data data_merge(struct data d1, struct data d2)
{
	struct data d;
	struct marker *m2 = d2.markers;

	d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2);

	/* Adjust for the length of d1 */
	for_each_marker(m2)
		m2->offset += d1.len;

	d2.markers = NULL; /* So data_free() doesn't clobber them */
	data_free(d2);

	return d;
}

struct data data_append_integer(struct data d, uint64_t value, int bits)
{
	uint8_t value_8;
	uint16_t value_16;
	uint32_t value_32;
	uint64_t value_64;

	switch (bits) {
	case 8:
		value_8 = value;
		return data_append_data(d, &value_8, 1);

	case 16:
		value_16 = cpu_to_fdt16(value);
		return data_append_data(d, &value_16, 2);

	case 32:
		value_32 = cpu_to_fdt32(value);
		return data_append_data(d, &value_32, 4);

	case 64:
		value_64 = cpu_to_fdt64(value);
		return data_append_data(d, &value_64, 8);

	default:
		die("Invalid literal size (%d)\n", bits);
	}
}

struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
{
	struct fdt_reserve_entry bere;

	bere.address = cpu_to_fdt64(re->address);
	bere.size = cpu_to_fdt64(re->size);

	return data_append_data(d, &bere, sizeof(bere));
}

struct data data_append_cell(struct data d, cell_t word)
{
	return data_append_integer(d, word, sizeof(word) * 8);
}

struct data data_append_addr(struct data d, uint64_t addr)
{
	return data_append_integer(d, addr, sizeof(addr) * 8);
}

struct data data_append_byte(struct data d, uint8_t byte)
{
	return data_append_data(d, &byte, 1);
}

struct data data_append_zeroes(struct data d, int len)
{
	d = data_grow_for(d, len);

	memset(d.val + d.len, 0, len);
	d.len += len;
	return d;
}

struct data data_append_align(struct data d, int align)
{
	int newlen = ALIGN(d.len, align);
	return data_append_zeroes(d, newlen - d.len);
}

struct data data_add_marker(struct data d, enum markertype type, char *ref)
{
	struct marker *m;

	m = xmalloc(sizeof(*m));
	m->offset = d.len;
	m->type = type;
	m->ref = ref;
	m->next = NULL;

	return data_append_markers(d, m);
}

bool data_is_one_string(struct data d)
{
	int i;
	int len = d.len;

	if (len == 0)
		return false;

	for (i = 0; i < len-1; i++)
		if (d.val[i] == '\0')
			return false;

	if (d.val[len-1] != '\0')
		return false;

	return true;
}