~ubuntu-branches/ubuntu/raring/linux-nexus7/raring-proposed

« back to all changes in this revision

Viewing changes to fs/open.c

  • Committer: Package Import Robot
  • Author(s): Tim Gardner, Andy Whitcroft, Erez Zadok, Miklos Szeredi, Neil Brown, Paolo Pisati, Tim Gardner
  • Date: 2013-02-27 11:55:02 UTC
  • Revision ID: package-import@ubuntu.com-20130227115502-979tupqdiwnd6bob
Tags: 3.1.10-10.28
[ Andy Whitcroft ]

* ubuntu: overlayfs -- overlayfs: add statfs support
  - LP: #1076317
* ubuntu: overlayfs -- overlayfs: apply device cgroup and security
  permissions to overlay files
  - LP: #1076317, #915941, #918212
  - CVE-2012-0055
* [packaging] Rename from linaro to nexus7 -- part 2

[ Erez Zadok ]

* ubuntu: overlayfs -- overlayfs: implement show_options
  - LP: #1076317

[ Miklos Szeredi ]

* ubuntu: overlayfs -- vfs: pass struct path to __dentry_open()
  - LP: #1076317
* ubuntu: overlayfs -- vfs: add i_op->open()
  - LP: #1076317
* ubuntu: overlayfs -- vfs: export do_splice_direct() to modules
  - LP: #1076317
* ubuntu: overlayfs -- vfs: introduce clone_private_mount()
  - LP: #1076317
* ubuntu: overlayfs -- overlay filesystem
  - LP: #1076317
* ubuntu: overlayfs -- fs: limit filesystem stacking depth
  - LP: #1076317

[ Neil Brown ]

* ubuntu: overlayfs -- overlay: overlay filesystem documentation
  - LP: #1076317

[ Paolo Pisati ]

* [Config] OVERLAYFS_FS=m
  - LP: #1076317
* SAUCE: compilation fix for missing symbols
  - LP: #1076317

[ Tim Gardner ]

* Rebased against git://phablet.ubuntu.com/CyanogenMod/android_kernel_asus_grouper.git phablet-10.1
* Updated configs to be more device consistent with
  arch/arm/configs/cyanogenmod_grouper_defconfig
  https://wiki.ubuntu.com/Touch/Porting#Kernel
  http://phablet.ubuntu.com/gitweb?p=CyanogenMod/android_kernel_asus_grouper.git;a=shortlog;h=refs/heads/phablet-10.1
* Pull config changes from git://phablet.ubuntu.com/CyanogenMod/android_kernel_asus_grouper.git phablet-10.1
  CONFIG_NAMESPACES=y
  CONFIG_UTS_NS=y
  CONFIG_IPC_NS=y
  CONFIG_USER_NS=y
  CONFIG_PID_NS=y
  CONFIG_NET_NS=y
  CONFIG_DEVTMPFS=y
  CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
  CONFIG_DNOTIFY=y
  CONFIG_FANOTIFY=y
  CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
  ONFIG_ANDROID_PARANOID_NETWORK=n
  ONFIG_DEVPTS_MULTIPLE_INSTANCES=y
  CONFIG_SYSVIPC=y
* [packaging] Rename from linaro to nexus7

Show diffs side-by-side

added added

removed removed

Lines of Context:
647
647
        return error;
648
648
}
649
649
 
650
 
static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
651
 
                                        struct file *f,
652
 
                                        int (*open)(struct inode *, struct file *),
653
 
                                        const struct cred *cred)
 
650
static struct file *__dentry_open(struct path *path, struct file *f,
 
651
                                  int (*open)(struct inode *, struct file *),
 
652
                                  const struct cred *cred)
