Пример #1
0
static ssize_t sdcardfskk_read(struct file *file, char __user *buf,
			   size_t count, loff_t *ppos)
{
	int err;
	struct file *lower_file;
	struct dentry *dentry = file->f_path.dentry;
#ifdef CONFIG_SDCARD_FS_FADV_NOACTIVE
	struct backing_dev_info *bdi;
#endif

	lower_file = sdcardfskk_lower_file(file);

#ifdef CONFIG_SDCARD_FS_FADV_NOACTIVE
	if (file->f_mode & FMODE_NOACTIVE) {
		if (!(lower_file->f_mode & FMODE_NOACTIVE)) {
			bdi = lower_file->f_mapping->backing_dev_info;
			lower_file->f_ra.ra_pages = bdi->ra_pages * 2;
			spin_lock(&lower_file->f_lock);
			lower_file->f_mode |= FMODE_NOACTIVE;
			spin_unlock(&lower_file->f_lock);
		}
	}
#endif

	err = vfs_read(lower_file, buf, count, ppos);
	/* update our inode atime upon a successful lower read */
	if (err >= 0)
		fsstack_copy_attr_atime(dentry->d_inode,
					lower_file->f_path.dentry->d_inode);

	return err;
}
Пример #2
0
/**
 * ecryptfs_readdir
 * @file: The eCryptfs directory file
 * @dirent: Directory entry handle
 * @filldir: The filldir callback function
 */
static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
	int rc;
	struct file *lower_file;
	struct inode *inode;
	struct ecryptfs_getdents_callback buf;

	lower_file = ecryptfs_file_to_lower(file);
	lower_file->f_pos = file->f_pos;
	inode = file_inode(file);
	memset(&buf, 0, sizeof(buf));
	buf.dirent = dirent;
	buf.dentry = file->f_path.dentry;
	buf.filldir = filldir;
	buf.filldir_called = 0;
	buf.entries_written = 0;
	buf.ctx.actor = ecryptfs_filldir;
	rc = iterate_dir(lower_file, &buf.ctx);
	file->f_pos = lower_file->f_pos;
	if (rc < 0)
		goto out;
	if (buf.filldir_called && !buf.entries_written)
		goto out;
	if (rc >= 0)
		fsstack_copy_attr_atime(inode,
					file_inode(lower_file));
out:
	return rc;
}
struct dentry *wrapfs_lookup(struct inode *dir, struct dentry *dentry,
			     struct nameidata *nd)
{
	struct dentry *ret, *parent;
	struct path lower_parent_path;
	int err = 0;

	BUG_ON(!nd);
	parent = dget_parent(dentry);

	wrapfs_get_lower_path(parent, &lower_parent_path);

	/* allocate dentry private data.  We free it in ->d_release */
	err = new_dentry_private_data(dentry);
	if (err) {
		ret = ERR_PTR(err);
		goto out;
	}
	ret = __wrapfs_lookup(dentry, nd->flags, &lower_parent_path);
	if (IS_ERR(ret))
		goto out;
	if (ret)
		dentry = ret;
	if (dentry->d_inode)
		fsstack_copy_attr_times(dentry->d_inode,
					wrapfs_lower_inode(dentry->d_inode));
	/* update parent directory's atime */
	fsstack_copy_attr_atime(parent->d_inode,
				wrapfs_lower_inode(parent->d_inode));

out:
	wrapfs_put_lower_path(parent, &lower_parent_path);
	dput(parent);
	return ret;
}
Пример #4
0
/**
 * ecryptfs_readdir
 * @file: The ecryptfs file struct
 * @dirent: Directory entry
 * @filldir: The filldir callback function
 */
static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
	int rc;
	struct file *lower_file;
	struct inode *inode;
	struct ecryptfs_getdents_callback buf;

	lower_file = ecryptfs_file_to_lower(file);
	lower_file->f_pos = file->f_pos;
	inode = file->f_path.dentry->d_inode;
	memset(&buf, 0, sizeof(buf));
	buf.dirent = dirent;
	buf.dentry = file->f_path.dentry;
	buf.filldir = filldir;
