cifs: convert cifsFileInfo->count to non-atomic counter
The count for cifsFileInfo is currently an atomic, but that just adds complexity for little value. We generally need to hold cifs_file_list_lock to traverse the lists anyway so we might as well make this counter non-atomic and simply use the cifs_file_list_lock to protect it. Signed-off-by: Jeff Layton <jlayton@redhat.com> Reviewed-by: Suresh Jayaraman <sjayaraman@suse.de> Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
parent
229aebb873
commit
5f6dbc9e4a
@ -395,16 +395,19 @@ struct cifsFileInfo {
|
|||||||
struct list_head llist; /* list of byte range locks we have. */
|
struct list_head llist; /* list of byte range locks we have. */
|
||||||
bool invalidHandle:1; /* file closed via session abend */
|
bool invalidHandle:1; /* file closed via session abend */
|
||||||
bool oplock_break_cancelled:1;
|
bool oplock_break_cancelled:1;
|
||||||
atomic_t count; /* reference count */
|
int count; /* refcount -- protected by cifs_file_list_lock */
|
||||||
struct mutex fh_mutex; /* prevents reopen race after dead ses*/
|
struct mutex fh_mutex; /* prevents reopen race after dead ses*/
|
||||||
struct cifs_search_info srch_inf;
|
struct cifs_search_info srch_inf;
|
||||||
struct work_struct oplock_break; /* work for oplock breaks */
|
struct work_struct oplock_break; /* work for oplock breaks */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Take a reference on the file private data */
|
/*
|
||||||
|
* Take a reference on the file private data. Must be called with
|
||||||
|
* cifs_file_list_lock held.
|
||||||
|
*/
|
||||||
static inline void cifsFileInfo_get(struct cifsFileInfo *cifs_file)
|
static inline void cifsFileInfo_get(struct cifsFileInfo *cifs_file)
|
||||||
{
|
{
|
||||||
atomic_inc(&cifs_file->count);
|
++cifs_file->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
|
void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
|
||||||
|
@ -232,6 +232,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
|
|||||||
if (pCifsFile == NULL)
|
if (pCifsFile == NULL)
|
||||||
return pCifsFile;
|
return pCifsFile;
|
||||||
|
|
||||||
|
pCifsFile->count = 1;
|
||||||
pCifsFile->netfid = fileHandle;
|
pCifsFile->netfid = fileHandle;
|
||||||
pCifsFile->pid = current->tgid;
|
pCifsFile->pid = current->tgid;
|
||||||
pCifsFile->uid = current_fsuid();
|
pCifsFile->uid = current_fsuid();
|
||||||
@ -242,7 +243,6 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
|
|||||||
mutex_init(&pCifsFile->fh_mutex);
|
mutex_init(&pCifsFile->fh_mutex);
|
||||||
mutex_init(&pCifsFile->lock_mutex);
|
mutex_init(&pCifsFile->lock_mutex);
|
||||||
INIT_LIST_HEAD(&pCifsFile->llist);
|
INIT_LIST_HEAD(&pCifsFile->llist);
|
||||||
atomic_set(&pCifsFile->count, 1);
|
|
||||||
INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break);
|
INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break);
|
||||||
|
|
||||||
spin_lock(&cifs_file_list_lock);
|
spin_lock(&cifs_file_list_lock);
|
||||||
@ -267,7 +267,8 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Release a reference on the file private data. This may involve closing
|
* Release a reference on the file private data. This may involve closing
|
||||||
* the filehandle out on the server.
|
* the filehandle out on the server. Must be called without holding
|
||||||
|
* cifs_file_list_lock.
|
||||||
*/
|
*/
|
||||||
void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
|
void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
|
||||||
{
|
{
|
||||||
@ -276,7 +277,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
|
|||||||
struct cifsLockInfo *li, *tmp;
|
struct cifsLockInfo *li, *tmp;
|
||||||
|
|
||||||
spin_lock(&cifs_file_list_lock);
|
spin_lock(&cifs_file_list_lock);
|
||||||
if (!atomic_dec_and_test(&cifs_file->count)) {
|
if (--cifs_file->count > 0) {
|
||||||
spin_unlock(&cifs_file_list_lock);
|
spin_unlock(&cifs_file_list_lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2322,6 +2323,7 @@ void cifs_oplock_break(struct work_struct *work)
|
|||||||
cifs_oplock_break_put(cfile);
|
cifs_oplock_break_put(cfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* must be called while holding cifs_file_list_lock */
|
||||||
void cifs_oplock_break_get(struct cifsFileInfo *cfile)
|
void cifs_oplock_break_get(struct cifsFileInfo *cfile)
|
||||||
{
|
{
|
||||||
cifs_sb_active(cfile->dentry->d_sb);
|
cifs_sb_active(cfile->dentry->d_sb);
|
||||||
|
Loading…
Reference in New Issue
Block a user