654
653
{
655
654
        static const struct file_operations empty_fops = {};
656
655
        struct inode *inode;
657
656
        int error;
658
657
 
 
658
        path_get(path);
659
659
        f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK |
660
660
                                FMODE_PREAD | FMODE_PWRITE;
661
661
 
662
662
        if (unlikely(f->f_flags & O_PATH))
663
663
                f->f_mode = FMODE_PATH;
664
664
 
665
 
        inode = dentry->d_inode;
 
665
        inode = path->dentry->d_inode;
666
666
        if (f->f_mode & FMODE_WRITE) {
667
 
                error = __get_file_write_access(inode, mnt);
 
667
                error = __get_file_write_access(inode, path->mnt);
668
668
                if (error)
669
669
                        goto cleanup_file;
670
670
                if (!special_file(inode->i_mode))
672
672
        }
673
673
 
674
674
        f->f_mapping = inode->i_mapping;
675
 
        f->f_path.dentry = dentry;
676
 
        f->f_path.mnt = mnt;
 
675
        f->f_path = *path;
677
676
        f->f_pos = 0;
678
677
        file_sb_list_add(f, inode->i_sb);
679
678
 
726
725
                         * here, so just reset the state.
727
726
                         */
728
727
                        file_reset_write(f);
729
 
                        mnt_drop_write(mnt);
 
728
                        mnt_drop_write(path->mnt);
730
729
                }
731
730
        }
732
731
        file_sb_list_del(f);
734
733
        f->f_path.mnt = NULL;
735
734
cleanup_file:
736
735
        put_filp(f);
737
 
        dput(dentry);
738
 
        mntput(mnt);
 
736
        path_put(path);
739
737
        return ERR_PTR(error);
740
738
}
741
739
 
761
759
struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
762
760
                int (*open)(struct inode *, struct file *))
763
761
{
 
762
        struct path path = { .dentry = dentry, .mnt = nd->path.mnt };
764
763
        const struct cred *cred = current_cred();
765
764
 
766
765
        if (IS_ERR(nd->intent.open.file))
767
766
                goto out;
768
767
        if (IS_ERR(dentry))
769
768
                goto out_err;
770
 
        nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt),
771
 
                                             nd->intent.open.file,
 
769
        nd->intent.open.file = __dentry_open(&path, nd->intent.open.file,
772
770
                                             open, cred);
773
771
out:
774
772
        return nd->intent.open.file;
796
794
        nd->intent.open.file = NULL;
797
795
 
798
796
        /* Has the filesystem initialised the file for us? */
799
 
        if (filp->f_path.dentry == NULL) {
800
 
                path_get(&nd->path);
801
 
                filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp,
802
 
                                     NULL, cred);
803
 
        }
 
797
        if (filp->f_path.dentry == NULL)
 
798
                filp = vfs_open(&nd->path, filp, cred);
 
799
 
804
800
        return filp;
805
801
}
806
802
 
811
807
struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags,
812
808
                         const struct cred *cred)
813
809
{
814
 
        int error;
815
810
        struct file *f;
 
811
        struct file *ret;
 
812
        struct path path = { .dentry = dentry, .mnt = mnt };
816
813
 
817
814
        validate_creds(cred);
818
815
 
819
816
        /* We must always pass in a valid mount pointer. */
820
817
        BUG_ON(!mnt);
821
818
 
822
 
        error = -ENFILE;
 
819
        ret = ERR_PTR(-ENFILE);
823
820
        f = get_empty_filp();
824
 
        if (f == NULL) {
825
 
                dput(dentry);
826
 
                mntput(mnt);
827
 
                return ERR_PTR(error);
 
821
        if (f != NULL) {
 
822
                f->f_flags = flags;
 
823
                ret = vfs_open(&path, f, cred);
828
824
        }
 
825
        path_put(&path);
829
826
 
830
 
        f->f_flags = flags;
831
 
        return __dentry_open(dentry, mnt, f, NULL, cred);
 
827
        return ret;
832
828
}
833
829
EXPORT_SYMBOL(dentry_open);
834
830
 
 
831
/**
 
832
 * vfs_open - open the file at the given path
 
833
 * @path: path to open
 
834
 * @filp: newly allocated file with f_flag initialized
 
835
 * @cred: credentials to use
 
836
 *
 
837
 * Open the file.  If successful, the returned file will have acquired
 
838
 * an additional reference for path.
 
839
 */
 
840
struct file *vfs_open(struct path *path, struct file *filp,
 
841
                      const struct cred *cred)
 
842
{
 
843
        struct inode *inode = path->dentry->d_inode;
 
844
 
 
845
        if (inode->i_op->open)
 
846
                return inode->i_op->open(path->dentry, filp, cred);
 
847
        else
 
848
                return __dentry_open(path, filp, NULL, cred);
 
849
}
 
850
EXPORT_SYMBOL(vfs_open);
 
851
 
835
852
static void __put_unused_fd(struct files_struct *files, unsigned int fd)
836
853
{
837
854
        struct fdtable *fdt = files_fdtable(files);