Print this page
3484 enhance and document tail follow support
Reviewed by: Joshua M. Clulow <jmc@joyent.com>


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 



  26 
  27 /*
  28  * File Events Notification
  29  * ------------------------
  30  *
  31  * The File Events Notification facility provides file and directory change
  32  * notification. It is implemented as an event source(PORT_SOURCE_FILE)
  33  * under the Event Ports framework. Therefore the API is an extension to
  34  * the Event Ports API.
  35  *
  36  * It uses the FEM (File Events Monitoring) framework to intercept
  37  * operations on the files & directories and generate appropriate events.
  38  *
  39  * It provides event notification in accordance with what an application
  40  * can find out by stat`ing the file and comparing time stamps. The various
  41  * system calls that update the file's access, modification, and change
  42  * time stamps are documented in the man page section 2.
  43  *
  44  * It is non intrusive. That is, having an active file event watch on a file
  45  * or directory will not prevent it from being removed or renamed or block an


1948 {
1949         int event = 0;
1950         /*
1951          * deliver events only if the operation was successful.
1952          */
1953         if (retval)
1954                 return;
1955 
1956         /*
1957          * These events occurring on the watched file.
1958          */
1959         if (op & FOP_MODIFIED_MASK) {
1960                 event  = FILE_MODIFIED;
1961         }
1962         if (op & FOP_ACCESS_MASK) {
1963                 event  |= FILE_ACCESS;
1964         }
1965         if (op & FOP_ATTRIB_MASK) {
1966                 event  |= FILE_ATTRIB;
1967         }
1968 


