From b907a8622e39eecfc4b243f3be3ad26559d1faee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Fabian=20Silva=20Delgado?= Date: Mon, 27 Jun 2016 21:01:09 -0300 Subject: Linux-libre 4.6.3-gnu --- fs/aufs/branch.c | 17 ++++++++--------- fs/aufs/cpup.c | 24 ++++++++++++++---------- fs/aufs/debug.c | 8 +++----- fs/aufs/dentry.c | 36 ++++++++++++++++++++---------------- fs/aufs/dentry.h | 6 ++++++ fs/aufs/dinfo.c | 32 ++++++++++++++++++-------------- fs/aufs/dir.c | 4 ++-- fs/aufs/export.c | 2 +- fs/aufs/f_op.c | 22 +++++++++++----------- fs/aufs/file.c | 8 ++++---- fs/aufs/hfsnotify.c | 4 ++-- fs/aufs/i_op.c | 6 +++--- fs/aufs/i_op_ren.c | 8 ++++---- fs/aufs/iinfo.c | 22 +++++++++++++--------- fs/aufs/inode.c | 2 +- fs/aufs/inode.h | 11 ++++++++--- fs/aufs/opts.c | 4 ++-- fs/aufs/super.c | 16 ++++++++-------- fs/aufs/whout.c | 8 ++++---- fs/aufs/xino.c | 8 ++++---- fs/dcache.c | 4 ++-- fs/ecryptfs/kthread.c | 13 +++++++++++-- fs/proc/root.c | 7 +++++++ 23 files changed, 156 insertions(+), 116 deletions(-) (limited to 'fs') 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 #include #include +#include #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); -- cgit v1.2.3