[PATCH 10/21] Unionfs: Introduce unionfs_mnt{get,put}

From: Josef 'Jeff' Sipek
Date: Mon Apr 09 2007 - 10:55:04 EST


From: Erez Zadok <ezk@xxxxxxxxxxxxx>

Helper inline functions to perform Unionfs's mntget/put ops on lower
branches.

Signed-off-by: Erez Zadok <ezk@xxxxxxxxxxxxx>
[jsipek: cleanup branching in unionfs_mnt{get,put} and compile fixes]
Signed-off-by: Josef 'Jeff' Sipek <jsipek@xxxxxxxxxxxxx>
---
fs/unionfs/commonfops.c | 8 ++++----
fs/unionfs/copyup.c | 6 +++---
fs/unionfs/dentry.c | 2 +-
fs/unionfs/dirhelper.c | 2 +-
fs/unionfs/lookup.c | 25 +++++++++++++------------
fs/unionfs/main.c | 7 ++++---
fs/unionfs/union.h | 35 ++++++++++++++++++++++++++++++++++-
7 files changed, 60 insertions(+), 25 deletions(-)

diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
index 8d0f8d1..c20dd6f 100644
--- a/fs/unionfs/commonfops.c
+++ b/fs/unionfs/commonfops.c
@@ -169,7 +169,7 @@ static int open_all_files(struct file *file)
continue;

dget(hidden_dentry);
- mntget(unionfs_lower_mnt_idx(dentry, bindex));
+ unionfs_mntget(dentry, bindex);
branchget(sb, bindex);

hidden_file = dentry_open(hidden_dentry,
@@ -214,7 +214,7 @@ static int open_highest_file(struct file *file, int willwrite)
}

dget(hidden_dentry);
- mntget(unionfs_lower_mnt_idx(dentry, bstart));
+ unionfs_mntget(dentry, bstart);
branchget(sb, bstart);
hidden_file = dentry_open(hidden_dentry,
unionfs_lower_mnt_idx(dentry, bstart), file->f_flags);
@@ -371,7 +371,7 @@ static int __open_dir(struct inode *inode, struct file *file)
continue;

