reset: Create subdirectory for StarFive drivers
[platform/kernel/linux-starfive.git] / ipc / shm.c
index 7d86f05..bd2fcc4 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -275,10 +275,8 @@ static inline void shm_rmid(struct shmid_kernel *s)
 }
 
 
-static int __shm_open(struct vm_area_struct *vma)
+static int __shm_open(struct shm_file_data *sfd)
 {
-       struct file *file = vma->vm_file;
-       struct shm_file_data *sfd = shm_file_data(file);
        struct shmid_kernel *shp;
 
        shp = shm_lock(sfd->ns, sfd->id);
@@ -302,7 +300,15 @@ static int __shm_open(struct vm_area_struct *vma)
 /* This is called by fork, once for every shm attach. */
 static void shm_open(struct vm_area_struct *vma)
 {
-       int err = __shm_open(vma);
+       struct file *file = vma->vm_file;
+       struct shm_file_data *sfd = shm_file_data(file);
+       int err;
+
+       /* Always call underlying open if present */
+       if (sfd->vm_ops->open)
+               sfd->vm_ops->open(vma);
+
+       err = __shm_open(sfd);
        /*
         * We raced in the idr lookup or with shm_destroy().
         * Either way, the ID is busted.
@@ -359,10 +365,8 @@ static bool shm_may_destroy(struct shmid_kernel *shp)
  * The descriptor has already been removed from the current->mm->mmap list
  * and will later be kfree()d.
  */
-static void shm_close(struct vm_area_struct *vma)
+static void __shm_close(struct shm_file_data *sfd)
 {
-       struct file *file = vma->vm_file;
-       struct shm_file_data *sfd = shm_file_data(file);
        struct shmid_kernel *shp;
        struct ipc_namespace *ns = sfd->ns;
 
@@ -388,6 +392,18 @@ done:
        up_write(&shm_ids(ns).rwsem);
 }
 
+static void shm_close(struct vm_area_struct *vma)
+{
+       struct file *file = vma->vm_file;
+       struct shm_file_data *sfd = shm_file_data(file);
+
+       /* Always call underlying close if present */
+       if (sfd->vm_ops->close)
+               sfd->vm_ops->close(vma);
+
+       __shm_close(sfd);
+}
+
 /* Called with ns->shm_ids(ns).rwsem locked */
 static int shm_try_destroy_orphaned(int id, void *p, void *data)
 {
@@ -583,13 +599,13 @@ static int shm_mmap(struct file *file, struct vm_area_struct *vma)
         * IPC ID that was removed, and possibly even reused by another shm
         * segment already.  Propagate this case as an error to caller.
         */
-       ret = __shm_open(vma);
+       ret = __shm_open(sfd);
        if (ret)
                return ret;
 
        ret = call_mmap(sfd->file, vma);
        if (ret) {
-               shm_close(vma);
+               __shm_close(sfd);
                return ret;
        }
        sfd->vm_ops = vma->vm_ops;