11f327613SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2e69e7fe5SEric Van Hensbergen /* 3e69e7fe5SEric Van Hensbergen * linux/fs/9p/vfs_file.c 4e69e7fe5SEric Van Hensbergen * 5e69e7fe5SEric Van Hensbergen * This file contians vfs file ops for 9P2000. 6e69e7fe5SEric Van Hensbergen * 7e69e7fe5SEric Van Hensbergen * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 8e69e7fe5SEric Van Hensbergen * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 9e69e7fe5SEric Van Hensbergen */ 10e69e7fe5SEric Van Hensbergen 11e69e7fe5SEric Van Hensbergen #include <linux/module.h> 12e69e7fe5SEric Van Hensbergen #include <linux/errno.h> 13e69e7fe5SEric Van Hensbergen #include <linux/fs.h> 14914e2637SAl Viro #include <linux/sched.h> 15e69e7fe5SEric Van Hensbergen #include <linux/file.h> 16e69e7fe5SEric Van Hensbergen #include <linux/stat.h> 17e69e7fe5SEric Van Hensbergen #include <linux/string.h> 18e69e7fe5SEric Van Hensbergen #include <linux/inet.h> 19e69e7fe5SEric Van Hensbergen #include <linux/list.h> 20637d020aSAbhishek Kulkarni #include <linux/pagemap.h> 21a099027cSM. Mohan Kumar #include <linux/utsname.h> 227c0f6ba6SLinus Torvalds #include <linux/uaccess.h> 23e69e7fe5SEric Van Hensbergen #include <linux/idr.h> 24070b3656SAl Viro #include <linux/uio.h> 25ce85dd58SAl Viro #include <linux/slab.h> 26bd238fb4SLatchesar Ionkov #include <net/9p/9p.h> 27bd238fb4SLatchesar Ionkov #include <net/9p/client.h> 28e69e7fe5SEric Van Hensbergen 29e69e7fe5SEric Van Hensbergen #include "v9fs.h" 30e69e7fe5SEric Van Hensbergen #include "v9fs_vfs.h" 31e69e7fe5SEric Van Hensbergen #include "fid.h" 3260e78d2cSAbhishek Kulkarni #include "cache.h" 33e69e7fe5SEric Van Hensbergen 347263cebeSAneesh Kumar K.V static const struct vm_operations_struct v9fs_file_vm_ops; 35fb89b45cSDominique Martinet static const struct vm_operations_struct v9fs_mmap_file_vm_ops; 367263cebeSAneesh Kumar K.V 37e69e7fe5SEric Van Hensbergen /** 38e69e7fe5SEric Van Hensbergen * v9fs_file_open - open a file (or directory) 39e69e7fe5SEric Van Hensbergen * @inode: inode to be opened 40e69e7fe5SEric Van Hensbergen * @file: file being opened 41e69e7fe5SEric Van Hensbergen * 42e69e7fe5SEric Van Hensbergen */ 43e69e7fe5SEric Van Hensbergen 44e69e7fe5SEric Van Hensbergen int v9fs_file_open(struct inode *inode, struct file *file) 45e69e7fe5SEric Van Hensbergen { 466a3124a3SLatchesar Ionkov int err; 476b39f6d2SAneesh Kumar K.V struct v9fs_inode *v9inode; 48bd238fb4SLatchesar Ionkov struct v9fs_session_info *v9ses; 495bfe97d7SDominique Martinet struct p9_fid *fid, *writeback_fid; 50bd238fb4SLatchesar Ionkov int omode; 51e69e7fe5SEric Van Hensbergen 525d385153SJoe Perches p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file); 536b39f6d2SAneesh Kumar K.V v9inode = V9FS_I(inode); 54bd238fb4SLatchesar Ionkov v9ses = v9fs_inode2v9ses(inode); 55ef56547eSM. Mohan Kumar if (v9fs_proto_dotl(v9ses)) 56f88657ceSAneesh Kumar K.V omode = v9fs_open_to_dotl_flags(file->f_flags); 57ef56547eSM. Mohan Kumar else 58ef56547eSM. Mohan Kumar omode = v9fs_uflags2omode(file->f_flags, 59ef56547eSM. Mohan Kumar v9fs_proto_dotu(v9ses)); 60bd238fb4SLatchesar Ionkov fid = file->private_data; 61bd238fb4SLatchesar Ionkov if (!fid) { 62b403f0e3SMiklos Szeredi fid = v9fs_fid_clone(file_dentry(file)); 63bd238fb4SLatchesar Ionkov if (IS_ERR(fid)) 64bd238fb4SLatchesar Ionkov return PTR_ERR(fid); 65bd238fb4SLatchesar Ionkov 66bd238fb4SLatchesar Ionkov err = p9_client_open(fid, omode); 676a3124a3SLatchesar Ionkov if (err < 0) { 68bd238fb4SLatchesar Ionkov p9_client_clunk(fid); 69bd238fb4SLatchesar Ionkov return err; 70bd238fb4SLatchesar Ionkov } 71ef56547eSM. Mohan Kumar if ((file->f_flags & O_APPEND) && 72ef56547eSM. Mohan Kumar (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses))) 732e4bef41SEric Van Hensbergen generic_file_llseek(file, 0, SEEK_END); 74e69e7fe5SEric Van Hensbergen } 75e69e7fe5SEric Van Hensbergen 76bd238fb4SLatchesar Ionkov file->private_data = fid; 775a7e0a8cSAneesh Kumar K.V mutex_lock(&v9inode->v_mutex); 78fb89b45cSDominique Martinet if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) && 79fb89b45cSDominique Martinet !v9inode->writeback_fid && 807add697aSAneesh Kumar K.V ((file->f_flags & O_ACCMODE) != O_RDONLY)) { 813cf387d7SAneesh Kumar K.V /* 826b39f6d2SAneesh Kumar K.V * clone a fid and add it to writeback_fid 833cf387d7SAneesh Kumar K.V * we do it during open time instead of 843cf387d7SAneesh Kumar K.V * page dirty time via write_begin/page_mkwrite 853cf387d7SAneesh Kumar K.V * because we want write after unlink usecase 863cf387d7SAneesh Kumar K.V * to work. 873cf387d7SAneesh Kumar K.V */ 885bfe97d7SDominique Martinet writeback_fid = v9fs_writeback_fid(file_dentry(file)); 89f8b139e2SYang Yingliang if (IS_ERR(writeback_fid)) { 90f8b139e2SYang Yingliang err = PTR_ERR(writeback_fid); 915a7e0a8cSAneesh Kumar K.V mutex_unlock(&v9inode->v_mutex); 923cf387d7SAneesh Kumar K.V goto out_error; 933cf387d7SAneesh Kumar K.V } 945bfe97d7SDominique Martinet v9inode->writeback_fid = (void *) writeback_fid; 953cf387d7SAneesh Kumar K.V } 965a7e0a8cSAneesh Kumar K.V mutex_unlock(&v9inode->v_mutex); 97fb89b45cSDominique Martinet if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) 9860e78d2cSAbhishek Kulkarni v9fs_cache_inode_set_cookie(inode, file); 99987a6485SGreg Kurz v9fs_open_fid_add(inode, fid); 100e69e7fe5SEric Van Hensbergen return 0; 1013cf387d7SAneesh Kumar K.V out_error: 1023cf387d7SAneesh Kumar K.V p9_client_clunk(file->private_data); 1033cf387d7SAneesh Kumar K.V file->private_data = NULL; 1043cf387d7SAneesh Kumar K.V return err; 105e69e7fe5SEric Van Hensbergen } 106e69e7fe5SEric Van Hensbergen 107e69e7fe5SEric Van Hensbergen /** 108e69e7fe5SEric Van Hensbergen * v9fs_file_lock - lock a file (or directory) 109ee443996SEric Van Hensbergen * @filp: file to be locked 110ee443996SEric Van Hensbergen * @cmd: lock command 111ee443996SEric Van Hensbergen * @fl: file lock structure 112e69e7fe5SEric Van Hensbergen * 113ee443996SEric Van Hensbergen * Bugs: this looks like a local only lock, we should extend into 9P 114e69e7fe5SEric Van Hensbergen * by using open exclusive 115e69e7fe5SEric Van Hensbergen */ 116e69e7fe5SEric Van Hensbergen 117e69e7fe5SEric Van Hensbergen static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) 118e69e7fe5SEric Van Hensbergen { 119e69e7fe5SEric Van Hensbergen int res = 0; 120496ad9aaSAl Viro struct inode *inode = file_inode(filp); 121e69e7fe5SEric Van Hensbergen 1225d385153SJoe Perches p9_debug(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl); 123e69e7fe5SEric Van Hensbergen 124e69e7fe5SEric Van Hensbergen if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { 12528fd1298SOGAWA Hirofumi filemap_write_and_wait(inode->i_mapping); 126fc0ecff6SAndrew Morton invalidate_mapping_pages(&inode->i_data, 0, -1); 127e69e7fe5SEric Van Hensbergen } 128e69e7fe5SEric Van Hensbergen 129e69e7fe5SEric Van Hensbergen return res; 130e69e7fe5SEric Van Hensbergen } 131e69e7fe5SEric Van Hensbergen 132a099027cSM. Mohan Kumar static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl) 133a099027cSM. Mohan Kumar { 134a099027cSM. Mohan Kumar struct p9_flock flock; 135a099027cSM. Mohan Kumar struct p9_fid *fid; 1365c4086b8SDominique Martinet uint8_t status = P9_LOCK_ERROR; 137a099027cSM. Mohan Kumar int res = 0; 138a099027cSM. Mohan Kumar unsigned char fl_type; 1395e172f75SDinu-Razvan Chis-Serban struct v9fs_session_info *v9ses; 140a099027cSM. Mohan Kumar 141a099027cSM. Mohan Kumar fid = filp->private_data; 142a099027cSM. Mohan Kumar BUG_ON(fid == NULL); 143a099027cSM. Mohan Kumar 144a099027cSM. Mohan Kumar if ((fl->fl_flags & FL_POSIX) != FL_POSIX) 145a099027cSM. Mohan Kumar BUG(); 146a099027cSM. Mohan Kumar 1474f656367SBenjamin Coddington res = locks_lock_file_wait(filp, fl); 148a099027cSM. Mohan Kumar if (res < 0) 149a099027cSM. Mohan Kumar goto out; 150a099027cSM. Mohan Kumar 151a099027cSM. Mohan Kumar /* convert posix lock to p9 tlock args */ 152a099027cSM. Mohan Kumar memset(&flock, 0, sizeof(flock)); 15351b8b4fbSJim Garlick /* map the lock type */ 15451b8b4fbSJim Garlick switch (fl->fl_type) { 15551b8b4fbSJim Garlick case F_RDLCK: 15651b8b4fbSJim Garlick flock.type = P9_LOCK_TYPE_RDLCK; 15751b8b4fbSJim Garlick break; 15851b8b4fbSJim Garlick case F_WRLCK: 15951b8b4fbSJim Garlick flock.type = P9_LOCK_TYPE_WRLCK; 16051b8b4fbSJim Garlick break; 16151b8b4fbSJim Garlick case F_UNLCK: 16251b8b4fbSJim Garlick flock.type = P9_LOCK_TYPE_UNLCK; 16351b8b4fbSJim Garlick break; 16451b8b4fbSJim Garlick } 165a099027cSM. Mohan Kumar flock.start = fl->fl_start; 166a099027cSM. Mohan Kumar if (fl->fl_end == OFFSET_MAX) 167a099027cSM. Mohan Kumar flock.length = 0; 168a099027cSM. Mohan Kumar else 169a099027cSM. Mohan Kumar flock.length = fl->fl_end - fl->fl_start + 1; 170a099027cSM. Mohan Kumar flock.proc_id = fl->fl_pid; 17150192abeSWill Deacon flock.client_id = fid->clnt->name; 172a099027cSM. Mohan Kumar if (IS_SETLKW(cmd)) 173a099027cSM. Mohan Kumar flock.flags = P9_LOCK_FLAGS_BLOCK; 174a099027cSM. Mohan Kumar 1755e172f75SDinu-Razvan Chis-Serban v9ses = v9fs_inode2v9ses(file_inode(filp)); 1765e172f75SDinu-Razvan Chis-Serban 177a099027cSM. Mohan Kumar /* 178a099027cSM. Mohan Kumar * if its a blocked request and we get P9_LOCK_BLOCKED as the status 179a099027cSM. Mohan Kumar * for lock request, keep on trying 180a099027cSM. Mohan Kumar */ 181a099027cSM. Mohan Kumar for (;;) { 182a099027cSM. Mohan Kumar res = p9_client_lock_dotl(fid, &flock, &status); 183a099027cSM. Mohan Kumar if (res < 0) 184ad80492dSKirill A. Shutemov goto out_unlock; 185a099027cSM. Mohan Kumar 186a099027cSM. Mohan Kumar if (status != P9_LOCK_BLOCKED) 187a099027cSM. Mohan Kumar break; 188a099027cSM. Mohan Kumar if (status == P9_LOCK_BLOCKED && !IS_SETLKW(cmd)) 189a099027cSM. Mohan Kumar break; 1905e172f75SDinu-Razvan Chis-Serban if (schedule_timeout_interruptible(v9ses->session_lock_timeout) 1915e172f75SDinu-Razvan Chis-Serban != 0) 192a0ea787bSJim Garlick break; 193b4dc44b3SDominique Martinet /* 194b4dc44b3SDominique Martinet * p9_client_lock_dotl overwrites flock.client_id with the 195b4dc44b3SDominique Martinet * server message, free and reuse the client name 196b4dc44b3SDominique Martinet */ 197b4dc44b3SDominique Martinet if (flock.client_id != fid->clnt->name) { 198b4dc44b3SDominique Martinet kfree(flock.client_id); 199b4dc44b3SDominique Martinet flock.client_id = fid->clnt->name; 200b4dc44b3SDominique Martinet } 201a099027cSM. Mohan Kumar } 202a099027cSM. Mohan Kumar 203a099027cSM. Mohan Kumar /* map 9p status to VFS status */ 204a099027cSM. Mohan Kumar switch (status) { 205a099027cSM. Mohan Kumar case P9_LOCK_SUCCESS: 206a099027cSM. Mohan Kumar res = 0; 207a099027cSM. Mohan Kumar break; 208a099027cSM. Mohan Kumar case P9_LOCK_BLOCKED: 209a099027cSM. Mohan Kumar res = -EAGAIN; 210a099027cSM. Mohan Kumar break; 211b642f726SKirill A. Shutemov default: 212b642f726SKirill A. Shutemov WARN_ONCE(1, "unknown lock status code: %d\n", status); 213df561f66SGustavo A. R. Silva fallthrough; 214a099027cSM. Mohan Kumar case P9_LOCK_ERROR: 215a099027cSM. Mohan Kumar case P9_LOCK_GRACE: 216a099027cSM. Mohan Kumar res = -ENOLCK; 217a099027cSM. Mohan Kumar break; 218a099027cSM. Mohan Kumar } 219a099027cSM. Mohan Kumar 220ad80492dSKirill A. Shutemov out_unlock: 221a099027cSM. Mohan Kumar /* 222a099027cSM. Mohan Kumar * incase server returned error for lock request, revert 223a099027cSM. Mohan Kumar * it locally 224a099027cSM. Mohan Kumar */ 225a099027cSM. Mohan Kumar if (res < 0 && fl->fl_type != F_UNLCK) { 226a099027cSM. Mohan Kumar fl_type = fl->fl_type; 227a099027cSM. Mohan Kumar fl->fl_type = F_UNLCK; 228b6478740SDominique Martinet /* Even if this fails we want to return the remote error */ 2292e3078afSLinus Torvalds locks_lock_file_wait(filp, fl); 230a099027cSM. Mohan Kumar fl->fl_type = fl_type; 231a099027cSM. Mohan Kumar } 232b4dc44b3SDominique Martinet if (flock.client_id != fid->clnt->name) 233b4dc44b3SDominique Martinet kfree(flock.client_id); 234a099027cSM. Mohan Kumar out: 235a099027cSM. Mohan Kumar return res; 236a099027cSM. Mohan Kumar } 237a099027cSM. Mohan Kumar 2381d769cd1SM. Mohan Kumar static int v9fs_file_getlock(struct file *filp, struct file_lock *fl) 2391d769cd1SM. Mohan Kumar { 2401d769cd1SM. Mohan Kumar struct p9_getlock glock; 2411d769cd1SM. Mohan Kumar struct p9_fid *fid; 2421d769cd1SM. Mohan Kumar int res = 0; 2431d769cd1SM. Mohan Kumar 2441d769cd1SM. Mohan Kumar fid = filp->private_data; 2451d769cd1SM. Mohan Kumar BUG_ON(fid == NULL); 2461d769cd1SM. Mohan Kumar 2471d769cd1SM. Mohan Kumar posix_test_lock(filp, fl); 2481d769cd1SM. Mohan Kumar /* 2491d769cd1SM. Mohan Kumar * if we have a conflicting lock locally, no need to validate 2501d769cd1SM. Mohan Kumar * with server 2511d769cd1SM. Mohan Kumar */ 2521d769cd1SM. Mohan Kumar if (fl->fl_type != F_UNLCK) 2531d769cd1SM. Mohan Kumar return res; 2541d769cd1SM. Mohan Kumar 2551d769cd1SM. Mohan Kumar /* convert posix lock to p9 tgetlock args */ 2561d769cd1SM. Mohan Kumar memset(&glock, 0, sizeof(glock)); 25751b8b4fbSJim Garlick glock.type = P9_LOCK_TYPE_UNLCK; 2581d769cd1SM. Mohan Kumar glock.start = fl->fl_start; 2591d769cd1SM. Mohan Kumar if (fl->fl_end == OFFSET_MAX) 2601d769cd1SM. Mohan Kumar glock.length = 0; 2611d769cd1SM. Mohan Kumar else 2621d769cd1SM. Mohan Kumar glock.length = fl->fl_end - fl->fl_start + 1; 2631d769cd1SM. Mohan Kumar glock.proc_id = fl->fl_pid; 26450192abeSWill Deacon glock.client_id = fid->clnt->name; 2651d769cd1SM. Mohan Kumar 2661d769cd1SM. Mohan Kumar res = p9_client_getlock_dotl(fid, &glock); 2671d769cd1SM. Mohan Kumar if (res < 0) 268b4dc44b3SDominique Martinet goto out; 26951b8b4fbSJim Garlick /* map 9p lock type to os lock type */ 27051b8b4fbSJim Garlick switch (glock.type) { 27151b8b4fbSJim Garlick case P9_LOCK_TYPE_RDLCK: 27251b8b4fbSJim Garlick fl->fl_type = F_RDLCK; 27351b8b4fbSJim Garlick break; 27451b8b4fbSJim Garlick case P9_LOCK_TYPE_WRLCK: 27551b8b4fbSJim Garlick fl->fl_type = F_WRLCK; 27651b8b4fbSJim Garlick break; 27751b8b4fbSJim Garlick case P9_LOCK_TYPE_UNLCK: 27851b8b4fbSJim Garlick fl->fl_type = F_UNLCK; 27951b8b4fbSJim Garlick break; 28051b8b4fbSJim Garlick } 28151b8b4fbSJim Garlick if (glock.type != P9_LOCK_TYPE_UNLCK) { 2821d769cd1SM. Mohan Kumar fl->fl_start = glock.start; 2831d769cd1SM. Mohan Kumar if (glock.length == 0) 2841d769cd1SM. Mohan Kumar fl->fl_end = OFFSET_MAX; 2851d769cd1SM. Mohan Kumar else 2861d769cd1SM. Mohan Kumar fl->fl_end = glock.start + glock.length - 1; 2879d5b86acSBenjamin Coddington fl->fl_pid = -glock.proc_id; 28851b8b4fbSJim Garlick } 289b4dc44b3SDominique Martinet out: 290b4dc44b3SDominique Martinet if (glock.client_id != fid->clnt->name) 291ce85dd58SAl Viro kfree(glock.client_id); 2921d769cd1SM. Mohan Kumar return res; 2931d769cd1SM. Mohan Kumar } 2941d769cd1SM. Mohan Kumar 295a099027cSM. Mohan Kumar /** 296a099027cSM. Mohan Kumar * v9fs_file_lock_dotl - lock a file (or directory) 297a099027cSM. Mohan Kumar * @filp: file to be locked 298a099027cSM. Mohan Kumar * @cmd: lock command 299a099027cSM. Mohan Kumar * @fl: file lock structure 300a099027cSM. Mohan Kumar * 301a099027cSM. Mohan Kumar */ 302a099027cSM. Mohan Kumar 303a099027cSM. Mohan Kumar static int v9fs_file_lock_dotl(struct file *filp, int cmd, struct file_lock *fl) 304a099027cSM. Mohan Kumar { 305496ad9aaSAl Viro struct inode *inode = file_inode(filp); 306a099027cSM. Mohan Kumar int ret = -ENOLCK; 307a099027cSM. Mohan Kumar 3084b8e9923SAl Viro p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n", 3094b8e9923SAl Viro filp, cmd, fl, filp); 310a099027cSM. Mohan Kumar 311a099027cSM. Mohan Kumar if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { 312a099027cSM. Mohan Kumar filemap_write_and_wait(inode->i_mapping); 313a099027cSM. Mohan Kumar invalidate_mapping_pages(&inode->i_data, 0, -1); 314a099027cSM. Mohan Kumar } 315a099027cSM. Mohan Kumar 316a099027cSM. Mohan Kumar if (IS_SETLK(cmd) || IS_SETLKW(cmd)) 317a099027cSM. Mohan Kumar ret = v9fs_file_do_lock(filp, cmd, fl); 3181d769cd1SM. Mohan Kumar else if (IS_GETLK(cmd)) 3191d769cd1SM. Mohan Kumar ret = v9fs_file_getlock(filp, fl); 320a099027cSM. Mohan Kumar else 321a099027cSM. Mohan Kumar ret = -EINVAL; 322a099027cSM. Mohan Kumar return ret; 323a099027cSM. Mohan Kumar } 324a099027cSM. Mohan Kumar 325a099027cSM. Mohan Kumar /** 326a099027cSM. Mohan Kumar * v9fs_file_flock_dotl - lock a file 327a099027cSM. Mohan Kumar * @filp: file to be locked 328a099027cSM. Mohan Kumar * @cmd: lock command 329a099027cSM. Mohan Kumar * @fl: file lock structure 330a099027cSM. Mohan Kumar * 331a099027cSM. Mohan Kumar */ 332a099027cSM. Mohan Kumar 333a099027cSM. Mohan Kumar static int v9fs_file_flock_dotl(struct file *filp, int cmd, 334a099027cSM. Mohan Kumar struct file_lock *fl) 335a099027cSM. Mohan Kumar { 336496ad9aaSAl Viro struct inode *inode = file_inode(filp); 337a099027cSM. Mohan Kumar int ret = -ENOLCK; 338a099027cSM. Mohan Kumar 3394b8e9923SAl Viro p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n", 3404b8e9923SAl Viro filp, cmd, fl, filp); 341a099027cSM. Mohan Kumar 342a099027cSM. Mohan Kumar if (!(fl->fl_flags & FL_FLOCK)) 343a099027cSM. Mohan Kumar goto out_err; 344a099027cSM. Mohan Kumar 345a099027cSM. Mohan Kumar if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { 346a099027cSM. Mohan Kumar filemap_write_and_wait(inode->i_mapping); 347a099027cSM. Mohan Kumar invalidate_mapping_pages(&inode->i_data, 0, -1); 348a099027cSM. Mohan Kumar } 349a099027cSM. Mohan Kumar /* Convert flock to posix lock */ 350a099027cSM. Mohan Kumar fl->fl_flags |= FL_POSIX; 351a099027cSM. Mohan Kumar fl->fl_flags ^= FL_FLOCK; 352a099027cSM. Mohan Kumar 353a099027cSM. Mohan Kumar if (IS_SETLK(cmd) | IS_SETLKW(cmd)) 354a099027cSM. Mohan Kumar ret = v9fs_file_do_lock(filp, cmd, fl); 355a099027cSM. Mohan Kumar else 356a099027cSM. Mohan Kumar ret = -EINVAL; 357a099027cSM. Mohan Kumar out_err: 358a099027cSM. Mohan Kumar return ret; 359a099027cSM. Mohan Kumar } 360a099027cSM. Mohan Kumar 361e69e7fe5SEric Van Hensbergen /** 362bc868036SDavid Howells * v9fs_file_read_iter - read from a file 363bc868036SDavid Howells * @iocb: The operation parameters 364bc868036SDavid Howells * @to: The buffer to read into 365fbedadc1SEric Van Hensbergen * 366fbedadc1SEric Van Hensbergen */ 367e69e7fe5SEric Van Hensbergen static ssize_t 368e494b6b5SAl Viro v9fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) 369e69e7fe5SEric Van Hensbergen { 370e494b6b5SAl Viro struct p9_fid *fid = iocb->ki_filp->private_data; 371b5ac1fb2SVincent Bernat int ret, err = 0; 372e1200fe6SAl Viro 373e494b6b5SAl Viro p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n", 374e494b6b5SAl Viro iov_iter_count(to), iocb->ki_pos); 375e69e7fe5SEric Van Hensbergen 37652cbee2aSSergey Alirzaev if (iocb->ki_filp->f_flags & O_NONBLOCK) 37752cbee2aSSergey Alirzaev ret = p9_client_read_once(fid, iocb->ki_pos, to, &err); 37852cbee2aSSergey Alirzaev else 379e494b6b5SAl Viro ret = p9_client_read(fid, iocb->ki_pos, to, &err); 380e1200fe6SAl Viro if (!ret) 381e1200fe6SAl Viro return err; 382fbedadc1SEric Van Hensbergen 383e494b6b5SAl Viro iocb->ki_pos += ret; 384bd238fb4SLatchesar Ionkov return ret; 385e69e7fe5SEric Van Hensbergen } 386e69e7fe5SEric Van Hensbergen 387e69e7fe5SEric Van Hensbergen /** 388bc868036SDavid Howells * v9fs_file_write_iter - write to a file 389bc868036SDavid Howells * @iocb: The operation parameters 390bc868036SDavid Howells * @from: The data to write 391e69e7fe5SEric Van Hensbergen * 392e69e7fe5SEric Van Hensbergen */ 393e69e7fe5SEric Van Hensbergen static ssize_t 394e494b6b5SAl Viro v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) 395e69e7fe5SEric Van Hensbergen { 396e494b6b5SAl Viro struct file *file = iocb->ki_filp; 3973309dd04SAl Viro ssize_t retval; 3983309dd04SAl Viro loff_t origin; 399c711a6b1SAl Viro int err = 0; 400e69e7fe5SEric Van Hensbergen 4013309dd04SAl Viro retval = generic_write_checks(iocb, from); 4023309dd04SAl Viro if (retval <= 0) 403c711a6b1SAl Viro return retval; 4043834b12aSHarsh Prateek Bora 4053309dd04SAl Viro origin = iocb->ki_pos; 4063309dd04SAl Viro retval = p9_client_write(file->private_data, iocb->ki_pos, from, &err); 407c711a6b1SAl Viro if (retval > 0) { 408e494b6b5SAl Viro struct inode *inode = file_inode(file); 409c711a6b1SAl Viro loff_t i_size; 410c711a6b1SAl Viro unsigned long pg_start, pg_end; 41109cbfeafSKirill A. Shutemov pg_start = origin >> PAGE_SHIFT; 41209cbfeafSKirill A. Shutemov pg_end = (origin + retval - 1) >> PAGE_SHIFT; 413c711a6b1SAl Viro if (inode->i_mapping && inode->i_mapping->nrpages) 414c711a6b1SAl Viro invalidate_inode_pages2_range(inode->i_mapping, 415c711a6b1SAl Viro pg_start, pg_end); 4163309dd04SAl Viro iocb->ki_pos += retval; 417c711a6b1SAl Viro i_size = i_size_read(inode); 4183309dd04SAl Viro if (iocb->ki_pos > i_size) { 4193309dd04SAl Viro inode_add_bytes(inode, iocb->ki_pos - i_size); 4205e3cc1eeSHou Tao /* 4215e3cc1eeSHou Tao * Need to serialize against i_size_write() in 4225e3cc1eeSHou Tao * v9fs_stat2inode() 4235e3cc1eeSHou Tao */ 4245e3cc1eeSHou Tao v9fs_i_size_write(inode, iocb->ki_pos); 425c711a6b1SAl Viro } 4263834b12aSHarsh Prateek Bora return retval; 427e69e7fe5SEric Van Hensbergen } 428c711a6b1SAl Viro return err; 429c711a6b1SAl Viro } 430e69e7fe5SEric Van Hensbergen 43102c24a82SJosef Bacik static int v9fs_file_fsync(struct file *filp, loff_t start, loff_t end, 43202c24a82SJosef Bacik int datasync) 4337a4439c4SM. Mohan Kumar { 4347a4439c4SM. Mohan Kumar struct p9_fid *fid; 43502c24a82SJosef Bacik struct inode *inode = filp->f_mapping->host; 4367a4439c4SM. Mohan Kumar struct p9_wstat wstat; 4377a4439c4SM. Mohan Kumar int retval; 4387a4439c4SM. Mohan Kumar 4393b49c9a1SJeff Layton retval = file_write_and_wait_range(filp, start, end); 44002c24a82SJosef Bacik if (retval) 44102c24a82SJosef Bacik return retval; 44202c24a82SJosef Bacik 4435955102cSAl Viro inode_lock(inode); 4445d385153SJoe Perches p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync); 4457a4439c4SM. Mohan Kumar 4467a4439c4SM. Mohan Kumar fid = filp->private_data; 4477a4439c4SM. Mohan Kumar v9fs_blank_wstat(&wstat); 4487a4439c4SM. Mohan Kumar 4497a4439c4SM. Mohan Kumar retval = p9_client_wstat(fid, &wstat); 4505955102cSAl Viro inode_unlock(inode); 45102c24a82SJosef Bacik 4527a4439c4SM. Mohan Kumar return retval; 4537a4439c4SM. Mohan Kumar } 4547a4439c4SM. Mohan Kumar 45502c24a82SJosef Bacik int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end, 45602c24a82SJosef Bacik int datasync) 457920e65dcSVenkateswararao Jujjuri (JV) { 458920e65dcSVenkateswararao Jujjuri (JV) struct p9_fid *fid; 45902c24a82SJosef Bacik struct inode *inode = filp->f_mapping->host; 460920e65dcSVenkateswararao Jujjuri (JV) int retval; 461920e65dcSVenkateswararao Jujjuri (JV) 4623b49c9a1SJeff Layton retval = file_write_and_wait_range(filp, start, end); 46302c24a82SJosef Bacik if (retval) 46402c24a82SJosef Bacik return retval; 46502c24a82SJosef Bacik 4665955102cSAl Viro inode_lock(inode); 4675d385153SJoe Perches p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync); 468920e65dcSVenkateswararao Jujjuri (JV) 469920e65dcSVenkateswararao Jujjuri (JV) fid = filp->private_data; 470920e65dcSVenkateswararao Jujjuri (JV) 471b165d601SVenkateswararao Jujjuri (JV) retval = p9_client_fsync(fid, datasync); 4725955102cSAl Viro inode_unlock(inode); 47302c24a82SJosef Bacik 474920e65dcSVenkateswararao Jujjuri (JV) return retval; 475920e65dcSVenkateswararao Jujjuri (JV) } 476920e65dcSVenkateswararao Jujjuri (JV) 4777263cebeSAneesh Kumar K.V static int 478fb89b45cSDominique Martinet v9fs_file_mmap(struct file *filp, struct vm_area_struct *vma) 4797263cebeSAneesh Kumar K.V { 4807263cebeSAneesh Kumar K.V int retval; 4817263cebeSAneesh Kumar K.V 482fb89b45cSDominique Martinet 483fb89b45cSDominique Martinet retval = generic_file_mmap(filp, vma); 4847263cebeSAneesh Kumar K.V if (!retval) 4857263cebeSAneesh Kumar K.V vma->vm_ops = &v9fs_file_vm_ops; 4867263cebeSAneesh Kumar K.V 4877263cebeSAneesh Kumar K.V return retval; 4887263cebeSAneesh Kumar K.V } 4897263cebeSAneesh Kumar K.V 4907263cebeSAneesh Kumar K.V static int 491fb89b45cSDominique Martinet v9fs_mmap_file_mmap(struct file *filp, struct vm_area_struct *vma) 492fb89b45cSDominique Martinet { 493fb89b45cSDominique Martinet int retval; 494fb89b45cSDominique Martinet struct inode *inode; 495fb89b45cSDominique Martinet struct v9fs_inode *v9inode; 496fb89b45cSDominique Martinet struct p9_fid *fid; 497fb89b45cSDominique Martinet 498fb89b45cSDominique Martinet inode = file_inode(filp); 499fb89b45cSDominique Martinet v9inode = V9FS_I(inode); 500fb89b45cSDominique Martinet mutex_lock(&v9inode->v_mutex); 501fb89b45cSDominique Martinet if (!v9inode->writeback_fid && 502c87a37ebSChengguang Xu (vma->vm_flags & VM_SHARED) && 503fb89b45cSDominique Martinet (vma->vm_flags & VM_WRITE)) { 504fb89b45cSDominique Martinet /* 505fb89b45cSDominique Martinet * clone a fid and add it to writeback_fid 506fb89b45cSDominique Martinet * we do it during mmap instead of 507fb89b45cSDominique Martinet * page dirty time via write_begin/page_mkwrite 508fb89b45cSDominique Martinet * because we want write after unlink usecase 509fb89b45cSDominique Martinet * to work. 510fb89b45cSDominique Martinet */ 511b403f0e3SMiklos Szeredi fid = v9fs_writeback_fid(file_dentry(filp)); 512fb89b45cSDominique Martinet if (IS_ERR(fid)) { 513fb89b45cSDominique Martinet retval = PTR_ERR(fid); 514fb89b45cSDominique Martinet mutex_unlock(&v9inode->v_mutex); 515fb89b45cSDominique Martinet return retval; 516fb89b45cSDominique Martinet } 517fb89b45cSDominique Martinet v9inode->writeback_fid = (void *) fid; 518fb89b45cSDominique Martinet } 519fb89b45cSDominique Martinet mutex_unlock(&v9inode->v_mutex); 520fb89b45cSDominique Martinet 521fb89b45cSDominique Martinet retval = generic_file_mmap(filp, vma); 522fb89b45cSDominique Martinet if (!retval) 523fb89b45cSDominique Martinet vma->vm_ops = &v9fs_mmap_file_vm_ops; 524fb89b45cSDominique Martinet 525fb89b45cSDominique Martinet return retval; 526fb89b45cSDominique Martinet } 527fb89b45cSDominique Martinet 528fe6340e2SSouptick Joarder static vm_fault_t 52911bac800SDave Jiang v9fs_vm_page_mkwrite(struct vm_fault *vmf) 5307263cebeSAneesh Kumar K.V { 5316b39f6d2SAneesh Kumar K.V struct v9fs_inode *v9inode; 5327263cebeSAneesh Kumar K.V struct page *page = vmf->page; 53311bac800SDave Jiang struct file *filp = vmf->vma->vm_file; 534496ad9aaSAl Viro struct inode *inode = file_inode(filp); 5357263cebeSAneesh Kumar K.V 5367263cebeSAneesh Kumar K.V 5375d385153SJoe Perches p9_debug(P9_DEBUG_VFS, "page %p fid %lx\n", 5387263cebeSAneesh Kumar K.V page, (unsigned long)filp->private_data); 5397263cebeSAneesh Kumar K.V 540*eb497943SDavid Howells v9inode = V9FS_I(inode); 541*eb497943SDavid Howells 542*eb497943SDavid Howells /* Wait for the page to be written to the cache before we allow it to 543*eb497943SDavid Howells * be modified. We then assume the entire page will need writing back. 544*eb497943SDavid Howells */ 545*eb497943SDavid Howells #ifdef CONFIG_9P_FSCACHE 546*eb497943SDavid Howells if (PageFsCache(page) && 547*eb497943SDavid Howells wait_on_page_fscache_killable(page) < 0) 548*eb497943SDavid Howells return VM_FAULT_RETRY; 549*eb497943SDavid Howells #endif 550*eb497943SDavid Howells 551120c2bcaSJan Kara /* Update file times before taking page lock */ 552120c2bcaSJan Kara file_update_time(filp); 553120c2bcaSJan Kara 5546b39f6d2SAneesh Kumar K.V BUG_ON(!v9inode->writeback_fid); 555*eb497943SDavid Howells if (lock_page_killable(page) < 0) 556*eb497943SDavid Howells return VM_FAULT_RETRY; 5577263cebeSAneesh Kumar K.V if (page->mapping != inode->i_mapping) 5587263cebeSAneesh Kumar K.V goto out_unlock; 55913575ca1SDarrick J. Wong wait_for_stable_page(page); 5607263cebeSAneesh Kumar K.V 5617263cebeSAneesh Kumar K.V return VM_FAULT_LOCKED; 5627263cebeSAneesh Kumar K.V out_unlock: 5637263cebeSAneesh Kumar K.V unlock_page(page); 5647263cebeSAneesh Kumar K.V return VM_FAULT_NOPAGE; 5657263cebeSAneesh Kumar K.V } 5667263cebeSAneesh Kumar K.V 567fb89b45cSDominique Martinet /** 568bc868036SDavid Howells * v9fs_mmap_file_read_iter - read from a file 569bc868036SDavid Howells * @iocb: The operation parameters 570bc868036SDavid Howells * @to: The buffer to read into 571fb89b45cSDominique Martinet * 572fb89b45cSDominique Martinet */ 573fb89b45cSDominique Martinet static ssize_t 574e494b6b5SAl Viro v9fs_mmap_file_read_iter(struct kiocb *iocb, struct iov_iter *to) 575fb89b45cSDominique Martinet { 576fb89b45cSDominique Martinet /* TODO: Check if there are dirty pages */ 577e494b6b5SAl Viro return v9fs_file_read_iter(iocb, to); 578fb89b45cSDominique Martinet } 579fb89b45cSDominique Martinet 580fb89b45cSDominique Martinet /** 581bc868036SDavid Howells * v9fs_mmap_file_write_iter - write to a file 582bc868036SDavid Howells * @iocb: The operation parameters 583bc868036SDavid Howells * @from: The data to write 584fb89b45cSDominique Martinet * 585fb89b45cSDominique Martinet */ 586fb89b45cSDominique Martinet static ssize_t 587e494b6b5SAl Viro v9fs_mmap_file_write_iter(struct kiocb *iocb, struct iov_iter *from) 588fb89b45cSDominique Martinet { 589fb89b45cSDominique Martinet /* 590fb89b45cSDominique Martinet * TODO: invalidate mmaps on filp's inode between 591fb89b45cSDominique Martinet * offset and offset+count 592fb89b45cSDominique Martinet */ 593e494b6b5SAl Viro return v9fs_file_write_iter(iocb, from); 594fb89b45cSDominique Martinet } 595fb89b45cSDominique Martinet 596fb89b45cSDominique Martinet static void v9fs_mmap_vm_close(struct vm_area_struct *vma) 597fb89b45cSDominique Martinet { 598fb89b45cSDominique Martinet struct inode *inode; 599fb89b45cSDominique Martinet 600fb89b45cSDominique Martinet struct writeback_control wbc = { 601fb89b45cSDominique Martinet .nr_to_write = LONG_MAX, 602fb89b45cSDominique Martinet .sync_mode = WB_SYNC_ALL, 603f5f7ab16SMatthew Wilcox (Oracle) .range_start = (loff_t)vma->vm_pgoff * PAGE_SIZE, 604fb89b45cSDominique Martinet /* absolute end, byte at end included */ 605f5f7ab16SMatthew Wilcox (Oracle) .range_end = (loff_t)vma->vm_pgoff * PAGE_SIZE + 606fb89b45cSDominique Martinet (vma->vm_end - vma->vm_start - 1), 607fb89b45cSDominique Martinet }; 608fb89b45cSDominique Martinet 609c87a37ebSChengguang Xu if (!(vma->vm_flags & VM_SHARED)) 610c87a37ebSChengguang Xu return; 611fb89b45cSDominique Martinet 612fb89b45cSDominique Martinet p9_debug(P9_DEBUG_VFS, "9p VMA close, %p, flushing", vma); 613fb89b45cSDominique Martinet 614fb89b45cSDominique Martinet inode = file_inode(vma->vm_file); 61525d23cd0SJosef Bacik filemap_fdatawrite_wbc(inode->i_mapping, &wbc); 616fb89b45cSDominique Martinet } 617fb89b45cSDominique Martinet 618fb89b45cSDominique Martinet 6197263cebeSAneesh Kumar K.V static const struct vm_operations_struct v9fs_file_vm_ops = { 6207263cebeSAneesh Kumar K.V .fault = filemap_fault, 621f1820361SKirill A. Shutemov .map_pages = filemap_map_pages, 6227263cebeSAneesh Kumar K.V .page_mkwrite = v9fs_vm_page_mkwrite, 6237263cebeSAneesh Kumar K.V }; 6247263cebeSAneesh Kumar K.V 625fb89b45cSDominique Martinet static const struct vm_operations_struct v9fs_mmap_file_vm_ops = { 626fb89b45cSDominique Martinet .close = v9fs_mmap_vm_close, 627fb89b45cSDominique Martinet .fault = filemap_fault, 628f1820361SKirill A. Shutemov .map_pages = filemap_map_pages, 629fb89b45cSDominique Martinet .page_mkwrite = v9fs_vm_page_mkwrite, 630fb89b45cSDominique Martinet }; 631fb89b45cSDominique Martinet 632e959b549SAneesh Kumar K.V 63329236f4eSAneesh Kumar K.V const struct file_operations v9fs_cached_file_operations = { 634e03abc0cSEric Van Hensbergen .llseek = generic_file_llseek, 635aad4f8bbSAl Viro .read_iter = generic_file_read_iter, 6368174202bSAl Viro .write_iter = generic_file_write_iter, 637e03abc0cSEric Van Hensbergen .open = v9fs_file_open, 638e03abc0cSEric Van Hensbergen .release = v9fs_dir_release, 639e03abc0cSEric Van Hensbergen .lock = v9fs_file_lock, 6407263cebeSAneesh Kumar K.V .mmap = v9fs_file_mmap, 641cf03f316SToke Høiland-Jørgensen .splice_read = generic_file_splice_read, 642960f4f8aSDominique Martinet .splice_write = iter_file_splice_write, 6437a4439c4SM. Mohan Kumar .fsync = v9fs_file_fsync, 644e03abc0cSEric Van Hensbergen }; 645e03abc0cSEric Van Hensbergen 64629236f4eSAneesh Kumar K.V const struct file_operations v9fs_cached_file_operations_dotl = { 647b04faaf3SVenkateswararao Jujjuri (JV) .llseek = generic_file_llseek, 648aad4f8bbSAl Viro .read_iter = generic_file_read_iter, 6498174202bSAl Viro .write_iter = generic_file_write_iter, 650b04faaf3SVenkateswararao Jujjuri (JV) .open = v9fs_file_open, 651b04faaf3SVenkateswararao Jujjuri (JV) .release = v9fs_dir_release, 652a099027cSM. Mohan Kumar .lock = v9fs_file_lock_dotl, 653a099027cSM. Mohan Kumar .flock = v9fs_file_flock_dotl, 6547263cebeSAneesh Kumar K.V .mmap = v9fs_file_mmap, 655cf03f316SToke Høiland-Jørgensen .splice_read = generic_file_splice_read, 656960f4f8aSDominique Martinet .splice_write = iter_file_splice_write, 657920e65dcSVenkateswararao Jujjuri (JV) .fsync = v9fs_file_fsync_dotl, 658b04faaf3SVenkateswararao Jujjuri (JV) }; 659b04faaf3SVenkateswararao Jujjuri (JV) 6604b6f5d20SArjan van de Ven const struct file_operations v9fs_file_operations = { 661e69e7fe5SEric Van Hensbergen .llseek = generic_file_llseek, 662e494b6b5SAl Viro .read_iter = v9fs_file_read_iter, 663e494b6b5SAl Viro .write_iter = v9fs_file_write_iter, 664e69e7fe5SEric Van Hensbergen .open = v9fs_file_open, 665e69e7fe5SEric Van Hensbergen .release = v9fs_dir_release, 666e69e7fe5SEric Van Hensbergen .lock = v9fs_file_lock, 66714b8869fSEric Van Hensbergen .mmap = generic_file_readonly_mmap, 668cf03f316SToke Høiland-Jørgensen .splice_read = generic_file_splice_read, 669960f4f8aSDominique Martinet .splice_write = iter_file_splice_write, 6707a4439c4SM. Mohan Kumar .fsync = v9fs_file_fsync, 671e69e7fe5SEric Van Hensbergen }; 6729b6533c9SSripathi Kodi 6739b6533c9SSripathi Kodi const struct file_operations v9fs_file_operations_dotl = { 6749b6533c9SSripathi Kodi .llseek = generic_file_llseek, 675e494b6b5SAl Viro .read_iter = v9fs_file_read_iter, 676e494b6b5SAl Viro .write_iter = v9fs_file_write_iter, 6779b6533c9SSripathi Kodi .open = v9fs_file_open, 6789b6533c9SSripathi Kodi .release = v9fs_dir_release, 679a099027cSM. Mohan Kumar .lock = v9fs_file_lock_dotl, 680a099027cSM. Mohan Kumar .flock = v9fs_file_flock_dotl, 6819b6533c9SSripathi Kodi .mmap = generic_file_readonly_mmap, 682cf03f316SToke Høiland-Jørgensen .splice_read = generic_file_splice_read, 683960f4f8aSDominique Martinet .splice_write = iter_file_splice_write, 684920e65dcSVenkateswararao Jujjuri (JV) .fsync = v9fs_file_fsync_dotl, 6859b6533c9SSripathi Kodi }; 686fb89b45cSDominique Martinet 687fb89b45cSDominique Martinet const struct file_operations v9fs_mmap_file_operations = { 688fb89b45cSDominique Martinet .llseek = generic_file_llseek, 689e494b6b5SAl Viro .read_iter = v9fs_mmap_file_read_iter, 690e494b6b5SAl Viro .write_iter = v9fs_mmap_file_write_iter, 691fb89b45cSDominique Martinet .open = v9fs_file_open, 692fb89b45cSDominique Martinet .release = v9fs_dir_release, 693fb89b45cSDominique Martinet .lock = v9fs_file_lock, 694fb89b45cSDominique Martinet .mmap = v9fs_mmap_file_mmap, 695cf03f316SToke Høiland-Jørgensen .splice_read = generic_file_splice_read, 696960f4f8aSDominique Martinet .splice_write = iter_file_splice_write, 697fb89b45cSDominique Martinet .fsync = v9fs_file_fsync, 698fb89b45cSDominique Martinet }; 699fb89b45cSDominique Martinet 700fb89b45cSDominique Martinet const struct file_operations v9fs_mmap_file_operations_dotl = { 701fb89b45cSDominique Martinet .llseek = generic_file_llseek, 702e494b6b5SAl Viro .read_iter = v9fs_mmap_file_read_iter, 703e494b6b5SAl Viro .write_iter = v9fs_mmap_file_write_iter, 704fb89b45cSDominique Martinet .open = v9fs_file_open, 705fb89b45cSDominique Martinet .release = v9fs_dir_release, 706fb89b45cSDominique Martinet .lock = v9fs_file_lock_dotl, 707fb89b45cSDominique Martinet .flock = v9fs_file_flock_dotl, 708fb89b45cSDominique Martinet .mmap = v9fs_mmap_file_mmap, 709cf03f316SToke Høiland-Jørgensen .splice_read = generic_file_splice_read, 710960f4f8aSDominique Martinet .splice_write = iter_file_splice_write, 711fb89b45cSDominique Martinet .fsync = v9fs_file_fsync_dotl, 712fb89b45cSDominique Martinet }; 713