retry:
	buf.filldir_called = 0;
	buf.entries_written = 0;
	buf.err = 0;
	rc = vfs_readdir(lower_file, ecryptfs_filldir, (void *)&buf);
	if (buf.err)
		rc = buf.err;
	if (buf.filldir_called && !buf.entries_written)
		goto retry;
	file->f_pos = lower_file->f_pos;
	if (rc >= 0)
		fsstack_copy_attr_atime(inode, lower_file->f_path.dentry->d_inode);
	return rc;
}
Пример #5
0
static int wrapfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
{
	int err;
	struct dentry *lower_dentry;
	struct path lower_path;

	if(wrapfs_get_debug(dentry->d_sb) & DEBUG_INODE)
		DEBUG_MESG("Enter");

	wrapfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;
	if (!lower_dentry->d_inode->i_op ||
	    !lower_dentry->d_inode->i_op->readlink) {
		err = -EINVAL;
		goto out;
	}

	err = lower_dentry->d_inode->i_op->readlink(lower_dentry,
						    buf, bufsiz);
	if (err < 0)
		goto out;
	fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode);

out:
	wrapfs_put_lower_path(dentry, &lower_path);

	if(wrapfs_get_debug(dentry->d_sb) & DEBUG_INODE)
		DEBUG_RETURN("Exit", err);

	return err;
}
static int u2fs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
{
	int err;
	struct dentry *lower_dentry;
	struct path lower_path;
	

	if((U2FS_D(dentry)->lower_path[LEFT].dentry) != NULL && 
		(U2FS_D(dentry)->lower_path[LEFT].mnt) != NULL)

		u2fs_get_lower_path(dentry, &lower_path, LEFT);
	else
		u2fs_get_lower_path(dentry, &lower_path, RIGHT);

	lower_dentry = lower_path.dentry;
	if (!lower_dentry->d_inode->i_op ||
	    !lower_dentry->d_inode->i_op->readlink) {
		err = -EINVAL;
		goto out;
	}

	err = lower_dentry->d_inode->i_op->readlink(lower_dentry,
						    buf, bufsiz);
	if (err < 0)
		goto out;
	fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode);

out:
	u2fs_put_lower_path(dentry, &lower_path);
	return err;
}
Пример #7
0
static int sdcardfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
{
	int err;
	struct dentry *lower_dentry;
	struct path lower_path;
	/* XXX readlink does not requires overriding credential */

	sdcardfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;
	if (!lower_dentry->d_inode->i_op ||
	    !lower_dentry->d_inode->i_op->readlink) {
		err = -EINVAL;
		goto out;
	}

	err = lower_dentry->d_inode->i_op->readlink(lower_dentry,
						    buf, bufsiz);
	if (err < 0)
		goto out;
	fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode);

out:
	sdcardfs_put_lower_path(dentry, &lower_path);
	return err;
}
Пример #8
0
static int wrapfs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
	int err = 0;
	struct file *lower_file = NULL;
	struct dentry *dentry = file->f_path.dentry;
	struct dentry *parent;
	struct inode *inode = NULL;
	int bindex = 0;

	inode = dentry->d_inode;
	parent = dget_parent(dentry);

	for (bindex = 0; bindex <= 1; bindex++) {
		lower_file = wrapfs_lower_file_idx(file, bindex);
		if (!lower_file)
			continue;
		err = vfs_readdir(lower_file, filldir, dirent);
		file->f_pos = lower_file->f_pos;
		if (err >= 0) {
			/* copy the atime */
			fsstack_copy_attr_atime(dentry->d_inode,
				lower_file->f_path.dentry->d_inode);
			}
		}
	dput(parent);
	return err;
}
Пример #9
0
static int diaryfs_readlink(struct dentry * dentry, char __user *buf, int bufsize) {
	int err;
	struct dentry * lower_dentry;
	struct path lower_path;

	diaryfs_get_lower_path(dentry, &lower_path); 
	lower_dentry = lower_path.dentry;
	if (!lower_dentry->d_inode->i_op ||
			!lower_dentry->d_inode->i_op->readlink) {
		err = -EINVAL;
		goto out;
	}

	/*
	err = lower_dentry->d_inode->i_op->readilnk(lower_dentry, buf, bufsize);
	if (err < 0)
		goto out; /FIXME
		*/

	fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode);

