Author: pluto Date: Sun Oct 19 17:11:30 2008 GMT Module: SOURCES Tag: LINUX_2_6 ---- Log message: - updated for 2.6.27.
---- Files affected: SOURCES: kernel-unionfs.patch (1.1.2.2 -> 1.1.2.3) ---- Diffs: ================================================================ Index: SOURCES/kernel-unionfs.patch diff -u SOURCES/kernel-unionfs.patch:1.1.2.2 SOURCES/kernel-unionfs.patch:1.1.2.3 --- SOURCES/kernel-unionfs.patch:1.1.2.2 Thu Sep 11 23:07:55 2008 +++ SOURCES/kernel-unionfs.patch Sun Oct 19 19:11:24 2008 @@ -532,10 +532,10 @@ + +For more information, see <http://unionfs.filesystems.org/>. diff --git a/MAINTAINERS b/MAINTAINERS -index 56a2f67..26a2176 100644 +index 0a613cb..d811b00 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -4093,6 +4093,14 @@ L: [EMAIL PROTECTED] +@@ -4144,6 +4144,14 @@ L: [EMAIL PROTECTED] W: http://www.kernel.dk S: Maintained @@ -551,10 +551,10 @@ P: Oliver Neukum M: [EMAIL PROTECTED] diff --git a/fs/Kconfig b/fs/Kconfig -index 2694648..ee32927 100644 +index abccb5d..3d9310a 100644 --- a/fs/Kconfig +++ b/fs/Kconfig -@@ -1031,6 +1031,47 @@ config CONFIGFS_FS +@@ -981,6 +981,47 @@ config CONFIGFS_FS endmenu @@ -602,7 +602,7 @@ menu "Miscellaneous filesystems" config ADFS_FS -@@ -1083,18 +1124,6 @@ config AFFS_FS +@@ -1033,18 +1074,6 @@ config AFFS_FS To compile this file system support as a module, choose M here: the module will be called affs. If unsure, say N. @@ -622,10 +622,10 @@ tristate "Apple Macintosh file system support (EXPERIMENTAL)" depends on BLOCK && EXPERIMENTAL diff --git a/fs/Makefile b/fs/Makefile -index 1e7a11b..dadf53b 100644 +index a1482a5..9bf3915 100644 --- a/fs/Makefile +++ b/fs/Makefile -@@ -85,6 +85,7 @@ obj-$(CONFIG_ISO9660_FS) += isofs/ +@@ -86,6 +86,7 @@ obj-$(CONFIG_ISO9660_FS) += isofs/ obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+ obj-$(CONFIG_HFS_FS) += hfs/ obj-$(CONFIG_ECRYPT_FS) += ecryptfs/ @@ -647,10 +647,10 @@ out: return rc; diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c -index c92cc1c..71fcaea 100644 +index 89209f0..d99a83e 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c -@@ -570,9 +570,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, +@@ -589,9 +589,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, lower_new_dir_dentry->d_inode, lower_new_dentry); if (rc) goto out_lock; @@ -662,7 +662,7 @@ out_lock: unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); dput(lower_new_dentry->d_parent); -@@ -907,7 +907,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) +@@ -913,7 +913,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) rc = notify_change(lower_dentry, ia); mutex_unlock(&lower_dentry->d_inode->i_mutex); out: @@ -672,10 +672,10 @@ } diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c -index d603631..59daba3 100644 +index 448dfd5..db2db5d 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c -@@ -211,7 +211,7 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, +@@ -197,7 +197,7 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, d_add(dentry, inode); else d_instantiate(dentry, inode); @@ -685,10 +685,10 @@ * other metadata */ fsstack_copy_inode_size(inode, lower_inode); diff --git a/fs/namei.c b/fs/namei.c -index 01e67dd..b51fde0 100644 +index 4ea63ed..3c8e0d6 100644 --- a/fs/namei.c +++ b/fs/namei.c -@@ -404,6 +404,7 @@ void release_open_intent(struct nameidata *nd) +@@ -392,6 +392,7 @@ void release_open_intent(struct nameidata *nd) else fput(nd->intent.open.file); } @@ -697,10 +697,10 @@ static inline struct dentry * do_revalidate(struct dentry *dentry, struct nameidata *nd) diff --git a/fs/splice.c b/fs/splice.c -index aa5f6f6..4282fdf 100644 +index 1bbc6f4..7de91ce 100644 --- a/fs/splice.c +++ b/fs/splice.c -@@ -878,8 +878,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); +@@ -887,8 +887,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); /* * Attempt to initiate a splice from pipe to file. */ @@ -711,7 +711,7 @@ { int ret; -@@ -895,13 +895,14 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +@@ -904,13 +904,14 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, return out->f_op->splice_write(pipe, out, ppos, len, flags); } @@ -729,7 +729,7 @@ { int ret; -@@ -917,6 +918,7 @@ static long do_splice_to(struct file *in, loff_t *ppos, +@@ -926,6 +927,7 @@ static long do_splice_to(struct file *in, loff_t *ppos, return in->f_op->splice_read(in, ppos, pipe, len, flags); } @@ -737,7 +737,7 @@ /** * splice_direct_to_actor - splices data directly between two non-pipes -@@ -986,7 +988,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, +@@ -995,7 +997,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, size_t read_len; loff_t pos = sd->pos, prev_pos = pos; @@ -746,7 +746,7 @@ if (unlikely(ret <= 0)) goto out_release; -@@ -1045,7 +1047,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, +@@ -1054,7 +1056,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, { struct file *file = sd->u.file; @@ -755,7 +755,7 @@ } /** -@@ -1119,7 +1121,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, +@@ -1128,7 +1130,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, } else off = &out->f_pos; @@ -764,7 +764,7 @@ if (off_out && copy_to_user(off_out, off, sizeof(loff_t))) ret = -EFAULT; -@@ -1140,7 +1142,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, +@@ -1149,7 +1151,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, } else off = &in->f_pos; @@ -885,11 +885,11 @@ EXPORT_SYMBOL_GPL(fsstack_copy_attr_all); diff --git a/fs/unionfs/Makefile b/fs/unionfs/Makefile new file mode 100644 -index 0000000..6614204 +index 0000000..fc98b38 --- /dev/null +++ b/fs/unionfs/Makefile @@ -0,0 +1,17 @@ -+UNIONFS_VERSION="2.4 (for 2.6.26)" ++UNIONFS_VERSION="2.5 (for 2.6.27-rc6)" + +EXTRA_CFLAGS += -DUNIONFS_VERSION=\"$(UNIONFS_VERSION)\" + @@ -908,10 +908,10 @@ +endif diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c new file mode 100644 -index 0000000..5861970 +index 0000000..ed3604e --- /dev/null +++ b/fs/unionfs/commonfops.c -@@ -0,0 +1,905 @@ +@@ -0,0 +1,879 @@ +/* + * Copyright (c) 2003-2008 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright @@ -938,7 +938,7 @@ + * stolen from NFS's silly rename + */ +static int copyup_deleted_file(struct file *file, struct dentry *dentry, -+ int bstart, int bindex) ++ struct dentry *parent, int bstart, int bindex) +{ + static unsigned int counter; + const int i_inosize = sizeof(dentry->d_inode->i_ino) * 2; @@ -985,8 +985,7 @@ + } while (tmp_dentry->d_inode != NULL); /* need negative dentry */ + dput(tmp_dentry); + -+ err = copyup_named_file(dentry->d_parent->d_inode, file, name, bstart, -+ bindex, ++ err = copyup_named_file(parent->d_inode, file, name, bstart, bindex, + i_size_read(file->f_path.dentry->d_inode)); + if (err) { + if (unlikely(err == -EEXIST)) @@ -1095,6 +1094,7 @@ + unionfs_lower_mnt_idx(dentry, bindex), + file->f_flags); + if (IS_ERR(lower_file)) { ++ branchput(sb, bindex); + err = PTR_ERR(lower_file); + goto out; + } else { @@ -1112,7 +1112,8 @@ + struct file *lower_file; + struct dentry *lower_dentry; + struct dentry *dentry = file->f_path.dentry; -+ struct inode *parent_inode = dentry->d_parent->d_inode; ++ struct dentry *parent = dget_parent(dentry); ++ struct inode *parent_inode = parent->d_inode; + struct super_block *sb = dentry->d_sb; + + bstart = dbstart(dentry); @@ -1148,15 +1149,16 @@ + + memcpy(&lower_file->f_ra, &file->f_ra, sizeof(struct file_ra_state)); +out: ++ dput(parent); + return err; +} + +/* perform a delayed copyup of a read-write file on a read-only branch */ -+static int do_delayed_copyup(struct file *file) ++static int do_delayed_copyup(struct file *file, struct dentry *parent) +{ + int bindex, bstart, bend, err = 0; + struct dentry *dentry = file->f_path.dentry; -+ struct inode *parent_inode = dentry->d_parent->d_inode; ++ struct inode *parent_inode = parent->d_inode; + + bstart = fbstart(file); + bend = fbend(file); @@ -1170,8 +1172,8 @@ + bindex, + i_size_read(dentry->d_inode)); + else -+ err = copyup_deleted_file(file, dentry, bstart, -+ bindex); ++ err = copyup_deleted_file(file, dentry, parent, ++ bstart, bindex); + /* if succeeded, set lower open-file flags and break */ + if (!err) { + struct file *lower_file; @@ -1207,6 +1209,7 @@ + * Expects dentry/parent to be locked already, and revalidated. + */ +static int __unionfs_file_revalidate(struct file *file, struct dentry *dentry, ++ struct dentry *parent, + struct super_block *sb, int sbgen, + int dgen, bool willwrite) +{ @@ -1288,7 +1291,7 @@ + is_robranch(dentry)) { + pr_debug("unionfs: do delay copyup of \"%s\"\n", + dentry->d_name.name); -+ err = do_delayed_copyup(file); ++ err = do_delayed_copyup(file, parent); + /* regular files have only one open lower file */ + if (!err && !S_ISDIR(dentry->d_inode->i_mode)) + fbend(file) = fbstart(file); @@ -1298,8 +1301,6 @@ + if (err) { + kfree(UNIONFS_F(file)->lower_files); + kfree(UNIONFS_F(file)->saved_branch_ids); -+ } else { -+ unionfs_check_file(file); + } + return err; +} @@ -1307,10 +1308,12 @@ +/* + * Revalidate the struct file + * @file: file to revalidate ++ * @parent: parent dentry (locked by caller) + * @willwrite: true if caller may cause changes to the file; false otherwise. + * Caller must lock/unlock dentry's branch configuration. + */ -+int unionfs_file_revalidate(struct file *file, bool willwrite) ++int unionfs_file_revalidate(struct file *file, struct dentry *parent, ++ bool willwrite) +{ + struct super_block *sb; + struct dentry *dentry; @@ -1320,14 +1323,14 @@ + dentry = file->f_path.dentry; + sb = dentry->d_sb; + verify_locked(dentry); ++ verify_locked(parent); + + /* + * First revalidate the dentry inside struct file, + * but not unhashed dentries. + */ -+reval_dentry: + if (!d_deleted(dentry) && -+ !__unionfs_d_revalidate_chain(dentry, NULL, willwrite)) { ++ !__unionfs_d_revalidate(dentry, parent, willwrite)) { + err = -ESTALE; + goto out; + } @@ -1335,59 +1338,14 @@ + sbgen = atomic_read(&UNIONFS_SB(sb)->generation); + dgen = atomic_read(&UNIONFS_D(dentry)->generation); + -+ if (unlikely(sbgen > dgen)) { -+ pr_debug("unionfs: retry dentry %s revalidation\n", ++ if (unlikely(sbgen > dgen)) { /* XXX: should never happen */ ++ pr_debug("unionfs: failed to revalidate dentry (%s)\n", + dentry->d_name.name); -+ schedule(); -+ goto reval_dentry; -+ } -+ BUG_ON(sbgen > dgen); -+ -+ err = __unionfs_file_revalidate(file, dentry, sb, -+ sbgen, dgen, willwrite); -+out: -+ return err; -+} -+ -+/* same as unionfs_file_revalidate, but parent dentry must be locked too */ -+int unionfs_file_revalidate_locked(struct file *file, bool willwrite) -+{ -+ struct super_block *sb; -+ struct dentry *dentry; -+ int sbgen, dgen; -+ int err = 0, valid; -+ -+ dentry = file->f_path.dentry; -+ sb = dentry->d_sb; -+ verify_locked(dentry); -+ verify_locked(dentry->d_parent); -+ -+ /* first revalidate (locked) parent, then child */ -+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, NULL, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; /* same as what real_lookup does */ -+ goto out; -+ } -+ -+reval_dentry: -+ if (!d_deleted(dentry) && -+ !__unionfs_d_revalidate_one_locked(dentry, NULL, willwrite)) { + err = -ESTALE; + goto out; + } + -+ sbgen = atomic_read(&UNIONFS_SB(sb)->generation); -+ dgen = atomic_read(&UNIONFS_D(dentry)->generation); -+ -+ if (unlikely(sbgen > dgen)) { -+ pr_debug("unionfs: retry (locked) dentry %s revalidation\n", -+ dentry->d_name.name); -+ schedule(); -+ goto reval_dentry; -+ } -+ BUG_ON(sbgen > dgen); -+ -+ err = __unionfs_file_revalidate(file, dentry, sb, ++ err = __unionfs_file_revalidate(file, dentry, parent, sb, + sbgen, dgen, willwrite); +out: + return err; @@ -1430,7 +1388,8 @@ +} + +/* unionfs_open helper function: open a file */ -+static int __open_file(struct inode *inode, struct file *file) ++static int __open_file(struct inode *inode, struct file *file, ++ struct dentry *parent) +{ + struct dentry *lower_dentry; + struct file *lower_file; @@ -1458,9 +1417,8 @@ + + /* copyup the file */ + for (bindex = bstart - 1; bindex >= 0; bindex--) { -+ err = copyup_file( -+ file->f_path.dentry->d_parent->d_inode, -+ file, bstart, bindex, size); ++ err = copyup_file(parent->d_inode, file, ++ bstart, bindex, size); + if (!err) + break; + } @@ -1499,16 +1457,23 @@ + int err = 0; + struct file *lower_file = NULL; + struct dentry *dentry = file->f_path.dentry; ++ struct dentry *parent; + int bindex = 0, bstart = 0, bend = 0; + int size; + int valid = 0; + + unionfs_read_lock(inode->i_sb, UNIONFS_SMUTEX_PARENT); ++ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); + unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ if (dentry != dentry->d_parent) -+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT); + -+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, NULL, false); ++ /* don't open unhashed/deleted files */ ++ if (d_deleted(dentry)) { ++ err = -ENOENT; ++ goto out_nofree; ++ } ++ ++ /* XXX: should I change 'false' below to the 'willwrite' flag? */ ++ valid = __unionfs_d_revalidate(dentry, parent, false); + if (unlikely(!valid)) { + err = -ESTALE; + goto out_nofree; @@ -1548,7 +1513,7 @@ + if (S_ISDIR(inode->i_mode)) + err = __open_dir(inode, file); /* open a dir */ + else -+ err = __open_file(inode, file); /* open a file */ ++ err = __open_file(inode, file, parent); /* open a file */ + + /* freeing the allocated resources, and fput the opened files */ + if (err) { @@ -1576,9 +1541,8 @@ + unionfs_check_file(file); + unionfs_check_inode(inode); + } -+ if (dentry != dentry->d_parent) -+ unionfs_unlock_dentry(dentry->d_parent); + unionfs_unlock_dentry(dentry); ++ unionfs_unlock_parent(dentry, parent); + unionfs_read_unlock(inode->i_sb); + return err; +} @@ -1595,21 +1559,24 @@ + struct unionfs_inode_info *inodeinfo; + struct super_block *sb = inode->i_sb; + struct dentry *dentry = file->f_path.dentry; ++ struct dentry *parent; + int bindex, bstart, bend; + int fgen, err = 0; + + unionfs_read_lock(sb, UNIONFS_SMUTEX_PARENT); ++ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); + unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); + + /* -+ * Yes, we have to revalidate this file even if it's being released. -+ * This is important for open-but-unlinked files, as well as mmap -+ * support. ++ * We try to revalidate, but the VFS ignores return return values ++ * from file->release, so we must always try to succeed here, ++ * including to do the kfree and dput below. So if revalidation ++ * failed, all we can do is print some message and keep going. + */ -+ err = unionfs_file_revalidate(file, UNIONFS_F(file)->wrote_to_file); -+ if (unlikely(err)) -+ goto out; -+ unionfs_check_file(file); ++ err = unionfs_file_revalidate(file, parent, ++ UNIONFS_F(file)->wrote_to_file); ++ if (!err) ++ unionfs_check_file(file); + fileinfo = UNIONFS_F(file); + BUG_ON(file->f_path.dentry->d_inode != inode); + inodeinfo = UNIONFS_I(inode); @@ -1650,8 +1617,8 @@ + } + kfree(fileinfo); + -+out: + unionfs_unlock_dentry(dentry); ++ unionfs_unlock_parent(dentry, parent); + unionfs_read_unlock(sb); + return err; +} @@ -1687,8 +1654,8 @@ + * We use fd_set and therefore we are limited to the number of the branches + * to FD_SETSIZE, which is currently 1024 - plenty for most people + */ -+static int unionfs_ioctl_queryfile(struct file *file, unsigned int cmd, -+ unsigned long arg) ++static int unionfs_ioctl_queryfile(struct file *file, struct dentry *parent, ++ unsigned int cmd, unsigned long arg) +{ + int err = 0; + fd_set branchlist; @@ -1700,7 +1667,7 @@ + dentry = file->f_path.dentry; + orig_bstart = dbstart(dentry); + orig_bend = dbend(dentry); -+ err = unionfs_partial_lookup(dentry); ++ err = unionfs_partial_lookup(dentry, parent); + if (err) + goto out; + bstart = dbstart(dentry); @@ -1746,11 +1713,13 @@ +{ + long err; + struct dentry *dentry = file->f_path.dentry; ++ struct dentry *parent; + + unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT); ++ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); + unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); + -+ err = unionfs_file_revalidate(file, true); ++ err = unionfs_file_revalidate(file, parent, true); + if (unlikely(err)) + goto out; + @@ -1765,7 +1734,7 @@ + + case UNIONFS_IOCTL_QUERYFILE: + /* Return list of branches containing the given file */ -+ err = unionfs_ioctl_queryfile(file, cmd, arg); ++ err = unionfs_ioctl_queryfile(file, parent, cmd, arg); + break; + + default: @@ -1777,6 +1746,7 @@ +out: + unionfs_check_file(file); + unionfs_unlock_dentry(dentry); ++ unionfs_unlock_parent(dentry, parent); + unionfs_read_unlock(dentry->d_sb); + return err; +} @@ -1786,12 +1756,15 @@ + int err = 0; + struct file *lower_file = NULL; + struct dentry *dentry = file->f_path.dentry; ++ struct dentry *parent; + int bindex, bstart, bend; + + unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT); ++ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); + unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); + -+ err = unionfs_file_revalidate(file, UNIONFS_F(file)->wrote_to_file); ++ err = unionfs_file_revalidate(file, parent, ++ UNIONFS_F(file)->wrote_to_file); + if (unlikely(err)) + goto out; + unionfs_check_file(file); @@ -1814,15 +1787,16 @@ + if (!err) + unionfs_check_file(file); + unionfs_unlock_dentry(dentry); ++ unionfs_unlock_parent(dentry, parent); + unionfs_read_unlock(dentry->d_sb); + return err; +} diff --git a/fs/unionfs/copyup.c b/fs/unionfs/copyup.c new file mode 100644 -index 0000000..bbd49c8 +index 0000000..ae6ea2b --- /dev/null +++ b/fs/unionfs/copyup.c -@@ -0,0 +1,880 @@ +@@ -0,0 +1,879 @@ +/* + * Copyright (c) 2003-2008 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright @@ -2009,7 +1983,6 @@ + args.symlink.parent = new_lower_parent_dentry->d_inode; + args.symlink.dentry = new_lower_dentry; + args.symlink.symbuf = symbuf; -+ args.symlink.mode = old_mode; + + run_sioq(__unionfs_symlink, &args); + err = args.err; @@ -3244,10 +3217,10 @@ +} diff --git a/fs/unionfs/dentry.c b/fs/unionfs/dentry.c new file mode 100644 -index 0000000..7f0c7f7 +index 0000000..583f4a4 --- /dev/null +++ b/fs/unionfs/dentry.c <<Diff was trimmed, longer than 597 lines>> ---- CVS-web: http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/SOURCES/kernel-unionfs.patch?r1=1.1.2.2&r2=1.1.2.3&f=u _______________________________________________ pld-cvs-commit mailing list [email protected] http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit
