diff options
author | Dave Kleikamp <shaggy@linux.vnet.ibm.com> | 2009-08-31 11:07:12 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2009-09-01 18:35:01 -0400 |
commit | 6ab409b53dcaf28f83d518a6702f904b7cee3f41 (patch) | |
tree | 050bfb690ac9df049343034681478a5bb174a823 /fs/cifs/cifsglob.h | |
parent | 1b49c5566136455764a8d17ead25784f534c202d (diff) |
cifs: Replace wrtPending with a real reference count
Currently, cifs_close() tries to wait until all I/O is complete and then
frees the file private data. If I/O does not completely in a reasonable
amount of time it frees the structure anyway, leaving a potential use-
after-free situation.
This patch changes the wrtPending counter to a complete reference count and
lets the last user free the structure.
Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Tested-by: Shirish Pargaonkar <shirishp@us.ibm.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/cifsglob.h')
-rw-r--r-- | fs/cifs/cifsglob.h | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index f100399ee05e..6cfc81a32703 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -351,11 +351,24 @@ struct cifsFileInfo { | |||
351 | bool closePend:1; /* file is marked to close */ | 351 | bool closePend:1; /* file is marked to close */ |
352 | bool invalidHandle:1; /* file closed via session abend */ | 352 | bool invalidHandle:1; /* file closed via session abend */ |
353 | bool messageMode:1; /* for pipes: message vs byte mode */ | 353 | bool messageMode:1; /* for pipes: message vs byte mode */ |
354 | atomic_t wrtPending; /* handle in use - defer close */ | 354 | atomic_t count; /* reference count */ |
355 | struct mutex fh_mutex; /* prevents reopen race after dead ses*/ | 355 | struct mutex fh_mutex; /* prevents reopen race after dead ses*/ |
356 | struct cifs_search_info srch_inf; | 356 | struct cifs_search_info srch_inf; |
357 | }; | 357 | }; |
358 | 358 | ||
359 | /* Take a reference on the file private data */ | ||
360 | static inline void cifsFileInfo_get(struct cifsFileInfo *cifs_file) | ||
361 | { | ||
362 | atomic_inc(&cifs_file->count); | ||
363 | } | ||
364 | |||
365 | /* Release a reference on the file private data */ | ||
366 | static inline void cifsFileInfo_put(struct cifsFileInfo *cifs_file) | ||
367 | { | ||
368 | if (atomic_dec_and_test(&cifs_file->count)) | ||
369 | kfree(cifs_file); | ||
370 | } | ||
371 | |||
359 | /* | 372 | /* |
360 | * One of these for each file inode | 373 | * One of these for each file inode |
361 | */ | 374 | */ |