dget(hidden_dentry);
- mntget(unionfs_lower_mnt_idx(file->f_dentry, bindex));
+ unionfs_mntget(file->f_dentry, bindex);
hidden_file = dentry_open(hidden_dentry,
unionfs_lower_mnt_idx(file->f_dentry, bindex),
file->f_flags);
@@ -431,7 +431,7 @@ static int __open_file(struct inode *inode, struct file *file)
/* dentry_open will decrement mnt refcnt if err.
* otherwise fput() will do an mntput() for us upon file close.
*/
- mntget(unionfs_lower_mnt_idx(file->f_dentry, bstart));
+ unionfs_mntget(file->f_dentry, bstart);
hidden_file = dentry_open(hidden_dentry,
unionfs_lower_mnt_idx(file->f_dentry, bstart),
hidden_flags);
diff --git a/fs/unionfs/copyup.c b/fs/unionfs/copyup.c
index e24d940..4ccef81 100644
--- a/fs/unionfs/copyup.c
+++ b/fs/unionfs/copyup.c
@@ -206,7 +206,7 @@ static int __copyup_reg_data(struct dentry *dentry,
int err = 0;

/* open old file */
- mntget(unionfs_lower_mnt_idx(dentry, old_bindex));
+ unionfs_mntget(dentry, old_bindex);
branchget(sb, old_bindex);
input_file = dentry_open(old_hidden_dentry,
unionfs_lower_mnt_idx(dentry, old_bindex),
@@ -223,7 +223,7 @@ static int __copyup_reg_data(struct dentry *dentry,

/* open new file */
dget(new_hidden_dentry);
- mntget(unionfs_lower_mnt_idx(dentry, new_bindex));
+ unionfs_mntget(dentry, new_bindex);
branchget(sb, new_bindex);
output_file = dentry_open(new_hidden_dentry,
unionfs_lower_mnt_idx(dentry, new_bindex),
@@ -555,7 +555,7 @@ static void __cleanup_dentry(struct dentry * dentry, int bindex,
dput(unionfs_lower_dentry_idx(dentry, i));
unionfs_set_lower_dentry_idx(dentry, i, NULL);

- mntput(unionfs_lower_mnt_idx(dentry, i));
+ unionfs_mntput(dentry, i);
unionfs_set_lower_mnt_idx(dentry, i, NULL);
} else {
if (new_bstart < 0)
diff --git a/fs/unionfs/dentry.c b/fs/unionfs/dentry.c
index cae4897..5ee1451 100644
--- a/fs/unionfs/dentry.c
+++ b/fs/unionfs/dentry.c
@@ -206,7 +206,7 @@ static void unionfs_d_release(struct dentry *dentry)
bend = dbend(dentry);
for (bindex = bstart; bindex <= bend; bindex++) {
dput(unionfs_lower_dentry_idx(dentry, bindex));
- mntput(unionfs_lower_mnt_idx(dentry, bindex));
+ unionfs_mntput(dentry, bindex);

unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
unionfs_set_lower_mnt_idx(dentry, bindex, NULL);
diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
index 0da8a8e..bb5f7bc 100644
--- a/fs/unionfs/dirhelper.c
+++ b/fs/unionfs/dirhelper.c
@@ -225,7 +225,7 @@ int check_empty(struct dentry *dentry, struct unionfs_dir_state **namelist)
continue;

dget(hidden_dentry);
- mntget(unionfs_lower_mnt_idx(dentry, bindex));
+ unionfs_mntget(dentry, bindex);
branchget(sb, bindex);
hidden_file =
dentry_open(hidden_dentry, unionfs_lower_mnt_idx(dentry, bindex),
diff --git a/fs/unionfs/lookup.c b/fs/unionfs/lookup.c
index 967bb5b..0572247 100644
--- a/fs/unionfs/lookup.c
+++ b/fs/unionfs/lookup.c
@@ -79,7 +79,8 @@ struct dentry *unionfs_lookup_backend(struct dentry *dentry, struct nameidata *n
struct dentry *parent_dentry = NULL;
int bindex, bstart, bend, bopaque;
int dentry_count = 0; /* Number of positive dentries. */
- int first_dentry_offset = -1;
+ int first_dentry_offset = -1; /* -1 is uninitialized */
+ struct dentry *first_dentry = NULL;
struct dentry *first_hidden_dentry = NULL;
struct vfsmount *first_hidden_mnt = NULL;
int locked_parent = 0;
@@ -176,7 +177,7 @@ struct dentry *unionfs_lookup_backend(struct dentry *dentry, struct nameidata *n
namelen + UNIONFS_WHLEN);
if (IS_ERR(wh_hidden_dentry)) {
dput(first_hidden_dentry);
- mntput(first_hidden_mnt);
+ unionfs_mntput(first_dentry, first_dentry_offset);
err = PTR_ERR(wh_hidden_dentry);
goto out_free;
}
@@ -194,7 +195,7 @@ struct dentry *unionfs_lookup_backend(struct dentry *dentry, struct nameidata *n
" %d.\n", wh_hidden_dentry->d_inode->i_mode);
dput(wh_hidden_dentry);
dput(first_hidden_dentry);
- mntput(first_hidden_mnt);
+ unionfs_mntput(first_dentry, first_dentry_offset);
goto out_free;
}

@@ -210,7 +211,7 @@ struct dentry *unionfs_lookup_backend(struct dentry *dentry, struct nameidata *n
namelen, nd);
if (IS_ERR(hidden_dentry)) {
dput(first_hidden_dentry);
- mntput(first_hidden_mnt);
+ unionfs_mntput(first_dentry, first_dentry_offset);
err = PTR_ERR(hidden_dentry);
goto out_free;
}
@@ -224,9 +225,8 @@ struct dentry *unionfs_lookup_backend(struct dentry *dentry, struct nameidata *n
/* FIXME: following line needs to be changed
* to allow mountpoint crossing
*/
- first_hidden_mnt = mntget(
- unionfs_lower_mnt_idx(parent_dentry,
- bindex));
+ first_dentry = parent_dentry;
+ first_hidden_mnt = unionfs_mntget(parent_dentry, bindex);
first_dentry_offset = bindex;
} else
dput(hidden_dentry);
@@ -245,7 +245,7 @@ struct dentry *unionfs_lookup_backend(struct dentry *dentry, struct nameidata *n
* mountpoint crossing
*/
unionfs_set_lower_mnt_idx(dentry, bindex,
- mntget(unionfs_lower_mnt_idx(parent_dentry, bindex)));
+ unionfs_mntget(parent_dentry, bindex));
set_dbend(dentry, bindex);

/* update parent directory's atime with the bindex */
@@ -266,7 +266,7 @@ struct dentry *unionfs_lookup_backend(struct dentry *dentry, struct nameidata *n
opaque = is_opaque_dir(dentry, bindex);
if (opaque < 0) {
dput(first_hidden_dentry);
- mntput(first_hidden_mnt);
+ unionfs_mntput(first_dentry, first_dentry_offset);
err = opaque;
goto out_free;
} else if (opaque) {
@@ -309,7 +309,8 @@ out_negative:
/* FIXME: the following line needs to be changed to allow
* mountpoint crossing
*/
- first_hidden_mnt = mntget(unionfs_lower_mnt_idx(dentry, bindex));
+ first_dentry = dentry;
+ first_hidden_mnt = unionfs_mntget(dentry, bindex);
}
unionfs_set_lower_dentry_idx(dentry, first_dentry_offset, first_hidden_dentry);
unionfs_set_lower_mnt_idx(dentry, first_dentry_offset, first_hidden_mnt);
@@ -330,7 +331,7 @@ out_positive:
* vfsmount - throw it out.
*/
dput(first_hidden_dentry);
- mntput(first_hidden_mnt);
+ unionfs_mntput(first_dentry, first_dentry_offset);

/* Partial lookups need to reinterpose, or throw away older negs. */
if (lookupmode == INTERPOSE_PARTIAL) {
@@ -365,7 +366,7 @@ out_free:
bend = dbend(dentry);
for (bindex = bstart; bindex <= bend; bindex++) {
dput(unionfs_lower_dentry_idx(dentry, bindex));
- mntput(unionfs_lower_mnt_idx(dentry, bindex));
+ unionfs_mntput(dentry, bindex);
}
}
kfree(UNIONFS_D(dentry)->lower_paths);
diff --git a/fs/unionfs/main.c b/fs/unionfs/main.c
index 1c93b13..b80b554 100644
--- a/fs/unionfs/main.c
+++ b/fs/unionfs/main.c
@@ -358,6 +358,7 @@ out:
for (i = 0; i < branches; i++)
if (hidden_root_info->lower_paths[i].dentry) {
dput(hidden_root_info->lower_paths[i].dentry);
+ /* initializing: can't use unionfs_mntput here */
mntput(hidden_root_info->lower_paths[i].mnt);
}

@@ -466,9 +467,8 @@ out_error:
m = hidden_root_info->lower_paths[bindex].mnt;

dput(d);
-
- if (m)
- mntput(m);
+ /* initializing: can't use unionfs_mntput here */
+ mntput(m);
}
}

@@ -618,6 +618,7 @@ out_dput:
m = hidden_root_info->lower_paths[bindex].mnt;

dput(d);
+ /* initializing: can't use unionfs_mntput here */
mntput(m);
}
kfree(hidden_root_info->lower_paths);
diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
index 715a3ad..53c7c2c 100644
--- a/fs/unionfs/union.h
+++ b/fs/unionfs/union.h
@@ -434,5 +434,38 @@ static inline void unlock_dir(struct dentry *dir)

extern int make_dir_opaque(struct dentry *dir, int bindex);

-#endif /* not _UNION_H_ */
+static inline struct vfsmount *unionfs_mntget(struct dentry *dentry, int bindex)
+{
+ struct vfsmount *mnt;
+ if (!dentry) {
+ if (bindex < 0)
+ return NULL;
+ BUG_ON(bindex < 0);
+ }
+ mnt = unionfs_lower_mnt_idx(dentry, bindex);
+ if (!mnt) {
+ if (bindex < 0)
+ return NULL;
+ BUG_ON(mnt && bindex < 0);
+ }
+ mnt = mntget(mnt);
+ return mnt;
+}

+static inline void unionfs_mntput(struct dentry *dentry, int bindex)
+{
+ struct vfsmount *mnt;
+ if (!dentry) {
+ if (bindex < 0)
+ return;
+ BUG_ON(dentry && bindex < 0);
+ }
+ mnt = unionfs_lower_mnt_idx(dentry, bindex);
+ if (!mnt) {
+ if (bindex < 0)
+ return;
+ BUG_ON(mnt && bindex < 0);
+ }
+ mntput(mnt);
+}
+#endif /* not _UNION_H_ */
--
1.5.0.3.268.g3dda

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/