out:
	diaryfs_put_lower_path(dentry, &lower_path);
	return err;	
}
Пример #10
0
static ssize_t unionfs_splice_read(struct file *file, loff_t *ppos,
				   struct pipe_inode_info *pipe, size_t len,
				   unsigned int flags)
{
	ssize_t err;
	struct file *lower_file;
	struct dentry *dentry = file->f_path.dentry;
	struct dentry *parent;

	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);

	err = unionfs_file_revalidate(file, parent, false);
	if (unlikely(err))
		goto out;

	lower_file = unionfs_lower_file(file);
	err = vfs_splice_to(lower_file, ppos, pipe, len, flags);
	/* update our inode atime upon a successful lower splice-read */
	if (err >= 0) {
		fsstack_copy_attr_atime(dentry->d_inode,
					lower_file->f_path.dentry->d_inode);
		unionfs_check_file(file);
	}

out:
	unionfs_unlock_dentry(dentry);
	unionfs_unlock_parent(dentry, parent);
	unionfs_read_unlock(dentry->d_sb);
	return err;
}
Пример #11
0
static ssize_t unionfs_read(struct file *file, char __user *buf,
			    size_t count, loff_t *ppos)
{
	int err;
	struct file *lower_file;
	struct dentry *dentry = file->f_path.dentry;
	struct dentry *parent;

	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);

	err = unionfs_file_revalidate(file, parent, false);
	if (unlikely(err))
		goto out;

	lower_file = unionfs_lower_file(file);
	err = vfs_read(lower_file, buf, count, ppos);
	/* update our inode atime upon a successful lower read */
	if (err >= 0) {
		fsstack_copy_attr_atime(dentry->d_inode,
					lower_file->f_path.dentry->d_inode);
		unionfs_check_file(file);
	}

out:
	unionfs_unlock_dentry(dentry);
	unionfs_unlock_parent(dentry, parent);
	unionfs_read_unlock(dentry->d_sb);
	return err;
}
/*
 * On success:
 *	fills dentry object appropriate values and returns NULL.
 * On fail (== error)
 *	returns error ptr
 *
 * @dir : Parent inode. It is locked (dir->i_mutex)
 * @dentry : Target dentry to lookup. we should set each of fields.
 *	     (dentry->d_name is initialized already)
 * @nd : nameidata of parent inode
 */
struct dentry *sdcardfs_lookup(struct inode *dir, struct dentry *dentry,
		unsigned int flags)

{
	struct dentry *ret = NULL, *parent;
	struct path lower_parent_path;
	int err = 0;
	struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
	const struct cred *saved_cred = NULL;

	parent = dget_parent(dentry);

	if(!check_caller_access_to_name(parent->d_inode, dentry->d_name.name,
						sbi->options.derive, 0, 0)) {
		ret = ERR_PTR(-EACCES);
		printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
                         "	dentry: %s, task:%s\n",
						 __func__, dentry->d_name.name, current->comm);
		goto out_err;
        }

	/* save current_cred and override it */
	OVERRIDE_CRED_PTR(SDCARDFS_SB(dir->i_sb), saved_cred);

	sdcardfs_get_lower_path(parent, &lower_parent_path);

	/* allocate dentry private data.  We free it in ->d_release */
	err = new_dentry_private_data(dentry);
	if (err) {
		ret = ERR_PTR(err);
		goto out;
	}

	ret = __sdcardfs_lookup(dentry, flags, &lower_parent_path);
	if (IS_ERR(ret))
	{
		goto out;
	}
	if (ret)
		dentry = ret;
	if (dentry->d_inode) {
		fsstack_copy_attr_times(dentry->d_inode,
					sdcardfs_lower_inode(dentry->d_inode));
		/* get drived permission */
		get_derived_permission(parent, dentry);
		fix_derived_permission(dentry->d_inode);
	}
	/* update parent directory's atime */
	fsstack_copy_attr_atime(parent->d_inode,
				sdcardfs_lower_inode(parent->d_inode));

out:
	sdcardfs_put_lower_path(parent, &lower_parent_path);
	REVERT_CRED(saved_cred);
