Skip to content

Commit

Permalink
CIFS: Move byte range lock list from fd to inode
Browse files Browse the repository at this point in the history
that let us do local lock checks before requesting to the server.

Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <smfrench@gmail.com>
  • Loading branch information
Pavel Shilovsky authored and Steve French committed Oct 14, 2011
1 parent fe11e4c commit d59dad2
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 17 deletions.
3 changes: 2 additions & 1 deletion fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,8 @@ cifs_init_once(void *inode)
struct cifsInodeInfo *cifsi = inode;

inode_init_once(&cifsi->vfs_inode);
INIT_LIST_HEAD(&cifsi->lockList);
INIT_LIST_HEAD(&cifsi->llist);
mutex_init(&cifsi->lock_mutex);
}

static int
Expand Down
7 changes: 4 additions & 3 deletions fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ struct cifsLockInfo {
__u64 length;
__u32 pid;
__u8 type;
__u16 netfid;
};

/*
Expand Down Expand Up @@ -526,8 +527,6 @@ struct cifsFileInfo {
struct dentry *dentry;
unsigned int f_flags;
struct tcon_link *tlink;
struct mutex lock_mutex;
struct list_head llist; /* list of byte range locks we have. */
bool invalidHandle:1; /* file closed via session abend */
bool oplock_break_cancelled:1;
int count; /* refcount protected by cifs_file_list_lock */
Expand Down Expand Up @@ -560,7 +559,9 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
*/

struct cifsInodeInfo {
struct list_head lockList;
struct list_head llist; /* brlocks for this inode */
bool can_cache_brlcks;
struct mutex lock_mutex; /* protect two fields above */
/* BB add in lists for dirty pages i.e. write caching info for oplock */
struct list_head openFileList;
__u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
Expand Down
30 changes: 17 additions & 13 deletions fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,6 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
pCifsFile->invalidHandle = false;
pCifsFile->tlink = cifs_get_tlink(tlink);
mutex_init(&pCifsFile->fh_mutex);
mutex_init(&pCifsFile->lock_mutex);
INIT_LIST_HEAD(&pCifsFile->llist);
INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break);

spin_lock(&cifs_file_list_lock);
Expand Down Expand Up @@ -331,12 +329,14 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
/* Delete any outstanding lock records. We'll lose them when the file
* is closed anyway.
*/
mutex_lock(&cifs_file->lock_mutex);
list_for_each_entry_safe(li, tmp, &cifs_file->llist, llist) {
mutex_lock(&cifsi->lock_mutex);
list_for_each_entry_safe(li, tmp, &cifsi->llist, llist) {
if (li->netfid != cifs_file->netfid)
continue;
list_del(&li->llist);
kfree(li);
}
mutex_unlock(&cifs_file->lock_mutex);
mutex_unlock(&cifsi->lock_mutex);

cifs_put_tlink(cifs_file->tlink);
dput(cifs_file->dentry);
Expand Down Expand Up @@ -639,20 +639,21 @@ int cifs_closedir(struct inode *inode, struct file *file)
return rc;
}

static int store_file_lock(struct cifsFileInfo *cfile, __u64 len,
static int store_file_lock(struct cifsInodeInfo *cinode, __u64 len,
__u64 offset, __u8 type, __u16 netfid)
{
struct cifsLockInfo *li =
kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL);
if (li == NULL)
return -ENOMEM;
li->netfid = netfid;
li->offset = offset;
li->length = len;
li->type = type;
li->pid = current->tgid;
mutex_lock(&cfile->lock_mutex);
list_add_tail(&li->llist, &cfile->llist);
mutex_unlock(&cfile->lock_mutex);
mutex_lock(&cinode->lock_mutex);
list_add_tail(&li->llist, &cinode->llist);
mutex_unlock(&cinode->lock_mutex);
return 0;
}

Expand Down Expand Up @@ -769,6 +770,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u8 type,
__u64 length = 1 + flock->fl_end - flock->fl_start;
struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data;
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
struct cifsInodeInfo *cinode = CIFS_I(file->f_path.dentry->d_inode);
__u16 netfid = cfile->netfid;

if (posix_lck) {
Expand All @@ -791,7 +793,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u8 type,
flock->fl_start, 0, lock, type, wait_flag, 0);
if (rc == 0) {
/* For Windows locks we must store them. */
rc = store_file_lock(cfile, length, flock->fl_start,
rc = store_file_lock(cinode, length, flock->fl_start,
type, netfid);
}
} else if (unlock) {
Expand All @@ -802,14 +804,16 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u8 type,
int stored_rc = 0;
struct cifsLockInfo *li, *tmp;

mutex_lock(&cfile->lock_mutex);
list_for_each_entry_safe(li, tmp, &cfile->llist, llist) {
mutex_lock(&cinode->lock_mutex);
list_for_each_entry_safe(li, tmp, &cinode->llist, llist) {
if (flock->fl_start > li->offset ||
(flock->fl_start + length) <
(li->offset + li->length))
continue;
if (current->tgid != li->pid)
continue;
if (cfile->netfid != li->netfid)
continue;

stored_rc = CIFSSMBLock(xid, tcon, netfid,
current->tgid, li->length,
Expand All @@ -822,7 +826,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u8 type,
kfree(li);
}
}
mutex_unlock(&cfile->lock_mutex);
mutex_unlock(&cinode->lock_mutex);
}
out:
if (flock->fl_flags & FL_POSIX)
Expand Down

0 comments on commit d59dad2

Please sign in to comment.