2 * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <linux/module.h>
17 #include <linux/backing-dev.h>
19 #include <linux/fsnotify.h>
20 #include <linux/mempool.h>
24 static int pohmelfs_send_lock_trans(struct pohmelfs_inode
*pi
,
25 u64 id
, u64 start
, u32 size
, int type
)
27 struct inode
*inode
= &pi
->vfs_inode
;
28 struct pohmelfs_sb
*psb
= POHMELFS_SB(inode
->i_sb
);
29 struct netfs_trans
*t
;
30 struct netfs_cmd
*cmd
;
34 int isize
= (type
& POHMELFS_LOCK_GRAB
) ? 0 : sizeof(struct netfs_inode_info
);
36 err
= pohmelfs_path_length(pi
);
43 t
= netfs_trans_alloc(psb
, path_len
+ sizeof(struct netfs_lock
) + isize
,
44 NETFS_TRANS_SINGLE_DST
, 0);
48 cmd
= netfs_trans_current(t
);
51 err
= pohmelfs_construct_path_string(pi
, data
, path_len
);
63 cmd
->cmd
= NETFS_LOCK
;
66 cmd
->size
= sizeof(struct netfs_lock
) + path_len
+ isize
;
70 netfs_convert_cmd(cmd
);
71 netfs_convert_lock(l
);
74 struct netfs_inode_info
*info
= (struct netfs_inode_info
*)(l
+ 1);
76 info
->mode
= inode
->i_mode
;
77 info
->nlink
= inode
->i_nlink
;
78 info
->uid
= inode
->i_uid
;
79 info
->gid
= inode
->i_gid
;
80 info
->blocks
= inode
->i_blocks
;
81 info
->rdev
= inode
->i_rdev
;
82 info
->size
= inode
->i_size
;
83 info
->version
= inode
->i_version
;
85 netfs_convert_inode_info(info
);
88 netfs_trans_update(cmd
, t
, path_len
+ sizeof(struct netfs_lock
) + isize
);
90 return netfs_trans_finish(t
, psb
);
95 printk("%s: err: %d.\n", __func__
, err
);
99 int pohmelfs_data_lock(struct pohmelfs_inode
*pi
, u64 start
, u32 size
, int type
)
101 struct pohmelfs_sb
*psb
= POHMELFS_SB(pi
->vfs_inode
.i_sb
);
102 struct pohmelfs_mcache
*m
;
105 struct inode
*inode
= &pi
->vfs_inode
;
107 dprintk("%s: %p: ino: %llu, start: %llu, size: %u, "
108 "type: %d, locked as: %d, owned: %d.\n",
109 __func__
, &pi
->vfs_inode
, pi
->ino
,
110 start
, size
, type
, pi
->lock_type
,
111 !!test_bit(NETFS_INODE_OWNED
, &pi
->state
));
113 if (!pohmelfs_need_lock(pi
, type
))
116 m
= pohmelfs_mcache_alloc(psb
, start
, size
, NULL
);
120 err
= pohmelfs_send_lock_trans(pi
, m
->gen
, start
, size
,
121 type
| POHMELFS_LOCK_GRAB
);
125 err
= wait_for_completion_timeout(&m
->complete
, psb
->mcache_timeout
);
132 printk("%s: %p: ino: %llu, mgen: %llu, start: %llu, size: %u, err: %d.\n",
133 __func__
, &pi
->vfs_inode
, pi
->ino
, m
->gen
, start
, size
, err
);
136 if (err
&& (err
!= -ENOENT
))
140 netfs_convert_inode_info(&m
->info
);
142 iattr
.ia_valid
= ATTR_MODE
| ATTR_UID
| ATTR_GID
| ATTR_SIZE
| ATTR_ATIME
;
143 iattr
.ia_mode
= m
->info
.mode
;
144 iattr
.ia_uid
= m
->info
.uid
;
145 iattr
.ia_gid
= m
->info
.gid
;
146 iattr
.ia_size
= m
->info
.size
;
147 iattr
.ia_atime
= CURRENT_TIME
;
149 dprintk("%s: %p: ino: %llu, mgen: %llu, start: %llu, isize: %llu -> %llu.\n",
150 __func__
, &pi
->vfs_inode
, pi
->ino
, m
->gen
, start
, inode
->i_size
, m
->info
.size
);
152 err
= pohmelfs_setattr_raw(inode
, &iattr
);
154 struct dentry
*dentry
= d_find_alias(inode
);
156 fsnotify_change(dentry
, iattr
.ia_valid
);
162 pi
->lock_type
= type
;
163 set_bit(NETFS_INODE_OWNED
, &pi
->state
);
165 pohmelfs_mcache_put(psb
, m
);
170 pohmelfs_mcache_put(psb
, m
);
174 int pohmelfs_data_unlock(struct pohmelfs_inode
*pi
, u64 start
, u32 size
, int type
)
176 dprintk("%s: %p: ino: %llu, start: %llu, size: %u, type: %d.\n",
177 __func__
, &pi
->vfs_inode
, pi
->ino
, start
, size
, type
);
179 clear_bit(NETFS_INODE_REMOTE_DIR_SYNCED
, &pi
->state
);
180 clear_bit(NETFS_INODE_OWNED
, &pi
->state
);
181 return pohmelfs_send_lock_trans(pi
, pi
->ino
, start
, size
, type
);