out_err:
	dput(parent);
	return ret;
}
Пример #13
0
static int
ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
{
	char *lower_buf;
	struct dentry *lower_dentry;
	struct ecryptfs_crypt_stat *crypt_stat;
	char *plaintext_name;
	size_t plaintext_name_size;
	mm_segment_t old_fs;
	int rc;

	lower_dentry = ecryptfs_dentry_to_lower(dentry);
	if (!lower_dentry->d_inode->i_op->readlink) {
		rc = -EINVAL;
		goto out;
	}
	crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
	/* Released in this function */
	lower_buf = kmalloc(bufsiz, GFP_KERNEL);
	if (lower_buf == NULL) {
		printk(KERN_ERR "%s: Out of memory whilst attempting to "
		       "kmalloc [%d] bytes\n", __func__, bufsiz);
		rc = -ENOMEM;
		goto out;
	}
	old_fs = get_fs();
	set_fs(get_ds());
	rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
						   (char __user *)lower_buf,
						   bufsiz);
	set_fs(old_fs);
	if (rc >= 0) {
		rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name,
							  &plaintext_name_size,
							  dentry, lower_buf,
							  rc);
		if (rc) {
			printk(KERN_ERR "%s: Error attempting to decode and "
			       "decrypt filename; rc = [%d]\n", __func__,
				rc);
			goto out_free_lower_buf;
		}
		rc = copy_to_user(buf, plaintext_name, plaintext_name_size);
		if (rc)
			rc = -EFAULT;
		else
			rc = plaintext_name_size;
		kfree(plaintext_name);
		fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode);
	}
out_free_lower_buf:
	kfree(lower_buf);
out:
	return rc;
}
Пример #14
0
static const char *ecryptfs_follow_link(struct dentry *dentry, void **cookie)
{
	size_t len;
	char *buf = ecryptfs_readlink_lower(dentry, &len);
	if (IS_ERR(buf))
		return buf;
	fsstack_copy_attr_atime(d_inode(dentry),
				d_inode(ecryptfs_dentry_to_lower(dentry)));
	buf[len] = '\0';
	return *cookie = buf;
}
Пример #15
0
static int
ecryptfs_readlink(struct dentry *dentry, char __user * buf, int bufsiz)
{
	int rc;
	struct dentry *lower_dentry;
	char *decoded_name;
	char *lower_buf;
	mm_segment_t old_fs;
	struct ecryptfs_crypt_stat *crypt_stat;

	lower_dentry = ecryptfs_dentry_to_lower(dentry);
	if (!lower_dentry->d_inode->i_op ||
	    !lower_dentry->d_inode->i_op->readlink) {
		rc = -EINVAL;
		goto out;
	}
	/* Released in this function */
	lower_buf = kmalloc(bufsiz, GFP_KERNEL);
	if (lower_buf == NULL) {
		ecryptfs_printk(KERN_ERR, "Out of memory\n");
		rc = -ENOMEM;
		goto out;
	}
	old_fs = get_fs();
	set_fs(get_ds());
	ecryptfs_printk(KERN_DEBUG, "Calling readlink w/ "
			"lower_dentry->d_name.name = [%s]\n",
			lower_dentry->d_name.name);
	rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
						   (char __user *)lower_buf,
						   bufsiz);
	set_fs(old_fs);
	if (rc >= 0) {
		crypt_stat = NULL;
		rc = ecryptfs_decode_filename(crypt_stat, lower_buf, rc,
					      &decoded_name);
		if (rc == -ENOMEM)
			goto out_free_lower_buf;
		if (rc > 0) {
			ecryptfs_printk(KERN_DEBUG, "Copying [%d] bytes "
					"to userspace: [%*s]\n", rc,
					decoded_name);
			if (copy_to_user(buf, decoded_name, rc))
				rc = -EFAULT;
		}
		kfree(decoded_name);
		fsstack_copy_attr_atime(dentry->d_inode,
					lower_dentry->d_inode);
	}
out_free_lower_buf:
	kfree(lower_buf);
out:
	return rc;
}
Пример #16
0
/**
 * ecryptfs_lookup_interpose - Dentry interposition for a lookup
 */
static int ecryptfs_lookup_interpose(struct dentry *dentry,
				     struct dentry *lower_dentry,
				     struct inode *dir_inode)
{
	struct inode *inode, *lower_inode = lower_dentry->d_inode;
	struct ecryptfs_dentry_info *dentry_info;
	struct vfsmount *lower_mnt;
	int rc = 0;

	lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
	fsstack_copy_attr_atime(dir_inode, lower_dentry->d_parent->d_inode);
	BUG_ON(!lower_dentry->d_count);

	dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL);
	ecryptfs_set_dentry_private(dentry, dentry_info);
	if (!dentry_info) {
		printk(KERN_ERR "%s: Out of memory whilst attempting "
		       "to allocate ecryptfs_dentry_info struct\n",
			__func__);
		dput(lower_dentry);
		mntput(lower_mnt);
		d_drop(dentry);
		return -ENOMEM;
	}
	ecryptfs_set_dentry_lower(dentry, lower_dentry);
	ecryptfs_set_dentry_lower_mnt(dentry, lower_mnt);

	if (!lower_dentry->d_inode) {
		/* We want to add because we couldn't find in lower */
		d_add(dentry, NULL);
		return 0;
	}
	inode = __ecryptfs_get_inode(lower_inode, dir_inode->i_sb);
	if (IS_ERR(inode)) {
		printk(KERN_ERR "%s: Error interposing; rc = [%ld]\n",
		       __func__, PTR_ERR(inode));
		return PTR_ERR(inode);
	}
	if (S_ISREG(inode->i_mode)) {
		rc = ecryptfs_i_size_read(dentry, inode);
		if (rc) {
			make_bad_inode(inode);
			return rc;
		}
	}

	if (inode->i_state & I_NEW)
		unlock_new_inode(inode);
	d_add(dentry, inode);

	return rc;
}
Пример #17
0
static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
	size_t len;
	char *buf = ecryptfs_readlink_lower(dentry, &len);
	if (IS_ERR(buf))
		goto out;
	fsstack_copy_attr_atime(dentry->d_inode,
				ecryptfs_dentry_to_lower(dentry)->d_inode);
	buf[len] = '\0';
out:
	nd_set_link(nd, buf);
	return NULL;
}
Пример #18
0
static int wrapfs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
	int err = 0;
	struct file *lower_file = NULL;
	struct dentry *wrapfs_dentry = file->f_path.dentry;
#ifdef EXTRA_CREDIT
	struct wrapfs_getdents_callback buf;
	
	if(wrapfs_get_debug(file->f_dentry->d_sb) & DEBUG_FILE)
		DEBUG_MESG("Enter");
#endif

	lower_file = wrapfs_lower_file(file);
	// lower_file->f_pos = file->f_pos;

#ifdef EXTRA_CREDIT
	if(wrapfs_get_debug(file->f_dentry->d_sb) & DEBUG_OTHER)
		DEBUG_MESG("Encrypting and Decrypting filenames");

	memset(&buf, 0, sizeof(buf));
	buf.dirent = dirent;
	buf.dentry = wrapfs_dentry;
	buf.filldir = filldir;
	buf.filldir_called = 0;
	buf.entries_written = 0;

	err = vfs_readdir(lower_file, wrapfs_filldir, (void *)&buf);

	if(err<0)
		goto out;
	if(buf.filldir_called && !buf.entries_written) {
		printk(KERN_ERR "wrapfs_readdir: filldir called but entries not written\n");
		goto out;
	}
#else
	err = vfs_readdir(lower_file, filldir, dirent);
#endif

	file->f_pos = lower_file->f_pos;
	if (err >= 0)		/* copy the atime */
		fsstack_copy_attr_atime(wrapfs_dentry->d_inode, lower_file->f_path.dentry->d_inode);

#ifdef EXTRA_CREDIT
	if(wrapfs_get_debug(file->f_dentry->d_sb) & DEBUG_FILE)
		DEBUG_RETURN("Exit", err);

out:
#endif
	return err;
}
Пример #19
0
static int wrapfs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
	int err = 0;
	struct file *lower_file = NULL;
	struct dentry *dentry = file->f_path.dentry;

	lower_file = wrapfs_lower_file(file);
	err = vfs_readdir(lower_file, filldir, dirent);
	file->f_pos = lower_file->f_pos;
	if (err >= 0)		/* copy the atime */
		fsstack_copy_attr_atime(dentry->d_inode,
					lower_file->f_path.dentry->d_inode);
	return err;
}
Пример #20
0
/**
 * ecryptfs_lookup_interpose - Dentry interposition for a lookup
 */
static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry,
				     struct dentry *lower_dentry)
{
	struct inode *inode, *lower_inode = d_inode(lower_dentry);
	struct ecryptfs_dentry_info *dentry_info;
	struct vfsmount *lower_mnt;
	int rc = 0;

	dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL);
	if (!dentry_info) {
		printk(KERN_ERR "%s: Out of memory whilst attempting "
		       "to allocate ecryptfs_dentry_info struct\n",
			__func__);
		dput(lower_dentry);
		return ERR_PTR(-ENOMEM);
	}

	lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
	fsstack_copy_attr_atime(d_inode(dentry->d_parent),
				d_inode(lower_dentry->d_parent));
	BUG_ON(!d_count(lower_dentry));

	ecryptfs_set_dentry_private(dentry, dentry_info);
	dentry_info->lower_path.mnt = lower_mnt;
	dentry_info->lower_path.dentry = lower_dentry;

	if (d_really_is_negative(lower_dentry)) {
		/* We want to add because we couldn't find in lower */
		d_add(dentry, NULL);
		return NULL;
	}
	inode = __ecryptfs_get_inode(lower_inode, dentry->d_sb);
	if (IS_ERR(inode)) {
		printk(KERN_ERR "%s: Error interposing; rc = [%ld]\n",
		       __func__, PTR_ERR(inode));
		return ERR_CAST(inode);
	}
	if (S_ISREG(inode->i_mode)) {
		rc = ecryptfs_i_size_read(dentry, inode);
		if (rc) {
			make_bad_inode(inode);
			return ERR_PTR(rc);
		}
	}

	if (inode->i_state & I_NEW)
		unlock_new_inode(inode);
	return d_splice_alias(inode, dentry);
}
/*
 * scfs_readdir
 */
static int scfs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
	struct file *lower_file = NULL;
	struct dentry *dentry = file->f_path.dentry;
	int ret = 0;

	lower_file = scfs_lower_file(file);
	lower_file->f_pos = file->f_pos;
	ret = vfs_readdir(lower_file, filldir, dirent);
	file->f_pos = lower_file->f_pos;
	if (ret >= 0)
		fsstack_copy_attr_atime(dentry->d_inode, lower_file->f_path.dentry->d_inode);

	return ret;
}
Пример #22
0
static ssize_t wrapfs_read(struct file *file, char __user *buf,
				size_t count, loff_t *ppos)
{

	int err;
	struct file *lower_file;
	struct dentry *dentry = file->f_path.dentry;
	lower_file = wrapfs_lower_file(file);
	err = vfs_read(lower_file, buf, count, ppos);
	/* update our inode atime upon a successful lower read */
	if (err >= 0)
		fsstack_copy_attr_atime(dentry->d_inode,
				lower_file->f_path.dentry->d_inode);
	return err;
}
Пример #23
0
static int sdcardfs_readdir(struct file *file, struct dir_context *ctx)
{
	int err = 0;
	struct file *lower_file = NULL;
	struct dentry *dentry = file->f_path.dentry;

	lower_file = sdcardfs_lower_file(file);

	lower_file->f_pos = file->f_pos;
	err = iterate_dir(lower_file, ctx);
	file->f_pos = lower_file->f_pos;
	if (err >= 0)		/* copy the atime */
		fsstack_copy_attr_atime(dentry->d_inode,
					lower_file->f_path.dentry->d_inode);
	return err;
}
Пример #24
0
static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
	char *buf;
	size_t len = PATH_MAX;
	int rc;

	rc = ecryptfs_readlink_lower(dentry, &buf, &len);
	if (rc)
		goto out;
	fsstack_copy_attr_atime(dentry->d_inode,
				ecryptfs_dentry_to_lower(dentry)->d_inode);
	buf[len] = '\0';
out:
	nd_set_link(nd, buf);
	return NULL;
}
Пример #25
0
static ssize_t fuse_shortcircuit_aio_read_write(struct kiocb *iocb,
						const struct iovec *iov,
						unsigned long nr_segs,
						loff_t pos, int do_write)
{
	ssize_t ret_val;
	struct fuse_file *ff;
	struct file *fuse_file, *lower_file;
	struct inode *fuse_inode, *lower_inode;

	ff = iocb->ki_filp->private_data;
	fuse_file = iocb->ki_filp;
	lower_file = ff->rw_lower_file;

	/* lock lower file to prevent it from being released */
	get_file(lower_file);
	iocb->ki_filp = lower_file;
	fuse_inode = fuse_file->f_path.dentry->d_inode;
	lower_inode = file_inode(lower_file);

	if (do_write) {
		if (!lower_file->f_op->aio_write)
			return -EIO;

		ret_val = lower_file->f_op->aio_write(iocb, iov, nr_segs, pos);

		if (ret_val >= 0 || ret_val == -EIOCBQUEUED) {
			fsstack_copy_inode_size(fuse_inode, lower_inode);
			fsstack_copy_attr_times(fuse_inode, lower_inode);
		}
	} else {
		if (!lower_file->f_op->aio_read)
			return -EIO;

		ret_val = lower_file->f_op->aio_read(iocb, iov, nr_segs, pos);
		if (ret_val >= 0 || ret_val == -EIOCBQUEUED)
			fsstack_copy_attr_atime(fuse_inode, lower_inode);
	}

	iocb->ki_filp = fuse_file;
	fput(lower_file);
	/* unlock lower file */

	return ret_val;
}
Пример #26
0
static int
ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
{
	char *kbuf;
	size_t kbufsiz, copied;
	int rc;

	rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz);
	if (rc)
		goto out;
	copied = min_t(size_t, bufsiz, kbufsiz);
	rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied;
	kfree(kbuf);
	fsstack_copy_attr_atime(dentry->d_inode,
				ecryptfs_dentry_to_lower(dentry)->d_inode);
