Re: linux-next: manual merge of the y2038 tree with the overlayfs tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi all,

This is now a conflict between the overlayfs tree and Linus' tree.  (I
restarted my merging after I noticed that Linus merged more stuff.)

On Fri, 15 Jun 2018 10:43:24 +1000 Stephen Rothwell <sfr@xxxxxxxxxxxxxxxx> wrote:
>
> Today's linux-next merge of the y2038 tree got conflicts in:
> 
>   fs/inode.c
>   fs/overlayfs/inode.c
>   fs/overlayfs/overlayfs.h
> 
> between various commits from the overlayfs tree and commits:
> 
>   8efd6894ff08 ("fs: add timespec64_truncate()")
>   95582b008388 ("vfs: change inode times to use struct timespec64")
> 
> from the y2038 tree.
> 
> I fixed it up (I copied the resolutions that used to be in the merge of
> the overlayfs into the y2038 tree - see below) and can carry the fix as
> necessary. This is now fixed as far as linux-next is concerned, but any
> non trivial conflicts should be mentioned to your upstream maintainer
> when your tree is submitted for merging.  You may also want to consider
> cooperating with the maintainer of the conflicting tree to minimise any
> particularly complex conflicts.
> 
> -- 
> Cheers,
> Stephen Rothwell
> 
> diff --cc fs/inode.c
> index 9a6fc2f2d220,9fe1f941be02..55373fcba3a5
> --- a/fs/inode.c
> +++ b/fs/inode.c
> @@@ -1635,10 -1681,11 +1635,10 @@@ static int update_time(struct inode *in
>    *	This function automatically handles read only file systems and media,
>    *	as well as the "noatime" flag and inode specific "noatime" markers.
>    */
>  -bool __atime_needs_update(const struct path *path, struct inode *inode,
>  -			  bool rcu)
>  +bool atime_needs_update(const struct path *path, struct inode *inode)
>   {
>   	struct vfsmount *mnt = path->mnt;
> - 	struct timespec now;
> + 	struct timespec64 now;
>   
>   	if (inode->i_flags & S_NOATIME)
>   		return false;
> @@@ -1661,10 -1708,10 +1661,10 @@@
>   
>   	now = current_time(inode);
>   
> - 	if (!relatime_need_update(mnt, inode, now))
>  -	if (!relatime_need_update(path, inode, timespec64_to_timespec(now), rcu))
> ++	if (!relatime_need_update(mnt, inode, timespec64_to_timespec(now)))
>   		return false;
>   
> - 	if (timespec_equal(&inode->i_atime, &now))
> + 	if (timespec64_equal(&inode->i_atime, &now))
>   		return false;
>   
>   	return true;
> @@@ -1674,9 -1721,9 +1674,9 @@@ void touch_atime(const struct path *pat
>   {
>   	struct vfsmount *mnt = path->mnt;
>   	struct inode *inode = d_inode(path->dentry);
> - 	struct timespec now;
> + 	struct timespec64 now;
>   
>  -	if (!__atime_needs_update(path, inode, false))
>  +	if (!atime_needs_update(path, inode))
>   		return;
>   
>   	if (!sb_start_write_trylock(inode->i_sb))
> diff --cc fs/overlayfs/file.c
> index f801e1175a0b,000000000000..c6bce11ac6d3
> mode 100644,000000..100644
> --- a/fs/overlayfs/file.c
> +++ b/fs/overlayfs/file.c
> @@@ -1,508 -1,0 +1,508 @@@
>  +/*
>  + * Copyright (C) 2017 Red Hat, Inc.
>  + *
>  + * This program is free software; you can redistribute it and/or modify it
>  + * under the terms of the GNU General Public License version 2 as published by
>  + * the Free Software Foundation.
>  + */
>  +
>  +#include <linux/cred.h>
>  +#include <linux/file.h>
>  +#include <linux/mount.h>
>  +#include <linux/xattr.h>
>  +#include <linux/uio.h>
>  +#include "overlayfs.h"
>  +
>  +static char ovl_whatisit(struct inode *inode, struct inode *realinode)
>  +{
>  +	if (realinode != ovl_inode_upper(inode))
>  +		return 'l';
>  +	if (ovl_has_upperdata(inode))
>  +		return 'u';
>  +	else
>  +		return 'm';
>  +}
>  +
>  +static struct file *ovl_open_realfile(const struct file *file,
>  +				      struct inode *realinode)
>  +{
>  +	struct inode *inode = file_inode(file);
>  +	struct file *realfile;
>  +	const struct cred *old_cred;
>  +
>  +	old_cred = ovl_override_creds(inode->i_sb);
>  +	realfile = path_open(&file->f_path, file->f_flags | O_NOATIME,
>  +			     realinode, current_cred(), false);
>  +	revert_creds(old_cred);
>  +
>  +	pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n",
>  +		 file, file, ovl_whatisit(inode, realinode), file->f_flags,
>  +		 realfile, IS_ERR(realfile) ? 0 : realfile->f_flags);
>  +
>  +	return realfile;
>  +}
>  +
>  +#define OVL_SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT)
>  +
>  +static int ovl_change_flags(struct file *file, unsigned int flags)
>  +{
>  +	struct inode *inode = file_inode(file);
>  +	int err;
>  +
>  +	/* No atime modificaton on underlying */
>  +	flags |= O_NOATIME;
>  +
>  +	/* If some flag changed that cannot be changed then something's amiss */
>  +	if (WARN_ON((file->f_flags ^ flags) & ~OVL_SETFL_MASK))
>  +		return -EIO;
>  +
>  +	flags &= OVL_SETFL_MASK;
>  +
>  +	if (((flags ^ file->f_flags) & O_APPEND) && IS_APPEND(inode))
>  +		return -EPERM;
>  +
>  +	if (flags & O_DIRECT) {
>  +		if (!file->f_mapping->a_ops ||
>  +		    !file->f_mapping->a_ops->direct_IO)
>  +			return -EINVAL;
>  +	}
>  +
>  +	if (file->f_op->check_flags) {
>  +		err = file->f_op->check_flags(flags);
>  +		if (err)
>  +			return err;
>  +	}
>  +
>  +	spin_lock(&file->f_lock);
>  +	file->f_flags = (file->f_flags & ~OVL_SETFL_MASK) | flags;
>  +	spin_unlock(&file->f_lock);
>  +
>  +	return 0;
>  +}
>  +
>  +static int ovl_real_fdget_meta(const struct file *file, struct fd *real,
>  +			       bool allow_meta)
>  +{
>  +	struct inode *inode = file_inode(file);
>  +	struct inode *realinode;
>  +
>  +	real->flags = 0;
>  +	real->file = file->private_data;
>  +
>  +	if (allow_meta)
>  +		realinode = ovl_inode_real(inode);
>  +	else
>  +		realinode = ovl_inode_realdata(inode);
>  +
>  +	/* Has it been copied up since we'd opened it? */
>  +	if (unlikely(file_inode(real->file) != realinode)) {
>  +		real->flags = FDPUT_FPUT;
>  +		real->file = ovl_open_realfile(file, realinode);
>  +
>  +		return PTR_ERR_OR_ZERO(real->file);
>  +	}
>  +
>  +	/* Did the flags change since open? */
>  +	if (unlikely((file->f_flags ^ real->file->f_flags) & ~O_NOATIME))
>  +		return ovl_change_flags(real->file, file->f_flags);
>  +
>  +	return 0;
>  +}
>  +
>  +static int ovl_real_fdget(const struct file *file, struct fd *real)
>  +{
>  +	return ovl_real_fdget_meta(file, real, false);
>  +}
>  +
>  +static int ovl_open(struct inode *inode, struct file *file)
>  +{
>  +	struct dentry *dentry = file_dentry(file);
>  +	struct file *realfile;
>  +	int err;
>  +
>  +	err = ovl_open_maybe_copy_up(dentry, file->f_flags);
>  +	if (err)
>  +		return err;
>  +
>  +	/* No longer need these flags, so don't pass them on to underlying fs */
>  +	file->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
>  +
>  +	realfile = ovl_open_realfile(file, ovl_inode_realdata(inode));
>  +	if (IS_ERR(realfile))
>  +		return PTR_ERR(realfile);
>  +
>  +	/* For O_DIRECT dentry_open() checks f_mapping->a_ops->direct_IO */
>  +	file->f_mapping = realfile->f_mapping;
>  +
>  +	file->private_data = realfile;
>  +
>  +	return 0;
>  +}
>  +
>  +static int ovl_release(struct inode *inode, struct file *file)
>  +{
>  +	fput(file->private_data);
>  +
>  +	return 0;
>  +}
>  +
>  +static loff_t ovl_llseek(struct file *file, loff_t offset, int whence)
>  +{
>  +	struct inode *realinode = ovl_inode_real(file_inode(file));
>  +
>  +	return generic_file_llseek_size(file, offset, whence,
>  +					realinode->i_sb->s_maxbytes,
>  +					i_size_read(realinode));
>  +}
>  +
>  +static void ovl_file_accessed(struct file *file)
>  +{
>  +	struct inode *inode, *upperinode;
>  +
>  +	if (file->f_flags & O_NOATIME)
>  +		return;
>  +
>  +	inode = file_inode(file);
>  +	upperinode = ovl_inode_upper(inode);
>  +
>  +	if (!upperinode)
>  +		return;
>  +
> - 	if ((!timespec_equal(&inode->i_mtime, &upperinode->i_mtime) ||
> - 	     !timespec_equal(&inode->i_ctime, &upperinode->i_ctime))) {
> ++	if ((!timespec64_equal(&inode->i_mtime, &upperinode->i_mtime) ||
> ++	     !timespec64_equal(&inode->i_ctime, &upperinode->i_ctime))) {
>  +		inode->i_mtime = upperinode->i_mtime;
>  +		inode->i_ctime = upperinode->i_ctime;
>  +	}
>  +
>  +	touch_atime(&file->f_path);
>  +}
>  +
>  +static rwf_t ovl_iocb_to_rwf(struct kiocb *iocb)
>  +{
>  +	int ifl = iocb->ki_flags;
>  +	rwf_t flags = 0;
>  +
>  +	if (ifl & IOCB_NOWAIT)
>  +		flags |= RWF_NOWAIT;
>  +	if (ifl & IOCB_HIPRI)
>  +		flags |= RWF_HIPRI;
>  +	if (ifl & IOCB_DSYNC)
>  +		flags |= RWF_DSYNC;
>  +	if (ifl & IOCB_SYNC)
>  +		flags |= RWF_SYNC;
>  +
>  +	return flags;
>  +}
>  +
>  +static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
>  +{
>  +	struct file *file = iocb->ki_filp;
>  +	struct fd real;
>  +	const struct cred *old_cred;
>  +	ssize_t ret;
>  +
>  +	if (!iov_iter_count(iter))
>  +		return 0;
>  +
>  +	ret = ovl_real_fdget(file, &real);
>  +	if (ret)
>  +		return ret;
>  +
>  +	old_cred = ovl_override_creds(file_inode(file)->i_sb);
>  +	ret = vfs_iter_read(real.file, iter, &iocb->ki_pos,
>  +			    ovl_iocb_to_rwf(iocb));
>  +	revert_creds(old_cred);
>  +
>  +	ovl_file_accessed(file);
>  +
>  +	fdput(real);
>  +
>  +	return ret;
>  +}
>  +
>  +static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
>  +{
>  +	struct file *file = iocb->ki_filp;
>  +	struct inode *inode = file_inode(file);
>  +	struct fd real;
>  +	const struct cred *old_cred;
>  +	ssize_t ret;
>  +
>  +	if (!iov_iter_count(iter))
>  +		return 0;
>  +
>  +	inode_lock(inode);
>  +	/* Update mode */
>  +	ovl_copyattr(ovl_inode_real(inode), inode);
>  +	ret = file_remove_privs(file);
>  +	if (ret)
>  +		goto out_unlock;
>  +
>  +	ret = ovl_real_fdget(file, &real);
>  +	if (ret)
>  +		goto out_unlock;
>  +
>  +	old_cred = ovl_override_creds(file_inode(file)->i_sb);
>  +	ret = vfs_iter_write(real.file, iter, &iocb->ki_pos,
>  +			     ovl_iocb_to_rwf(iocb));
>  +	revert_creds(old_cred);
>  +
>  +	/* Update size */
>  +	ovl_copyattr(ovl_inode_real(inode), inode);
>  +
>  +	fdput(real);
>  +
>  +out_unlock:
>  +	inode_unlock(inode);
>  +
>  +	return ret;
>  +}
>  +
>  +static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
>  +{
>  +	struct fd real;
>  +	const struct cred *old_cred;
>  +	int ret;
>  +
>  +	ret = ovl_real_fdget_meta(file, &real, !datasync);
>  +	if (ret)
>  +		return ret;
>  +
>  +	/* Don't sync lower file for fear of receiving EROFS error */
>  +	if (file_inode(real.file) == ovl_inode_upper(file_inode(file))) {
>  +		old_cred = ovl_override_creds(file_inode(file)->i_sb);
>  +		ret = vfs_fsync_range(real.file, start, end, datasync);
>  +		revert_creds(old_cred);
>  +	}
>  +
>  +	fdput(real);
>  +
>  +	return ret;
>  +}
>  +
>  +static int ovl_mmap(struct file *file, struct vm_area_struct *vma)
>  +{
>  +	struct fd real;
>  +	const struct cred *old_cred;
>  +	int ret;
>  +
>  +	ret = ovl_real_fdget(file, &real);
>  +	if (ret)
>  +		return ret;
>  +
>  +	/* transfer ref: */
>  +	fput(vma->vm_file);
>  +	vma->vm_file = get_file(real.file);
>  +	fdput(real);
>  +
>  +	if (!vma->vm_file->f_op->mmap)
>  +		return -ENODEV;
>  +
>  +	old_cred = ovl_override_creds(file_inode(file)->i_sb);
>  +	ret = call_mmap(vma->vm_file, vma);
>  +	revert_creds(old_cred);
>  +
>  +	ovl_file_accessed(file);
>  +
>  +	return ret;
>  +}
>  +
>  +static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
>  +{
>  +	struct inode *inode = file_inode(file);
>  +	struct fd real;
>  +	const struct cred *old_cred;
>  +	int ret;
>  +
>  +	ret = ovl_real_fdget(file, &real);
>  +	if (ret)
>  +		return ret;
>  +
>  +	old_cred = ovl_override_creds(file_inode(file)->i_sb);
>  +	ret = vfs_fallocate(real.file, mode, offset, len);
>  +	revert_creds(old_cred);
>  +
>  +	/* Update size */
>  +	ovl_copyattr(ovl_inode_real(inode), inode);
>  +
>  +	fdput(real);
>  +
>  +	return ret;
>  +}
>  +
>  +static long ovl_real_ioctl(struct file *file, unsigned int cmd,
>  +			   unsigned long arg)
>  +{
>  +	struct fd real;
>  +	const struct cred *old_cred;
>  +	long ret;
>  +
>  +	ret = ovl_real_fdget(file, &real);
>  +	if (ret)
>  +		return ret;
>  +
>  +	old_cred = ovl_override_creds(file_inode(file)->i_sb);
>  +	ret = vfs_ioctl(real.file, cmd, arg);
>  +	revert_creds(old_cred);
>  +
>  +	fdput(real);
>  +
>  +	return ret;
>  +}
>  +
>  +static long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>  +{
>  +	long ret;
>  +	struct inode *inode = file_inode(file);
>  +
>  +	switch (cmd) {
>  +	case FS_IOC_GETFLAGS:
>  +		ret = ovl_real_ioctl(file, cmd, arg);
>  +		break;
>  +
>  +	case FS_IOC_SETFLAGS:
>  +		if (!inode_owner_or_capable(inode))
>  +			return -EACCES;
>  +
>  +		ret = mnt_want_write_file(file);
>  +		if (ret)
>  +			return ret;
>  +
>  +		ret = ovl_copy_up_with_data(file_dentry(file));
>  +		if (!ret) {
>  +			ret = ovl_real_ioctl(file, cmd, arg);
>  +
>  +			inode_lock(inode);
>  +			ovl_copyflags(ovl_inode_real(inode), inode);
>  +			inode_unlock(inode);
>  +		}
>  +
>  +		mnt_drop_write_file(file);
>  +		break;
>  +
>  +	default:
>  +		ret = -ENOTTY;
>  +	}
>  +
>  +	return ret;
>  +}
>  +
>  +static long ovl_compat_ioctl(struct file *file, unsigned int cmd,
>  +			     unsigned long arg)
>  +{
>  +	switch (cmd) {
>  +	case FS_IOC32_GETFLAGS:
>  +		cmd = FS_IOC_GETFLAGS;
>  +		break;
>  +
>  +	case FS_IOC32_SETFLAGS:
>  +		cmd = FS_IOC_SETFLAGS;
>  +		break;
>  +
>  +	default:
>  +		return -ENOIOCTLCMD;
>  +	}
>  +
>  +	return ovl_ioctl(file, cmd, arg);
>  +}
>  +
>  +enum ovl_copyop {
>  +	OVL_COPY,
>  +	OVL_CLONE,
>  +	OVL_DEDUPE,
>  +};
>  +
>  +static s64 ovl_copyfile(struct file *file_in, loff_t pos_in,
>  +			struct file *file_out, loff_t pos_out,
>  +			u64 len, unsigned int flags, enum ovl_copyop op)
>  +{
>  +	struct inode *inode_out = file_inode(file_out);
>  +	struct fd real_in, real_out;
>  +	const struct cred *old_cred;
>  +	s64 ret;
>  +
>  +	ret = ovl_real_fdget(file_out, &real_out);
>  +	if (ret)
>  +		return ret;
>  +
>  +	ret = ovl_real_fdget(file_in, &real_in);
>  +	if (ret) {
>  +		fdput(real_out);
>  +		return ret;
>  +	}
>  +
>  +	old_cred = ovl_override_creds(file_inode(file_out)->i_sb);
>  +	switch (op) {
>  +	case OVL_COPY:
>  +		ret = vfs_copy_file_range(real_in.file, pos_in,
>  +					  real_out.file, pos_out, len, flags);
>  +		break;
>  +
>  +	case OVL_CLONE:
>  +		ret = vfs_clone_file_range(real_in.file, pos_in,
>  +					   real_out.file, pos_out, len);
>  +		break;
>  +
>  +	case OVL_DEDUPE:
>  +		ret = vfs_dedupe_file_range_one(real_in.file, pos_in,
>  +						real_out.file, pos_out, len);
>  +		break;
>  +	}
>  +	revert_creds(old_cred);
>  +
>  +	/* Update size */
>  +	ovl_copyattr(ovl_inode_real(inode_out), inode_out);
>  +
>  +	fdput(real_in);
>  +	fdput(real_out);
>  +
>  +	return ret;
>  +}
>  +
>  +static ssize_t ovl_copy_file_range(struct file *file_in, loff_t pos_in,
>  +				   struct file *file_out, loff_t pos_out,
>  +				   size_t len, unsigned int flags)
>  +{
>  +	return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, flags,
>  +			    OVL_COPY);
>  +}
>  +
>  +static int ovl_clone_file_range(struct file *file_in, loff_t pos_in,
>  +				struct file *file_out, loff_t pos_out, u64 len)
>  +{
>  +	return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, 0,
>  +			    OVL_CLONE);
>  +}
>  +
>  +static loff_t ovl_dedupe_file_range(struct file *file_in, loff_t pos_in,
>  +				    struct file *file_out, loff_t pos_out,
>  +				    loff_t len)
>  +{
>  +	/*
>  +	 * Don't copy up because of a dedupe request, this wouldn't make sense
>  +	 * most of the time (data would be duplicated instead of deduplicated).
>  +	 */
>  +	if (!ovl_inode_upper(file_inode(file_in)) ||
>  +	    !ovl_inode_upper(file_inode(file_out)))
>  +		return -EPERM;
>  +
>  +	return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, 0,
>  +			    OVL_DEDUPE);
>  +}
>  +
>  +const struct file_operations ovl_file_operations = {
>  +	.open		= ovl_open,
>  +	.release	= ovl_release,
>  +	.llseek		= ovl_llseek,
>  +	.read_iter	= ovl_read_iter,
>  +	.write_iter	= ovl_write_iter,
>  +	.fsync		= ovl_fsync,
>  +	.mmap		= ovl_mmap,
>  +	.fallocate	= ovl_fallocate,
>  +	.unlocked_ioctl	= ovl_ioctl,
>  +	.compat_ioctl	= ovl_compat_ioctl,
>  +
>  +	.copy_file_range	= ovl_copy_file_range,
>  +	.clone_file_range	= ovl_clone_file_range,
>  +	.dedupe_file_range	= ovl_dedupe_file_range,
>  +};
> diff --cc fs/overlayfs/inode.c
> index e31d64206a01,d7cca60f28e6..e0bb217c01e2
> --- a/fs/overlayfs/inode.c
> +++ b/fs/overlayfs/inode.c
> @@@ -439,7 -384,39 +439,7 @@@ struct posix_acl *ovl_get_acl(struct in
>   	return acl;
>   }
>   
> - int ovl_update_time(struct inode *inode, struct timespec *ts, int flags)
>  -static bool ovl_open_need_copy_up(struct dentry *dentry, int flags)
>  -{
>  -	/* Copy up of disconnected dentry does not set upper alias */
>  -	if (ovl_dentry_upper(dentry) &&
>  -	    (ovl_dentry_has_upper_alias(dentry) ||
>  -	     (dentry->d_flags & DCACHE_DISCONNECTED)))
>  -		return false;
>  -
>  -	if (special_file(d_inode(dentry)->i_mode))
>  -		return false;
>  -
>  -	if (!(OPEN_FMODE(flags) & FMODE_WRITE) && !(flags & O_TRUNC))
>  -		return false;
>  -
>  -	return true;
>  -}
>  -
>  -int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags)
>  -{
>  -	int err = 0;
>  -
>  -	if (ovl_open_need_copy_up(dentry, file_flags)) {
>  -		err = ovl_want_write(dentry);
>  -		if (!err) {
>  -			err = ovl_copy_up_flags(dentry, file_flags);
>  -			ovl_drop_write(dentry);
>  -		}
>  -	}
>  -
>  -	return err;
>  -}
>  -
> + int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags)
>   {
>   	if (flags & S_ATIME) {
>   		struct ovl_fs *ofs = inode->i_sb->s_fs_info;
> diff --cc fs/overlayfs/overlayfs.h
> index ac9fbc3d08ea,9fe10247f9d4..f61839e1054c
> --- a/fs/overlayfs/overlayfs.h
> +++ b/fs/overlayfs/overlayfs.h
> @@@ -349,18 -330,10 +349,18 @@@ int ovl_xattr_get(struct dentry *dentry
>   		  void *value, size_t size);
>   ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
>   struct posix_acl *ovl_get_acl(struct inode *inode, int type);
> - int ovl_update_time(struct inode *inode, struct timespec *ts, int flags);
>  -int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags);
> + int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags);
>   bool ovl_is_private_xattr(const char *name);
>   
>  +struct ovl_inode_params {
>  +	struct inode *newinode;
>  +	struct dentry *upperdentry;
>  +	struct ovl_path *lowerpath;
>  +	struct dentry *index;
>  +	unsigned int numlower;
>  +	char *redirect;
>  +	struct dentry *lowerdata;
>  +};
>   struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, dev_t rdev);
>   struct inode *ovl_lookup_inode(struct super_block *sb, struct dentry *real,
>   			       bool is_upper);



-- 
Cheers,
Stephen Rothwell

Attachment: pgpBiuXQK0qd6.pgp
Description: OpenPGP digital signature


[Index of Archives]     [Linux Kernel]     [Linux USB Development]     [Yosemite News]     [Linux SCSI]

  Powered by Linux