aboutsummaryrefslogtreecommitdiffstats
path: root/fs/aufs/f
diff options
context:
space:
mode:
Diffstat (limited to 'fs/aufs/f')
-rw-r--r--fs/aufs/f298
1 files changed, 298 insertions, 0 deletions
diff --git a/fs/aufs/f b/fs/aufs/f
new file mode 100644
index 000000000000..500a2ab32cb6
--- /dev/null
+++ b/fs/aufs/f
@@ -0,0 +1,298 @@
+--- /home/bruce/poky/build/tmp/work-shared/qemux86-64/kernel-source/fs/aufs/i_op.c 2017-12-23 23:06:53.241340968 -0500
++++ i_op.c 2017-12-23 23:14:58.070185032 -0500
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2005-2016 Junjiro R. Okajima
++ * Copyright (C) 2005-2017 Junjiro R. Okajima
+ *
+ * This program, aufs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -31,12 +31,15 @@
+ int err;
+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND));
+
++ err = -EPERM;
++ if (write_mask && IS_IMMUTABLE(h_inode))
++ goto out;
++
+ err = -EACCES;
+- if ((write_mask && IS_IMMUTABLE(h_inode))
+- || ((mask & MAY_EXEC)
+- && S_ISREG(h_inode->i_mode)
+- && (path_noexec(h_path)
+- || !(h_inode->i_mode & S_IXUGO))))
++ if (((mask & MAY_EXEC)
++ && S_ISREG(h_inode->i_mode)
++ && (path_noexec(h_path)
++ || !(h_inode->i_mode & S_IXUGO))))
+ goto out;
+
+ /*
+@@ -249,27 +252,28 @@
+ /* ---------------------------------------------------------------------- */
+
+ struct aopen_node {
+- struct hlist_node hlist;
++ struct hlist_bl_node hblist;
+ struct file *file, *h_file;
+ };
+
+ static int au_do_aopen(struct inode *inode, struct file *file)
+ {
+- struct au_sphlhead *aopen;
++ struct hlist_bl_head *aopen;
++ struct hlist_bl_node *pos;
+ struct aopen_node *node;
+ struct au_do_open_args args = {
+- .no_lock = 1,
+- .open = au_do_open_nondir
++ .aopen = 1,
++ .open = au_do_open_nondir
+ };
+
+ aopen = &au_sbi(inode->i_sb)->si_aopen;
+- spin_lock(&aopen->spin);
+- hlist_for_each_entry(node, &aopen->head, hlist)
++ hlist_bl_lock(aopen);
++ hlist_bl_for_each_entry(node, pos, aopen, hblist)
+ if (node->file == file) {
+ args.h_file = node->h_file;
+ break;
+ }
+- spin_unlock(&aopen->spin);
++ hlist_bl_unlock(aopen);
+ /* AuDebugOn(!args.h_file); */
+
+ return au_do_open(file, &args);
+@@ -279,10 +283,10 @@
+ struct file *file, unsigned int open_flag,
+ umode_t create_mode, int *opened)
+ {
+- int err, h_opened = *opened;
++ int err, unlocked, h_opened = *opened;
+ unsigned int lkup_flags;
+ struct dentry *parent, *d;
+- struct au_sphlhead *aopen;
++ struct hlist_bl_head *aopen;
+ struct vfsub_aopen_args args = {
+ .open_flag = open_flag,
+ .create_mode = create_mode,
+@@ -324,6 +328,7 @@
+ || !(open_flag & O_CREAT))
+ goto out_no_open;
+
++ unlocked = 0;
+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
+ if (unlikely(err))
+ goto out;
+@@ -354,6 +359,9 @@
+ put_filp(args.file);
+ goto out_unlock;
+ }
++ di_write_unlock(parent);
++ di_write_unlock(dentry);
++ unlocked = 1;
+
+ /* some filesystems don't set FILE_CREATED while succeeded? */
+ *opened |= FILE_CREATED;
+@@ -364,17 +372,21 @@
+ args.file = NULL;
+ }
+ aopen = &au_sbi(dir->i_sb)->si_aopen;
+- au_sphl_add(&aopen_node.hlist, aopen);
++ au_hbl_add(&aopen_node.hblist, aopen);
+ err = finish_open(file, dentry, au_do_aopen, opened);
+- au_sphl_del(&aopen_node.hlist, aopen);
++ au_hbl_del(&aopen_node.hblist, aopen);
+ AuTraceErr(err);
+ AuDbgFile(file);
+ if (aopen_node.h_file)
+ fput(aopen_node.h_file);
+
+ out_unlock:
+- di_write_unlock(parent);
+- aufs_read_unlock(dentry, AuLock_DW);
++ if (unlocked)
++ si_read_unlock(dentry->d_sb);
++ else {
++ di_write_unlock(parent);
++ aufs_read_unlock(dentry, AuLock_DW);
++ }
+ AuDbgDentry(dentry);
+ if (unlikely(err < 0))
+ goto out;
+@@ -420,10 +432,10 @@
+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) {
+ h_parent = au_h_dptr(parent, bcpup);
+ h_dir = d_inode(h_parent);
+- inode_lock_nested(h_dir, AuLsc_I_PARENT);
++ vfsub_inode_lock_shared_nested(h_dir, AuLsc_I_PARENT);
+ err = au_lkup_neg(dentry, bcpup, /*wh*/0);
+ /* todo: no unlock here */
+- inode_unlock(h_dir);
++ inode_unlock_shared(h_dir);
+
+ AuDbg("bcpup %d\n", bcpup);
+ if (!err) {
+@@ -807,10 +819,10 @@
+ a->h_path.dentry = au_h_dptr(dentry, btop);
+ a->h_inode = d_inode(a->h_path.dentry);
+ if (ia && (ia->ia_valid & ATTR_SIZE)) {
+- inode_lock_nested(a->h_inode, AuLsc_I_CHILD);
++ vfsub_inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD);
+ if (ia->ia_size < i_size_read(a->h_inode))
+ sz = ia->ia_size;
+- inode_unlock(a->h_inode);
++ inode_unlock_shared(a->h_inode);
+ }
+
+ hi_wh = NULL;
+@@ -885,6 +897,10 @@
+ inode = d_inode(dentry);
+ IMustLock(inode);
+
++ err = setattr_prepare(dentry, ia);
++ if (unlikely(err))
++ goto out;
++
+ err = -ENOMEM;
+ a = kzalloc(sizeof(*a), GFP_NOFS);
+ if (unlikely(!a))
+@@ -903,7 +919,8 @@
+ /* currently ftruncate(2) only */
+ AuDebugOn(!d_is_reg(dentry));
+ file = ia->ia_file;
+- err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1);
++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1,
++ /*fi_lsc*/0);
+ if (unlikely(err))
+ goto out_si;
+ ia->ia_file = au_hf_top(file);
+@@ -993,7 +1010,7 @@
+ out_si:
+ si_read_unlock(sb);
+ out_kfree:
+- au_delayed_kfree(a);
++ kfree(a);
+ out:
+ AuTraceErr(err);
+ return err;
+@@ -1028,8 +1045,8 @@
+ return err;
+ }
+
+-ssize_t au_srxattr(struct dentry *dentry, struct inode *inode,
+- struct au_srxattr *arg)
++ssize_t au_sxattr(struct dentry *dentry, struct inode *inode,
++ struct au_sxattr *arg)
+ {
+ int err;
+ struct path h_path;
+@@ -1063,13 +1080,11 @@
+ arg->u.set.name, arg->u.set.value,
+ arg->u.set.size, arg->u.set.flags);
+ break;
+- case AU_XATTR_REMOVE:
+- err = vfsub_removexattr(h_path.dentry, arg->u.remove.name);
+- break;
+ case AU_ACL_SET:
+ err = -EOPNOTSUPP;
+ h_inode = d_inode(h_path.dentry);
+ if (h_inode->i_op->set_acl)
++ /* this will call posix_acl_update_mode */
+ err = h_inode->i_op->set_acl(h_inode,
+ arg->u.acl_set.acl,
+ arg->u.acl_set.type);
+@@ -1086,7 +1101,7 @@
+ di_write_unlock(dentry);
+ si_read_unlock(sb);
+ out_kfree:
+- au_delayed_kfree(a);
++ kfree(a);
+ out:
+ AuTraceErr(err);
+ return err;
+@@ -1123,11 +1138,12 @@
+ }
+
+ /*
+- * common routine for aufs_getattr() and aufs_getxattr().
++ * common routine for aufs_getattr() and au_getxattr().
+ * returns zero or negative (an error).
+ * @dentry will be read-locked in success.
+ */
+-int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path)
++int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path,
++ int locked)
+ {
+ int err;
+ unsigned int mnt_flags, sigen;
+@@ -1144,6 +1160,9 @@
+ mnt_flags = au_mntflags(sb);
+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE);
+
++ if (unlikely(locked))
++ goto body; /* skip locking dinfo */
++
+ /* support fstat(2) */
+ if (!d_unlinked(dentry) && !udba_none) {
+ sigen = au_sigen(sb);
+@@ -1171,6 +1190,7 @@
+ } else
+ di_read_lock_child(dentry, AuLock_IR);
+
++body:
+ inode = d_inode(dentry);
+ bindex = au_ibtop(inode);
+ h_path->mnt = au_sbr_mnt(sb, bindex);
+@@ -1209,7 +1229,7 @@
+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM);
+ if (unlikely(err))
+ goto out;
+- err = au_h_path_getattr(dentry, /*force*/0, &h_path);
++ err = au_h_path_getattr(dentry, /*force*/0, &h_path, /*locked*/0);
+ if (unlikely(err))
+ goto out_si;
+ if (unlikely(!h_path.dentry))
+@@ -1290,7 +1310,7 @@
+ err = 0;
+ AuDbg("%pf\n", h_inode->i_op->get_link);
+ AuDbgDentry(h_dentry);
+- ret = h_inode->i_op->get_link(h_dentry, h_inode, done);
++ ret = vfs_get_link(h_dentry, done);
+ dput(h_dentry);
+ if (IS_ERR(ret))
+ err = PTR_ERR(ret);
+@@ -1384,10 +1404,7 @@
+ .getattr = aufs_getattr,
+
+ #ifdef CONFIG_AUFS_XATTR
+- .setxattr = aufs_setxattr,
+- .getxattr = aufs_getxattr,
+ .listxattr = aufs_listxattr,
+- .removexattr = aufs_removexattr,
+ #endif
+
+ .readlink = generic_readlink,
+@@ -1416,10 +1433,7 @@
+ .getattr = aufs_getattr,
+
+ #ifdef CONFIG_AUFS_XATTR
+- .setxattr = aufs_setxattr,
+- .getxattr = aufs_getxattr,
+ .listxattr = aufs_listxattr,
+- .removexattr = aufs_removexattr,
+ #endif
+
+ .update_time = aufs_update_time,
+@@ -1437,10 +1451,7 @@
+ .getattr = aufs_getattr,
+
+ #ifdef CONFIG_AUFS_XATTR
+- .setxattr = aufs_setxattr,
+- .getxattr = aufs_getxattr,
+ .listxattr = aufs_listxattr,
+- .removexattr = aufs_removexattr,
+ #endif
+
+ .update_time = aufs_update_time