out:
	return rc;
}
Пример #27
0
/**
 * lofs_readdir
 * @file:       The lofs directory file.
 * @dirent:     Buffer to fill with directory entries.
 * @filldir:    The filldir callback function
 */
static int lofs_readdir(struct file *file, void *dirent, filldir_t filldir)
{
        int rc;
        struct file *lower_file;
        struct inode *inode;

        lower_file = lofs_file_to_lower(file);
        if (lower_file->f_pos != file->f_pos) {
            vfs_llseek(lower_file, file->f_pos, 0 /* SEEK_SET */);
        }
        inode = FILE_TO_DENTRY(file)->d_inode;
        rc = vfs_readdir(lower_file, filldir, dirent);
        file->f_pos = lower_file->f_pos;
        if (rc >= 0) {
            fsstack_copy_attr_atime(inode,FILE_TO_DENTRY(lower_file)->d_inode);
        }
        return rc;
}
Пример #28
0
static ssize_t diaryfs_listxattr(struct dentry * dentry, char * buffer, size_t buffer_size) {
	int err;
	struct dentry * lower_dentry;
	struct path lower_path; 

	diaryfs_get_lower_path(dentry, &lower_path);
	lower_dentry = lower_path.dentry;
	if (!lower_dentry->d_inode->i_op->listxattr) {
		err = -EOPNOTSUPP;
		goto out;
	}
	err = vfs_listxattr(lower_dentry, buffer, buffer_size);
	if (err)
		goto out;
	fsstack_copy_attr_atime(dentry->d_inode, lower_path.dentry->d_inode);
out:
	diaryfs_put_lower_path(dentry, &lower_path);
	return err;
}
Пример #29
0
static const char *ecryptfs_get_link(struct dentry *dentry,
				     struct inode *inode,
				     struct delayed_call *done)
{
	size_t len;
	char *buf;

	if (!dentry)
		return ERR_PTR(-ECHILD);

	buf = ecryptfs_readlink_lower(dentry, &len);
	if (IS_ERR(buf))
		return buf;
	fsstack_copy_attr_atime(d_inode(dentry),
				d_inode(ecryptfs_dentry_to_lower(dentry)));
	buf[len] = '\0';
	set_delayed_call(done, kfree_link, buf);
	return buf;
}
Пример #30
0
int ccfs_readdir (struct file *filp, void *dirent, filldir_t filldir) {
	int rc;
	struct file *lower_file;
	struct inode *inode;

	lower_file = ccfs_get_nested_file(filp);
	mdbg(INFO3, "Read filp %p with lower file: %p Pos: %lu (Upper pos: %lu)", filp, lower_file, (unsigned long)lower_file->f_pos, (unsigned long)filp->f_pos);
	lower_file->f_pos = filp->f_pos;
	inode = filp->f_path.dentry->d_inode;
	rc = vfs_readdir(lower_file, filldir, dirent);
	mdbg(INFO3, "Read return code: %d", rc);
	filp->f_pos = lower_file->f_pos;	
	if (rc >= 0)
		fsstack_copy_attr_atime(inode, lower_file->f_path.dentry->d_inode);

	// The following does not seem to be true at least with kernel 2.6.33.1, so we leave dirs cacheable again
	// We need to disable file caching after readdir, as some filesystems (9P) are not able to repear readdirs on a same file!
	//ccfs_inode_to_private(inode)->cacheable = 0;

	return rc;
}