1969         if (event) {
1970                 port_fop_sendevent(vp,  event, NULL, NULL);
1971         }
1972 }
1973 
1974 static int port_forceunmount(vfs_t *vfsp)
1975 {
1976         char *fsname = vfssw[vfsp->vfs_fstype].vsw_name;
1977 
1978         if (fsname == NULL) {
1979                 return (0);
1980         }
1981 
1982         if (strcmp(fsname, MNTTYPE_NFS) == 0) {
1983                 return (1);
1984         }
1985 
1986         if (strcmp(fsname, MNTTYPE_NFS3) == 0) {
1987                 return (1);
1988         }


2130         vnode_t         *vp = (vnode_t *)vf->fa_fnode->fn_available;
2131 
2132         retval =  vnext_read(vf, uiop, ioflag, cr, ct);
2133         port_fop(vp, FOP_FILE_READ, retval);
2134         return (retval);
2135 }
2136 
2137 
2138 /*
2139  * AT_SIZE - is for the open(O_TRUNC) case.
2140  */
2141 int
2142 port_fop_setattr(femarg_t *vf, vattr_t *vap, int flags, cred_t *cr,
2143     caller_context_t *ct)
2144 {
2145         int             retval;
2146         vnode_t         *vp = (vnode_t *)vf->fa_fnode->fn_available;
2147         int             events = 0;
2148 
2149         retval = vnext_setattr(vf, vap, flags, cr, ct);



2150         if (vap->va_mask & (AT_SIZE|AT_MTIME)) {
2151                 events |= FOP_FILE_SETATTR_MTIME;
2152         }
2153         if (vap->va_mask & AT_ATIME) {
2154                 events |= FOP_FILE_SETATTR_ATIME;
2155         }
2156         events |= FOP_FILE_SETATTR_CTIME;
2157 
2158         port_fop(vp, events, retval);
2159         return (retval);
2160 }
2161 
2162 int
2163 port_fop_create(femarg_t *vf, char *name, vattr_t *vap, vcexcl_t excl,
2164     int mode, vnode_t **vpp, cred_t *cr, int flag,
2165     caller_context_t *ct, vsecattr_t *vsecp)
2166 {
2167         int             retval, got = 1;
2168         vnode_t         *vp = (vnode_t *)vf->fa_fnode->fn_available;
2169         vattr_t         vatt, vatt1;


2305 int
2306 port_fop_vnevent(femarg_t *vf, vnevent_t vnevent, vnode_t *dvp, char *name,
2307     caller_context_t *ct)
2308 {
2309         vnode_t         *vp = (vnode_t *)vf->fa_fnode->fn_available;
2310 
2311         switch (vnevent) {
2312         case    VE_RENAME_SRC:
2313                         port_fop_sendevent(vp, FILE_RENAME_FROM, dvp, name);
2314                 break;
2315         case    VE_RENAME_DEST:
2316                         port_fop_sendevent(vp, FILE_RENAME_TO, dvp, name);
2317                 break;
2318         case    VE_REMOVE:
2319                         port_fop_sendevent(vp, FILE_DELETE, dvp, name);
2320                 break;
2321         case    VE_RMDIR:
2322                         port_fop_sendevent(vp, FILE_DELETE, dvp, name);
2323                 break;
2324         case    VE_CREATE:
2325                         port_fop_sendevent(vp, FILE_MODIFIED|FILE_ATTRIB,
2326                             NULL, NULL);
2327                 break;
2328         case    VE_LINK:
2329                         port_fop_sendevent(vp, FILE_ATTRIB, NULL, NULL);
2330                 break;
2331 
2332         case    VE_RENAME_DEST_DIR:
2333                         port_fop_sendevent(vp, FILE_MODIFIED|FILE_ATTRIB,
2334                             NULL, NULL);
2335                 break;
2336 
2337         case    VE_MOUNTEDOVER:
2338                         port_fop_sendevent(vp, MOUNTEDOVER, NULL, NULL);
2339                 break;
2340         default:
2341                 break;
2342         }
2343         return (vnext_vnevent(vf, vnevent, dvp, name, ct));
2344 }


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*
  27  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  28  */
  29 
  30 /*
  31  * File Events Notification
  32  * ------------------------
  33  *
  34  * The File Events Notification facility provides file and directory change
  35  * notification. It is implemented as an event source(PORT_SOURCE_FILE)
  36  * under the Event Ports framework. Therefore the API is an extension to
  37  * the Event Ports API.
  38  *
  39  * It uses the FEM (File Events Monitoring) framework to intercept
  40  * operations on the files & directories and generate appropriate events.
  41  *
  42  * It provides event notification in accordance with what an application
  43  * can find out by stat`ing the file and comparing time stamps. The various
  44  * system calls that update the file's access, modification, and change
  45  * time stamps are documented in the man page section 2.
  46  *
  47  * It is non intrusive. That is, having an active file event watch on a file
  48  * or directory will not prevent it from being removed or renamed or block an


1951 {
1952         int event = 0;
1953         /*
1954          * deliver events only if the operation was successful.
1955          */
1956         if (retval)
1957                 return;
1958 
1959         /*
1960          * These events occurring on the watched file.
1961          */
1962         if (op & FOP_MODIFIED_MASK) {
1963                 event  = FILE_MODIFIED;
1964         }
1965         if (op & FOP_ACCESS_MASK) {
1966                 event  |= FILE_ACCESS;
1967         }
1968         if (op & FOP_ATTRIB_MASK) {
1969                 event  |= FILE_ATTRIB;
1970         }
1971         if (op & FOP_TRUNC_MASK) {
1972                 event  |= FILE_TRUNC;
1973         }
1974         if (event) {
1975                 port_fop_sendevent(vp,  event, NULL, NULL);
1976         }
1977 }
1978 
1979 static int port_forceunmount(vfs_t *vfsp)
1980 {
1981         char *fsname = vfssw[vfsp->vfs_fstype].vsw_name;
1982 
1983         if (fsname == NULL) {
1984                 return (0);
1985         }
1986 
1987         if (strcmp(fsname, MNTTYPE_NFS) == 0) {
1988                 return (1);
1989         }
1990 
1991         if (strcmp(fsname, MNTTYPE_NFS3) == 0) {
1992                 return (1);
1993         }


2135         vnode_t         *vp = (vnode_t *)vf->fa_fnode->fn_available;
2136 
2137         retval =  vnext_read(vf, uiop, ioflag, cr, ct);
2138         port_fop(vp, FOP_FILE_READ, retval);
2139         return (retval);
2140 }
2141 
2142 
2143 /*
2144  * AT_SIZE - is for the open(O_TRUNC) case.
2145  */
2146 int
2147 port_fop_setattr(femarg_t *vf, vattr_t *vap, int flags, cred_t *cr,
2148     caller_context_t *ct)
2149 {
2150         int             retval;
2151         vnode_t         *vp = (vnode_t *)vf->fa_fnode->fn_available;
2152         int             events = 0;
2153 
2154         retval = vnext_setattr(vf, vap, flags, cr, ct);
2155         if (vap->va_mask & AT_SIZE) {
2156                 events |= FOP_FILE_TRUNC;
2157         }
2158         if (vap->va_mask & (AT_SIZE|AT_MTIME)) {
2159                 events |= FOP_FILE_SETATTR_MTIME;
2160         }
2161         if (vap->va_mask & AT_ATIME) {
2162                 events |= FOP_FILE_SETATTR_ATIME;
2163         }
2164         events |= FOP_FILE_SETATTR_CTIME;
2165 
2166         port_fop(vp, events, retval);
2167         return (retval);
2168 }
2169 
2170 int
2171 port_fop_create(femarg_t *vf, char *name, vattr_t *vap, vcexcl_t excl,
2172     int mode, vnode_t **vpp, cred_t *cr, int flag,
2173     caller_context_t *ct, vsecattr_t *vsecp)
2174 {
2175         int             retval, got = 1;
2176         vnode_t         *vp = (vnode_t *)vf->fa_fnode->fn_available;
2177         vattr_t         vatt, vatt1;


2313 int
2314 port_fop_vnevent(femarg_t *vf, vnevent_t vnevent, vnode_t *dvp, char *name,
2315     caller_context_t *ct)
2316 {
2317         vnode_t         *vp = (vnode_t *)vf->fa_fnode->fn_available;
2318 
2319         switch (vnevent) {
2320         case    VE_RENAME_SRC:
2321                         port_fop_sendevent(vp, FILE_RENAME_FROM, dvp, name);
2322                 break;
2323         case    VE_RENAME_DEST:
2324                         port_fop_sendevent(vp, FILE_RENAME_TO, dvp, name);
2325                 break;
2326         case    VE_REMOVE:
2327                         port_fop_sendevent(vp, FILE_DELETE, dvp, name);
2328                 break;
2329         case    VE_RMDIR:
2330                         port_fop_sendevent(vp, FILE_DELETE, dvp, name);
2331                 break;
2332         case    VE_CREATE:
2333                         port_fop_sendevent(vp,
2334                             FILE_MODIFIED|FILE_ATTRIB|FILE_TRUNC, NULL, NULL);
2335                 break;
2336         case    VE_LINK:
2337                         port_fop_sendevent(vp, FILE_ATTRIB, NULL, NULL);
2338                 break;
2339 
2340         case    VE_RENAME_DEST_DIR:
2341                         port_fop_sendevent(vp, FILE_MODIFIED|FILE_ATTRIB,
2342                             NULL, NULL);
2343                 break;
2344 
2345         case    VE_MOUNTEDOVER:
2346                         port_fop_sendevent(vp, MOUNTEDOVER, NULL, NULL);
2347                 break;
2348         default:
2349                 break;
2350         }
2351         return (vnext_vnevent(vf, vnevent, dvp, name, ct));
2352 }