+static int shm_release(struct inode *ino, struct file *file)
+{
+ struct shm_file_data *sfd = shm_file_data(file);
+
+ put_ipc_ns(sfd->ns);
+ shm_file_data(file) = NULL;
+ kfree(sfd);
+ return 0;
+}
+
+static int shm_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+ int (*fsync) (struct file *, struct dentry *, int datasync);
+ struct shm_file_data *sfd = shm_file_data(file);
+ int ret = -EINVAL;
+
+ fsync = sfd->file->f_op->fsync;
+ if (fsync)
+ ret = fsync(sfd->file, sfd->file->f_path.dentry, datasync);
+ return ret;
+}
+
+static unsigned long shm_get_unmapped_area(struct file *file,
+ unsigned long addr, unsigned long len, unsigned long pgoff,
+ unsigned long flags)
+{
+ struct shm_file_data *sfd = shm_file_data(file);
+ return get_unmapped_area(sfd->file, addr, len, pgoff, flags);
+}
+
+int is_file_shm_hugepages(struct file *file)
+{
+ int ret = 0;
+
+ if (file->f_op == &shm_file_operations) {
+ struct shm_file_data *sfd;
+ sfd = shm_file_data(file);
+ ret = is_file_hugepages(sfd->file);
+ }
+ return ret;
+}
+
+static const struct file_operations shm_file_operations = {
+ .mmap = shm_mmap,
+ .fsync = shm_fsync,
+ .release = shm_release,
+ .get_unmapped_area = shm_get_unmapped_area,