vfs_gpfs: Avoid calling gpfs_is_offline on every i/o
authorVolker Lendecke <vl@samba.org>
Wed, 2 Sep 2015 11:20:08 +0000 (13:20 +0200)
committerChristof Schmitt <cs@samba.org>
Fri, 4 Sep 2015 23:50:09 +0000 (01:50 +0200)
Asks gpfs as long as a file is offline. Once it was reported online once,
we'll not ask anymore.  This assumes that while we have a file open it
won't be migrated away. This might not *always* be true, but probably
close enough. And as long as we don't have a proper notification mechanism
and as long as polling is too expensive, this seems like a good strategy.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Christof Schmitt <cs@samba.org>
Autobuild-User(master): Christof Schmitt <cs@samba.org>
Autobuild-Date(master): Sat Sep  5 01:50:09 CEST 2015 on sn-devel-104

source3/modules/vfs_gpfs.c

index f40bba76bd0523bb21faefd54802d6665bb32c0a..ee4c1f68129d159c46e008e7caabb391f0ece3cf 100644 (file)
@@ -54,6 +54,10 @@ struct gpfs_config_data {
        bool recalls;
 };
 
+struct gpfs_fsp_extension {
+       bool offline;
+};
+
 static inline unsigned int gpfs_acl_flags(gpfs_acl_t *gacl)
 {
        if (gacl->acl_level == GPFS_ACL_LEVEL_V4FLAGS) {
@@ -1958,7 +1962,26 @@ static bool vfs_gpfs_is_offline(struct vfs_handle_struct *handle,
 static bool vfs_gpfs_fsp_is_offline(struct vfs_handle_struct *handle,
                                    struct files_struct *fsp)
 {
-       return vfs_gpfs_is_offline(handle, fsp->fsp_name, &fsp->fsp_name->st);
+       struct gpfs_fsp_extension *ext;
+
+       ext = VFS_FETCH_FSP_EXTENSION(handle, fsp);
+       if (ext == NULL) {
+               /*
+                * Something bad happened, always ask.
+                */
+               return vfs_gpfs_is_offline(handle, fsp->fsp_name,
+                                          &fsp->fsp_name->st);
+       }
+
+       if (ext->offline) {
+               /*
+                * As long as it's offline, ask.
+                */
+               ext->offline = vfs_gpfs_is_offline(handle, fsp->fsp_name,
+                                                  &fsp->fsp_name->st);
+       }
+
+       return ext->offline;
 }
 
 static bool vfs_gpfs_aio_force(struct vfs_handle_struct *handle,
@@ -2207,6 +2230,8 @@ static int vfs_gpfs_open(struct vfs_handle_struct *handle,
                         int flags, mode_t mode)
 {
        struct gpfs_config_data *config;
+       int ret;
+       struct gpfs_fsp_extension *ext;
 
        SMB_VFS_HANDLE_GET_DATA(handle, config,
                                struct gpfs_config_data,
@@ -2223,7 +2248,24 @@ static int vfs_gpfs_open(struct vfs_handle_struct *handle,
        if (config->syncio) {
                flags |= O_SYNC;
        }
-       return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+
+       ext = VFS_ADD_FSP_EXTENSION(handle, fsp, struct gpfs_fsp_extension,
+                                   NULL);
+       if (ext == NULL) {
+               errno = ENOMEM;
+               return -1;
+       }
+
+       /*
+        * Assume the file is offline until gpfs tells us it's online.
+        */
+       *ext = (struct gpfs_fsp_extension) { .offline = true };
+
+       ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+       if (ret == -1) {
+               VFS_REMOVE_FSP_EXTENSION(handle, fsp);
+       }
+       return ret;
 }
 
 static ssize_t vfs_gpfs_pread(vfs_handle_struct *handle, files_struct *fsp,