r/o bind mounts: filesystem helpers for custom 'struct file's
[linux-2.6.git] / fs / file_table.c
index ce3f39a..3176fef 100644 (file)
@@ -137,6 +137,66 @@ fail:
 
 EXPORT_SYMBOL(get_empty_filp);
 
+/**
+ * alloc_file - allocate and initialize a 'struct file'
+ * @mnt: the vfsmount on which the file will reside
+ * @dentry: the dentry representing the new file
+ * @mode: the mode with which the new file will be opened
+ * @fop: the 'struct file_operations' for the new file
+ *
+ * Use this instead of get_empty_filp() to get a new
+ * 'struct file'.  Do so because of the same initialization
+ * pitfalls reasons listed for init_file().  This is a
+ * preferred interface to using init_file().
+ *
+ * If all the callers of init_file() are eliminated, its
+ * code should be moved into this function.
+ */
+struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry,
+               mode_t mode, const struct file_operations *fop)
+{
+       struct file *file;
+       struct path;
+
+       file = get_empty_filp();
+       if (!file)
+               return NULL;
+
+       init_file(file, mnt, dentry, mode, fop);
+       return file;
+}
+EXPORT_SYMBOL(alloc_file);
+
+/**
+ * init_file - initialize a 'struct file'
+ * @file: the already allocated 'struct file' to initialized
+ * @mnt: the vfsmount on which the file resides
+ * @dentry: the dentry representing this file
+ * @mode: the mode the file is opened with
+ * @fop: the 'struct file_operations' for this file
+ *
+ * Use this instead of setting the members directly.  Doing so
+ * avoids making mistakes like forgetting the mntget() or
+ * forgetting to take a write on the mnt.
+ *
+ * Note: This is a crappy interface.  It is here to make
+ * merging with the existing users of get_empty_filp()
+ * who have complex failure logic easier.  All users
+ * of this should be moving to alloc_file().
+ */
+int init_file(struct file *file, struct vfsmount *mnt, struct dentry *dentry,
+          mode_t mode, const struct file_operations *fop)
+{
+       int error = 0;
+       file->f_path.dentry = dentry;
+       file->f_path.mnt = mntget(mnt);
+       file->f_mapping = dentry->d_inode->i_mapping;
+       file->f_mode = mode;
+       file->f_op = fop;
+       return error;
+}
+EXPORT_SYMBOL(init_file);
+
 void fastcall fput(struct file *file)
 {
        if (atomic_dec_and_test(&file->f_count))