[EMAIL PROTECTED] wrote:
> Hello Michael,
> 
> Michael Haas:
>> a bug has been reported in Ubuntu. The user is using mythbuntu-diskless,
>> which means that the lower branch is a read-only squashfs and the upper
>> branch is a writeable NFS share. With the recent aufs changes in Ubuntu
>> intrepid, the user is seeing this problem:
>> http://launchpadlibrarian.net/18342118/DSC00183.JPG
> 
> It shows the call stack only, and looks like,,,
> 
> nfs_setattr [nfs]
> unlock_page
> __do_fault
> kmap_atomic_prot
> fnotify_change
> call_notify_change [aufs]
> vfsub_fnotify_change [aufs]
> vfsub_notify_change [aufs]
> aufs_do_setattr [aufs]
> aufs_fsetattr [aufs]
>       :::
> 
> Very strange.
> I don't know the functions aufs_fsetattr(), aufs_do_setattr() and
> vfsub_fnotify_change(). At least, there is no such function in current
> and near past aufs source files. Additionally I am unsure they have ever
> been.
> Is it I that wrote them?

No, I did. They're used with AppArmor, which removed ia_file and
ATTR_FILE from struct iattr and replaced it with a fsetattr fop. See
attached.

Let me take a look. This patch was written a few months ago and things
might have changed in an incompatible way.

-Jeff

-- 
Jeff Mahoney
SUSE Labs
From: Jeff Mahoney <[EMAIL PROTECTED]>
Subject: Add fsetattr

 An AppArmor patch removed ia_file and ATTR_FILE from struct iattr and
 replaced it with the fsetattr file_operation.

 This patch fixes aufs to use it.

Signed-off-by: Jeff Mahoney <[EMAIL PROTECTED]>
---
 fs/aufs25/dir.c   |    1 +
 fs/aufs25/f_op.c  |    1 +
 fs/aufs25/i_op.c  |   25 ++++++++++++++-----------
 fs/aufs25/inode.h |    1 +
 fs/aufs25/misc.c  |    5 ++---
 fs/aufs25/vfsub.c |   13 ++++++++++---
 fs/aufs25/vfsub.h |    2 ++
 7 files changed, 31 insertions(+), 17 deletions(-)

--- a/fs/aufs25/dir.c
+++ b/fs/aufs25/dir.c
@@ -546,4 +546,5 @@ struct file_operations aufs_dir_fop = {
        .release        = aufs_release_dir,
        .flush          = aufs_flush,
        .fsync          = aufs_fsync_dir,
+       .fsetattr       = aufs_fsetattr,
 };
--- a/fs/aufs25/f_op.c
+++ b/fs/aufs25/f_op.c
@@ -665,4 +665,5 @@ struct file_operations aufs_file_fop = {
        .splice_write   = aufs_splice_write,
        .splice_read    = aufs_splice_read,
 #endif
+       .fsetattr       = aufs_fsetattr,
 };
--- a/fs/aufs25/i_op.c
+++ b/fs/aufs25/i_op.c
@@ -727,13 +727,13 @@ static int au_lock_and_icpup(struct dent
        return err;
 }
 
-static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
+static int aufs_do_setattr(struct dentry *dentry, struct iattr *ia,
+                          struct file *file)
 {
        int err;
        struct inode *inode;
        struct super_block *sb;
        __u32 events;
-       struct file *file;
        loff_t sz;
        struct au_icpup_args *a;
 
@@ -751,12 +751,8 @@ static int aufs_setattr(struct dentry *d
        si_read_lock(sb, AuLock_FLUSH);
        vfsub_args_init(&a->vargs, a->ign, au_test_dlgt(au_mntflags(sb)), 0);
 
-       if (ia->ia_valid & ATTR_FILE) {
-               /* currently ftruncate(2) only */
-               file = ia->ia_file;
+        if (file)
                fi_write_lock(file);
-               ia->ia_file = au_h_fptr(file, au_fbstart(file));
-       }
 
        sz = -1;
        if ((ia->ia_valid & ATTR_SIZE)
@@ -800,11 +796,8 @@ static int aufs_setattr(struct dentry *d
        au_unpin(&a->pin);
        di_write_unlock(dentry);
  out_si:
-       if (file) {
+       if (file)
                fi_write_unlock(file);
-               ia->ia_file = file;
-               ia->ia_valid |= ATTR_FILE;
-       }
        si_read_unlock(sb);
        kfree(a);
  out:
@@ -812,6 +805,16 @@ static int aufs_setattr(struct dentry *d
        return err;
 }
 
+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
+{
+      return aufs_do_setattr(dentry, ia, NULL);
+}
+
+int aufs_fsetattr(struct file *file, struct iattr *ia)
+{
+      return aufs_do_setattr(file->f_dentry, ia, file);
+}
+
 /* ---------------------------------------------------------------------- */
 
 static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
--- a/fs/aufs25/inode.h
+++ b/fs/aufs25/inode.h
@@ -84,6 +84,7 @@ int au_test_h_perm_sio(struct inode *h_i
 
 /* i_op.c */
 extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
+int aufs_fsetattr(struct file *file, struct iattr *ia);
 
 /* au_wr_dir flags */
 #define AuWrDir_ADD_ENTRY      1
--- a/fs/aufs25/misc.c
+++ b/fs/aufs25/misc.c
@@ -267,13 +267,12 @@ int au_copy_file(struct file *dst, struc
                if (err == 1) {
                        ia = (void *)buf;
                        ia->ia_size = dst->f_pos;
-                       ia->ia_valid = ATTR_SIZE | ATTR_FILE;
-                       ia->ia_file = dst;
+                       ia->ia_valid = ATTR_SIZE;
                        vfsub_args_reinit(vargs);
                        vfsub_ign_hinode(vargs, vfsub_events_notify_change(ia),
                                         hdir);
                        mutex_lock_nested(&h_i->i_mutex, AuLsc_I_CHILD2);
-                       err = vfsub_notify_change(h_d, ia, vargs);
+                       err = vfsub_fnotify_change(h_d, ia, vargs, dst);
                        mutex_unlock(&h_i->i_mutex);
                }
        }
--- a/fs/aufs25/vfsub.c
+++ b/fs/aufs25/vfsub.c
@@ -477,6 +477,7 @@ struct notify_change_args {
        struct dentry *h_dentry;
        struct iattr *ia;
        struct vfsub_args *vargs;
+       struct file *file;
 };
 
 static void call_notify_change(void *args)
@@ -493,7 +494,7 @@ static void call_notify_change(void *arg
        if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
                vfsub_ignore(a->vargs);
                lockdep_off();
-               *a->errp = notify_change(a->h_dentry, NULL, a->ia);
+               *a->errp = fnotify_change(a->h_dentry, NULL, a->ia, a->file);
                lockdep_on();
                if (!*a->errp)
                        au_update_fuse_h_inode(NULL, a->h_dentry); /*ignore*/
@@ -525,8 +526,8 @@ static void vfsub_notify_change_dlgt(str
 }
 #endif
 
-int vfsub_notify_change(struct dentry *dentry, struct iattr *ia,
-                       struct vfsub_args *vargs)
+int vfsub_fnotify_change(struct dentry *dentry, struct iattr *ia,
+                       struct vfsub_args *vargs, struct file *file)
 {
        int err;
        struct notify_change_args args = {
@@ -570,6 +571,12 @@ int vfsub_sio_notify_change(struct au_hi
        return err;
 }
 
+int vfsub_notify_change(struct dentry *dentry, struct iattr *ia,
+                       struct vfsub_args *vargs)
+{
+       return vfsub_fnotify_change(dentry, ia, vargs, NULL);
+}
+
 /* ---------------------------------------------------------------------- */
 
 struct unlink_args {
--- a/fs/aufs25/vfsub.h
+++ b/fs/aufs25/vfsub.h
@@ -508,6 +508,8 @@ int vfsub_sio_notify_change(struct au_hi
 
 /* ---------------------------------------------------------------------- */
 
+int vfsub_fnotify_change(struct dentry *dentry, struct iattr *ia,
+                       struct vfsub_args *vargs, struct file *file);
 int vfsub_notify_change(struct dentry *dentry, struct iattr *ia,
                        struct vfsub_args *vargs);
 int vfsub_unlink(struct inode *dir, struct dentry *dentry,

Attachment: signature.asc
Description: OpenPGP digital signature

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/

Reply via email to