vsprintf: factor out skip_space code in a separate function
[safe/jmp/linux-2.6] / net / sunrpc / rpc_pipe.c
index 1613d85..49278f8 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/workqueue.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
+#include <linux/sunrpc/cache.h>
 
 static struct vfsmount *rpc_mount __read_mostly;
 static int rpc_mount_count;
@@ -406,19 +407,6 @@ struct rpc_filelist {
        umode_t mode;
 };
 
-enum {
-       RPCAUTH_info,
-       RPCAUTH_EOF
-};
-
-static const struct rpc_filelist authfiles[] = {
-       [RPCAUTH_info] = {
-               .name = "info",
-               .i_fop = &rpc_info_operations,
-               .mode = S_IFREG | S_IRUSR,
-       },
-};
-
 struct vfsmount *rpc_get_mount(void)
 {
        int err;
@@ -428,11 +416,13 @@ struct vfsmount *rpc_get_mount(void)
                return ERR_PTR(err);
        return rpc_mount;
 }
+EXPORT_SYMBOL_GPL(rpc_get_mount);
 
 void rpc_put_mount(void)
 {
        simple_release_fs(&rpc_mount, &rpc_mount_count);
 }
+EXPORT_SYMBOL_GPL(rpc_put_mount);
 
 static int rpc_delete_dentry(struct dentry *dentry)
 {
@@ -698,8 +688,9 @@ out_bad:
        return err;
 }
 
