summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2016-06-27 21:01:09 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2016-06-27 21:01:09 -0300
commitb907a8622e39eecfc4b243f3be3ad26559d1faee (patch)
treeb99ead386fccde5ea8252b5b5ebff8ffd83cd03d /fs
parent68f052d01b53b858897d80beb0095920abe5868e (diff)
Linux-libre 4.6.3-gnupck-4.6.3-gnu
Diffstat (limited to 'fs')
-rw-r--r--fs/aufs/branch.c17
-rw-r--r--fs/aufs/cpup.c24
-rw-r--r--fs/aufs/debug.c8
-rw-r--r--fs/aufs/dentry.c36
-rw-r--r--fs/aufs/dentry.h6
-rw-r--r--fs/aufs/dinfo.c32
-rw-r--r--fs/aufs/dir.c4
-rw-r--r--fs/aufs/export.c2
-rw-r--r--fs/aufs/f_op.c22
-rw-r--r--fs/aufs/file.c8
-rw-r--r--fs/aufs/hfsnotify.c4
-rw-r--r--fs/aufs/i_op.c6
-rw-r--r--fs/aufs/i_op_ren.c8
-rw-r--r--fs/aufs/iinfo.c22
-rw-r--r--fs/aufs/inode.c2
-rw-r--r--fs/aufs/inode.h11
-rw-r--r--fs/aufs/opts.c4
-rw-r--r--fs/aufs/super.c16
-rw-r--r--fs/aufs/whout.c8
-rw-r--r--fs/aufs/xino.c8
-rw-r--r--fs/dcache.c4
-rw-r--r--fs/ecryptfs/kthread.c13
-rw-r--r--fs/proc/root.c7
23 files changed, 156 insertions, 116 deletions
diff --git a/fs/aufs/branch.c b/fs/aufs/branch.c
index 5259d30d1..07c842d14 100644
--- a/fs/aufs/branch.c
+++ b/fs/aufs/branch.c
@@ -300,7 +300,7 @@ static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
bindex = au_br_index(sb, br->br_id);
if (0 <= bindex) {
hdir = au_hi(d_inode(sb->s_root), bindex);
- au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
} else {
h_dentry = au_br_dentry(br);
h_inode = d_inode(h_dentry);
@@ -314,7 +314,7 @@ static int au_br_init_wh(struct super_block *sb, struct au_branch *br,
wbr_wh_write_unlock(wbr);
}
if (hdir)
- au_hn_imtx_unlock(hdir);
+ au_hn_inode_unlock(hdir);
else
inode_unlock(h_inode);
vfsub_mnt_drop_write(au_br_mnt(br));
@@ -425,7 +425,7 @@ static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex,
AuRwMustWriteLock(&dinfo->di_rwsem);
- hdp = dinfo->di_hdentry + bindex;
+ hdp = au_hdentry(dinfo, bindex);
memmove(hdp + 1, hdp, sizeof(*hdp) * amount);
au_h_dentry_init(hdp);
dinfo->di_bbot++;
@@ -900,14 +900,13 @@ static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex,
AuRwMustWriteLock(&dinfo->di_rwsem);
- hdp = dinfo->di_hdentry;
+ hdp = au_hdentry(dinfo, bindex);
if (bindex < bbot)
- memmove(hdp + bindex, hdp + bindex + 1,
- sizeof(*hdp) * (bbot - bindex));
- hdp[0 + bbot].hd_dentry = NULL;
+ memmove(hdp, hdp + 1, sizeof(*hdp) * (bbot - bindex));
+ /* au_h_dentry_init(au_hdentry(dinfo, bbot); */
dinfo->di_bbot--;
- p = krealloc(hdp, sizeof(*p) * bbot, AuGFP_SBILIST);
+ p = krealloc(dinfo->di_hdentry, sizeof(*p) * bbot, AuGFP_SBILIST);
if (p)
dinfo->di_hdentry = p;
/* harmless error */
@@ -1115,7 +1114,7 @@ static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg)
inode = ilookup(sb, ibusy.ino);
if (!inode
|| inode->i_ino == AUFS_ROOT_INO
- || is_bad_inode(inode))
+ || au_is_bad_inode(inode))
goto out_unlock;
ii_read_lock_child(inode);
diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c
index dbf96fd60..52f87de63 100644
--- a/fs/aufs/cpup.c
+++ b/fs/aufs/cpup.c
@@ -1087,23 +1087,27 @@ static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
int err;
unsigned int flags_orig;
aufs_bindex_t bsrc_orig;
- struct dentry *h_d_dst, *h_d_start;
struct au_dinfo *dinfo;
- struct au_hdentry *hdp;
+ struct {
+ struct au_hdentry *hd;
+ struct dentry *h_dentry;
+ } hdst, hsrc;
dinfo = au_di(cpg->dentry);
AuRwMustWriteLock(&dinfo->di_rwsem);
bsrc_orig = cpg->bsrc;
cpg->bsrc = dinfo->di_btop;
- hdp = dinfo->di_hdentry;
- h_d_dst = hdp[0 + cpg->bdst].hd_dentry;
+ hdst.hd = au_hdentry(dinfo, cpg->bdst);
+ hdst.h_dentry = hdst.hd->hd_dentry;
+ hdst.hd->hd_dentry = wh_dentry;
dinfo->di_btop = cpg->bdst;
- hdp[0 + cpg->bdst].hd_dentry = wh_dentry;
- h_d_start = NULL;
+
+ hsrc.h_dentry = NULL;
if (file) {
- h_d_start = hdp[0 + cpg->bsrc].hd_dentry;
- hdp[0 + cpg->bsrc].hd_dentry = au_hf_top(file)->f_path.dentry;
+ hsrc.hd = au_hdentry(dinfo, cpg->bsrc);
+ hsrc.h_dentry = hsrc.hd->hd_dentry;
+ hsrc.hd->hd_dentry = au_hf_top(file)->f_path.dentry;
}
flags_orig = cpg->flags;
cpg->flags = !AuCpup_DTIME;
@@ -1112,9 +1116,9 @@ static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry,
if (file) {
if (!err)
err = au_reopen_nondir(file);
- hdp[0 + cpg->bsrc].hd_dentry = h_d_start;
+ hsrc.hd->hd_dentry = hsrc.h_dentry;
}
- hdp[0 + cpg->bdst].hd_dentry = h_d_dst;
+ hdst.hd->hd_dentry = hdst.h_dentry;
dinfo->di_btop = cpg->bsrc;
cpg->bsrc = bsrc_orig;
diff --git a/fs/aufs/debug.c b/fs/aufs/debug.c
index 14e69cbc8..4fdc9d422 100644
--- a/fs/aufs/debug.c
+++ b/fs/aufs/debug.c
@@ -133,7 +133,7 @@ void au_dpri_inode(struct inode *inode)
int err, hn;
err = do_pri_inode(-1, inode, -1, NULL);
- if (err || !au_test_aufs(inode->i_sb) || is_bad_inode(inode))
+ if (err || !au_test_aufs(inode->i_sb) || au_is_bad_inode(inode))
return;
iinfo = au_ii(inode);
@@ -184,7 +184,7 @@ static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
&& d_is_positive(dentry)
&& au_test_aufs(dentry->d_sb))
inode = d_inode(dentry);
- if (inode && !is_bad_inode(inode)) {
+ if (inode && !au_is_bad_inode(inode)) {
iinfo = au_ii(inode);
hi = au_hinode(iinfo, bindex);
hn = !!au_hn(hi);
@@ -199,7 +199,6 @@ void au_dpri_dentry(struct dentry *dentry)
struct au_dinfo *dinfo;
aufs_bindex_t bindex;
int err;
- struct au_hdentry *hdp;
err = do_pri_dentry(-1, dentry);
if (err || !au_test_aufs(dentry->d_sb))
@@ -214,9 +213,8 @@ void au_dpri_dentry(struct dentry *dentry)
dinfo->di_tmpfile);
if (dinfo->di_btop < 0)
return;
- hdp = dinfo->di_hdentry;
for (bindex = dinfo->di_btop; bindex <= dinfo->di_bbot; bindex++)
- do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry);
+ do_pri_dentry(bindex, au_hdentry(dinfo, bindex)->hd_dentry);
}
static int do_pri_file(aufs_bindex_t bindex, struct file *file)
diff --git a/fs/aufs/dentry.c b/fs/aufs/dentry.c
index ce2a13632..080fac9c8 100644
--- a/fs/aufs/dentry.c
+++ b/fs/aufs/dentry.c
@@ -394,8 +394,9 @@ static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
bbot = dinfo->di_bbot;
bwh = dinfo->di_bwh;
bdiropq = dinfo->di_bdiropq;
- p = dinfo->di_hdentry + dinfo->di_btop;
- for (bindex = dinfo->di_btop; bindex <= bbot; bindex++, p++) {
+ bindex = dinfo->di_btop;
+ p = au_hdentry(dinfo, bindex);
+ for (; bindex <= bbot; bindex++, p++) {
if (!p->hd_dentry)
continue;
@@ -414,7 +415,7 @@ static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
}
/* swap two lower dentries, and loop again */
- q = dinfo->di_hdentry + new_bindex;
+ q = au_hdentry(dinfo, new_bindex);
tmp = *q;
*q = *p;
*p = tmp;
@@ -438,16 +439,18 @@ static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
dinfo->di_btop = -1;
dinfo->di_bbot = -1;
bbot = au_dbbot(parent);
- p = dinfo->di_hdentry;
- for (bindex = 0; bindex <= bbot; bindex++, p++)
+ bindex = 0;
+ p = au_hdentry(dinfo, bindex);
+ for (; bindex <= bbot; bindex++, p++)
if (p->hd_dentry) {
dinfo->di_btop = bindex;
break;
}
if (dinfo->di_btop >= 0) {
- p = dinfo->di_hdentry + bbot;
- for (bindex = bbot; bindex >= 0; bindex--, p--)
+ bindex = bbot;
+ p = au_hdentry(dinfo, bindex);
+ for (; bindex >= 0; bindex--, p--)
if (p->hd_dentry) {
dinfo->di_bbot = bindex;
err = 0;
@@ -564,14 +567,14 @@ static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
err = 0;
AuDebugOn(dinfo->di_btop < 0);
orig_h.mode = 0;
- orig_h.dentry = dinfo->di_hdentry[dinfo->di_btop].hd_dentry;
+ orig_h.dentry = au_hdentry(dinfo, dinfo->di_btop)->hd_dentry;
orig_h.inode = NULL;
if (d_is_positive(orig_h.dentry)) {
orig_h.inode = d_inode(orig_h.dentry);
orig_h.mode = orig_h.inode->i_mode & S_IFMT;
}
if (tmp->di_btop >= 0) {
- tmp_h.dentry = tmp->di_hdentry[tmp->di_btop].hd_dentry;
+ tmp_h.dentry = au_hdentry(tmp, tmp->di_btop)->hd_dentry;
if (d_is_positive(tmp_h.dentry)) {
tmp_h.inode = d_inode(tmp_h.dentry);
tmp_h.mode = tmp_h.inode->i_mode & S_IFMT;
@@ -600,7 +603,7 @@ static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
AuDebugOn(dinfo->di_btop != dinfo->di_bbot);
au_set_h_dptr(dentry, dinfo->di_btop, NULL);
au_di_cp(dinfo, tmp);
- hd = tmp->di_hdentry + tmp->di_btop;
+ hd = au_hdentry(tmp, tmp->di_btop);
au_set_h_dptr(dentry, tmp->di_btop,
dget(hd->hd_dentry));
}
@@ -651,13 +654,13 @@ static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
dinfo->di_bbot = tmp->di_bbot;
dinfo->di_bwh = tmp->di_bwh;
dinfo->di_bdiropq = tmp->di_bdiropq;
- hd = tmp->di_hdentry;
bbot = dinfo->di_bbot;
- for (bindex = tmp->di_btop; bindex <= bbot;
- bindex++) {
+ bindex = tmp->di_btop;
+ hd = au_hdentry(tmp, bindex);
+ for (; bindex <= bbot; bindex++, hd++) {
if (au_h_dptr(dentry, bindex))
continue;
- h_dentry = hd[bindex].hd_dentry;
+ h_dentry = hd->hd_dentry;
if (!h_dentry)
continue;
AuDebugOn(d_is_negative(h_dentry));
@@ -668,7 +671,8 @@ static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo,
au_set_h_dptr(dentry, bindex,
dget(h_dentry));
}
- err = au_refresh_hinode(inode, dentry);
+ if (inode)
+ err = au_refresh_hinode(inode, dentry);
au_dbg_verify_dinode(dentry);
}
} else {
@@ -1036,7 +1040,7 @@ static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags)
inode = NULL;
if (d_really_is_positive(dentry))
inode = d_inode(dentry);
- if (unlikely(inode && is_bad_inode(inode))) {
+ if (unlikely(inode && au_is_bad_inode(inode))) {
err = -EINVAL;
AuTraceErr(err);
goto out_dgrade;
diff --git a/fs/aufs/dentry.h b/fs/aufs/dentry.h
index 3e48b5cde..c52fe583f 100644
--- a/fs/aufs/dentry.h
+++ b/fs/aufs/dentry.h
@@ -145,6 +145,12 @@ static inline void au_h_dentry_init(struct au_hdentry *hdentry)
hdentry->hd_dentry = NULL;
}
+static inline struct au_hdentry *au_hdentry(struct au_dinfo *di,
+ aufs_bindex_t bindex)
+{
+ return di->di_hdentry + bindex;
+}
+
static inline void au_hdput(struct au_hdentry *hd)
{
if (hd)
diff --git a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c
index b2eb8c2de..43b550973 100644
--- a/fs/aufs/dinfo.c
+++ b/fs/aufs/dinfo.c
@@ -56,7 +56,7 @@ void au_di_free(struct au_dinfo *dinfo)
bindex = dinfo->di_btop;
if (bindex >= 0) {
bbot = dinfo->di_bbot;
- p = dinfo->di_hdentry + bindex;
+ p = au_hdentry(dinfo, bindex);
while (bindex++ <= bbot)
au_hdput(p++);
}
@@ -308,7 +308,7 @@ struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry))
return NULL;
AuDebugOn(bindex < 0);
- d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry;
+ d = au_hdentry(au_di(dentry), bindex)->hd_dentry;
AuDebugOn(d && au_dcount(d) <= 0);
return d;
}
@@ -397,11 +397,14 @@ aufs_bindex_t au_dbtaildir(struct dentry *dentry)
void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
struct dentry *h_dentry)
{
- struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
+ struct au_dinfo *dinfo;
+ struct au_hdentry *hd;
struct au_branch *br;
DiMustWriteLock(dentry);
+ dinfo = au_di(dentry);
+ hd = au_hdentry(dinfo, bindex);
au_hdput(hd);
hd->hd_dentry = h_dentry;
if (h_dentry) {
@@ -451,6 +454,7 @@ void au_update_dbrange(struct dentry *dentry, int do_put_zero)
struct au_dinfo *dinfo;
struct dentry *h_d;
struct au_hdentry *hdp;
+ aufs_bindex_t bindex, bbot;
DiMustWriteLock(dentry);
@@ -458,21 +462,21 @@ void au_update_dbrange(struct dentry *dentry, int do_put_zero)
if (!dinfo || dinfo->di_btop < 0)
return;
- hdp = dinfo->di_hdentry;
if (do_put_zero) {
- aufs_bindex_t bindex, bbot;
-
bbot = dinfo->di_bbot;
- for (bindex = dinfo->di_btop; bindex <= bbot; bindex++) {
- h_d = hdp[0 + bindex].hd_dentry;
+ bindex = dinfo->di_btop;
+ hdp = au_hdentry(dinfo, bindex);
+ for (; bindex <= bbot; bindex++, hdp++) {
+ h_d = hdp->hd_dentry;
if (h_d && d_is_negative(h_d))
au_set_h_dptr(dentry, bindex, NULL);
}
}
- dinfo->di_btop = -1;
- while (++dinfo->di_btop <= dinfo->di_bbot)
- if (hdp[0 + dinfo->di_btop].hd_dentry)
+ dinfo->di_btop = 0;
+ hdp = au_hdentry(dinfo, dinfo->di_btop);
+ for (; dinfo->di_btop <= dinfo->di_bbot; dinfo->di_btop++, hdp++)
+ if (hdp->hd_dentry)
break;
if (dinfo->di_btop > dinfo->di_bbot) {
dinfo->di_btop = -1;
@@ -480,9 +484,9 @@ void au_update_dbrange(struct dentry *dentry, int do_put_zero)
return;
}
- dinfo->di_bbot++;
- while (0 <= --dinfo->di_bbot)
- if (hdp[0 + dinfo->di_bbot].hd_dentry)
+ hdp = au_hdentry(dinfo, dinfo->di_bbot);
+ for (; dinfo->di_bbot >= 0; dinfo->di_bbot--, hdp--)
+ if (hdp->hd_dentry)
break;
AuDebugOn(dinfo->di_btop > dinfo->di_bbot || dinfo->di_bbot < 0);
}
diff --git a/fs/aufs/dir.c b/fs/aufs/dir.c
index 4dc666eb4..716158c3c 100644
--- a/fs/aufs/dir.c
+++ b/fs/aufs/dir.c
@@ -127,14 +127,14 @@ static void au_do_dir_ts(void *arg)
if (err)
goto out_unlock;
hdir = au_hi(dir, btop);
- au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
h_dir = au_h_iptr(dir, btop);
if (h_dir->i_nlink
&& timespec_compare(&h_dir->i_mtime, &dt.dt_mtime) < 0) {
dt.dt_h_path = h_path;
au_dtime_revert(&dt);
}
- au_hn_imtx_unlock(hdir);
+ au_hn_inode_unlock(hdir);
vfsub_mnt_drop_write(h_path.mnt);
au_cpup_attr_timesizes(dir);
diff --git a/fs/aufs/export.c b/fs/aufs/export.c
index 8755b1ef0..98a7036c2 100644
--- a/fs/aufs/export.c
+++ b/fs/aufs/export.c
@@ -220,7 +220,7 @@ static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
dentry = ERR_PTR(-ESTALE);
sigen = au_sigen(sb);
- if (unlikely(is_bad_inode(inode)
+ if (unlikely(au_is_bad_inode(inode)
|| IS_DEADDIR(inode)
|| sigen != au_iigen(inode, NULL)))
goto out_iput;
diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c
index b0b0fff5f..504b76751 100644
--- a/fs/aufs/f_op.c
+++ b/fs/aufs/f_op.c
@@ -341,11 +341,20 @@ static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter)
sb = inode->i_sb;
si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
- h_file = au_read_pre(file, /*keep_fi*/0);
+ h_file = au_read_pre(file, /*keep_fi*/1);
err = PTR_ERR(h_file);
if (IS_ERR(h_file))
goto out;
+ if (au_test_loopback_kthread()) {
+ au_warn_loopback(h_file->f_path.dentry->d_sb);
+ if (file->f_mapping != h_file->f_mapping) {
+ file->f_mapping = h_file->f_mapping;
+ smp_mb(); /* unnecessary? */
+ }
+ }
+ fi_read_unlock(file);
+
err = au_do_iter(h_file, MAY_READ, kio, iov_iter);
/* todo: necessary? */
/* file->f_ra = h_file->f_ra; */
@@ -394,20 +403,11 @@ static ssize_t aufs_splice_read(struct file *file, loff_t *ppos,
sb = inode->i_sb;
si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
- h_file = au_read_pre(file, /*keep_fi*/1);
+ h_file = au_read_pre(file, /*keep_fi*/0);
err = PTR_ERR(h_file);
if (IS_ERR(h_file))
goto out;
- if (au_test_loopback_kthread()) {
- au_warn_loopback(h_file->f_path.dentry->d_sb);
- if (file->f_mapping != h_file->f_mapping) {
- file->f_mapping = h_file->f_mapping;
- smp_mb(); /* unnecessary? */
- }
- }
- fi_read_unlock(file);
-
err = vfsub_splice_to(h_file, ppos, pipe, len, flags);
/* todo: necessasry? */
/* file->f_ra = h_file->f_ra; */
diff --git a/fs/aufs/file.c b/fs/aufs/file.c
index 27c5bf825..0113f3ef4 100644
--- a/fs/aufs/file.c
+++ b/fs/aufs/file.c
@@ -339,11 +339,11 @@ static int au_reopen_wh(struct file *file, aufs_bindex_t btgt,
btop = dinfo->di_btop;
dinfo->di_btop = btgt;
- hdp = dinfo->di_hdentry;
- h_dentry = hdp[0 + btgt].hd_dentry;
- hdp[0 + btgt].hd_dentry = hi_wh;
+ hdp = au_hdentry(dinfo, btgt);
+ h_dentry = hdp->hd_dentry;
+ hdp->hd_dentry = hi_wh;
err = au_reopen_nondir(file);
- hdp[0 + btgt].hd_dentry = h_dentry;
+ hdp->hd_dentry = h_dentry;
dinfo->di_btop = btop;
return err;
diff --git a/fs/aufs/hfsnotify.c b/fs/aufs/hfsnotify.c
index 07b4ecc53..6afef3f07 100644
--- a/fs/aufs/hfsnotify.c
+++ b/fs/aufs/hfsnotify.c
@@ -18,7 +18,7 @@ static void au_hfsn_free_mark(struct fsnotify_mark *mark)
{
struct au_hnotify *hn = container_of(mark, struct au_hnotify,
hn_mark);
- AuDbg("here\n");
+ /* AuDbg("here\n"); */
au_cache_free_hnotify(hn);
smp_mb__before_atomic();
if (atomic64_dec_and_test(&au_hfsn_ifree))
@@ -142,7 +142,7 @@ static void au_hfsn_free_group(struct fsnotify_group *group)
{
struct au_br_hfsnotify *hfsn = group->private;
- AuDbg("here\n");
+ /* AuDbg("here\n"); */
kfree(hfsn);
}
diff --git a/fs/aufs/i_op.c b/fs/aufs/i_op.c
index 1572a7d4d..ac3bf9437 100644
--- a/fs/aufs/i_op.c
+++ b/fs/aufs/i_op.c
@@ -294,8 +294,8 @@ static int aufs_atomic_open(struct inode *dir, struct dentry *dentry,
* another error will be returned later.
*/
d_drop(d);
- dput(d);
AuDbgDentry(d);
+ dput(d);
}
AuDbgDentry(dentry);
}
@@ -508,7 +508,7 @@ out:
void au_pin_hdir_unlock(struct au_pin *p)
{
if (p->hdir)
- au_hn_imtx_unlock(p->hdir);
+ au_hn_inode_unlock(p->hdir);
}
int au_pin_hdir_lock(struct au_pin *p)
@@ -520,7 +520,7 @@ int au_pin_hdir_lock(struct au_pin *p)
goto out;
/* even if an error happens later, keep this lock */
- au_hn_imtx_lock_nested(p->hdir, p->lsc_hi);
+ au_hn_inode_lock_nested(p->hdir, p->lsc_hi);
err = -EBUSY;
if (unlikely(p->hdir->hi_inode != d_inode(p->h_parent)))
diff --git a/fs/aufs/i_op_ren.c b/fs/aufs/i_op_ren.c
index fdc299221..df697de83 100644
--- a/fs/aufs/i_op_ren.c
+++ b/fs/aufs/i_op_ren.c
@@ -92,9 +92,9 @@ static void au_ren_rev_diropq(int err, struct au_ren_args *a)
{
int rerr;
- au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
+ au_hn_inode_lock_nested(a->src_hinode, AuLsc_I_CHILD);
rerr = au_diropq_remove(a->src_dentry, a->btgt);
- au_hn_imtx_unlock(a->src_hinode);
+ au_hn_inode_unlock(a->src_hinode);
au_set_dbdiropq(a->src_dentry, a->src_bdiropq);
if (rerr)
RevertFailure("remove diropq %pd", a->src_dentry);
@@ -249,9 +249,9 @@ static int au_ren_diropq(struct au_ren_args *a)
err = 0;
a->src_bdiropq = au_dbdiropq(a->src_dentry);
a->src_hinode = au_hi(a->src_inode, a->btgt);
- au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD);
+ au_hn_inode_lock_nested(a->src_hinode, AuLsc_I_CHILD);
diropq = au_diropq_create(a->src_dentry, a->btgt);
- au_hn_imtx_unlock(a->src_hinode);
+ au_hn_inode_unlock(a->src_hinode);
if (IS_ERR(diropq))
err = PTR_ERR(diropq);
else
diff --git a/fs/aufs/iinfo.c b/fs/aufs/iinfo.c
index 3a10d8f13..fae4c2795 100644
--- a/fs/aufs/iinfo.c
+++ b/fs/aufs/iinfo.c
@@ -122,7 +122,7 @@ void au_update_ibrange(struct inode *inode, int do_put_zero)
struct au_iinfo *iinfo;
aufs_bindex_t bindex, bbot;
- AuDebugOn(is_bad_inode(inode));
+ AuDebugOn(au_is_bad_inode(inode));
IiMustWriteLock(inode);
iinfo = au_ii(inode);
@@ -180,6 +180,7 @@ int au_iinfo_init(struct inode *inode)
{
struct au_iinfo *iinfo;
struct super_block *sb;
+ struct au_hinode *hi;
int nbr, i;
sb = inode->i_sb;
@@ -187,12 +188,13 @@ int au_iinfo_init(struct inode *inode)
nbr = au_sbbot(sb) + 1;
if (unlikely(nbr <= 0))
nbr = 1;
- iinfo->ii_hinode = kmalloc_array(nbr, sizeof(*iinfo->ii_hinode),
- GFP_NOFS);
- if (iinfo->ii_hinode) {
+ hi = kmalloc_array(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS);
+ if (hi) {
au_ninodes_inc(sb);
- for (i = 0; i < nbr; i++)
- au_hinode_init(iinfo->ii_hinode + i);
+
+ iinfo->ii_hinode = hi;
+ for (i = 0; i < nbr; i++, hi++)
+ au_hinode_init(hi);
iinfo->ii_generation.ig_generation = au_sigen(sb);
iinfo->ii_btop = -1;
@@ -213,9 +215,11 @@ int au_hinode_realloc(struct au_iinfo *iinfo, int nbr)
err = -ENOMEM;
hip = krealloc(iinfo->ii_hinode, sizeof(*hip) * nbr, GFP_NOFS);
if (hip) {
- for (i = iinfo->ii_bbot + 1; i < nbr; i++)
- au_hinode_init(hip + i);
iinfo->ii_hinode = hip;
+ i = iinfo->ii_bbot + 1;
+ hip += i;
+ for (; i < nbr; i++, hip++)
+ au_hinode_init(hip);
err = 0;
}
@@ -230,7 +234,7 @@ void au_iinfo_fin(struct inode *inode)
aufs_bindex_t bindex, bbot;
const unsigned char unlinked = !inode->i_nlink;
- AuDebugOn(is_bad_inode(inode));
+ AuDebugOn(au_is_bad_inode(inode));
sb = inode->i_sb;
au_ninodes_dec(sb);
diff --git a/fs/aufs/inode.c b/fs/aufs/inode.c
index d599b4c80..a4b994e8c 100644
--- a/fs/aufs/inode.c
+++ b/fs/aufs/inode.c
@@ -34,7 +34,7 @@ static int au_ii_refresh(struct inode *inode, int *update)
struct au_iinfo *iinfo;
struct au_hinode *p, *q, tmp;
- AuDebugOn(is_bad_inode(inode));
+ AuDebugOn(au_is_bad_inode(inode));
IiMustWriteLock(inode);
*update = 0;
diff --git a/fs/aufs/inode.h b/fs/aufs/inode.h
index 0d654e83a..14f788268 100644
--- a/fs/aufs/inode.h
+++ b/fs/aufs/inode.h
@@ -467,6 +467,11 @@ static inline struct au_hinode *au_hinode(struct au_iinfo *iinfo,
return iinfo->ii_hinode + bindex;
}
+static inline int au_is_bad_inode(struct inode *inode)
+{
+ return !!(is_bad_inode(inode) || !au_hinode(au_ii(inode), 0));
+}
+
static inline aufs_bindex_t au_ii_br_id(struct inode *inode,
aufs_bindex_t bindex)
{
@@ -653,20 +658,20 @@ static inline void au_hn_resume(struct au_hinode *hdir)
au_hn_ctl(hdir, /*do_set*/1);
}
-static inline void au_hn_imtx_lock(struct au_hinode *hdir)
+static inline void au_hn_inode_lock(struct au_hinode *hdir)
{
inode_lock(hdir->hi_inode);
au_hn_suspend(hdir);
}
-static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir,
+static inline void au_hn_inode_lock_nested(struct au_hinode *hdir,
unsigned int sc __maybe_unused)
{
inode_lock_nested(hdir->hi_inode, sc);
au_hn_suspend(hdir);
}
-static inline void au_hn_imtx_unlock(struct au_hinode *hdir)
+static inline void au_hn_inode_unlock(struct au_hinode *hdir)
{
au_hn_resume(hdir);
inode_unlock(hdir->hi_inode);
diff --git a/fs/aufs/opts.c b/fs/aufs/opts.c
index 23a146d17..79c7d7156 100644
--- a/fs/aufs/opts.c
+++ b/fs/aufs/opts.c
@@ -1656,13 +1656,13 @@ int au_opts_verify(struct super_block *sb, unsigned long sb_flags,
continue;
hdir = au_hi(dir, bindex);
- au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
if (wbr)
wbr_wh_write_lock(wbr);
err = au_wh_init(br, sb);
if (wbr)
wbr_wh_write_unlock(wbr);
- au_hn_imtx_unlock(hdir);
+ au_hn_inode_unlock(hdir);
if (!err && do_free) {
kfree(wbr);
diff --git a/fs/aufs/super.c b/fs/aufs/super.c
index 18190aa5f..8bd2d9ca4 100644
--- a/fs/aufs/super.c
+++ b/fs/aufs/super.c
@@ -23,6 +23,7 @@ static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused)
if (c) {
au_icntnr_init(c);
c->vfs_inode.i_version = 1; /* sigen(sb); */
+ c->iinfo.ii_hinode = NULL;
return &c->vfs_inode;
}
return NULL;
@@ -38,7 +39,7 @@ static void aufs_destroy_inode_cb(struct rcu_head *head)
static void aufs_destroy_inode(struct inode *inode)
{
- if (!is_bad_inode(inode))
+ if (!au_is_bad_inode(inode))
au_iinfo_fin(inode);
call_rcu(&inode->i_rcu, aufs_destroy_inode_cb);
}
@@ -85,11 +86,12 @@ static int au_show_brs(struct seq_file *seq, struct super_block *sb)
err = 0;
bbot = au_sbbot(sb);
- hdp = au_di(sb->s_root)->di_hdentry;
- for (bindex = 0; !err && bindex <= bbot; bindex++) {
+ bindex = 0;
+ hdp = au_hdentry(au_di(sb->s_root), bindex);
+ for (; !err && bindex <= bbot; bindex++, hdp++) {
br = au_sbr(sb, bindex);
path.mnt = au_br_mnt(br);
- path.dentry = hdp[bindex].hd_dentry;
+ path.dentry = hdp->hd_dentry;
err = au_seq_path(seq, &path);
if (!err) {
au_optstr_br_perm(&perm, br->br_perm);
@@ -164,7 +166,6 @@ static int au_show_xino(struct seq_file *seq, struct super_block *sb)
struct qstr *name;
struct file *f;
struct dentry *d, *h_root;
- struct au_hdentry *hdp;
AuRwMustAnyLock(&sbinfo->si_rwsem);
@@ -178,8 +179,7 @@ static int au_show_xino(struct seq_file *seq, struct super_block *sb)
brid = au_xino_brid(sb);
if (brid >= 0) {
bindex = au_br_index(sb, brid);
- hdp = au_di(sb->s_root)->di_hdentry;
- h_root = hdp[0 + bindex].hd_dentry;
+ h_root = au_hdentry(au_di(sb->s_root), bindex)->hd_dentry;
}
d = f->f_path.dentry;
name = &d->d_name;
@@ -503,7 +503,7 @@ static unsigned long long au_iarray_cb(struct super_block *sb, void *a,
head = arg;
spin_lock(&sb->s_inode_list_lock);
list_for_each_entry(inode, head, i_sb_list) {
- if (!is_bad_inode(inode)
+ if (!au_is_bad_inode(inode)
&& au_ii(inode)->ii_btop >= 0) {
spin_lock(&inode->i_lock);
if (atomic_read(&inode->i_count)) {
diff --git a/fs/aufs/whout.c b/fs/aufs/whout.c
index 78f97ed60..16a96f88f 100644
--- a/fs/aufs/whout.c
+++ b/fs/aufs/whout.c
@@ -553,7 +553,7 @@ static void reinit_br_wh(void *arg)
h_root = au_h_dptr(a->sb->s_root, bindex);
AuDebugOn(h_root != au_br_dentry(a->br));
- au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
wbr_wh_write_lock(wbr);
err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode,
h_root, a->br);
@@ -577,7 +577,7 @@ static void reinit_br_wh(void *arg)
if (!err)
err = au_wh_init(a->br, a->sb);
wbr_wh_write_unlock(wbr);
- au_hn_imtx_unlock(hdir);
+ au_hn_inode_unlock(hdir);
di_read_unlock(a->sb->s_root, AuLock_IR);
if (!err)
au_fhsm_wrote(a->sb, bindex, /*force*/0);
@@ -1005,12 +1005,12 @@ static void call_rmdir_whtmp(void *args)
err = vfsub_mnt_want_write(au_br_mnt(a->br));
if (unlikely(err))
goto out_mnt;
- au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT);
+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT);
err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent,
a->br);
if (!err)
err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist);
- au_hn_imtx_unlock(hdir);
+ au_hn_inode_unlock(hdir);
vfsub_mnt_drop_write(au_br_mnt(a->br));
out_mnt:
diff --git a/fs/aufs/xino.c b/fs/aufs/xino.c
index c0eb51f3c..4d1d5d439 100644
--- a/fs/aufs/xino.c
+++ b/fs/aufs/xino.c
@@ -232,7 +232,7 @@ static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
bindex = au_br_index(sb, brid);
if (bindex >= 0) {
ldir->hdir = au_hi(d_inode(sb->s_root), bindex);
- au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT);
+ au_hn_inode_lock_nested(ldir->hdir, AuLsc_I_PARENT);
} else {
ldir->parent = dget_parent(xino->f_path.dentry);
ldir->dir = d_inode(ldir->parent);
@@ -243,7 +243,7 @@ static void au_xino_lock_dir(struct super_block *sb, struct file *xino,
static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir)
{
if (ldir->hdir)
- au_hn_imtx_unlock(ldir->hdir);
+ au_hn_inode_unlock(ldir->hdir);
else {
inode_unlock(ldir->dir);
dput(ldir->parent);
@@ -585,7 +585,7 @@ void au_xino_delete_inode(struct inode *inode, const int unlinked)
struct au_branch *br;
vfs_writef_t xwrite;
- AuDebugOn(is_bad_inode(inode));
+ AuDebugOn(au_is_bad_inode(inode));
sb = inode->i_sb;
mnt_flags = au_mntflags(sb);
@@ -1113,7 +1113,6 @@ static int au_xino_set_br(struct super_block *sb, struct file *base)
ino = AUFS_ROOT_INO;
writef = au_sbi(sb)->si_xwrite;
for (bindex = 0, p = fpair; bindex <= bbot; bindex++, p++) {
- br = au_sbr(sb, bindex);
bshared = is_sb_shared(sb, bindex, bindex - 1);
if (bshared >= 0) {
/* shared xino */
@@ -1123,6 +1122,7 @@ static int au_xino_set_br(struct super_block *sb, struct file *base)
if (!p->new) {
/* new xino */
+ br = au_sbr(sb, bindex);
p->old = br->br_xino.xi_file;
p->new = au_xino_create2(base, br->br_xino.xi_file);
err = PTR_ERR(p->new);
diff --git a/fs/dcache.c b/fs/dcache.c
index 0dd0237f8..51dd68796 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1620,7 +1620,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
struct dentry *dentry = __d_alloc(parent->d_sb, name);
if (!dentry)
return NULL;
-
+ dentry->d_flags |= DCACHE_RCUACCESS;
spin_lock(&parent->d_lock);
/*
* don't need child lock because it is not subject
@@ -2339,7 +2339,6 @@ static void __d_rehash(struct dentry * entry, struct hlist_bl_head *b)
{
BUG_ON(!d_unhashed(entry));
hlist_bl_lock(b);
- entry->d_flags |= DCACHE_RCUACCESS;
hlist_bl_add_head_rcu(&entry->d_hash, b);
hlist_bl_unlock(b);
}
@@ -2638,6 +2637,7 @@ static void __d_move(struct dentry *dentry, struct dentry *target,
/* ... and switch them in the tree */
if (IS_ROOT(dentry)) {
/* splicing a tree */
+ dentry->d_flags |= DCACHE_RCUACCESS;
dentry->d_parent = target->d_parent;
target->d_parent = target;
list_del_init(&target->d_child);
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
index 866bb18ef..e818f5ac7 100644
--- a/fs/ecryptfs/kthread.c
+++ b/fs/ecryptfs/kthread.c
@@ -25,6 +25,7 @@
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/mount.h>
+#include <linux/file.h>
#include "ecryptfs_kernel.h"
struct ecryptfs_open_req {
@@ -147,7 +148,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
flags |= IS_RDONLY(d_inode(lower_dentry)) ? O_RDONLY : O_RDWR;
(*lower_file) = dentry_open(&req.path, flags, cred);
if (!IS_ERR(*lower_file))
- goto out;
+ goto have_file;
if ((flags & O_ACCMODE) == O_RDONLY) {
rc = PTR_ERR((*lower_file));
goto out;
@@ -165,8 +166,16 @@ int ecryptfs_privileged_open(struct file **lower_file,
mutex_unlock(&ecryptfs_kthread_ctl.mux);
wake_up(&ecryptfs_kthread_ctl.wait);
wait_for_completion(&req.done);
- if (IS_ERR(*lower_file))
+ if (IS_ERR(*lower_file)) {
rc = PTR_ERR(*lower_file);
+ goto out;
+ }
+have_file:
+ if ((*lower_file)->f_op->mmap == NULL) {
+ fput(*lower_file);
+ *lower_file = NULL;
+ rc = -EMEDIUMTYPE;
+ }
out:
return rc;
}
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 361ab4ee4..ec649c92d 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -121,6 +121,13 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
if (IS_ERR(sb))
return ERR_CAST(sb);
+ /*
+ * procfs isn't actually a stacking filesystem; however, there is
+ * too much magic going on inside it to permit stacking things on
+ * top of it
+ */
+ sb->s_stack_depth = FILESYSTEM_MAX_STACK_DEPTH;
+
if (!proc_parse_options(options, ns)) {
deactivate_locked_super(sb);
return ERR_PTR(-EINVAL);