-struct dentry *rpc_mkdir_populate(struct dentry *parent,
-               struct qstr *name, umode_t mode, void *private)
+static struct dentry *rpc_mkdir_populate(struct dentry *parent,
+               struct qstr *name, umode_t mode, void *private,
+               int (*populate)(struct dentry *, void *), void *args_populate)
 {
        struct dentry *dentry;
        struct inode *dir = parent->d_inode;
@@ -712,10 +703,11 @@ struct dentry *rpc_mkdir_populate(struct dentry *parent,
        error = __rpc_mkdir(dir, dentry, mode, NULL, private);
        if (error != 0)
                goto out_err;
-       error = rpc_populate(dentry, authfiles,
-                       RPCAUTH_info, RPCAUTH_EOF, private);
-       if (error)
-               goto err_rmdir;
+       if (populate != NULL) {
+               error = populate(dentry, args_populate);
+               if (error)
+                       goto err_rmdir;
+       }
 out:
        mutex_unlock(&dir->i_mutex);
        return dentry;
@@ -726,11 +718,8 @@ out_err:
        goto out;
 }
 
-/**
- * rpc_remove_client_dir - Remove a directory created with rpc_create_client_dir()
- * @dentry: directory to remove
- */
-int rpc_remove_client_dir(struct dentry *dentry)
+static int rpc_rmdir_depopulate(struct dentry *dentry,
+               void (*depopulate)(struct dentry *))
 {
        struct dentry *parent;
        struct inode *dir;
@@ -739,7 +728,8 @@ int rpc_remove_client_dir(struct dentry *dentry)
        parent = dget_parent(dentry);
        dir = parent->d_inode;
        mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
-       rpc_depopulate(dentry, authfiles, RPCAUTH_info, RPCAUTH_EOF);
+       if (depopulate != NULL)
+               depopulate(dentry);
        error = __rpc_rmdir(dir, dentry);
        mutex_unlock(&dir->i_mutex);
        dput(parent);
@@ -843,9 +833,35 @@ rpc_unlink(struct dentry *dentry)
 }
 EXPORT_SYMBOL_GPL(rpc_unlink);
 
+enum {
+       RPCAUTH_info,
+       RPCAUTH_EOF
+};
+
+static const struct rpc_filelist authfiles[] = {
+       [RPCAUTH_info] = {
+               .name = "info",
+               .i_fop = &rpc_info_operations,
+               .mode = S_IFREG | S_IRUSR,
+       },
+};
+
+static int rpc_clntdir_populate(struct dentry *dentry, void *private)
+{
+       return rpc_populate(dentry,
+                           authfiles, RPCAUTH_info, RPCAUTH_EOF,
+                           private);
+}
+
+static void rpc_clntdir_depopulate(struct dentry *dentry)
+{
+       rpc_depopulate(dentry, authfiles, RPCAUTH_info, RPCAUTH_EOF);
+}
+
 /**
  * rpc_create_client_dir - Create a new rpc_client directory in rpc_pipefs
- * @path: path from the rpc_pipefs root to the new directory
+ * @dentry: dentry from the rpc_pipefs root to the new directory
+ * @name: &struct qstr for the name
  * @rpc_client: rpc client to associate with this directory
  *
  * This creates a directory at the given @path associated with
@@ -854,16 +870,68 @@ EXPORT_SYMBOL_GPL(rpc_unlink);
  * later be created using rpc_mkpipe().
  */
 struct dentry *rpc_create_client_dir(struct dentry *dentry,
-                                    struct qstr *name,
-                                    struct rpc_clnt *rpc_client)
+                                  struct qstr *name,
+                                  struct rpc_clnt *rpc_client)
 {
-       return rpc_mkdir_populate(dentry, name, S_IRUGO | S_IXUGO, rpc_client);
+       return rpc_mkdir_populate(dentry, name, S_IRUGO | S_IXUGO, NULL,
+                       rpc_clntdir_populate, rpc_client);
+}
+
+/**
+ * rpc_remove_client_dir - Remove a directory created with rpc_create_client_dir()
+ * @dentry: directory to remove
+ */
+int rpc_remove_client_dir(struct dentry *dentry)
+{
+       return rpc_rmdir_depopulate(dentry, rpc_clntdir_depopulate);
+}
+
+static const struct rpc_filelist cache_pipefs_files[3] = {
+       [0] = {
+               .name = "channel",
+               .i_fop = &cache_file_operations_pipefs,
+               .mode = S_IFREG|S_IRUSR|S_IWUSR,
+       },
+       [1] = {
+               .name = "content",
+               .i_fop = &content_file_operations_pipefs,
+               .mode = S_IFREG|S_IRUSR,
+       },
+       [2] = {
+               .name = "flush",
+               .i_fop = &cache_flush_operations_pipefs,
+               .mode = S_IFREG|S_IRUSR|S_IWUSR,
+       },
+};
+
+static int rpc_cachedir_populate(struct dentry *dentry, void *private)
+{
+       return rpc_populate(dentry,
+                           cache_pipefs_files, 0, 3,
+                           private);
+}
+
+static void rpc_cachedir_depopulate(struct dentry *dentry)
+{
+       rpc_depopulate(dentry, cache_pipefs_files, 0, 3);
+}
+
+struct dentry *rpc_create_cache_dir(struct dentry *parent, struct qstr *name,
+                                   mode_t umode, struct cache_detail *cd)
+{
+       return rpc_mkdir_populate(parent, name, umode, NULL,
+                       rpc_cachedir_populate, cd);
+}
+
+void rpc_remove_cache_dir(struct dentry *dentry)
+{
+       rpc_rmdir_depopulate(dentry, rpc_cachedir_depopulate);
 }
 
 /*
  * populate the filesystem
  */
-static struct super_operations s_ops = {
+static const struct super_operations s_ops = {
        .alloc_inode    = rpc_alloc_inode,
        .destroy_inode  = rpc_destroy_inode,
        .statfs         = simple_statfs,
@@ -881,6 +949,7 @@ enum {
        RPCAUTH_portmap,
        RPCAUTH_statd,
        RPCAUTH_nfsd4_cb,
+       RPCAUTH_cache,
        RPCAUTH_RootEOF
 };
 
@@ -909,6 +978,10 @@ static const struct rpc_filelist files[] = {
                .name = "nfsd4_cb",
                .mode = S_IFDIR | S_IRUGO | S_IXUGO,
        },
+       [RPCAUTH_cache] = {
+               .name = "cache",
+               .mode = S_IFDIR | S_IRUGO | S_IXUGO,
+       },
 };
 
 static int